Light ModeLight
Light ModeDark

One Bug Per Day

One H/M every day from top Wardens

Checkmark

Join over 1120 wardens!

Checkmark

Receive the email at any hour!

Ad

Incorrect accounting of utilization, supply / borrow rates due to vulnerable implementation in IsolateLogic::executeIsolateLiquidate

mediumCode4rena

Lines of code

https://github.com/code-423n4/2024-07-benddao/blob/117ef61967d4b318fc65170061c9577e674fffa1/src/libraries/logic/IsolateLogic.sol#L461

Vulnerability details

Impact

Incorrect accounting of utilization, supply / borrow rates due to vulnerable implementation in IsolateLogic::executeIsolateLiquidate.

Proof of Concept

When an isolate loan ( borrow against a single nft token) is auctioned and liquidated, the liquidator (caller of IsolateLogic::executeIsolateLiquidate) may need to repay extra amount of debt(vars.totalExtraAmount) if the bid amount doesn't fully cover total debt(vars.totalBorrowAmount).

The problem is the above case is not correctly implemented when interests rates are updated (InterestLogic.updateInterestRates(poolData, debtAssetData, (vars.totalBorrowAmount + vars.totalExtraAmount), 0)).

In InterestLogic::updateInterestRates, utilization is recalculated based on liquidityAdded and liquidityTaken. In the context of IsolateLogic::executeIsolateLiquidate, the liquidtyAdded for a loan is the repayment of debt (vars.borrowAmount) which includes loanData.bidAmount + extraAmount.

solidity
//src/libraries/logic/IsolateLogic.sol function executeIsolateLiquidate(InputTypes.ExecuteIsolateLiquidateParams memory params) internal { ... for (vars.nidx = 0; vars.nidx < params.nftTokenIds.length; vars.nidx++) { ... // Last bid can not cover borrow amount and liquidator need pay the extra amount if (loanData.bidAmount < vars.borrowAmount) { |> vars.extraBorrowAmounts[vars.nidx] = vars.borrowAmount - loanData.bidAmount;//@audit-info note: vars.borrowAmount = extraAmount + loanData.bidAmount } ... // update interest rate according latest borrow amount (utilizaton) //@audit (vars.totalBorrowAmount + vars.totalExtraAmount) is incorrect input, which inflates `liquidityAdded` in updateInterestRates. |> InterestLogic.updateInterestRates(poolData, debtAssetData, (vars.totalBorrowAmount + vars.totalExtraAmount), 0); // bid already in pool and now repay the borrow but need to increase liquidity //@audit-info note: only total debt (vars.totalBorrowAmount) are added to liquidity. |> VaultLogic.erc20TransferOutBidAmountToLiqudity(debtAssetData, vars.totalBorrowAmount); ...

(https://github.com/code-423n4/2024-07-benddao/blob/117ef61967d4b318fc65170061c9577e674fffa1/src/libraries/logic/IsolateLogic.sol#L461)

In InterestLogic::updateInterestRates, (vars.totalBorrowAmount + vars.totalExtraAmount) inflates liquidityAdded, which inflates vars.availableLiquidityPlusDebt and deflates utilization rate vars.assetUtilizationRate. This will cause an inflated borrow rate / supply rate based on the interest rate model.

solidity
function updateInterestRates( DataTypes.PoolData storage poolData, DataTypes.AssetData storage assetData, uint256 liquidityAdded, uint256 liquidityTaken ) internal { ... // calculate the total asset supply vars.availableLiquidityPlusDebt = assetData.availableLiquidity + |> liquidityAdded - liquidityTaken + vars.totalAssetDebt; if (vars.availableLiquidityPlusDebt > 0) { vars.assetUtilizationRate = vars.totalAssetDebt.rayDiv(vars.availableLiquidityPlusDebt); } ... vars.nextGroupBorrowRate = IInterestRateModel(loopGroupData.rateModel).calculateGroupBorrowRate( vars.loopGroupId, vars.assetUtilizationRate ); ...

(https://github.com/code-423n4/2024-07-benddao/blob/117ef61967d4b318fc65170061c9577e674fffa1/src/libraries/logic/InterestLogic.sol#L165)

Flows: IsolateLiquidation::isolateLiquidate ->IsolateLogic.executeIsolateLiquidate -> InterestLogic.updateInterestRates

Tools Used

Manual

Recommended Mitigation Steps

Consider changing into InterestLogic.updateInterestRates(poolData, debtAssetData, vars.totalBorrowAmount, 0)

Assessed type

Error