DeFi开发指南

DeFi开发指南

DeFi(去中心化金融)是区块链最重要的应用领域之一。本章将介绍DeFi开发的核心概念和实践。

基础概念

1. 代币标准

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 1. ERC20代币
contract ERC20Token is ERC20 {
    constructor(string memory name, string memory symbol) 
        ERC20(name, symbol) 
    {
        _mint(msg.sender, 1000000 * 10 ** decimals());
    }
}

// 2. ERC721 NFT
contract ERC721Token is ERC721 {
    constructor(string memory name, string memory symbol)
        ERC721(name, symbol)
    {}

    function mint(address to, uint256 tokenId) public {
        _mint(to, tokenId);
    }
}

// 3. ERC1155多代币
contract ERC1155Token is ERC1155 {
    constructor(string memory uri)
        ERC1155(uri)
    {}

    function mint(address to, uint256 id, uint256 amount, bytes memory data)
        public
    {
        _mint(to, id, amount, data);
    }
}

2. 价格预言机

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 1. Chainlink预言机接口
interface AggregatorV3Interface {
    function latestRoundData()
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );
}

// 2. 价格获取合约
contract PriceFeed {
    AggregatorV3Interface internal priceFeed;

    constructor(address _priceFeed) {
        priceFeed = AggregatorV3Interface(_priceFeed);
    }

    function getLatestPrice() public view returns (int) {
        (
            uint80 roundID,
            int price,
            uint startedAt,
            uint timeStamp,
            uint80 answeredInRound
        ) = priceFeed.latestRoundData();
        return price;
    }
}

// 3. 价格更新监听器
contract PriceListener {
    event PriceUpdated(int256 price);

    function onPriceUpdate(int256 price) external {
        // 处理价格更新
        emit PriceUpdated(price);
    }
}

3. 流动性池

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 1. 基础流动性池
contract LiquidityPool {
    IERC20 public token0;
    IERC20 public token1;
    uint public reserve0;
    uint public reserve1;

    constructor(address _token0, address _token1) {
        token0 = IERC20(_token0);
        token1 = IERC20(_token1);
    }

    // 添加流动性
    function addLiquidity(uint amount0, uint amount1) external {
        token0.transferFrom(msg.sender, address(this), amount0);
        token1.transferFrom(msg.sender, address(this), amount1);

        reserve0 += amount0;
        reserve1 += amount1;
    }

    // 移除流动性
    function removeLiquidity(uint amount0, uint amount1) external {
        require(amount0 <= reserve0 && amount1 <= reserve1, "Insufficient liquidity");

        token0.transfer(msg.sender, amount0);
        token1.transfer(msg.sender, amount1);

        reserve0 -= amount0;
        reserve1 -= amount1;
    }
}

// 2. 恒定乘积做市商
contract CPMM {
    uint public constant K = 1000000; // 恒定乘积

    function calculateSwapAmount(
        uint inputAmount,
        uint inputReserve,
        uint outputReserve
    ) public pure returns (uint) {
        uint inputAmountWithFee = inputAmount * 997; // 0.3% 手续费
        uint numerator = inputAmountWithFee * outputReserve;
        uint denominator = (inputReserve * 1000) + inputAmountWithFee;
        return numerator / denominator;
    }
}

借贷协议

1. 借贷池

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 1. 借贷池合约
contract LendingPool {
    mapping(address => uint) public deposits;
    mapping(address => uint) public borrows;
    mapping(address => uint) public collateral;

    uint public constant COLLATERAL_RATIO = 150; // 150% 抵押率
    uint public constant LIQUIDATION_THRESHOLD = 125; // 125% 清算阈值

    // 存款
    function deposit(uint amount) external {
        require(amount > 0, "Amount must be greater than 0");
        deposits[msg.sender] += amount;
        // 转入代币
    }

    // 借款
    function borrow(uint amount) external {
        require(amount > 0, "Amount must be greater than 0");
        require(
            collateral[msg.sender] * COLLATERAL_RATIO / 100 >= 
            (borrows[msg.sender] + amount),
            "Insufficient collateral"
        );

        borrows[msg.sender] += amount;
        // 转出代币
    }

    // 还款
    function repay(uint amount) external {
        require(amount > 0, "Amount must be greater than 0");
        require(borrows[msg.sender] >= amount, "Amount exceeds debt");

        borrows[msg.sender] -= amount;
        // 转入代币
    }

    // 提取抵押品
    function withdrawCollateral(uint amount) external {
        require(amount > 0, "Amount must be greater than 0");
        require(collateral[msg.sender] >= amount, "Insufficient collateral");
        require(
            (collateral[msg.sender] - amount) * COLLATERAL_RATIO / 100 >= 
            borrows[msg.sender],
            "Would break collateral ratio"
        );

        collateral[msg.sender] -= amount;
        // 转出抵押品
    }
}

