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 從公開儲存庫中收錄這些內容。

檢舉或申請下架