Skip to content
Request an audit

‹ All findings

totalCdsDepositedAmountWithOptionFees is incorrectly reduced in CDSLib::withdrawUser(), leading to stuck option fees

Crit/HighAutonomint·Sherlock · Hedged stablecoin · 4th December 2024CodebaseH-33

Summary

totalCdsDepositedAmountWithOptionFees in CDSLib::withdrawUser() is reduced by:

solidity
totalCdsDepositedAmountWithOptionFees -= (params.cdsDepositDetails.depositedAmount - params.cdsDepositDetails.liquidationAmount + params.optionsFeesToGetFromOtherChain);

This is incorrect as the correct amount to reduce in option fees is params.optionFees - params.optionsFeesToGetFromOtherChain, not optionsFeesToGetFromOtherChain in this chain. As such, depending on the cds amounts of each chain, it will lead to too many/little option fees registered in the local chain, which will lead to stuck option fees.###

Root Cause

In CDSLib.sol:731, totalCdsDepositedAmountWithOptionFees is reduced by the incorrect amount.

Internal pre-conditions

None.

External pre-conditions

None.

Attack Path

  1. Cds depositor withdraws, having option fees, in which params.optionsFeesToGetFromOtherChain is null. Suppose a liquidation happened of 500, deposited amount is 1000 and options fees are 50, the resulting totalCdsDepositedAmountWithOptionFees is :
solidity
totalCdsDepositedAmountWithOptionFees -= (params.cdsDepositDetails.depositedAmount - params.cdsDepositDetails.liquidationAmount + params.optionsFeesToGetFromOtherChain); = 550 - (1000 - 500 + 0) = 50

Note: for simplicity, it was assumed that the liquidation that happened reduced totalCdsDepositedAmountWithOptionFees by 500, which is not precise but it's an okay approximation for this example. The user withdraws the option fees, but the CDS contract still has the 50 option fees stored in totalCdsDepositedAmountWithOptionFees, even though it is not actually backed.

Impact

As totalCdsDepositedAmountWithOptionFees is 50, but the global totalCdsDepositedAmountWithOptionFees is null (it was correctly decreased), it will lead to incorrect calculations when getting the option fees proportions. For example, if someone deposits 1000 cds and another user deposits borrows (suppose it pays more 50 USD), it will add option fees on deposit. Then, when the borrower withdraws and the cds depositor withdraws, getOptionsFeesProportions() will calculate totalOptionFeesInOtherChain as 1050 - 1100, which underflows.

PoC

See above.

Mitigation

The correct code is:

solidity
totalCdsDepositedAmountWithOptionFees -= (params.cdsDepositDetails.depositedAmount - params.cdsDepositDetails.liquidationAmount + (params.optionFees - params.optionsFeesToGetFromOtherChain));