// 2. 利率模型
contract InterestRateModel {
    uint public constant BASE_RATE = 2; // 2% 基础利率
    uint public constant MULTIPLIER = 15; // 15% 乘数
    uint public constant JUMP_MULTIPLIER = 300; // 300% 跳跃乘数
    uint public constant OPTIMAL_UTILIZATION = 80; // 80% 最优利用率

    function calculateInterestRate(
        uint totalBorrows,
        uint totalDeposits
    ) public pure returns (uint) {
        if (totalDeposits == 0) return 0;

        uint utilization = totalBorrows * 100 / totalDeposits;

        if (utilization <= OPTIMAL_UTILIZATION) {
            return BASE_RATE + (utilization * MULTIPLIER / OPTIMAL_UTILIZATION);
        } else {
            uint normalRate = BASE_RATE + MULTIPLIER;
            uint excessUtilization = utilization - OPTIMAL_UTILIZATION;
            return normalRate + (excessUtilization * JUMP_MULTIPLIER / (100 - OPTIMAL_UTILIZATION));
        }
    }
}

2. 清算机制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 1. 清算合约
contract Liquidator {
    LendingPool public lendingPool;
    PriceFeed public priceFeed;

    constructor(address _lendingPool, address _priceFeed) {
        lendingPool = LendingPool(_lendingPool);
        priceFeed = PriceFeed(_priceFeed);
    }

    // 检查是否可清算
    function canLiquidate(address borrower) public view returns (bool) {
        uint collateralValue = getCollateralValue(borrower);
        uint borrowValue = getBorrowValue(borrower);

        return collateralValue * 100 / borrowValue < 
               lendingPool.LIQUIDATION_THRESHOLD();
    }

    // 执行清算
    function liquidate(address borrower, uint amount) external {
        require(canLiquidate(borrower), "Position is not liquidatable");

        // 计算可清算的抵押品数量
        uint collateralToSeize = calculateSeizeAmount(amount);

        // 执行清算
        // 1. 转入清算金额
        // 2. 偿还借款人的债务
        // 3. 转出抵押品给清算人
    }

    // 计算可清算的抵押品数量
    function calculateSeizeAmount(uint amount) public view returns (uint) {
        // 计算逻辑
        return amount * 110 / 100; // 10% 奖励
    }
}

// 2. 价格监控器
contract PriceMonitor {
    event CollateralPriceDropped(address borrower, uint currentRatio);

    function checkCollateralRatio(address borrower) external {
        uint collateralRatio = getCollateralRatio(borrower);
        if (collateralRatio < SAFE_RATIO) {
            emit CollateralPriceDropped(borrower, collateralRatio);
        }
    }
}

3. 闪电贷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// 1. 闪电贷合约
contract FlashLoan {
    mapping(address => uint) public poolBalance;

    event FlashLoan(address indexed borrower, uint amount);

    // 闪电贷接口
    function flashLoan(uint amount) external {
        require(amount <= poolBalance[address(this)], "Insufficient liquidity");

        uint balanceBefore = poolBalance[address(this)];

        // 转出代币
        IERC20(token).transfer(msg.sender, amount);

        // 调用借款人的回调函数
        IFlashLoanReceiver(msg.sender).executeOperation(
            address(token),
            amount,
            0,
            address(0),
            bytes("")
        );

        // 检查还款
        uint balanceAfter = poolBalance[address(this)];
        require(
            balanceAfter >= balanceBefore,
            "Flash loan not repaid"
        );

        emit FlashLoan(msg.sender, amount);
    }
}

