You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
liquidationProtocolFeeAmount are not subtracted from the collaterals of borrower during the liquidation process.
Summary
Liquidation process does not consider liquidationProtocolFeeAmount as burned collateral from the borrower, leaving this amount on his PositionBalance.
Vulnerability Detail
During a liquidation, the liquidator seizes an amount of the borrower's collaterals while a percentage of them goes to the protocol as liquidationFee. However, during the _burnCollateralTokens() call of LiquidationLogic, the liquidationProtocolFeeAmount, which represents the portion of the collaterals that will go to the protocol, is not burned from the collaterals of the borrower. We can the implementation here :
function _burnCollateralTokens(
DataTypes.ReserveData storagecollateralReserve,
DataTypes.ExecuteLiquidationCallParams memoryparams,
LiquidationCallLocalVars memoryvars,
DataTypes.PositionBalance storagebalances,
DataTypes.ReserveSupplies storagetotalSupplies
) internal {
DataTypes.ReserveCache memory collateralReserveCache = collateralReserve.cache(totalSupplies);
collateralReserve.updateState(params.reserveFactor, collateralReserveCache);
collateralReserve.updateInterestRates(
totalSupplies,
collateralReserveCache,
params.collateralAsset,
IPool(params.pool).getReserveFactor(),
0,
@> vars.actualCollateralToLiquidate,
params.position,
params.data.interestRateData
);
// Burn the equivalent amount of aToken, sending the underlying to the liquidator
@> balances.withdrawCollateral(totalSupplies, vars.actualCollateralToLiquidate, collateralReserveCache.nextLiquidityIndex);
IERC20(params.collateralAsset).safeTransfer(msg.sender, vars.actualCollateralToLiquidate);
}
As we can see, the only amount that will be subtracted from the collaterals of the borrower and will deflate his supplyShares is the vars.actualCollateralToLiquidate which is the liquidator's portion. When is the time to handle the liquidationProtocolFeeAmount, we can see that it just performs the safe transfer out without updating neither the colaterals of the borrower nor the underlyingBalance of the reserve and the interest rates. We can see this implementation here :
function executeLiquidationCall(
mapping(address=> DataTypes.ReserveData) storagereservesData,
mapping(uint256=>address) storagereservesList,
mapping(address=>mapping(bytes32=> DataTypes.PositionBalance)) storagebalances,
mapping(address=> DataTypes.ReserveSupplies) storagetotalSupplies,
mapping(bytes32=> DataTypes.UserConfigurationMap) storageusersConfig,
DataTypes.ExecuteLiquidationCallParams memoryparams
) external// ..._burnCollateralTokens(
collateralReserve, params, vars, balances[params.collateralAsset][params.position], totalSupplies[params.collateralAsset]
);
// Transfer fee to treasury if it is non-zeroif (vars.liquidationProtocolFeeAmount !=0) {
uint256 liquidityIndex = collateralReserve.getNormalizedIncome();
uint256 scaledDownLiquidationProtocolFee = vars.liquidationProtocolFeeAmount.rayDiv(liquidityIndex);
uint256 scaledDownUserBalance = balances[params.collateralAsset][params.position].supplyShares;
if (scaledDownLiquidationProtocolFee > scaledDownUserBalance) {
vars.liquidationProtocolFeeAmount = scaledDownUserBalance.rayMul(liquidityIndex);
}
@>IERC20(params.collateralAsset).safeTransfer(IPool(params.pool).factory().treasury(), vars.liquidationProtocolFeeAmount);
}
// ...
Since the liquidationProtocolFeeAmount is not subtracted from the borrower's collaterals during the liquidation process, the borrower's PositionBalance remains artificially inflated. This discrepancy may cause inconsistencies in accounting, potentially allowing the borrower to access more liquidity or reducing the effectiveness of future liquidations. Moreover, it could lead to incorrect protocol state and affect the calculation of other parameters like interest rates or underlyingBalance of the reserve.
sherlock-admin3
changed the title
Polished Iris Antelope - liquidationProtocolFeeAmount are not subtracted from the collaterals of borrower during the liquidation process.
zarkk01 - liquidationProtocolFeeAmount are not subtracted from the collaterals of borrower during the liquidation process.
Oct 3, 2024
zarkk01
High
liquidationProtocolFeeAmount
are not subtracted from the collaterals of borrower during the liquidation process.Summary
Liquidation process does not consider
liquidationProtocolFeeAmount
as burned collateral from the borrower, leaving this amount on hisPositionBalance
.Vulnerability Detail
During a liquidation, the liquidator seizes an amount of the borrower's collaterals while a percentage of them goes to the protocol as
liquidationFee
. However, during the_burnCollateralTokens()
call ofLiquidationLogic
, theliquidationProtocolFeeAmount
, which represents the portion of the collaterals that will go to the protocol, is not burned from the collaterals of the borrower. We can the implementation here :Link to code
As we can see, the only amount that will be subtracted from the collaterals of the borrower and will deflate his
supplyShares
is thevars.actualCollateralToLiquidate
which is the liquidator's portion. When is the time to handle theliquidationProtocolFeeAmount
, we can see that it just performs the safe transfer out without updating neither the colaterals of the borrower nor theunderlyingBalance
of the reserve and the interest rates. We can see this implementation here :Link to code
Impact
Since the
liquidationProtocolFeeAmount
is not subtracted from the borrower's collaterals during the liquidation process, the borrower'sPositionBalance
remains artificially inflated. This discrepancy may cause inconsistencies in accounting, potentially allowing the borrower to access more liquidity or reducing the effectiveness of future liquidations. Moreover, it could lead to incorrect protocol state and affect the calculation of other parameters like interest rates orunderlyingBalance
of the reserve.Code Snippet
https://github.com/sherlock-audit/2024-06-new-scope/blob/main/zerolend-one/contracts/core/pool/logic/LiquidationLogic.sol#L94
https://github.com/sherlock-audit/2024-06-new-scope/blob/main/zerolend-one/contracts/core/pool/logic/LiquidationLogic.sol#L207
Tool used
Manual Review
Recommendation
Consider implementing this change so to assure that the calculations are right during the liquidation process :
Duplicate of #228
The text was updated successfully, but these errors were encountered: