Summary
After we liquidate via liquidation type1 method, all cds owner's liquidation share will change. This will cause some liquidated collateral will be locked.
Root Cause
When one borrow position is unhealthy, the admin will liquidate this position. We will record each liquidated position's needed liquidation amount. When cds owners withdraw their positions, we will loop all liquidated positions to check this position's used liquidated amount.
When we record this liquidated position's needed liquidation amount, we use liquidationAmountNeeded. But we update omniChainData.totalAvailableLiquidationAmount via deducting liquidationAmountNeeded - cdsProfits.
When cds owners withdraw their positions, liquidationAmountNeeded amount will be deducted from their liquidation amount, but we only deduct liquidationAmountNeeded - cdsProfits from the totalAvailableLiquidationAmount. This will cause the left liquidation amount from all cds owners will be less than totalAvailableLiquidationAmount.
For example:
- Alice deposits 2000 USDT/USDA and opt in the liquidation. The liquidation amount is 2000 USDA.
totalAvailableLiquidationAmount= 2000 USDA. - Bob borrows some UDSA and is liquidated because the ether price drops. Assume
liquidationAmountNeeded= 1000 USDA,cdsProfits= 150 USDA. ThentotalAvailableLiquidationAmountafter the first liquidation will be 1150 USDA. - Cathy borrows some USDA and is liquidated because the ether price drops.
- Alice withdraw her position and we will calculate the deducted liquidation amount. 4.1. In the first loop round, share is 100%, we will deduct 1000 from Alice's liquidation amount.
params.cdsDepositDetails.liquidationAmount= 1000. 4.2 In the second loop round,liquidationData.availableLiquidationAmountis 1150 USDA. Alice's share will be less than 100%. But Alice is the only cds owners. Alice cannot get all liquidated collateral. This will cause some liquidated collateral will be locked.
liquidationInfo = CDSInterface.LiquidationInfo(
liquidationAmountNeeded,
cdsProfits,
depositDetail.depositedAmount,
omniChainData.totalAvailableLiquidationAmount,
depositDetail.assetName,
((depositDetail.depositedAmount * exchangeRate) / 1 ether)
);
...
omniChainData.totalAvailableLiquidationAmount -= liquidationAmountNeeded - cdsProfits; for (uint128 i = (liquidationIndexAtDeposit + 1); i <= params.omniChainData.noOfLiquidations; i++) {
uint128 liquidationAmount = params.cdsDepositDetails.liquidationAmount;
if (liquidationAmount > 0) {
CDSInterface.LiquidationInfo memory liquidationData = omniChainCDSLiqIndexToInfo[i];
uint128 share = (liquidationAmount * 1e10) / uint128(liquidationData.availableLiquidationAmount);
params.cdsDepositDetails.liquidationAmount -= getUserShare(liquidationData.liquidationAmount, share);
...
}Internal pre-conditions
N/A
External pre-conditions
N/A
Attack Path
- Alice deposits 2000 USDT/USDA and opt in the liquidation. The liquidation amount is 2000 USDA.
totalAvailableLiquidationAmount= 2000 USDA. - Bob borrows some UDSA and is liquidated because the ether price drops. Assume
liquidationAmountNeeded= 1000 USDA,cdsProfits= 150 USDA. ThentotalAvailableLiquidationAmountafter the first liquidation will be 1150 USDA. - Cathy borrows some USDA and is liquidated because the ether price drops.
- Alice withdraw her position and we will calculate the deducted liquidation amount. 4.1. In the first loop round, share is 100%, we will deduct 1000 from Alice's liquidation amount.
params.cdsDepositDetails.liquidationAmount= 1000. 4.2 In the second loop round,liquidationData.availableLiquidationAmountis 1150 USDA. Alice's share will be less than 100%. But Alice is the only cds owners. Alice cannot get all liquidated collateral. This will cause some liquidated collateral will be locked.
Impact
Some liquidated collateral will be locked.
PoC
N/A