// 2. 闪电贷接收器
interface IFlashLoanReceiver {
    function executeOperation(
        address asset,
        uint256 amount,
        uint256 premium,
        address initiator,
        bytes calldata params
    ) external returns (bool);
}

// 3. 闪电贷套利示例
contract FlashLoanArbitrage is IFlashLoanReceiver {
    function executeOperation(
        address asset,
        uint256 amount,
        uint256 premium,
        address initiator,
        bytes calldata params
    ) external override returns (bool) {
        // 1. 在DEX A中卖出代币
        uint received = swapExactTokensForTokens(
            amount,
            token0,
            token1,
            dexA
        );

        // 2. 在DEX B中买回代币
        uint bought = swapExactTokensForTokens(
            received,
            token1,
            token0,
            dexB
        );

        // 3. 还款
        require(bought >= amount + premium, "Insufficient profit");
        IERC20(asset).transfer(msg.sender, amount + premium);

        return true;
    }
}

收益聚合器

1. 收益农场

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// 1. 收益农场合约
contract YieldFarm {
    IERC20 public stakingToken;
    IERC20 public rewardToken;

    uint public rewardRate;
    uint public lastUpdateTime;
    uint public rewardPerTokenStored;

    mapping(address => uint) public userRewardPerTokenPaid;
    mapping(address => uint) public rewards;
    mapping(address => uint) private _balances;
    uint private _totalSupply;

    // 质押代币
    function stake(uint amount) external {
        require(amount > 0, "Cannot stake 0");
        _totalSupply += amount;
        _balances[msg.sender] += amount;
        stakingToken.transferFrom(msg.sender, address(this), amount);
        updateReward(msg.sender);
    }

    // 提取质押
    function withdraw(uint amount) external {
        require(amount > 0, "Cannot withdraw 0");
        _totalSupply -= amount;
        _balances[msg.sender] -= amount;
        stakingToken.transfer(msg.sender, amount);
        updateReward(msg.sender);
    }

    // 领取奖励
    function getReward() external {
        updateReward(msg.sender);
        uint reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            rewardToken.transfer(msg.sender, reward);
        }
    }

    // 更新奖励
    function updateReward(address account) private {
        rewardPerTokenStored = rewardPerToken();
        lastUpdateTime = block.timestamp;
        if (account != address(0)) {
            rewards[account] = earned(account);
            userRewardPerTokenPaid[account] = rewardPerTokenStored;
        }
    }
}

// 2. 自动复投策略
contract AutoCompound {
    IYieldFarm public farm;
    uint public constant COMPOUND_INTERVAL = 1 days;
    uint public lastCompound;

    function compound() external {
        require(
            block.timestamp >= lastCompound + COMPOUND_INTERVAL,
            "Too soon"
        );

        // 1. 收获奖励
        farm.getReward();

        // 2. 将奖励兑换为质押代币
        uint rewards = getRewardBalance();
        if (rewards > 0) {
            swapRewardsToStakingToken(rewards);
        }

        // 3. 重新质押
        uint stakingTokens = getStakingTokenBalance();
        if (stakingTokens > 0) {
            farm.stake(stakingTokens);
        }

        lastCompound = block.timestamp;
    }
}

2. 收益优化器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// 1. 收益优化器合约
contract YieldOptimizer {
    struct Strategy {
        address protocol;
        uint allocation;
        uint apy;
    }

    Strategy[] public strategies;
    uint public totalFunds;

    // 添加新策略
    function addStrategy(
        address protocol,
        uint allocation,
        uint apy
    ) external {
        require(allocation <= 100, "Invalid allocation");
        strategies.push(Strategy(protocol, allocation, apy));
    }

    // 更新策略分配
    function updateAllocation(
        uint[] calldata newAllocations
    ) external {
        require(
            newAllocations.length == strategies.length,
            "Invalid length"
        );

        uint total;
        for (uint i = 0; i < newAllocations.length; i++) {
            total += newAllocations[i];
            strategies[i].allocation = newAllocations[i];
        }

        require(total == 100, "Total must be 100%");
    }

    // 重新平衡资金
    function rebalance() external {
        for (uint i = 0; i < strategies.length; i++) {
            Strategy memory strategy = strategies[i];
            uint targetAmount = totalFunds * strategy.allocation / 100;
            uint currentAmount = getCurrentAllocation(strategy.protocol);

            if (currentAmount < targetAmount) {
                // 增加分配
                depositToStrategy(
                    strategy.protocol,
                    targetAmount - currentAmount
                );
            } else if (currentAmount > targetAmount) {
                // 减少分配
                withdrawFromStrategy(
                    strategy.protocol,
                    currentAmount - targetAmount
                );
            }
        }
    }
}

