diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index c22946c77..61114b808 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -376,7 +376,8 @@ contract Comptroller is // Skipping the cap check for uncapped coins to save some gas if (borrowCap != type(uint256).max) { uint256 totalBorrows = VToken(vToken).totalBorrows(); - uint256 nextTotalBorrows = totalBorrows + borrowAmount; + uint256 badDebt = VToken(vToken).badDebt(); + uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt; if (nextTotalBorrows > borrowCap) { revert BorrowCapExceeded(vToken, borrowCap); } diff --git a/tests/hardhat/Fork/Shortfall.ts b/tests/hardhat/Fork/Shortfall.ts index b06357477..181de7991 100644 --- a/tests/hardhat/Fork/Shortfall.ts +++ b/tests/hardhat/Fork/Shortfall.ts @@ -77,8 +77,8 @@ const grabTokensTo = async (userAddress: string) => { const trxHolder = await initMainnetUser("0x3DdfA8eC3052539b6C9549F12cEA2C295cfF5296", parseEther("2")); const usdtHolder = await initMainnetUser("0xF977814e90dA44bFA03b6295A0616a897441aceC", parseEther("2")); - trx.connect(trxHolder).transfer(userAddress, parseUnits("10000", 6)); - usdt.connect(usdtHolder).transfer(userAddress, parseUnits("10000", 18)); + await trx.connect(trxHolder).transfer(userAddress, parseUnits("10000", 6)); + await usdt.connect(usdtHolder).transfer(userAddress, parseUnits("10000", 18)); }; const setupRiskManagementContracts = async () => { @@ -113,7 +113,7 @@ const setupRiskManagementContracts = async () => { MINIMUM_POOL_BAD_DEBT, ACM, ])) as Shortfall; - shortfall.updatePoolRegistry(POOL_REGISTRY); + await shortfall.updatePoolRegistry(POOL_REGISTRY); }; const setupTokens = async () => { diff --git a/tests/integration/index.ts b/tests/integration/index.ts index 3125a4b31..ef2573e35 100644 --- a/tests/integration/index.ts +++ b/tests/integration/index.ts @@ -335,6 +335,47 @@ describe("Positive Cases", function () { expect(Number(liquidity)).to.be.closeTo(preComputeLiquidity.toNumber(), Number(convertToUnit(1, 14))); expect(shortfall).to.equal(0); }); + + it("Should revert when borrow cap is reached", async () => { + // Minting amount to account 1 so that it can also heal account + const faucetAmount = convertToUnit(20, 18); + await BTCB.connect(acc1Signer).faucet(faucetAmount); + await BNX.connect(acc1Signer).faucet(faucetAmount); + + const mintAmountForAccount1 = convertToUnit(10, 18); + await BTCB.connect(acc1Signer).approve(vBTCB.address, mintAmountForAccount1); + + // Minting in vBTCB so that vToken also has sufficient funds + await vBTCB.connect(acc1Signer).mint(mintAmountForAccount1); + + // Setting market caps for market + const borrowCap = convertToUnit(10, 18); + await Comptroller.setMarketBorrowCaps([vBTCB.address], [borrowCap]); + + const mintAmountForBNX = convertToUnit(1, 16); + await vBNX.connect(acc2Signer).mint(mintAmountForBNX); + + const BTCBBorrowAmount = convertToUnit(46, 17); + await vBTCB.connect(acc2Signer).borrow(BTCBBorrowAmount); + + // Mining blocks + await mine(300000000); + + await BTCB.connect(acc1Signer).approve(vBTCB.address, convertToUnit(10, 18)); + await Comptroller.connect(acc1Signer).healAccount(acc2); + + // Now another user should not be able to borrow equal to borrowCap - totalBorrows as there is badDebt also + await expect(vBTCB.connect(acc1Signer).borrow(borrowCap)).to.be.revertedWithCustomError( + Comptroller, + "BorrowCapExceeded", + ); + + // User should be able to borrow equal to borrowCap - badDebt as there is badDebt also. + const amountToBorrow = BigInt(borrowCap) - BigInt((await vBTCB.badDebt()).toString()); + await expect(vBTCB.connect(acc1Signer).borrow(amountToBorrow)) + .to.emit(vBTCB, "Borrow") + .withArgs(acc1, amountToBorrow, amountToBorrow, amountToBorrow); + }); }); });