91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在DeFi應用中集成Curve協議

發布時間:2021-12-22 16:40:12 來源:億速云 閱讀:125 作者:柒染 欄目:互聯網科技

這篇文章給大家介紹如何在DeFi應用中集成Curve協議,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

Curve.Fi是一組規模龐大的DEFi協議,這個教程的目的是幫助你關注智能合約開發的現代方法,以及如何在自己的Defi應用中集成Curve.Fi這種大型協議的關鍵點。

1、Curve.Fi開發教程的組織方式

是的,我已經說過我們將深入研究代碼。盡管我們不是在談論AMM模型的數學運算,也不是在Curve.Fi合約中使用的其他一些特定技巧,但是我們仍然需要了解一些內容。當然,這不是在談論成功的DeFi開發-我沒有給出提示。這是我經驗的一部分,在這里我將分享一些有關Curve智能合約的基本架構以及我們如何與這些架構集成的知識。實際上,下圖中包含了本教程的全部內容:

如何在DeFi應用中集成Curve協議

我們研究的是Y-Pool,它以一種簡單明了的方式組織。存款(Deposit)合約將你的資金打包成Y-Token,然后將其發送到兌換(Swap)合約,兌換合約為用戶生成LP代幣。如果你要提取流通性份額以及所賺取的收益,則合約會執行相同的操作,但是方式相反。這一切都與金融合約有關(當然,如果我們對池平衡和股數計算背后的復雜邏輯選擇視而不見)。

此外,我們還有Gauge和Minter合同,它們是Curve.Fi DAO的一部分。這些合約使你可以獲得CRV代幣獎勵并將其抵押,以便獲得協議治理的投票權。

在我們充分了解這些需要交互的合約后,就可以開始我們的開發了。

2、從Curve.Fi用戶交互界面開始

你可能還記得,我們正在處理一些使用Vyper開發的外部合約。為了與這些合約交互,我們需要創建一些接口。這并不是最困難的工作:只需要仔細查看原始合約并挑出將要調用的方法即可。

讓我們將從存款合約開始。我們需要資金進出的方法,以及一些數據查看界面(例如,查看已注冊的代幣及其Y對應代幣)。

contract ICurveFi_DepositY { 
    function add_liquidity(uint256[4] calldata uamounts, uint256 min_mint_amount) external;
    function remove_liquidity(uint256 _amount, uint256[4] calldata min_uamounts) external;
    function remove_liquidity_imbalance(uint256[4] calldata uamounts, uint256 max_burn_amount) external;

    function coins(int128 i) external view returns (address);
    function underlying_coins(int128 i) external view returns (address);
    function underlying_coins() external view returns (address[4] memory);
    function curve() external view returns (address);
    function token() external view returns (address);
}

然后用相同的方法處理兌換合約(你可能還記得,該合約為用戶鑄造LP代幣)。

contract ICurveFi_Gauge {
    function lp_token() external view returns(address);
    function crv_token() external view returns(address);
 
    function balanceOf(address addr) external view returns (uint256);
    function deposit(uint256 _value) external;
    function withdraw(uint256 _value) external;

    function claimable_tokens(address addr) external returns (uint256);
    function minter() external view returns(address); //use minter().mint(gauge_addr) to claim CRV

    function integrate_fraction(address _for) external view returns(uint256);
    function user_checkpoint(address _for) external returns(bool);
}

現在該處理DAO的主要合約-流動性計量器合約。它執行復雜的功能,但我們主要需要用于創建檢查點的方法以及查看Minter和CRV代幣地址的界面。

contract ICurveFi_Gauge {
    function lp_token() external view returns(address);
    function crv_token() external view returns(address);
 
    function balanceOf(address addr) external view returns (uint256);
    function deposit(uint256 _value) external;
    function withdraw(uint256 _value) external;

    function claimable_tokens(address addr) external returns (uint256);
    function minter() external view returns(address); //use minter().mint(gauge_addr) to claim CRV

    function integrate_fraction(address _for) external view returns(uint256);
    function user_checkpoint(address _for) external returns(bool);
}

還有從用戶界面的角度來看其實是最簡單的合約— Minter。實際上,我們只需要minter方法本身,以及一個可以查看有效獎勵的方法。

contract ICurveFi_Minter {
    function mint(address gauge_addr) external;
    function minted(address _for, address gauge_addr) external view returns(uint256);

    function toggle_approve_mint(address minting_user) external;
    function token() external view returns(address);
}

最后一個是YToken接口,不過它并非最不重要,因為我們要交互的就是Curve的Y池。YToken是一個簡單的ERC20接口,幾乎沒有其他額外的方法。

contract IYERC20 { 
    //ERC20 functions
    //
    //

    //Y-token functions
    function deposit(uint256 amount) external;
    function withdraw(uint256 shares) external;
    function getPricePerFullShare() external view returns (uint256);

    function token() external returns(address);
}

現在我們準備創建一些代碼來與此協議交互。

3、基于Curve.Fi以正確的順序轉移資金

