sherlock-audit / 2024-02-jala-swap-judging

6 stars 4 forks source link

mahmud - Less Amount of Wrapped token is sent to the `JalaRouter02` than should be when calling `swapExactTokensForETH` in the `JalaMasterRouter`. #224

Closed sherlock-admin closed 6 months ago

sherlock-admin commented 6 months ago

mahmud

high

Less Amount of Wrapped token is sent to the JalaRouter02 than should be when calling swapExactTokensForETH in the JalaMasterRouter.

Summary

In the swapExactTokensForETH function in the JalaMasterRouter contract, the amount of token sent into the JalaRouter02 contract is less than it should be.

Vulnerability Detail

In the swapExactTokensForETH function in the JalaMasterRouter contract, the input token(underlying) is first wrapped and then the wrapped token is then sent to the JalaRouter02 contract for the swap. The underlying token's decimal is usually less than the wrapped token's decimal(18) and therefore the input amount(in underlying token) is supposed to be multiplied by the decimalOffset to match the decimal of the wrapped token before being sent to the JalaRouter02 contract for the swap. However, the input amount (amountIn) is sent directly to the JalaRouter02 contract without being multiplied by the decimalOffset effectly reducing the amount of wrapped token sent to the JalaRouter02 contract.

Impact

Lesser wrapped tokens are sent to the JalaRouter02 contract than should be.

Code Snippet

https://github.com/sherlock-audit/2024-02-jala-swap/blob/030d3ed54214754301154bce0e58ea534100a7e3/jalaswap-dex-contract/contracts/JalaMasterRouter.sol#L300

Tool used

Manual Review

Recommendation

Get the tokenOffset and multiply it with the amountIn before sending to the JalaRouter02 contract.

function swapExactTokensForETH(
        address originTokenAddress,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override returns (uint256[] memory amounts) {
        address wrappedTokenIn = IChilizWrapperFactory(wrapperFactory).wrappedTokenFor(originTokenAddress);

        require(path[0] == wrappedTokenIn, "MS: !path");
+        uint256 tokenOffset = IChilizWrappedERC20(wrappedTokenIn).getDecimalsOffset();

        TransferHelper.safeTransferFrom(originTokenAddress, msg.sender, address(this), amountIn);
        _approveAndWrap(originTokenAddress, amountIn);
        IERC20(wrappedTokenIn).approve(router, IERC20(wrappedTokenIn).balanceOf(address(this)));

+        amounts = IJalaRouter02(router).swapExactTokensForETH(amountIn * tokenOffset, amountOutMin, path, to, deadline);
    }

Duplicate of #146