Skip to content

Latest commit

 

History

History
90 lines (69 loc) · 4.12 KB

095.md

File metadata and controls

90 lines (69 loc) · 4.12 KB

Low Tangerine Cod

High

users will not get usda profits from liquidations

Summary

cds holders do not withdraw share of liquidated usda profits the same like share of collateralAmount.

Root Cause

Protocol does track the amount of usda that are going to cds holders who opted for liquidation but doesn't give it to holders when they withdraw the same way like its happening for liquidated collateral

->        uint128 cdsProfits = (((depositDetail.depositedAmountInETH * depositDetail.ethPriceAtDeposit) / BorrowLib.USDA_PRECISION) / 100) - returnToTreasury - returnToAbond;
        // Liquidation amount in usda needed for liquidation
        uint128 liquidationAmountNeeded = returnToTreasury + returnToAbond;
        // Check whether the cds have enough usda for liquidation
        require(omniChainData.totalAvailableLiquidationAmount >= liquidationAmountNeeded, "Don't have enough USDa in CDS to liquidate");

        // Store the liquidation info in cds
        liquidationInfo = CDSInterface.LiquidationInfo(
            liquidationAmountNeeded,
->            cdsProfits,
            depositDetail.depositedAmount,
            omniChainData.totalAvailableLiquidationAmount,
            depositDetail.assetName,
            ((depositDetail.depositedAmount * exchangeRate) / 1 ether)
        );

Core_logic/borrowLiquidation.sol#L221

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

always happening

Impact

Holders lose their share of liquidated assets.

PoC

No response

Mitigation

+                uint128 usdaToSend;
                for (uint128 i = (liquidationIndexAtDeposit + 1); i <= params.omniChainData.noOfLiquidations; i++) {
                    uint128 liquidationAmount = params.cdsDepositDetails.liquidationAmount;
                    // If the user available liquidation is non zero
                    if (liquidationAmount > 0) {
                        CDSInterface.LiquidationInfo memory liquidationData = omniChainCDSLiqIndexToInfo[i];
                        // Calculate the share by taking ratio between
                        // User's available liquidation amount and total available liquidation amount
                        uint128 share = (liquidationAmount * 1e10) / uint128(liquidationData.availableLiquidationAmount);
                        // Update users available liquidation amount
                        params.cdsDepositDetails.liquidationAmount -= getUserShare(liquidationData.liquidationAmount, share);
+                        usdaToSend += getUserShare(liquidationData.profits, share);
                        // Based on the collateral type calculate the liquidated collateral to give to user
                        if (liquidationData.assetName == IBorrowing.AssetName.ETH) {
                            // increment eth amount
                            params.ethAmount += getUserShare(liquidationData.collateralAmount, share);
                        } else if (liquidationData.assetName == IBorrowing.AssetName.WeETH) {
                            // increment weeth amount and weth amount value
                            weETHAmount += getUserShare(liquidationData.collateralAmount, share);
                            weETHAmountInETHValue += getUserShare(liquidationData.collateralAmountInETHValue, share);
                        } else if (liquidationData.assetName == IBorrowing.AssetName.WrsETH) {
                            // increment rseth amount and rseth amount value
                            rsETHAmount += getUserShare(liquidationData.collateralAmount, share);
                            rsETHAmountInETHValue += getUserShare(liquidationData.collateralAmountInETHValue, share);
                        }
                    }
                }
+                bool success = interfaces.usda.contractTransferFrom(
+                    address(interfaces.treasury),
+                    msg.sender,
+                    usdaToSend
+                ); // transfer amount to msg.sender