[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CSTFS80EFXSTJ9KED339H6":3,"skill-same:01M6CSTFS80EFXSTJ9KED339H6":82},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":48,"repositoryHtmlUrl":49,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6CSTFS80EFXSTJ9KED339H6","defi-protocol-templates",null,"Implement DeFi protocols with production-ready templates for staking, AMMs, governance, and lending systems. Use when building decentralized finance applications or smart contract protocols.","Sam-06060\u002Fjarvis-assistant","Sam-06060","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F208600848?v=4","01M6CRKT7C7FXD21V6HXF293S0","Samson Frank Ganta","01M6CRKTBEKYFD8YX5Z1GT99EE",6,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fdefi-protocol-templates\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37],"protocol","defi","templates","defi protocol templates","implement","governance","finance","lending","protocols","Production","applications","use","ready","community","2026-11-10 10:12:30",false,"---\nname: defi-protocol-templates\ndescription: \"Implement DeFi protocols with production-ready templates for staking, AMMs, governance, and lending systems. Use when building decentralized finance applications or smart contract protocols.\"\nrisk: unknown\nsource: community\ndate_added: \"2026-02-27\"\n---\n\n# DeFi Protocol Templates\n\nProduction-ready templates for common DeFi protocols including staking, AMMs, governance, lending, and flash loans.\n\n## Do not use this skill when\n\n- The task is unrelated to defi protocol templates\n- You need a different domain or tool outside this scope\n\n## Instructions\n\n- Clarify goals, constraints, and required inputs.\n- Apply relevant best practices and validate outcomes.\n- Provide actionable steps and verification.\n- If detailed examples are required, open `resources\u002Fimplementation-playbook.md`.\n\n## Use this skill when\n\n- Building staking platforms with reward distribution\n- Implementing AMM (Automated Market Maker) protocols\n- Creating governance token systems\n- Developing lending\u002Fborrowing protocols\n- Integrating flash loan functionality\n- Launching yield farming platforms\n\n## Staking Contract\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Fsecurity\u002FReentrancyGuard.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Faccess\u002FOwnable.sol\";\n\ncontract StakingRewards is ReentrancyGuard, Ownable {\n    IERC20 public stakingToken;\n    IERC20 public rewardsToken;\n\n    uint256 public rewardRate = 100; \u002F\u002F Rewards per second\n    uint256 public lastUpdateTime;\n    uint256 public rewardPerTokenStored;\n\n    mapping(address => uint256) public userRewardPerTokenPaid;\n    mapping(address => uint256) public rewards;\n    mapping(address => uint256) public balances;\n\n    uint256 private _totalSupply;\n\n    event Staked(address indexed user, uint256 amount);\n    event Withdrawn(address indexed user, uint256 amount);\n    event RewardPaid(address indexed user, uint256 reward);\n\n    constructor(address _stakingToken, address _rewardsToken) {\n        stakingToken = IERC20(_stakingToken);\n        rewardsToken = IERC20(_rewardsToken);\n    }\n\n    modifier updateReward(address account) {\n        rewardPerTokenStored = rewardPerToken();\n        lastUpdateTime = block.timestamp;\n\n        if (account != address(0)) {\n            rewards[account] = earned(account);\n            userRewardPerTokenPaid[account] = rewardPerTokenStored;\n        }\n        _;\n    }\n\n    function rewardPerToken() public view returns (uint256) {\n        if (_totalSupply == 0) {\n            return rewardPerTokenStored;\n        }\n        return rewardPerTokenStored +\n            ((block.timestamp - lastUpdateTime) * rewardRate * 1e18) \u002F _totalSupply;\n    }\n\n    function earned(address account) public view returns (uint256) {\n        return (balances[account] *\n            (rewardPerToken() - userRewardPerTokenPaid[account])) \u002F 1e18 +\n            rewards[account];\n    }\n\n    function stake(uint256 amount) external nonReentrant updateReward(msg.sender) {\n        require(amount > 0, \"Cannot stake 0\");\n        _totalSupply += amount;\n        balances[msg.sender] += amount;\n        stakingToken.transferFrom(msg.sender, address(this), amount);\n        emit Staked(msg.sender, amount);\n    }\n\n    function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) {\n        require(amount > 0, \"Cannot withdraw 0\");\n        _totalSupply -= amount;\n        balances[msg.sender] -= amount;\n        stakingToken.transfer(msg.sender, amount);\n        emit Withdrawn(msg.sender, amount);\n    }\n\n    function getReward() public nonReentrant updateReward(msg.sender) {\n        uint256 reward = rewards[msg.sender];\n        if (reward > 0) {\n            rewards[msg.sender] = 0;\n            rewardsToken.transfer(msg.sender, reward);\n            emit RewardPaid(msg.sender, reward);\n        }\n    }\n\n    function exit() external {\n        withdraw(balances[msg.sender]);\n        getReward();\n    }\n}\n```\n\n## AMM (Automated Market Maker)\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\n\ncontract SimpleAMM {\n    IERC20 public token0;\n    IERC20 public token1;\n\n    uint256 public reserve0;\n    uint256 public reserve1;\n\n    uint256 public totalSupply;\n    mapping(address => uint256) public balanceOf;\n\n    event Mint(address indexed to, uint256 amount);\n    event Burn(address indexed from, uint256 amount);\n    event Swap(address indexed trader, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out);\n\n    constructor(address _token0, address _token1) {\n        token0 = IERC20(_token0);\n        token1 = IERC20(_token1);\n    }\n\n    function addLiquidity(uint256 amount0, uint256 amount1) external returns (uint256 shares) {\n        token0.transferFrom(msg.sender, address(this), amount0);\n        token1.transferFrom(msg.sender, address(this), amount1);\n\n        if (totalSupply == 0) {\n            shares = sqrt(amount0 * amount1);\n        } else {\n            shares = min(\n                (amount0 * totalSupply) \u002F reserve0,\n                (amount1 * totalSupply) \u002F reserve1\n            );\n        }\n\n        require(shares > 0, \"Shares = 0\");\n        _mint(msg.sender, shares);\n        _update(\n            token0.balanceOf(address(this)),\n            token1.balanceOf(address(this))\n        );\n\n        emit Mint(msg.sender, shares);\n    }\n\n    function removeLiquidity(uint256 shares) external returns (uint256 amount0, uint256 amount1) {\n        uint256 bal0 = token0.balanceOf(address(this));\n        uint256 bal1 = token1.balanceOf(address(this));\n\n        amount0 = (shares * bal0) \u002F totalSupply;\n        amount1 = (shares * bal1) \u002F totalSupply;\n\n        require(amount0 > 0 && amount1 > 0, \"Amount0 or amount1 = 0\");\n\n        _burn(msg.sender, shares);\n        _update(bal0 - amount0, bal1 - amount1);\n\n        token0.transfer(msg.sender, amount0);\n        token1.transfer(msg.sender, amount1);\n\n        emit Burn(msg.sender, shares);\n    }\n\n    function swap(address tokenIn, uint256 amountIn) external returns (uint256 amountOut) {\n        require(tokenIn == address(token0) || tokenIn == address(token1), \"Invalid token\");\n\n        bool isToken0 = tokenIn == address(token0);\n        (IERC20 tokenIn_, IERC20 tokenOut, uint256 resIn, uint256 resOut) = isToken0\n            ? (token0, token1, reserve0, reserve1)\n            : (token1, token0, reserve1, reserve0);\n\n        tokenIn_.transferFrom(msg.sender, address(this), amountIn);\n\n        \u002F\u002F 0.3% fee\n        uint256 amountInWithFee = (amountIn * 997) \u002F 1000;\n        amountOut = (resOut * amountInWithFee) \u002F (resIn + amountInWithFee);\n\n        tokenOut.transfer(msg.sender, amountOut);\n\n        _update(\n            token0.balanceOf(address(this)),\n            token1.balanceOf(address(this))\n        );\n\n        emit Swap(msg.sender, isToken0 ? amountIn : 0, isToken0 ? 0 : amountIn, isToken0 ? 0 : amountOut, isToken0 ? amountOut : 0);\n    }\n\n    function _mint(address to, uint256 amount) private {\n        balanceOf[to] += amount;\n        totalSupply += amount;\n    }\n\n    function _burn(address from, uint256 amount) private {\n        balanceOf[from] -= amount;\n        totalSupply -= amount;\n    }\n\n    function _update(uint256 res0, uint256 res1) private {\n        reserve0 = res0;\n        reserve1 = res1;\n    }\n\n    function sqrt(uint256 y) private pure returns (uint256 z) {\n        if (y > 3) {\n            z = y;\n            uint256 x = y \u002F 2 + 1;\n            while (x \u003C z) {\n                z = x;\n                x = (y \u002F x + x) \u002F 2;\n            }\n        } else if (y != 0) {\n            z = 1;\n        }\n    }\n\n    function min(uint256 x, uint256 y) private pure returns (uint256) {\n        return x \u003C= y ? x : y;\n    }\n}\n```\n\n## Governance Token\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002Fextensions\u002FERC20Votes.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Faccess\u002FOwnable.sol\";\n\ncontract GovernanceToken is ERC20Votes, Ownable {\n    constructor() ERC20(\"Governance Token\", \"GOV\") ERC20Permit(\"Governance Token\") {\n        _mint(msg.sender, 1000000 * 10**decimals());\n    }\n\n    function _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal override(ERC20Votes) {\n        super._afterTokenTransfer(from, to, amount);\n    }\n\n    function _mint(address to, uint256 amount) internal override(ERC20Votes) {\n        super._mint(to, amount);\n    }\n\n    function _burn(address account, uint256 amount) internal override(ERC20Votes) {\n        super._burn(account, amount);\n    }\n}\n\ncontract Governor is Ownable {\n    GovernanceToken public governanceToken;\n\n    struct Proposal {\n        uint256 id;\n        address proposer;\n        string description;\n        uint256 forVotes;\n        uint256 againstVotes;\n        uint256 startBlock;\n        uint256 endBlock;\n        bool executed;\n        mapping(address => bool) hasVoted;\n    }\n\n    uint256 public proposalCount;\n    mapping(uint256 => Proposal) public proposals;\n\n    uint256 public votingPeriod = 17280; \u002F\u002F ~3 days in blocks\n    uint256 public proposalThreshold = 100000 * 10**18;\n\n    event ProposalCreated(uint256 indexed proposalId, address proposer, string description);\n    event VoteCast(address indexed voter, uint256 indexed proposalId, bool support, uint256 weight);\n    event ProposalExecuted(uint256 indexed proposalId);\n\n    constructor(address _governanceToken) {\n        governanceToken = GovernanceToken(_governanceToken);\n    }\n\n    function propose(string memory description) external returns (uint256) {\n        require(\n            governanceToken.getPastVotes(msg.sender, block.number - 1) >= proposalThreshold,\n            \"Proposer votes below threshold\"\n        );\n\n        proposalCount++;\n        Proposal storage newProposal = proposals[proposalCount];\n        newProposal.id = proposalCount;\n        newProposal.proposer = msg.sender;\n        newProposal.description = description;\n        newProposal.startBlock = block.number;\n        newProposal.endBlock = block.number + votingPeriod;\n\n        emit ProposalCreated(proposalCount, msg.sender, description);\n        return proposalCount;\n    }\n\n    function vote(uint256 proposalId, bool support) external {\n        Proposal storage proposal = proposals[proposalId];\n        require(block.number >= proposal.startBlock, \"Voting not started\");\n        require(block.number \u003C= proposal.endBlock, \"Voting ended\");\n        require(!proposal.hasVoted[msg.sender], \"Already voted\");\n\n        uint256 weight = governanceToken.getPastVotes(msg.sender, proposal.startBlock);\n        require(weight > 0, \"No voting power\");\n\n        proposal.hasVoted[msg.sender] = true;\n\n        if (support) {\n            proposal.forVotes += weight;\n        } else {\n            proposal.againstVotes += weight;\n        }\n\n        emit VoteCast(msg.sender, proposalId, support, weight);\n    }\n\n    function execute(uint256 proposalId) external {\n        Proposal storage proposal = proposals[proposalId];\n        require(block.number > proposal.endBlock, \"Voting not ended\");\n        require(!proposal.executed, \"Already executed\");\n        require(proposal.forVotes > proposal.againstVotes, \"Proposal failed\");\n\n        proposal.executed = true;\n\n        \u002F\u002F Execute proposal logic here\n\n        emit ProposalExecuted(proposalId);\n    }\n}\n```\n\n## Flash Loan\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\n\ninterface IFlashLoanReceiver {\n    function executeOperation(\n        address asset,\n        uint256 amount,\n        uint256 fee,\n        bytes calldata params\n    ) external returns (bool);\n}\n\ncontract FlashLoanProvider {\n    IERC20 public token;\n    uint256 public feePercentage = 9; \u002F\u002F 0.09% fee\n\n    event FlashLoan(address indexed borrower, uint256 amount, uint256 fee);\n\n    constructor(address _token) {\n        token = IERC20(_token);\n    }\n\n    function flashLoan(\n        address receiver,\n        uint256 amount,\n        bytes calldata params\n    ) external {\n        uint256 balanceBefore = token.balanceOf(address(this));\n        require(balanceBefore >= amount, \"Insufficient liquidity\");\n\n        uint256 fee = (amount * feePercentage) \u002F 10000;\n\n        \u002F\u002F Send tokens to receiver\n        token.transfer(receiver, amount);\n\n        \u002F\u002F Execute callback\n        require(\n            IFlashLoanReceiver(receiver).executeOperation(\n                address(token),\n                amount,\n                fee,\n                params\n            ),\n            \"Flash loan failed\"\n        );\n\n        \u002F\u002F Verify repayment\n        uint256 balanceAfter = token.balanceOf(address(this));\n        require(balanceAfter >= balanceBefore + fee, \"Flash loan not repaid\");\n\n        emit FlashLoan(receiver, amount, fee);\n    }\n}\n\n\u002F\u002F Example flash loan receiver\ncontract FlashLoanReceiver is IFlashLoanReceiver {\n    function executeOperation(\n        address asset,\n        uint256 amount,\n        uint256 fee,\n        bytes calldata params\n    ) external override returns (bool) {\n        \u002F\u002F Decode params and execute arbitrage, liquidation, etc.\n        \u002F\u002F ...\n\n        \u002F\u002F Approve repayment\n        IERC20(asset).approve(msg.sender, amount + fee);\n\n        return true;\n    }\n}\n```\n\n## Resources\n\n- **references\u002Fstaking.md**: Staking mechanics and reward distribution\n- **references\u002Fliquidity-pools.md**: AMM mathematics and pricing\n- **references\u002Fgovernance-tokens.md**: Governance and voting systems\n- **references\u002Flending-protocols.md**: Lending\u002Fborrowing implementation\n- **references\u002Fflash-loans.md**: Flash loan security and use cases\n- **assets\u002Fstaking-contract.sol**: Production staking template\n- **assets\u002Famm-contract.sol**: Full AMM implementation\n- **assets\u002Fgovernance-token.sol**: Governance system\n- **assets\u002Flending-protocol.sol**: Lending platform template\n\n## Best Practices\n\n1. **Use Established Libraries**: OpenZeppelin, Solmate\n2. **Test Thoroughly**: Unit tests, integration tests, fuzzing\n3. **Audit Before Launch**: Professional security audits\n4. **Start Simple**: MVP first, add features incrementally\n5. **Monitor**: Track contract health and user activity\n6. **Upgradability**: Consider proxy patterns for upgrades\n7. **Emergency Controls**: Pause mechanisms for critical issues\n\n## Common DeFi Patterns\n\n- **Time-Weighted Average Price (TWAP)**: Price oracle resistance\n- **Liquidity Mining**: Incentivize liquidity provision\n- **Vesting**: Lock tokens with gradual release\n- **Multisig**: Require multiple signatures for critical operations\n- **Timelocks**: Delay execution of governance decisions\n","# DeFi Protocol Templates\n\nProduction-ready templates for common DeFi protocols including staking, AMMs, governance, lending, and flash loans.\n\n## Do not use this skill when\n\n- The task is unrelated to defi protocol templates\n- You need a different domain or tool outside this scope\n\n## Instructions\n\n- Clarify goals, constraints, and required inputs.\n- Apply relevant best practices and validate outcomes.\n- Provide actionable steps and verification.\n- If detailed examples are required, open `resources\u002Fimplementation-playbook.md`.\n\n## Use this skill when\n\n- Building staking platforms with reward distribution\n- Implementing AMM (Automated Market Maker) protocols\n- Creating governance token systems\n- Developing lending\u002Fborrowing protocols\n- Integrating flash loan functionality\n- Launching yield farming platforms\n\n## Staking Contract\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Fsecurity\u002FReentrancyGuard.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Faccess\u002FOwnable.sol\";\n\ncontract StakingRewards is ReentrancyGuard, Ownable {\n    IERC20 public stakingToken;\n    IERC20 public rewardsToken;\n\n    uint256 public rewardRate = 100; \u002F\u002F Rewards per second\n    uint256 public lastUpdateTime;\n    uint256 public rewardPerTokenStored;\n\n    mapping(address => uint256) public userRewardPerTokenPaid;\n    mapping(address => uint256) public rewards;\n    mapping(address => uint256) public balances;\n\n    uint256 private _totalSupply;\n\n    event Staked(address indexed user, uint256 amount);\n    event Withdrawn(address indexed user, uint256 amount);\n    event RewardPaid(address indexed user, uint256 reward);\n\n    constructor(address _stakingToken, address _rewardsToken) {\n        stakingToken = IERC20(_stakingToken);\n        rewardsToken = IERC20(_rewardsToken);\n    }\n\n    modifier updateReward(address account) {\n        rewardPerTokenStored = rewardPerToken();\n        lastUpdateTime = block.timestamp;\n\n        if (account != address(0)) {\n            rewards[account] = earned(account);\n            userRewardPerTokenPaid[account] = rewardPerTokenStored;\n        }\n        _;\n    }\n\n    function rewardPerToken() public view returns (uint256) {\n        if (_totalSupply == 0) {\n            return rewardPerTokenStored;\n        }\n        return rewardPerTokenStored +\n            ((block.timestamp - lastUpdateTime) * rewardRate * 1e18) \u002F _totalSupply;\n    }\n\n    function earned(address account) public view returns (uint256) {\n        return (balances[account] *\n            (rewardPerToken() - userRewardPerTokenPaid[account])) \u002F 1e18 +\n            rewards[account];\n    }\n\n    function stake(uint256 amount) external nonReentrant updateReward(msg.sender) {\n        require(amount > 0, \"Cannot stake 0\");\n        _totalSupply += amount;\n        balances[msg.sender] += amount;\n        stakingToken.transferFrom(msg.sender, address(this), amount);\n        emit Staked(msg.sender, amount);\n    }\n\n    function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) {\n        require(amount > 0, \"Cannot withdraw 0\");\n        _totalSupply -= amount;\n        balances[msg.sender] -= amount;\n        stakingToken.transfer(msg.sender, amount);\n        emit Withdrawn(msg.sender, amount);\n    }\n\n    function getReward() public nonReentrant updateReward(msg.sender) {\n        uint256 reward = rewards[msg.sender];\n        if (reward > 0) {\n            rewards[msg.sender] = 0;\n            rewardsToken.transfer(msg.sender, reward);\n            emit RewardPaid(msg.sender, reward);\n        }\n    }\n\n    function exit() external {\n        withdraw(balances[msg.sender]);\n        getReward();\n    }\n}\n```\n\n## AMM (Automated Market Maker)\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\n\ncontract SimpleAMM {\n    IERC20 public token0;\n    IERC20 public token1;\n\n    uint256 public reserve0;\n    uint256 public reserve1;\n\n    uint256 public totalSupply;\n    mapping(address => uint256) public balanceOf;\n\n    event Mint(address indexed to, uint256 amount);\n    event Burn(address indexed from, uint256 amount);\n    event Swap(address indexed trader, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out);\n\n    constructor(address _token0, address _token1) {\n        token0 = IERC20(_token0);\n        token1 = IERC20(_token1);\n    }\n\n    function addLiquidity(uint256 amount0, uint256 amount1) external returns (uint256 shares) {\n        token0.transferFrom(msg.sender, address(this), amount0);\n        token1.transferFrom(msg.sender, address(this), amount1);\n\n        if (totalSupply == 0) {\n            shares = sqrt(amount0 * amount1);\n        } else {\n            shares = min(\n                (amount0 * totalSupply) \u002F reserve0,\n                (amount1 * totalSupply) \u002F reserve1\n            );\n        }\n\n        require(shares > 0, \"Shares = 0\");\n        _mint(msg.sender, shares);\n        _update(\n            token0.balanceOf(address(this)),\n            token1.balanceOf(address(this))\n        );\n\n        emit Mint(msg.sender, shares);\n    }\n\n    function removeLiquidity(uint256 shares) external returns (uint256 amount0, uint256 amount1) {\n        uint256 bal0 = token0.balanceOf(address(this));\n        uint256 bal1 = token1.balanceOf(address(this));\n\n        amount0 = (shares * bal0) \u002F totalSupply;\n        amount1 = (shares * bal1) \u002F totalSupply;\n\n        require(amount0 > 0 && amount1 > 0, \"Amount0 or amount1 = 0\");\n\n        _burn(msg.sender, shares);\n        _update(bal0 - amount0, bal1 - amount1);\n\n        token0.transfer(msg.sender, amount0);\n        token1.transfer(msg.sender, amount1);\n\n        emit Burn(msg.sender, shares);\n    }\n\n    function swap(address tokenIn, uint256 amountIn) external returns (uint256 amountOut) {\n        require(tokenIn == address(token0) || tokenIn == address(token1), \"Invalid token\");\n\n        bool isToken0 = tokenIn == address(token0);\n        (IERC20 tokenIn_, IERC20 tokenOut, uint256 resIn, uint256 resOut) = isToken0\n            ? (token0, token1, reserve0, reserve1)\n            : (token1, token0, reserve1, reserve0);\n\n        tokenIn_.transferFrom(msg.sender, address(this), amountIn);\n\n        \u002F\u002F 0.3% fee\n        uint256 amountInWithFee = (amountIn * 997) \u002F 1000;\n        amountOut = (resOut * amountInWithFee) \u002F (resIn + amountInWithFee);\n\n        tokenOut.transfer(msg.sender, amountOut);\n\n        _update(\n            token0.balanceOf(address(this)),\n            token1.balanceOf(address(this))\n        );\n\n        emit Swap(msg.sender, isToken0 ? amountIn : 0, isToken0 ? 0 : amountIn, isToken0 ? 0 : amountOut, isToken0 ? amountOut : 0);\n    }\n\n    function _mint(address to, uint256 amount) private {\n        balanceOf[to] += amount;\n        totalSupply += amount;\n    }\n\n    function _burn(address from, uint256 amount) private {\n        balanceOf[from] -= amount;\n        totalSupply -= amount;\n    }\n\n    function _update(uint256 res0, uint256 res1) private {\n        reserve0 = res0;\n        reserve1 = res1;\n    }\n\n    function sqrt(uint256 y) private pure returns (uint256 z) {\n        if (y > 3) {\n            z = y;\n            uint256 x = y \u002F 2 + 1;\n            while (x \u003C z) {\n                z = x;\n                x = (y \u002F x + x) \u002F 2;\n            }\n        } else if (y != 0) {\n            z = 1;\n        }\n    }\n\n    function min(uint256 x, uint256 y) private pure returns (uint256) {\n        return x \u003C= y ? x : y;\n    }\n}\n```\n\n## Governance Token\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002Fextensions\u002FERC20Votes.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Faccess\u002FOwnable.sol\";\n\ncontract GovernanceToken is ERC20Votes, Ownable {\n    constructor() ERC20(\"Governance Token\", \"GOV\") ERC20Permit(\"Governance Token\") {\n        _mint(msg.sender, 1000000 * 10**decimals());\n    }\n\n    function _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal override(ERC20Votes) {\n        super._afterTokenTransfer(from, to, amount);\n    }\n\n    function _mint(address to, uint256 amount) internal override(ERC20Votes) {\n        super._mint(to, amount);\n    }\n\n    function _burn(address account, uint256 amount) internal override(ERC20Votes) {\n        super._burn(account, amount);\n    }\n}\n\ncontract Governor is Ownable {\n    GovernanceToken public governanceToken;\n\n    struct Proposal {\n        uint256 id;\n        address proposer;\n        string description;\n        uint256 forVotes;\n        uint256 againstVotes;\n        uint256 startBlock;\n        uint256 endBlock;\n        bool executed;\n        mapping(address => bool) hasVoted;\n    }\n\n    uint256 public proposalCount;\n    mapping(uint256 => Proposal) public proposals;\n\n    uint256 public votingPeriod = 17280; \u002F\u002F ~3 days in blocks\n    uint256 public proposalThreshold = 100000 * 10**18;\n\n    event ProposalCreated(uint256 indexed proposalId, address proposer, string description);\n    event VoteCast(address indexed voter, uint256 indexed proposalId, bool support, uint256 weight);\n    event ProposalExecuted(uint256 indexed proposalId);\n\n    constructor(address _governanceToken) {\n        governanceToken = GovernanceToken(_governanceToken);\n    }\n\n    function propose(string memory description) external returns (uint256) {\n        require(\n            governanceToken.getPastVotes(msg.sender, block.number - 1) >= proposalThreshold,\n            \"Proposer votes below threshold\"\n        );\n\n        proposalCount++;\n        Proposal storage newProposal = proposals[proposalCount];\n        newProposal.id = proposalCount;\n        newProposal.proposer = msg.sender;\n        newProposal.description = description;\n        newProposal.startBlock = block.number;\n        newProposal.endBlock = block.number + votingPeriod;\n\n        emit ProposalCreated(proposalCount, msg.sender, description);\n        return proposalCount;\n    }\n\n    function vote(uint256 proposalId, bool support) external {\n        Proposal storage proposal = proposals[proposalId];\n        require(block.number >= proposal.startBlock, \"Voting not started\");\n        require(block.number \u003C= proposal.endBlock, \"Voting ended\");\n        require(!proposal.hasVoted[msg.sender], \"Already voted\");\n\n        uint256 weight = governanceToken.getPastVotes(msg.sender, proposal.startBlock);\n        require(weight > 0, \"No voting power\");\n\n        proposal.hasVoted[msg.sender] = true;\n\n        if (support) {\n            proposal.forVotes += weight;\n        } else {\n            proposal.againstVotes += weight;\n        }\n\n        emit VoteCast(msg.sender, proposalId, support, weight);\n    }\n\n    function execute(uint256 proposalId) external {\n        Proposal storage proposal = proposals[proposalId];\n        require(block.number > proposal.endBlock, \"Voting not ended\");\n        require(!proposal.executed, \"Already executed\");\n        require(proposal.forVotes > proposal.againstVotes, \"Proposal failed\");\n\n        proposal.executed = true;\n\n        \u002F\u002F Execute proposal logic here\n\n        emit ProposalExecuted(proposalId);\n    }\n}\n```\n\n## Flash Loan\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\n\ninterface IFlashLoanReceiver {\n    function executeOperation(\n        address asset,\n        uint256 amount,\n        uint256 fee,\n        bytes calldata params\n    ) external returns (bool);\n}\n\ncontract FlashLoanProvider {\n    IERC20 public token;\n    uint256 public feePercentage = 9; \u002F\u002F 0.09% fee\n\n    event FlashLoan(address indexed borrower, uint256 amount, uint256 fee);\n\n    constructor(address _token) {\n        token = IERC20(_token);\n    }\n\n    function flashLoan(\n        address receiver,\n        uint256 amount,\n        bytes calldata params\n    ) external {\n        uint256 balanceBefore = token.balanceOf(address(this));\n        require(balanceBefore >= amount, \"Insufficient liquidity\");\n\n        uint256 fee = (amount * feePercentage) \u002F 10000;\n\n        \u002F\u002F Send tokens to receiver\n        token.transfer(receiver, amount);\n\n        \u002F\u002F Execute callback\n        require(\n            IFlashLoanReceiver(receiver).executeOperation(\n                address(token),\n                amount,\n                fee,\n                params\n            ),\n            \"Flash loan failed\"\n        );\n\n        \u002F\u002F Verify repayment\n        uint256 balanceAfter = token.balanceOf(address(this));\n        require(balanceAfter >= balanceBefore + fee, \"Flash loan not repaid\");\n\n        emit FlashLoan(receiver, amount, fee);\n    }\n}\n\n\u002F\u002F Example flash loan receiver\ncontract FlashLoanReceiver is IFlashLoanReceiver {\n    function executeOperation(\n        address asset,\n        uint256 amount,\n        uint256 fee,\n        bytes calldata params\n    ) external override returns (bool) {\n        \u002F\u002F Decode params and execute arbitrage, liquidation, etc.\n        \u002F\u002F ...\n\n        \u002F\u002F Approve repayment\n        IERC20(asset).approve(msg.sender, amount + fee);\n\n        return true;\n    }\n}\n```\n\n## Resources\n\n- **references\u002Fstaking.md**: Staking mechanics and reward distribution\n- **references\u002Fliquidity-pools.md**: AMM mathematics and pricing\n- **references\u002Fgovernance-tokens.md**: Governance and voting systems\n- **references\u002Flending-protocols.md**: Lending\u002Fborrowing implementation\n- **references\u002Fflash-loans.md**: Flash loan security and use cases\n- **assets\u002Fstaking-contract.sol**: Production staking template\n- **assets\u002Famm-contract.sol**: Full AMM implementation\n- **assets\u002Fgovernance-token.sol**: Governance system\n- **assets\u002Flending-protocol.sol**: Lending platform template\n\n## Best Practices\n\n1. **Use Established Libraries**: OpenZeppelin, Solmate\n2. **Test Thoroughly**: Unit tests, integration tests, fuzzing\n3. **Audit Before Launch**: Professional security audits\n4. **Start Simple**: MVP first, add features incrementally\n5. **Monitor**: Track contract health and user activity\n6. **Upgradability**: Consider proxy patterns for upgrades\n7. **Emergency Controls**: Pause mechanisms for critical issues\n\n## Common DeFi Patterns\n\n- **Time-Weighted Average Price (TWAP)**: Price oracle resistance\n- **Liquidity Mining**: Incentivize liquidity provision\n- **Vesting**: Lock tokens with gradual release\n- **Multisig**: Require multiple signatures for critical operations\n- **Timelocks**: Delay execution of governance decisions\n",{"name":5,"risk":43,"source":37,"date_added":44,"description":7},"unknown","2026-02-27","main","a50a3aa6b39fb0e1b7db88bef1bfc9c93606e126","modules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fdefi-protocol-templates",0,"https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant","https:\u002F\u002Fgithub.com\u002FSam-06060","Mobile Application Developer | Kotlin | Flutter, KMP, Swfit, Android,Swift UI | Building at Saar It Resources | Creator of Jarvis (AI Assistant)","2026-06-23 05:13:38",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add Sam-06060\u002Fjarvis-assistant --skill defi-protocol-templates",{"tool":59,"command":60},"bunx","bunx skills add Sam-06060\u002Fjarvis-assistant --skill defi-protocol-templates",{"tool":62,"command":63},"pnpm","pnpm dlx skills add Sam-06060\u002Fjarvis-assistant --skill defi-protocol-templates","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fdefi-protocol-templates\u002FSKILL.md",true,[67,73,78],{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"example.html","REFERENCE","参考文档",48695,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-retro-windows\u002Fexample.html",{"path":74,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":76,"sourceHtmlUrl":77},"LICENSE","许可证",1067,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-retro-windows\u002FLICENSE",{"path":79,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":80,"sourceHtmlUrl":81},"template.json",1670,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-retro-windows\u002Ftemplate.json",[83,96,112,139,158,185],{"skillNo":84,"name":85,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":93,"publishedAt":38},"01M6GDRVS6FXX3ESH0C9DW01C0","test_skill","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fscratch\u002Ftest_skill\u002FSKILL.md",[88],{"categoryNo":89,"categoryName":90,"taxonomyType":91,"taxonomyTypeDesc":92},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[94,95],"Test Skill","test",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":38},"01M6GDRQ40HX22MA6XWC31RHHK","zustand-store-ts","Create Zustand stores following established patterns with proper TypeScript types and middleware.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzustand-store-ts\u002FSKILL.md",[],[103,104,105,106,107,108,109,37,110,111],"zustand store ts","zustand","store","with","types","middleware","patterns","create","typescript",{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":121,"publishedAt":38},"01M6GDRKEA0WE670SPFWX5GKCN","zoom-automation","Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoom-automation\u002FSKILL.md",[118],{"categoryNo":119,"categoryName":120,"taxonomyType":91,"taxonomyTypeDesc":92},"01JBSEEDCAT000000000000023","Skill与智能体开发",[122,123,124,125,126,127,128,129,130,131,132,133,134,135,37,136,137,138],"automation","zoom automation","zoom","first","Tools","search","MCP","via","meeting","automate","critical","creation","webinars","composio","recordings","management","tracking",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":146,"publishedAt":38},"01M6GDRFS1452PC71JQ38S24HR","zoho-crm-automation","Automate Zoho CRM tasks via Rube MCP (Composio): create\u002Fupdate records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoho-crm-automation\u002FSKILL.md",[145],{"categoryNo":119,"categoryName":120,"taxonomyType":91,"taxonomyTypeDesc":92},[147,122,148,149,150,151,152,37,127,153,135,154,132,131,126,155,110,156,128,157],"crm automation","zoho crm","crm","zoho crm automation","zoho","leads","contacts","records","update","tasks","manage",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":167,"publishedAt":38},"01M6GDRCKQBAVTGHX5XBH26KPZ","zod-validation-expert","Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzod-validation-expert\u002FSKILL.md",[164],{"categoryNo":165,"categoryName":166,"taxonomyType":91,"taxonomyTypeDesc":92},"01JBSEEDCAT000000000000009","前端开发",[168,169,170,171,172,111,173,174,175,176,177,178,106,179,180,181,182,37,183,184],"expert","zod","zod validation expert","validation","react","safe","parsing","errors","schema validation","react hook form","hook","trpc","form","type","next","schema","Next.js",{"skillNo":186,"name":187,"nameZh":6,"description":188,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":189,"categories":190,"keywords":192,"publishedAt":38},"01M6GDR658B08K4MY0RWD4A6EH","zeroize-audit","Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C\u002FC++\u002FRust code handling secrets, keys, passwords, or other sensitive data.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzeroize-audit\u002FSKILL.md",[191],{"categoryNo":119,"categoryName":120,"taxonomyType":91,"taxonomyTypeDesc":92},[193,194,195,196,197,198,199,200,37,201,202,203,204,205,206,207,208,209,210,128],"zeroize audit","audit","write","passwords","get","project","c++","activate","assembly","read","Bash","secrets","analysis","data","flow","verification","code","rust"]