The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: medium
Valid

distributeAssets function doesn’t recover liquidated positions debt leaving the protocol to cover the losses

Summary:

The protocol allows users to stake TST and EUROs in the Liquidation Pool, offering rewards derived from borrowing fees and liquidations. However, an issue arises in the liquidation process. When liquidated positions are sold to stakers at a discounted rate, based on their stake proportion, the proceeds from these sales fall short of covering the original debts of the positions. This results in losses for the protocol.

Vulnerability Details:

The distributeAssets function, used in liquidations, disperses assets from liquidated positions to stakers based on their stake's weight and at a discounted rate.

The user's share from the liquidated position is calculated as follows:

uint256 _portion = asset.amount * _positionStake / stakeTotal;

The cost in euros that a user pays for this portion is calculated with a discount based on the initial collateral rate:

uint256 costInEuros = _portion * 10 ** (18 - asset.token.dec) * uint256(assetPriceUsd) / uint256(priceEurUsd)
* _hundredPC / _collateralRate;

However, this discount rate coincides with the rate at which borrowers are liquidated at. This means that when borrowers are liquidated under this rate, the discounted price offered to stakers results in the protocol recovering less than the original debt amount, incurring losses.

function maxMintable() private view returns (uint256) {
return euroCollateral() * ISmartVaultManagerV3(manager).HUNDRED_PC()
/ ISmartVaultManagerV3(manager).collateralRate();
}

Proof Of Concept

Consider this scenario:

User A deposits 110 USD of collateral and borrows 100 EUROs at a collateral rate of 110%.

  • maxMintable = euroCollateral x HUNDRED_PC / collateralRate = 110 x 100000 / 110000 = 100USD

The collateral value drops to 105 USD, triggering liquidation.

The liquidated assets are distributed as follows (assuming 1 staker):

  • _portion = 105 USD x 1 / 1 = 105 USD

  • costInEuros = 105 USD x 1 / 1 x 100000 / 110000 = 95 EUROs

In this example, the liquidated assets are sold for 95 EUROs, less than the initial debt of 100 EUROs, causing the protocol to incur a loss of 5 EUROs.

Impact:

The protocol faces consistent losses in its liquidation process, as it consistently fails to recover the full amount of the initial debt. These losses accumulate with each liquidation.

Tools Used:

  • Manual analysis

Recommendation:

The distributeAssets function needs to be restructured to ensure that the protocol can adequately cover the debt from liquidated positions while still providing stakers with a discount. This could be achieved by adjusting the discount rate applied in the distributeAssets function, ensuring a more balanced and financially sustainable liquidation process.

Updates

Lead Judging Commences

hrishibhat Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

distributeAssets-issue

0xCiphky Submitter
almost 2 years ago
hrishibhat Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Bad-debt

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!