Defi Protocol Templates

作者 wshobson46891e7e60da无许可证收录于 2026年10月8日更新于 2026年10月8日

Implement DeFi protocols with production-ready templates for staking, AMMs, governance, and flash loans. Use when building decentralized finance applications or smart contract protocols.

AI 生成的概览

提供质押、AMM、治理和闪电贷等 DeFi 协议的 Solidity 模板。

功能
该技能提供常见去中心化金融协议的生产级 Solidity 合约模板,包括质押奖励合约和简单自动做市商。它还指向一个参考文件,其中包含更多模式和完整示例。产出是用于智能合约开发的源代码和实现指导。
适用场景
适用于构建去中心化金融应用或智能合约协议时,例如带奖励分配的质押平台、AMM、治理代币系统或闪电贷集成。
运行要求
需要 Solidity 开发环境和 OpenZeppelin 合约(IERC20、ReentrancyGuard、Ownable);不包含脚本,只有说明和参考文档。

DeFi Protocol Templates

Production-ready templates for common DeFi protocols including staking, AMMs, governance, and flash loans.

When to Use This Skill

  • Building staking platforms with reward distribution
  • Implementing AMM (Automated Market Maker) protocols
  • Creating governance token systems
  • Integrating flash loan functionality

Staking Contract

solidity
// SPDX-License-Identifier: MITpragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";import "@openzeppelin/contracts/security/ReentrancyGuard.sol";import "@openzeppelin/contracts/access/Ownable.sol";
contract StakingRewards is ReentrancyGuard, Ownable {    IERC20 public stakingToken;    IERC20 public rewardsToken;
    uint256 public rewardRate = 100; // Rewards per second    uint256 public lastUpdateTime;    uint256 public rewardPerTokenStored;
    mapping(address => uint256) public userRewardPerTokenPaid;    mapping(address => uint256) public rewards;    mapping(address => uint256) public balances;
    uint256 private _totalSupply;
    event Staked(address indexed user, uint256 amount);    event Withdrawn(address indexed user, uint256 amount);    event RewardPaid(address indexed user, uint256 reward);
    constructor(address _stakingToken, address _rewardsToken) {        stakingToken = IERC20(_stakingToken);        rewardsToken = IERC20(_rewardsToken);    }
    modifier updateReward(address account) {        rewardPerTokenStored = rewardPerToken();        lastUpdateTime = block.timestamp;
        if (account != address(0)) {            rewards[account] = earned(account);            userRewardPerTokenPaid[account] = rewardPerTokenStored;        }        _;    }
    function rewardPerToken() public view returns (uint256) {        if (_totalSupply == 0) {            return rewardPerTokenStored;        }        return rewardPerTokenStored +            ((block.timestamp - lastUpdateTime) * rewardRate * 1e18) / _totalSupply;    }
    function earned(address account) public view returns (uint256) {        return (balances[account] *            (rewardPerToken() - userRewardPerTokenPaid[account])) / 1e18 +            rewards[account];    }
    function stake(uint256 amount) external nonReentrant updateReward(msg.sender) {        require(amount > 0, "Cannot stake 0");        _totalSupply += amount;        balances[msg.sender] += amount;        stakingToken.transferFrom(msg.sender, address(this), amount);        emit Staked(msg.sender, amount);    }
    function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) {        require(amount > 0, "Cannot withdraw 0");        _totalSupply -= amount;        balances[msg.sender] -= amount;        stakingToken.transfer(msg.sender, amount);        emit Withdrawn(msg.sender, amount);    }
    function getReward() public nonReentrant updateReward(msg.sender) {        uint256 reward = rewards[msg.sender];        if (reward > 0) {            rewards[msg.sender] = 0;            rewardsToken.transfer(msg.sender, reward);            emit RewardPaid(msg.sender, reward);        }    }
    function exit() external {        withdraw(balances[msg.sender]);        getReward();    }}

AMM (Automated Market Maker)

solidity
// SPDX-License-Identifier: MITpragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract SimpleAMM {    IERC20 public token0;    IERC20 public token1;
    uint256 public reserve0;    uint256 public reserve1;
    uint256 public totalSupply;    mapping(address => uint256) public balanceOf;
    event Mint(address indexed to, uint256 amount);    event Burn(address indexed from, uint256 amount);    event Swap(address indexed trader, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out);
    constructor(address _token0, address _token1) {        token0 = IERC20(_token0);        token1 = IERC20(_token1);    }
    function addLiquidity(uint256 amount0, uint256 amount1) external returns (uint256 shares) {        token0.transferFrom(msg.sender, address(this), amount0);        token1.transferFrom(msg.sender, address(this), amount1);
        if (totalSupply == 0) {            shares = sqrt(amount0 * amount1);        } else {            shares = min(                (amount0 * totalSupply) / reserve0,                (amount1 * totalSupply) / reserve1            );        }
        require(shares > 0, "Shares = 0");        _mint(msg.sender, shares);        _update(            token0.balanceOf(address(this)),            token1.balanceOf(address(this))        );
        emit Mint(msg.sender, shares);    }
    function removeLiquidity(uint256 shares) external returns (uint256 amount0, uint256 amount1) {        uint256 bal0 = token0.balanceOf(address(this));        uint256 bal1 = token1.balanceOf(address(this));
        amount0 = (shares * bal0) / totalSupply;        amount1 = (shares * bal1) / totalSupply;
        require(amount0 > 0 && amount1 > 0, "Amount0 or amount1 = 0");
        _burn(msg.sender, shares);        _update(bal0 - amount0, bal1 - amount1);
        token0.transfer(msg.sender, amount0);        token1.transfer(msg.sender, amount1);
        emit Burn(msg.sender, shares);    }
    function swap(address tokenIn, uint256 amountIn) external returns (uint256 amountOut) {        require(tokenIn == address(token0) || tokenIn == address(token1), "Invalid token");
        bool isToken0 = tokenIn == address(token0);        (IERC20 tokenIn_, IERC20 tokenOut, uint256 resIn, uint256 resOut) = isToken0            ? (token0, token1, reserve0, reserve1)            : (token1, token0, reserve1, reserve0);
        tokenIn_.transferFrom(msg.sender, address(this), amountIn);
        // 0.3% fee        uint256 amountInWithFee = (amountIn * 997) / 1000;        amountOut = (resOut * amountInWithFee) / (resIn + amountInWithFee);
        tokenOut.transfer(msg.sender, amountOut);
        _update(            token0.balanceOf(address(this)),            token1.balanceOf(address(this))        );
        emit Swap(msg.sender, isToken0 ? amountIn : 0, isToken0 ? 0 : amountIn, isToken0 ? 0 : amountOut, isToken0 ? amountOut : 0);    }
    function _mint(address to, uint256 amount) private {        balanceOf[to] += amount;        totalSupply += amount;    }
    function _burn(address from, uint256 amount) private {        balanceOf[from] -= amount;        totalSupply -= amount;    }
    function _update(uint256 res0, uint256 res1) private {        reserve0 = res0;        reserve1 = res1;    }
    function sqrt(uint256 y) private pure returns (uint256 z) {        if (y > 3) {            z = y;            uint256 x = y / 2 + 1;            while (x < z) {                z = x;                x = (y / x + x) / 2;            }        } else if (y != 0) {            z = 1;        }    }
    function min(uint256 x, uint256 y) private pure returns (uint256) {        return x <= y ? x : y;    }}

Additional patterns and templates

More detailed templates and worked examples live in references/details.md. Read that file for the full pattern library.

来源与署名

来源:wshobson/agents位于plugins/blockchain-web3/skills/defi-protocol-templates提交46891e7

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架