Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitter Crepe Lizard - Lack of slippage protection in redeemUSDT #1046

Open
sherlock-admin2 opened this issue Dec 30, 2024 · 0 comments
Open

Comments

@sherlock-admin2
Copy link
Contributor

Bitter Crepe Lizard

Medium

Lack of slippage protection in redeemUSDT

Summary

The redeemUSDT function lacks slippage protection, which could result in users receiving fewer USDT tokens than expected due to market movements. Specifically, the function calculates the USDT amount based on fixed prices (usdaPrice and usdtPrice) without including a minOutputAmount parameter to ensure users receive a minimum acceptable amount of USDT. This exposes users to potential losses during volatile market conditions or delays in transaction execution.

Vulnerability Details

The redeemUSDT function in CDSLib.sol uses fixed prices (usdaPrice and usdtPrice) for calculating the output USDT amount. However, these prices may not reflect the actual exchange rate at the time of transaction execution due to potential market movements or execution delays. Additionall y, there is no mechanism to enforce a minimum acceptable output amount, leaving users vulnerable to slippage.
CDSLib.sol#L382-L418

 function redeemUSDT(
        CDSInterface.Interfaces memory interfaces,
        uint256 burnedUSDaInRedeem,
        uint128 usdaAmount,
        uint64 usdaPrice,
        uint64 usdtPrice
    ) external returns (uint256) { 
        // CHeck the usdaAmount is non zero
        if (usdaAmount == 0) revert CDSInterface.CDS_NeedsMoreThanZero();
        // Check the user has enough usda balance
        if (interfaces.usda.balanceOf(msg.sender) < usdaAmount)
            revert CDSInterface.CDS_Insufficient_USDa_Balance();
        // Increment burnedUSDaInRedeem
        burnedUSDaInRedeem += usdaAmount;
        // GET the omnichain data
        IGlobalVariables.OmniChainData memory omniChainData = interfaces.globalVariables.getOmniChainData();
        // Increment burnedUSDaInRedeem
        omniChainData.burnedUSDaInRedeem += usdaAmount;
        // burn usda
        bool transfer = interfaces.usda.burnFromUser(msg.sender, usdaAmount);
        if (!transfer) revert CDSInterface.CDS_TransferFailed(IBorrowing.AssetName.USDa);
        // calculate the USDT USDa ratio
@>      uint128 usdtAmount = ((usdaPrice * usdaAmount) / usdtPrice);//@audit no slippage

      // more code

The actual exchange rate at execution time could be different from what the user expected when initiating the transaction.

Example Scenario:

- User submits transaction when:
  usdaPrice = $1.00
  usdtPrice = $1.00
- Transaction gets delayed
- Market moves: 
  usdaPrice drops to $0.99
  usdtPrice rises to $1.01

  Calculation:
Original expected: (1.00 * 1000) / 1.00 = 1000 USDT
Actual received: (0.99 * 1000) / 1.01 = 980.19 USDT

Loss: ~19.81 USDT due to market movement

Impact

Users may receive significantly fewer USDT tokens than expected, especially during periods of high market volatility or delayed transaction execution.

Tools Used

Manual Review

Recommendation

Add a minOutputAmount parameter to the redeemUSDT function to ensure users receive a minimum acceptable amount of USDT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant