Solidity

如何計算鏈上的 AAVE 收益率

  • September 29, 2022

我正在開展一個項目,該項目涉及在保持原始存款餘額的同時跟踪和提取鏈上的 AAVE 收益。我對如何準確計算特定時間點的 AAVE 產量感到困惑。我最初的方法是只保存存款金額,然後通過以下方式計​​算收益率:

收益率 = aToken_balance - deposit_amount

但這似乎不起作用。我發現,在計算出這個收益值之後,如果我們試圖提取這個值,我們得到的 aToken 餘額將偏離(高於或低於)我們的初始存款金額。我知道 aTokens 有動態的 supply/balanceOf,但必須有一種方法可以準確計算:“我此時有 X 錢”

我正在 Polygon Mainnet 的一個分支上進行測試,我想知道它是否與我的測試環境有關(即模擬時間在沒有人實際與 AAVE 互動的主網分支上傳遞)?測試契約和問題的螢幕截圖如下。非常感謝任何見解。

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IPool.sol";

contract AaveTest2 {
   IPool public aavePoolManager = IPool(0x794a61358D6845594F94dc1DB02A252b5b4814aD);
   address public usdc = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
   address public ausdc = 0x625E7708f30cA75bfd92586e17077590C60eb4cD;
   address public dai = 0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063;
   address public adai = 0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE;

   uint public totalStakedUSDC;
   uint public totalStakedDAI;

   constructor() {}


   function aaveDepositUSDC(uint amount) public {
       IERC20(usdc).approve(address(aavePoolManager), amount);
       aavePoolManager.supply(usdc, amount, address(this), 0);
       totalStakedUSDC += amount;
   }

   function calculateYieldUSDC() public view returns (uint) {
       uint yield = IERC20(ausdc).balanceOf(address(this)) - totalStakedUSDC;
       return yield;
   }
   
   function withdrawYieldUSDC() public {
       uint yield = calculateYieldUSDC();
       aavePoolManager.withdraw(usdc, yield, address(this));
   }

   function withdrawUSDC(uint amount) public {
       aavePoolManager.withdraw(usdc, amount, address(this));
       totalStakedUSDC -= amount;
   }

   function aaveDepositDAI(uint amount) public {
       IERC20(dai).approve(address(aavePoolManager), amount);
       aavePoolManager.supply(dai, amount, address(this), 0);
       totalStakedDAI += amount;
   }

   function calculateYieldDAI() public view returns (uint) {
       uint yield = IERC20(adai).balanceOf(address(this)) - totalStakedDAI;
       return yield;
   }
   
   function withdrawYieldDAI() public {
       uint yield = calculateYieldDAI();
       aavePoolManager.withdraw(dai, yield, address(this));
   }

   function withdrawDAI(uint amount) public {
       aavePoolManager.withdraw(dai, amount, address(this));
       totalStakedDAI -= amount;
   }
}

範例 1

範例 2

範例 3

如果我沒記錯的話。Aave 使用索引來跟踪您的 aToken 的價值。

第 1 步,檢索索引

(, , , , , , ,uint256 liquidityIndex, , ) = IdataProvider.getReserveData(asset_address);

這應該在 ray 中返回一個數字

第 2 步,檢索您的縮放餘額

uint256 scaledBalance = AToken(asset_address).scaledBalanceOf(address(this));

第3步,做數學得到你的目前值

uint256 value_now = (scaledBalance * liquidityIndex) * 1e18 / 1e27;

引用自:https://ethereum.stackexchange.com/questions/136530