Skip to content

Latest commit

 

History

History
101 lines (79 loc) · 2.94 KB

008.md

File metadata and controls

101 lines (79 loc) · 2.94 KB

Low Tangerine Cod

High

Anyone can withdraw all usdt from treasury for 1usda

Summary

redeemUSDT doesn't have any validation on input data

Root Cause

redeemUSDT allows to swap all usdt from treasury for 1 usda due to not validation in input data

    function redeemUSDT(
        uint128 usdaAmount,
        uint64 usdaPrice,
        uint64 usdtPrice
    ) external payable nonReentrant whenNotPaused(IMultiSign.Functions(6)) {
        burnedUSDaInRedeem = CDSLib.redeemUSDT(
            Interfaces(
                treasury,
                globalVariables,
                usda,
                usdt,
                borrowing,
                CDSInterface(address(this))
            ),
            burnedUSDaInRedeem,
            usdaAmount,
            usdaPrice,
            usdtPrice
        );

Core_logic/CDS.sol#L506 Any price here can be made by user usdaPrice * usdaAmount) / usdtPrice

    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);

        interfaces.treasury.approveTokens(IBorrowing.AssetName.TUSDT, address(interfaces.cds), usdtAmount);
        // Transfer usdt to user
        bool success = interfaces.usdt.transferFrom(
            address(interfaces.treasury),
            msg.sender,
            usdtAmount
        );
        if (!success) revert CDSInterface.CDS_TransferFailed(IBorrowing.AssetName.TUSDT);

        interfaces.globalVariables.setOmniChainData(omniChainData);

        return burnedUSDaInRedeem;
    }

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

call like this redeemUSDT( 1, interfaces.usdt.balanceOf(interfaces.treasury), 1)

Impact

Steall all TUSDT from treasury

PoC

No response

Mitigation

Validate prices that user passes