MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: low
Invalid

Unsafe ERC20 Method across multiple contracts, resulting in unexpected behavior and malfunction

Summary

ERC20 functions may not behave as expected.

For example: return values are not always meaningful.

Among other issues, if the approve, transfer, or transferFrom fails, it will not be known immediately.

Vulnerability Details

The ERC20 standard does not require approve and other functions to return a boolean indicating success.

ERC20 tokens do not have a standardized return value for the transfer and transferFrom functions.

Some implementations might not return a value, while others could return false on failure instead of reverting the transaction. This can lead to unexpected behavior if the return value is not properly checked.

In the provided code, the direct call to approve on the IERC20 interface does not check the return value:

Found in contracts/L1Sender.sol Line: 69

IERC20(unwrappedDepositToken).approve(oldToken_, 0);

transferFrom example -
Found in contracts/mock/GatewayRouterMock.sol Line: 15

IERC20(_token).transferFrom(msg.sender, _to, _amount);

There are other instances of these (check github attachments above).

Previous similar findings in other contests:

Impact

This is not ideal for unsafe ERC20 approve,transfer,transferFrom that do not handle non-standard erc20 behavior.

The contract will malfunction for certain tokens. Resulting in silent failures, that will cause the entire contract or parts of the contract to break/ not behave as intended.

This might even result in financial loss.

Tools Used

Manual Review, Analyzer, AI

Recommendations

OpenZeppelin's SafeERC20 library wraps ERC20 functions and ensures that they behave as expected, regardless of the token implementation. It reverts the transaction if the token contract does not return true (or if it does not return any value, which is interpreted as false).

To mitigate potential issues with non-compliant ERC20 tokens, it is recommended to use SafeERC20 for interactions with ERC20 tokens. Here's how you would use SafeERC20 to safely call approve, transfer and transferFrom:

  1. First, import the library:

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
  1. Then include this line inside the contract code:

using SafeERC20 for IERC20;
  1. Now, make changes to all these lines, across 4 contracts:


approve > safeIncreaseAllowance() or safeDecreaseAllowance(), as per need.

Change in contracts/L1Sender.sol Line: 69

Change in contracts/L1Sender.sol Line: 76

Change in contracts/L1Sender.sol Line: 91

Change in contracts/L1Sender.sol Line: 95

NOTE : We are not switching approve with safeApprove because, safeApprove is deprecated.


Using SafeERC20's safeTransferFrom instead of directly calling transferFrom would be a safer approach to interact with ERC20 tokens in smart contracts.

It reverts the transaction if the token does not explicitly return true or if the call to the token contract does not use all the provided gas (which is a common indication of a failing transfer or transferFrom).

transferFrom > safeTransferFrom

Change in contracts/mock/GatewayRouterMock.sol Line: 15

IERC20(_token).safeTransferFrom(msg.sender, _to, _amount);

Change in contracts/mock/SwapRouterMock.sol Line: 9

IERC20(params_.tokenIn).safeTransferFrom(msg.sender, address(this), params_.amountIn);

Change in contracts/mock/tokens/WStETHMock.sol Line: 25

stETH.safeTransferFrom(msg.sender, address(this), stETHAmount_);

transfer > safeTransfer

Change in contracts/mock/SwapRouterMock.sol Line: 10

IERC20(params_.tokenOut).safeTransfer(params_.recipient, params_.amountIn);

This changes will ensure that the transaction reverts if the token does not behave as expected, providing a safer interaction with the token contract.

Updates

Lead Judging Commences

inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.