Description:
i_aavePool.getUserAccountData(address(this))
will return the totalCollateralBase
in the BASE_CURRENCY of AAVEV3 (i.e USD with 8 Decimals). However in AAVEV3, AAVE can turn on a single oracle use on any E-mode category. When it is used, the IAaveOracle
(the oracle used internally by AavePool
) will return a different price from AggregatorV3Interface
.
function getTotalMeowllateralInAave() public view returns (uint256) {
(uint256 totalCollateralBase, , , , , ) = i_aavePool.getUserAccountData(address(this));
(, int256 collateralToUsdPrice, , , ) = i_priceFeed.latestRoundData();
return totalCollateralBase.mulDiv(PRECISION, uint256(collateralToUsdPrice) * EXTRA_DECIMALS);
}
Impact:
It will lead to incorrect calculation in getTotalMeowllateralInAave
as the pricing used to totalCollateralBase
in Aave will be different to collateralToUsdPrice
returned by i_priceFeed
, thus the getTotalMeowllateralInAave
will have slight mismatch in calculation.
Proof of Concept:
Add the following mainnet addresses in HelperConfig.s.sol
function getMainnetConfig() internal pure returns (NetworkConfig memory) {
return NetworkConfig ({
aavePool: 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2,
euroPriceFeed: 0xb49f677943BC038e9857d61E7d053CaA2C1734C1,
ethUsdPriceFeed: 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419,
btcUsdPriceFeed: 0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c,
usdcUsdPriceFeed: 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6,
weth: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,
wbtc: 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599,
usdc: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
});
}
Add the following test in KittyFiTest.t.sol
modifier userDepositsBTCCollateral(){
deal(config.wbtc, user, 10e8);
uint256 wbtcToDeposit = 5e8;
vm.prank(meowntainer);
kittyPool.meownufactureKittyVault(config.wbtc, config.btcUsdPriceFeed);
wbtcVault = KittyVault(kittyPool.getTokenToVault(config.wbtc));
vm.startPrank(user);
IERC20(config.wbtc).approve(address(wbtcVault), wbtcToDeposit);
kittyPool.depawsitMeowllateral(config.wbtc, wbtcToDeposit);
vm.stopPrank();
_;
}
function test_btcPriceDifference() public userDepositsBTCCollateral{
uint256 wbtcToSupply = 1e8;
vm.prank(meowntainer);
wbtcVault.purrrCollateralToAave(wbtcToSupply);
assertEq(wbtcVault.totalMeowllateralInVault(), 4e8);
(uint256 totalCollateralBaseBTC, , , , , ) = IAavePool(config.aavePool).getUserAccountData(address(wbtcVault));
console.log("totalCollateralBaseBTC", totalCollateralBaseBTC);
AggregatorV3Interface btcUsdPriceFeed = AggregatorV3Interface(config.btcUsdPriceFeed);
(, int256 btcUSDPrice, , , ) = btcUsdPriceFeed.latestRoundData();
console.log("btc price in oracle", uint256(btcUSDPrice));
}
Run the test using the command:
forge test --via-ir --fork-url https:
Log
totalCollateralBaseBTC 5720896508833
btc price in oracle 5719859727059
Value of 1 BTC in aave is 5720896508833 i.e 57208.96508833 USD
Value of 1 BTC in chainlink is 5719859727059 i.e 57198.59727059 USD
Difference between price: ~10USD per BTC
Recommended Mitigation:
Use IAaveOracle
to fetch collateralToUsdPrice