Smart contract unable to operate due to lack of token funds
Description
Brief/Intro
Liquidator will ended with underflow exception while normal liquidation process acquiring the borrow balance of the violator
Vulnerability Details
Liquidation is normal process in market when loan went to underCollateralized normally liquidator acquire the assets by calling executeLiquidate() function in LoanManagerLogic from hub. But inside this this function which calls the updateLiquidationBorrows() to transfer the funds from the Violator to liquidator here it calls the transferBorrowFromViolator() function in order to repay and decrease the balance of the violator . Below code snippet we can see :-
/// @dev Calc the borrow balance and amount to repay and decrease them from violator borrow/// @param loan The user loan to transfer the borrow from/// @param poolId The pool ID of the borrow/// @param repayBorrowAmount The amount to repay/// @return repaidBorrowAmount The borrow amount repaid/// @return repaidBorrowBalance The borrow balance repaidfunctiontransferBorrowFromViolator(LoanManagerState.UserLoanstorage loan,uint8 poolId,uint256 repayBorrowAmount ) externalreturns (uint256 repaidBorrowAmount,uint256 repaidBorrowBalance,uint256 loanStableRate) { LoanManagerState.UserLoanBorrow storage loanBorrow = loan.borrows[poolId];// violator loanBorrow has beed updated in prepareLiquidation repaidBorrowBalance = repayBorrowAmount; repaidBorrowAmount = Math.min(repaidBorrowBalance, loanBorrow.amount);// @audit check here loanStableRate = loanBorrow.stableInterestRate; loanBorrow.amount -= repaidBorrowAmount; loanBorrow.balance -= repaidBorrowBalance; // @audit check hereif (loanBorrow.balance ==0) clearBorrow(loan, poolId); }
In above we see that balance will be decreased by the liquidator parameter repayAmount. [https://github.com/Folks-Finance/folks-finance-xchain-contracts/blob/main/contracts/hub/Hub.sol#L118] Which will directly subtract with violator borrow balance after that if the borrow balance is zero then it will clear the borrow here is main issue without validation the user input it will directly subtracts with loanBorrow.
For Scenario We look below numbers :-
In above we can see the balances of violator and liquidator before liquidation which is fetch from the user defined functions.
Violator have borrow 1000 USDC and underCollateralized Liquidator tries to acquire by paying 965 USDC but it will halt the process by panic code 0x11 underFlow or overflow Vm exception. Liquidator by seeing the violator borrow balance and try to acquire by lesser amount than the borrow balance it will landed in halted in hub chain.
Impact Details
1 . Temporary blocks the liquidation process and liquidator funds.
2 . Liquidator doesn't allow to acquire the default loans ended with exception which will cause halt of normal process in VM because it not handle with try catch.
3 . Smart contracts which is associated with Liquidation Logic will not be able to access due to the error while acquiring the borrow balance.
The above impact assessed with protocol, if any query please ping me.
1 . Add the check if repayBorrowAmount which is liquidator input is greater than the violator balance cause the panic error if so, then no need to subtract
Then we can clear the balance.
2 . Add mechanism that how much can liquidator can repay to acquire full borrow balance to prevent the panic code error.
Proof of concept
Proof of Concept
Output :-
In the above we can see the balances of both violator and liquidator before liquidation when initiate the liquidate function it halt by panic error.
LoanManager (unit tests)
Deployment
✔ Should set admin and contracts correctly (1537ms)
Liquidate the Just Borrowed loan
Violator Borrow Balance Before Liquidation 1000000000n
Violator Collateral Balance Before Liquidation 1000000000000000000n
Liquidator Borrow Balance Before Liquidation 0n
Liquidator Collateral Balance Before Liquidation 1000000000n
Repay Amount 965000000n
1) Should successfully liquidate stable borrow when seizing new borrow and collateral
1 passing (2s)
1 failing
1) LoanManager (unit tests)
Liquidate the Just Borrowed loan
Should successfully liquidate stable borrow when seizing new borrow and collateral:
Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)
at UserLoanLogic.transferBorrowFromViolator (contracts/hub/logic/UserLoanLogic.sol:128)
at LiquidationLogic.updateLiquidationBorrows (contracts/hub/logic/LiquidationLogic.sol:49)
at LoanManagerLogic.executeLiquidate (contracts/hub/logic/LoanManagerLogic.sol:478)
at LoanManager.liquidate (contracts/hub/LoanManager.sol:248)
at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:427:41)
at async HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)
at async send (node_modules/ethers/src.ts/contract/contract.ts:313:20)
at async Proxy.liquidate (node_modules/ethers/src.ts/contract/contract.ts:352:16)
at async Context.<anonymous> (test/hub/Rebalance.test.ts:780:27)