// 2. APY追踪器
contract APYTracker {
    struct APYData {
        uint timestamp;
        uint apy;
    }

    mapping(address => APYData[]) public apyHistory;

    function updateAPY(address protocol, uint apy) external {
        apyHistory[protocol].push(APYData(
            block.timestamp,
            apy
        ));
    }

    function getAverageAPY(
        address protocol,
        uint period
    ) external view returns (uint) {
        APYData[] storage history = apyHistory[protocol];
        uint total;
        uint count;

        for (uint i = history.length; i > 0; i--) {
            if (block.timestamp - history[i-1].timestamp > period) {
                break;
            }
            total += history[i-1].apy;
            count++;
        }

        return count > 0 ? total / count : 0;
    }
}

3. 风险管理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 1. 风险评估合约
contract RiskManager {
    struct ProtocolRisk {
        uint tvlScore;      // TVL分数
        uint auditScore;    // 审计分数
        uint timeScore;     // 运行时间分数
        uint complexityScore; // 复杂度分数
    }

    mapping(address => ProtocolRisk) public protocolRisks;

    // 评估协议风险
    function assessProtocol(
        address protocol
    ) external view returns (uint) {
        ProtocolRisk memory risk = protocolRisks[protocol];

        // 计算综合风险分数
        uint totalScore = risk.tvlScore +
                         risk.auditScore +
                         risk.timeScore +
                         risk.complexityScore;

        return totalScore / 4; // 平均分
    }

    // 设置风险阈值
    function setRiskThresholds(
        uint minTVL,
        uint minAuditScore,
        uint minTime,
        uint maxComplexity
    ) external {
        // 设置风险阈值
    }
}

// 2. 紧急提款
contract EmergencyWithdraw {
    bool public emergencyStop;

    modifier notStopped {
        require(!emergencyStop, "Protocol is stopped");
        _;
    }

    modifier onlyEmergency {
        require(emergencyStop, "Not in emergency");
        _;
    }

    // 启动紧急停止
    function enableEmergencyStop() external {
        emergencyStop = true;
    }

    // 紧急提款
    function emergencyWithdraw() external onlyEmergency {
        // 提取所有资金
        uint balance = address(this).balance;
        if (balance > 0) {
            payable(msg.sender).transfer(balance);
        }

        // 提取所有代币
        IERC20[] memory tokens = getRegisteredTokens();
        for (uint i = 0; i < tokens.length; i++) {
            uint tokenBalance = tokens[i].balanceOf(address(this));
            if (tokenBalance > 0) {
                tokens[i].transfer(msg.sender, tokenBalance);
            }
        }
    }
}

练习题

  1. 实现一个简单的收益农场:
1
2
3
4
// 练习:实现收益农场
contract YieldFarm {
    // 你的代码
}
  1. 创建闪电贷套利合约:
1
2
3
4
// 练习:实现闪电贷套利
contract FlashLoanArbitrage {
    // 你的代码
}
  1. 实现收益优化器:
1
2
3
4
// 练习:实现收益优化器
contract YieldOptimizer {
    // 你的代码
}
  1. 创建风险评估系统:
1
2
3
4
// 练习:实现风险评估
contract RiskAssessment {
    // 你的代码
}
  1. 实现自动复投策略:
1
2
3
4
// 练习:实现自动复投
contract AutoCompounder {
    // 你的代码
}

参考资源

  1. Uniswap V2文档
  2. Aave文档
  3. Compound文档
  4. Yearn Finance文档
  5. DeFi安全最佳实践