From 19b3e50d30e388c3bc1dad1fea583f6533448e06 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 28 Nov 2024 13:59:30 +0300 Subject: [PATCH] fix(framework): borrow up to available cash in comptroller checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Sometimes markets don't have huge amounts of cash available, e.g. on sepolia there's a shortage of WETH. This makes generic checks fail. However, it's a normal situation, especially on testnets – WETH wraps Sepolia ETH, so people supply free faucet tokens and borrow a token that has a higher demand. Solution: Ensure that the borrowed amount is less than available cash --- .../checks/checkIsolatedPoolsComptrollers.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vip-framework/checks/checkIsolatedPoolsComptrollers.ts b/src/vip-framework/checks/checkIsolatedPoolsComptrollers.ts index 78527e68f..1e410e676 100644 --- a/src/vip-framework/checks/checkIsolatedPoolsComptrollers.ts +++ b/src/vip-framework/checks/checkIsolatedPoolsComptrollers.ts @@ -50,9 +50,14 @@ const calculateBorrowableAmount = async ( const supplyTokenUSDAmountScaled = suppliedAmount.mul(supplyTokenPrice).div(EXP_SCALE); const borrowableAmountUSD = supplyTokenUSDAmountScaled.mul(supplyMarketCF).div(EXP_SCALE); const borrowTokenPriceScaled = borrowTokenPrice.mul(parseUnits("1", borrowUnderlyingDecimals)).div(EXP_SCALE); // scaled to 18 decimals - const borrowTokenAmount = borrowableAmountUSD.div(borrowTokenPriceScaled); - - return parseUnits(borrowTokenAmount.toString(), borrowUnderlyingDecimals); + const borrowTokenAmountScaled = borrowableAmountUSD.div(borrowTokenPriceScaled); + const borrowTokenAmount = parseUnits(borrowTokenAmountScaled.toString(), borrowUnderlyingDecimals); + await borrowMarket.accrueInterest(); + const cash = await borrowMarket.getCash(); + const reserves = await borrowMarket.totalReserves(); + const availableCash = cash.sub(reserves).mul(9).div(10); // applying 0.9 factor to account for interests + + return borrowTokenAmount.gt(availableCash) ? availableCash : borrowTokenAmount; }; const runPoolTests = async (pool: PoolMetadata, poolSupplier: string) => {