sherlock-audit / 2024-05-midas-judging

13 stars 6 forks source link

joicygiore - Due to the token decimal conversion involved, `mTBILL::mint()` and `mTBILL::mint()` should add additional checks, otherwise the 1:1 price ratio will be broken #95

Closed sherlock-admin4 closed 6 months ago

sherlock-admin4 commented 6 months ago

joicygiore

medium

Due to the token decimal conversion involved, mTBILL::mint() and mTBILL::mint() should add additional checks, otherwise the 1:1 price ratio will be broken

Summary

Due to the token decimal conversion involved, mTBILL::mint() and mTBILL::mint() should add additional checks, otherwise the 1:1 price ratio will be broken and some dust will be generated.

Vulnerability Detail

1e6 USDC can be exchanged for 1e18 mTBILL. Due to the limitation of decimal points, 99999999999999999999 mTBILL can only be exchanged for 99999999 USDC, and 99999999 USDC can only be exchanged for 999999990000000000000 mTBILL, so the actual mint and burn amounts should be integer multiples of 1e12. Although this is a small difference, it is more in line with the 1:1 price required by the sponsor.

    function mint(address to, uint256 amount)
        external
        onlyRole(M_TBILL_MINT_OPERATOR_ROLE, msg.sender)
    {
@>        _mint(to, amount);
    }

    /**
     * @inheritdoc IMTbill
     */
    function burn(address from, uint256 amount)
        external
        onlyRole(M_TBILL_BURN_OPERATOR_ROLE, msg.sender)
    {
@>        _burn(from, amount);
    }
FixedPointMathLib.divWadDown(9999999000000000000,9999999999999999999) // 999999900000000000
FixedPointMathLib.divWadDown(9999999000000000000,9999999000000000000) // 1000000000000000000

Impact

Due to the token decimal conversion involved, mTBILL::mint() and mTBILL::mint() should add additional checks, otherwise the 1:1 price ratio will be broken and some dust will be generated.

Code Snippet

https://github.com/sherlock-audit/2024-05-midas/blob/main/midas-contracts/contracts/mTBILL.sol#L37-L52

Tool used

Manual Review

Recommendation

Add amount check

    function mint(address to, uint256 amount)
        external
        onlyRole(M_TBILL_MINT_OPERATOR_ROLE, msg.sender)
    {
+       require(amount % 1e12 == 0,'amount error');
        _mint(to, amount);
    }

    /**
     * @inheritdoc IMTbill
     */
    function burn(address from, uint256 amount)
        external
        onlyRole(M_TBILL_BURN_OPERATOR_ROLE, msg.sender)
    {
+       require(amount % 1e12 == 0,'amount error');
        _burn(from, amount);
    }

The same check can be applied to DepositVault::deposit(), and the deposit amount is also an integer multiple of 1e12. Otherwise, due to decimal conversion, there will be a deviation between the content in the event and the amount received by tokensReceiver, which is not conducive to data query

    function deposit(address tokenIn, uint256 amountUsdIn)
        external
        onlyGreenlisted(msg.sender) 
        whenNotPaused 
    {
+       require(amountUsdIn % 1e12 == 0,'amountUsdIn error');

    }