diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 752207e6..a4db008f 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -996,7 +996,7 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( //removing the stable liquidity at the old rate - const avgRateBefore = calcExpectedAverageStableBorrowRate( + const avgRateBefore = calcExpectedAverageStableBorrowRateRebalance( reserveDataBeforeAction.averageStableBorrowRate, expectedReserveData.totalStableDebt, userStableDebt.negated(), @@ -1004,7 +1004,7 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( ); // adding it again at the new rate - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( + expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRateRebalance( avgRateBefore, expectedReserveData.totalStableDebt.minus(userStableDebt), userStableDebt, @@ -1044,6 +1044,8 @@ export const calcExpectedUserDataAfterStableRateRebalance = ( ): UserReserveData => { const expectedUserData = { ...userDataBeforeAction }; + expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; + expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance( reserveDataBeforeAction, userDataBeforeAction, @@ -1056,12 +1058,18 @@ export const calcExpectedUserDataAfterStableRateRebalance = ( txTimestamp ); + expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( + reserveDataBeforeAction, + userDataBeforeAction, + txTimestamp + ); + expectedUserData.stableRateLastUpdated = txTimestamp; expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt; - expectedUserData.stableBorrowRate = reserveDataBeforeAction.stableBorrowRate; - + // Stable rate after burn + expectedUserData.stableBorrowRate = expectedDataAfterAction.averageStableBorrowRate; expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; expectedUserData.currentATokenBalance = calcExpectedATokenBalance( @@ -1104,7 +1112,7 @@ const calcExpectedAverageStableBorrowRate = ( ) => { const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalStableDebtBefore); const weightedAmountBorrowed = rate.multipliedBy(amountChanged); - const totalBorrowedStable = totalStableDebtBefore.plus(new BigNumber(amountChanged)); + const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged); if (totalBorrowedStable.eq(0)) return new BigNumber('0'); @@ -1114,6 +1122,24 @@ const calcExpectedAverageStableBorrowRate = ( .decimalPlaces(0, BigNumber.ROUND_DOWN); }; +const calcExpectedAverageStableBorrowRateRebalance = ( + avgStableRateBefore: BigNumber, + totalStableDebtBefore: BigNumber, + amountChanged: BigNumber, + rate: BigNumber +) => { + const weightedTotalBorrows = avgStableRateBefore.rayMul(totalStableDebtBefore); + const weightedAmountBorrowed = rate.rayMul(amountChanged.wadToRay()); + const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged.wadToRay()); + + if (totalBorrowedStable.eq(0)) return new BigNumber('0'); + + return weightedTotalBorrows + .plus(weightedAmountBorrowed) + .rayDiv(totalBorrowedStable) + .decimalPlaces(0, BigNumber.ROUND_DOWN); +}; + export const calcExpectedVariableDebtTokenBalance = ( reserveData: ReserveData, userData: UserReserveData, @@ -1211,7 +1237,6 @@ export const calcExpectedInterestRates = ( ): BigNumber[] => { const { reservesParams } = configuration; - const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol); const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[ reserveIndex diff --git a/test/uniswapAdapters.repay.spec.ts b/test/uniswapAdapters.repay.spec.ts index 27f91e02..c271917e 100644 --- a/test/uniswapAdapters.repay.spec.ts +++ b/test/uniswapAdapters.repay.spec.ts @@ -17,6 +17,7 @@ import { eContractid } from '../helpers/types'; import { StableDebtToken } from '../types/StableDebtToken'; import { BUIDLEREVM_CHAINID } from '../helpers/buidler-constants'; import { MAX_UINT_AMOUNT } from '../helpers/constants'; +import { VariableDebtToken } from '../types'; const { parseEther } = ethers.utils; const { expect } = require('chai'); @@ -797,7 +798,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); }); - it('should correctly repay debt using the same asset as collateral', async () => { + it('should correctly repay debt via flash loan using the same asset as collateral', async () => { const { users, pool, aDai, dai, uniswapRepayAdapter, helpersContract } = testEnv; const user = users[0].signer; const userAddress = users[0].address; @@ -813,16 +814,18 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { // Open user Debt await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress); - const daiStableDebtTokenAddress = ( + const daiVariableDebtTokenAddress = ( await helpersContract.getReserveTokensAddresses(dai.address) - ).stableDebtTokenAddress; + ).variableDebtTokenAddress; - const daiStableDebtContract = await getContract( - eContractid.StableDebtToken, - daiStableDebtTokenAddress + const daiVariableDebtContract = await getContract( + eContractid.VariableDebtToken, + daiVariableDebtTokenAddress ); - const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.balanceOf( + userAddress + ); const flashLoanDebt = new BigNumber(amountCollateralToSwap.toString()) .multipliedBy(1.0009) @@ -835,7 +838,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { const params = buildRepayAdapterParams( dai.address, amountCollateralToSwap, - 1, + 2, 0, 0, 0, @@ -857,18 +860,30 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { ); const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); - const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userDaiVariableDebtAmount = await daiVariableDebtContract.balanceOf(userAddress); const userADaiBalance = await aDai.balanceOf(userAddress); const adapterADaiBalance = await aDai.balanceOf(uniswapRepayAdapter.address); const userDaiBalance = await dai.balanceOf(userAddress); - expect(adapterADaiBalance).to.be.eq(Zero); - expect(adapterDaiBalance).to.be.eq(Zero); - expect(userDaiStableDebtAmountBefore).to.be.gte(debtAmount); - expect(userDaiStableDebtAmount).to.be.lt(debtAmount); - expect(userADaiBalance).to.be.lt(userADaiBalanceBefore); - expect(userADaiBalance).to.be.gte(userADaiBalanceBefore.sub(flashLoanDebt)); - expect(userDaiBalance).to.be.eq(userDaiBalanceBefore); + expect(adapterADaiBalance).to.be.eq(Zero, 'adapter aDAI balance should be zero'); + expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI balance should be zero'); + expect(userDaiVariableDebtAmountBefore).to.be.gte( + debtAmount, + ' user DAI variable debt before should be gte debtAmount' + ); + expect(userDaiVariableDebtAmount).to.be.lt( + debtAmount, + 'user dai variable debt amount should be lt debt amount' + ); + expect(userADaiBalance).to.be.lt( + userADaiBalanceBefore, + 'user aDAI balance should be lt aDAI prior balance' + ); + expect(userADaiBalance).to.be.gte( + userADaiBalanceBefore.sub(flashLoanDebt), + 'user aDAI balance should be gte aDAI prior balance sub flash loan debt' + ); + expect(userDaiBalance).to.be.eq(userDaiBalanceBefore, 'user dai balance eq prior balance'); }); }); @@ -1387,16 +1402,18 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { // Open user Debt await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress); - const daiStableDebtTokenAddress = ( + const daiVariableDebtTokenAddress = ( await helpersContract.getReserveTokensAddresses(dai.address) - ).stableDebtTokenAddress; + ).variableDebtTokenAddress; - const daiStableDebtContract = await getContract( + const daiVariableDebtContract = await getContract( eContractid.StableDebtToken, - daiStableDebtTokenAddress + daiVariableDebtTokenAddress ); - const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.balanceOf( + userAddress + ); await aDai.connect(user).approve(uniswapRepayAdapter.address, amountCollateralToSwap); const userADaiBalanceBefore = await aDai.balanceOf(userAddress); @@ -1407,7 +1424,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { dai.address, amountCollateralToSwap, amountCollateralToSwap, - 1, + 2, { amount: 0, deadline: 0, @@ -1419,18 +1436,33 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { ); const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); - const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userDaiVariableDebtAmount = await daiVariableDebtContract.balanceOf(userAddress); const userADaiBalance = await aDai.balanceOf(userAddress); const adapterADaiBalance = await aDai.balanceOf(uniswapRepayAdapter.address); const userDaiBalance = await dai.balanceOf(userAddress); - expect(adapterADaiBalance).to.be.eq(Zero); - expect(adapterDaiBalance).to.be.eq(Zero); - expect(userDaiStableDebtAmountBefore).to.be.gte(debtAmount); - expect(userDaiStableDebtAmount).to.be.lt(debtAmount); - expect(userADaiBalance).to.be.lt(userADaiBalanceBefore); - expect(userADaiBalance).to.be.gte(userADaiBalanceBefore.sub(amountCollateralToSwap)); - expect(userDaiBalance).to.be.eq(userDaiBalanceBefore); + expect(adapterADaiBalance).to.be.eq(Zero, 'adapter aADAI should be zero'); + expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI should be zero'); + expect(userDaiVariableDebtAmountBefore).to.be.gte( + debtAmount, + 'user dai variable debt before should be gte debtAmount' + ); + expect(userDaiVariableDebtAmount).to.be.lt( + debtAmount, + 'current user dai variable debt amount should be less than debtAmount' + ); + expect(userADaiBalance).to.be.lt( + userADaiBalanceBefore, + 'current user aDAI balance should be less than prior balance' + ); + expect(userADaiBalance).to.be.gte( + userADaiBalanceBefore.sub(amountCollateralToSwap), + 'current user aDAI balance should be gte user balance sub swapped collateral' + ); + expect(userDaiBalance).to.be.eq( + userDaiBalanceBefore, + 'user DAI balance should remain equal' + ); }); }); });