Files
Heyue_test/document/ytLp用户前端交互文档.md
2025-12-15 14:45:51 +00:00

7.9 KiB
Raw Permalink Blame History

ytLp用户前端交互文档 1.用户添加流动性 Solidity function addLiquidity( address _token, //YT代币或WUSD地址 uint256 _amount, //代币数量 uint256 _minUsdy, //最小USDY数量 uint256 _minYtLP //最小ytLP数量 ) _minUsdy和_minYtLP计算方式滑点可以让用户在界面选择 TypeScript /**

  • 计算添加流动性的 _minUsdy 和 _minYtLP 参数

  • @param {string} token - 代币地址

  • @param {BigNumber} amount - 代币数量

  • @param {number} slippageTolerance - 滑点容忍度 (0.005 = 0.5%)

  • @returns {Promise<{minUsdy, minYtLP, expectedYtLP, feeInfo}>} */ async function calculateAddLiquidityParams(token, amount, slippageTolerance = 0.005) { const PRICE_PRECISION = ethers.BigNumber.from("1000000000000000000000000000000"); const BASIS_POINTS = 10000;

    try { // 1. 获取价格使用MinPrice const tokenPrice = await ytVault.getMinPrice(token);

     // 2. 计算理论USDY扣费前
     const theoreticalUsdy = amount.mul(tokenPrice).div(PRICE_PRECISION);
    
     // 3. 获取手续费率
     const feeBasisPoints = await ytVault.getSwapFeeBasisPoints(
         token,
         USDY_ADDRESS,
         theoreticalUsdy
     );
    
     // 4. 计算扣费后的代币和USDY
     const amountAfterFees = amount
         .mul(BASIS_POINTS - feeBasisPoints)
         .div(BASIS_POINTS);
    
     const usdyAmount = amountAfterFees.mul(tokenPrice).div(PRICE_PRECISION);
    
     // 5. 获取AUM和供应量
     const [aum, ytLPSupply] = await Promise.all([
         ytPoolManager.getAumInUsdy(true),  // 使用MaxPrice
         ytLP.totalSupply()
     ]);
    
     // 6. 计算预期ytLP
     let expectedYtLP;
     if (ytLPSupply.eq(0)) {
         expectedYtLP = usdyAmount;
     } else {
         expectedYtLP = usdyAmount.mul(ytLPSupply).div(aum);
     }
    
     // 7. 应用滑点
     const minUsdy = usdyAmount.mul(
         ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
     ).div(10000);
    
     const minYtLP = expectedYtLP.mul(
         ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
     ).div(10000);
    
     return {
         minUsdy,
         minYtLP,
         expectedYtLP,
         usdyAmount,
         feeInfo: {
             feeBasisPoints: feeBasisPoints.toNumber(),
             feeAmount: amount.sub(amountAfterFees),
             amountAfterFees
         },
         priceInfo: {
             tokenPrice: ethers.utils.formatUnits(tokenPrice, 30),
             aum: ethers.utils.formatEther(aum),
             ytLPSupply: ethers.utils.formatEther(ytLPSupply)
         }
     };
    

    } catch (error) { console.error("计算添加流动性参数失败:", error); throw error; } }

2.用户移除流动性 Solidity function removeLiquidity( address _tokenOut, //出代币地址 uint256 _ytLPAmount, //ytLP数量 uint256 _minOut, //最小输出数量 address _receiver //接收地址 ) _minOut计算方式滑点可以让用户在界面选择 TypeScript /**

  • 计算移除流动性的 _minOut 参数

  • @param {string} tokenOut - 目标代币地址

  • @param {BigNumber} ytLPAmount - ytLP数量

  • @param {number} slippageTolerance - 滑点容忍度 (0.01 = 1%)

  • @returns {Promise<{minOut, expectedOut, feeBps, priceInfo}>} */ async function calculateMinOut(tokenOut, ytLPAmount, slippageTolerance = 0.01) { const PRICE_PRECISION = ethers.BigNumber.from("1000000000000000000000000000000"); const BASIS_POINTS = 10000;

    try { // 1. 获取AUM和供应量 const [aum, ytLPSupply] = await Promise.all([ ytPoolManager.getAumInUsdy(false), ytLP.totalSupply() ]);

     // 2. 计算USDY价值
     const usdyAmount = ytLPAmount.mul(aum).div(ytLPSupply);
    
     // 3. 获取代币价格和手续费(并行查询)
     const [tokenPrice, feeBasisPoints] = await Promise.all([
         ytVault.getMaxPrice(tokenOut),
         ytVault.getRedemptionFeeBasisPoints(tokenOut, usdyAmount)
     ]);
    
     // 4. 计算理论输出
     const theoreticalOut = usdyAmount.mul(PRICE_PRECISION).div(tokenPrice);
    
     // 5. 扣除手续费
     const expectedOut = theoreticalOut
         .mul(BASIS_POINTS - feeBasisPoints)
         .div(BASIS_POINTS);
    
     // 6. 应用滑点
     const minOut = expectedOut.mul(
         ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
     ).div(10000);
    
     return {
         minOut,
         expectedOut,
         theoreticalOut,
         usdyAmount,
         feeBasisPoints: feeBasisPoints.toNumber(),
         priceInfo: {
             tokenPrice: ethers.utils.formatUnits(tokenPrice, 30),
             aum: ethers.utils.formatEther(aum),
             ytLPSupply: ethers.utils.formatEther(ytLPSupply)
         }
     };
    

    } catch (error) { console.error("计算_minOut失败:", error); throw error; } }

3.用户交换代币 TypeScript function swapYT( address _tokenIn, //输入代币地址 address _tokenOut, //输出代币地址 uint256 _amountIn, //输入数量 uint256 _minOut, //最小输出数量 address _receiver //接收地址 ) _minOut计算方式滑点可以让用户在界面选择 TypeScript /**

  • 计算 swapYT 的 _minOut 参数

  • @param {string} tokenIn - 输入代币地址

  • @param {string} tokenOut - 输出代币地址

  • @param {BigNumber} amountIn - 输入数量

  • @param {number} slippageTolerance - 滑点容忍度 (0.005 = 0.5%)

  • @returns {Promise<{minOut, expectedOut, feeInfo, priceInfo}>} */ async function calculateSwapMinOut(tokenIn, tokenOut, amountIn, slippageTolerance = 0.005) { const PRICE_PRECISION = ethers.BigNumber.from("1000000000000000000000000000000"); const BASIS_POINTS = 10000;

    try { // 1. 获取价格(并行查询) const [priceIn, priceOut] = await Promise.all([ ytVault.getMinPrice(tokenIn), // 输入用MinPrice ytVault.getMaxPrice(tokenOut) // 输出用MaxPrice ]);

     // 2. 计算USDY价值
     const usdyAmount = amountIn.mul(priceIn).div(PRICE_PRECISION);
    
     // 3. 获取手续费率
     const feeBasisPoints = await ytVault.getSwapFeeBasisPoints(
         tokenIn,
         tokenOut,
         usdyAmount
     );
    
     // 4. 计算理论输出
     const theoreticalOut = usdyAmount.mul(PRICE_PRECISION).div(priceOut);
    
     // 5. 扣除手续费
     const expectedOut = theoreticalOut
         .mul(BASIS_POINTS - feeBasisPoints)
         .div(BASIS_POINTS);
    
     // 6. 应用滑点
     const minOut = expectedOut.mul(
         ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
     ).div(10000);
    
     return {
         minOut,
         expectedOut,
         theoreticalOut,
         usdyAmount,
         feeBasisPoints: feeBasisPoints.toNumber(),
         priceInfo: {
             priceIn: ethers.utils.formatUnits(priceIn, 30),
             priceOut: ethers.utils.formatUnits(priceOut, 30),
             effectiveRate: theoreticalOut.mul(10000).div(amountIn).toNumber() / 100
         },
         feeInfo: {
             feeBps: feeBasisPoints.toNumber(),
             feeAmount: theoreticalOut.sub(expectedOut)
         }
     };
    

    } catch (error) { console.error("计算 _minOut 失败:", error); throw error; } }