我們的實驗合約的主要目標是展示如何將Curve協議作為資金流終點來組織資金的流動。因此,我們將有兩種主要方法:一種用于完整的存款流程(具有從Curve.Fi可獲得的所有好處),另一種用于提款流程。

讓我們從存款開始。

function multiStepDeposit(uint256[4] memory _amounts) public {
    address[4] memory stablecoins = ICurveFi_DepositY(curveFi_Deposit).underlying_coins();

    for (uint256 i = 0; i < stablecoins.length; i++) {
        IERC20(stablecoins[i]).safeTransferFrom(_msgSender(), address(this), _amounts[i]);
        IERC20(stablecoins[i]).safeApprove(curveFi_Deposit, _amounts[i]);
    }

    //Step 1 - deposit stablecoins and get Curve.Fi LP tokens
    ICurveFi_DepositY(curveFi_Deposit).add_liquidity(_amounts, 0); //0 to mint all Curve has to 

    //Step 2 - stake Curve LP tokens into Gauge and get CRV rewards
    uint256 curveLPBalance = IERC20(curveFi_LPToken).balanceOf(address(this));

    IERC20(curveFi_LPToken).safeApprove(curveFi_LPGauge, curveLPBalance);
    ICurveFi_Gauge(curveFi_LPGauge).deposit(curveLPBalance);

    //Step 3 - get all the rewards (and make whatever you need with them)
    crvTokenClaim();
    uint256 crvAmount = IERC20(curveFi_CRVToken).balanceOf(address(this));
    IERC20(curveFi_CRVToken).safeTransfer(_msgSender(), crvAmount);
}

正像你看見的,我們在multiStepDeposit()方法中執行了幾個動作。首先,將我們的資金(在本例中為選定的穩定幣)存入Deposit合約,以便接收Curve LP代幣。第二步是將LP代幣存入Gauge合約,以便獲得CRV代幣獎勵。第三步取決于你自己 —— 可以使用CRV獎勵做任何想做的事情。

實際上,相同的方案也適用于multiStepWithdraw()方法,但順序相反。

function multiStepWithdraw(uint256[4] memory _amounts) public {
    address[4] memory stablecoins = ICurveFi_DepositY(curveFi_Deposit).underlying_coins();

    //Step 1 - Calculate amount of Curve LP-tokens to unstake
    uint256 nWithdraw;
    uint256 i;
    for (i = 0; i < stablecoins.length; i++) {
        nWithdraw = nWithdraw.add(normalize(stablecoins[i], _amounts[i]));
    }
    uint256 withdrawShares = calculateShares(nWithdraw);

    //Check if you can re-use unstaked LP tokens
    uint256 notStaked = curveLPTokenUnstaked();
    if (notStaked > 0) {
        withdrawShares = withdrawShares.sub(notStaked);
    }

    //Step 2 - Unstake Curve LP tokens from Gauge
    ICurveFi_Gauge(curveFi_LPGauge).withdraw(withdrawShares);

    //Step 3 - Withdraw stablecoins from CurveDeposit
    IERC20(curveFi_LPToken).safeApprove(curveFi_Deposit, withdrawShares);
    ICurveFi_DepositY(curveFi_Deposit).remove_liquidity_imbalance(_amounts, withdrawShares);
    
    //Step 4 - Send stablecoins to the requestor
    //
}

是的,解決方案非常簡單,某種程度上看起來很笨拙,并且存在幾個明顯的漏洞 —— 雖然這些代碼僅用于演示目的。你可以添加所需的所有檢查,將階段拆分為不同的方法,為方法設置不同的權限,并執行使你的DeFi項目成功所需的所有其他工作。

4、測試Curve.Fi解決方案

教程的最后一步是添加幾個單元測試,以驗證解決方案是否有效。雖然在這里我們面臨幾個問題。第一個(也是主要的)問題是Curve.Fi協議環境。為了測試解決方案,我們需要在本地環境(在我們的例子中為Ganache)上模擬完整的Curve協議。由于這是一組復雜的合約,而且是在Vyper上編寫的,因此我們不能僅將它們編譯并部署到我們的Ganache節點中。

我已經完成了一些工作,并準備了Curve協議的測試存根,可以將其與你的項目一起編譯并部署你的測試網上。除了出于測試目的的幾種簡化,這些測試存根與原始的Curve協議完全相同。你可以在這里下載。

因此,我們可以跳過將Vyper代碼轉換為可測試的Solidity合約的無聊部分,直接查看單元測試的輸出:

如何在DeFi應用中集成Curve協議

關于如何在DeFi應用中集成Curve協議就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

十堰市| 玛沁县| 游戏| 海原县| 海口市| 潍坊市| 长岭县| 文水县| 洞口县| 马龙县| 康平县| 天台县| 屏南县| 安宁市| 白朗县| 伽师县| 定州市| 多伦县| 平陆县| 建宁县| 同江市| 岳普湖县| 伊宁县| 津南区| 东丽区| 宕昌县| 马山县| 新沂市| 家居| 奉节县| 调兵山市| 辽阳市| 玛多县| 长葛市| 嘉义县| 三门峡市| 阿克| 南昌市| 仁化县| 正定县| 北票市|