code-423n4 / 2021-12-amun-findings

0 stars 0 forks source link

`SingleTokenJoin#joinTokenSingle()` Change `inputAmount` to `maxInputAmount` can avoid dust INTERMEDIATE_TOKEN and save gas #215

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

https://github.com/code-423n4/2021-12-amun/blob/98f6e2ff91f5fcebc0489f5871183566feaec307/contracts/basket/contracts/singleJoinExit/SingleTokenJoin.sol#L47-L71

function joinTokenSingle(JoinTokenStruct calldata _joinTokenStruct)
        external
    {
        // ######## INIT TOKEN #########
        IERC20 inputToken = IERC20(_joinTokenStruct.inputToken);

        inputToken.safeTransferFrom(
            msg.sender,
            address(this),
            _joinTokenStruct.inputAmount
        );

        _joinTokenSingle(_joinTokenStruct);

        // ######## SEND TOKEN #########
        uint256 remainingIntermediateBalance = INTERMEDIATE_TOKEN.balanceOf(
            address(this)
        );
        if (remainingIntermediateBalance > 0) {
            INTERMEDIATE_TOKEN.safeTransfer(
                msg.sender,
                remainingIntermediateBalance
            );
        }
    }

SingleTokenJoin#joinTokenSingle() can be changed to:

  1. Calculate amounts of basket underlying tokens required for outputAmount;
  2. Calculate the amount of INTERMEDIATE_TOKEN needed based on the amounts of basket underlying tokens (the output of above);
  3. Calculate the amount of inputToken needed based on the amount of INTERMEDIATE_TOKEN (the output of above);
  4. Transfer only the amount of inputToken required from msg.sender;

This way we can avoid unnecessary dust INTERMEDIATE_TOKEN.