Era

ZKsync
FoundryLayer 2
500,000 USDC
View results
Submission Details
Severity: medium
Valid

Incompatibility in `L1ERC20Bridge` contract with ERC20 tokens that do not return boolean on approval (e.g., USDT)

Summary

The IERC20.approve function is utilized in the deposit and _approveFundsToAssetRouter functions of the L1ERC20Bridge contract. However, certain ERC20 tokens, like USDT, do not return a boolean value upon approval, leading to a revert during standard bridging operations.

Vulnerability Details

deposit function of L1ERC20Bridge contract is the entry point of a bridging operation that initiates a deposit by locking funds on the contract and sending the request. In order to deposit the token into L1_ASSET_ROUTER, it forgoes an approval action upon the bridging token asset.
_approveFundsToAssetRouter is called to do the job, which utilizes IERC20.approve function inside. Below is the definition of _approveFundsToAssetRouter:

function _approveFundsToAssetRouter(address _from, IERC20 _token, uint256 _amount) internal returns (uint256) {
uint256 balanceBefore = _token.balanceOf(address(this));
_token.safeTransferFrom(_from, address(this), _amount);
>> bool success = _token.approve(address(L1_ASSET_ROUTER), _amount);
if (!success) {
revert ApprovalFailed();
}
uint256 balanceAfter = _token.balanceOf(address(this));
return balanceAfter - balanceBefore;
}

There is an issue with the _token.approve with tokens such as USDT because certain ERC20 tokens don't strictly follow ERC20 standard and their approve functions don't return a boolean value reflecting the result of approval action. Hence, the success variable won't be true despite having completed approval action and _approveFundsToAssetRouter function will revert with ApprovalFailed error.

Note: Another usage of IERC20.approve is spotted inside despoit function, but it won't be reached in such cases as the function is already reverted with an error in _approveFundsToAssetRouter.

Impact

The issue causes a Denial of Service (DoS) in the L1ERC20Bridge contract for tokens whose approve function does not return a boolean, such as USDT, preventing these tokens from being bridged.

Tools Used

Manual Review

Recommendations

Use OpenZeppelin's SafeERC20.forceApprove instead of IERC20.approve

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`L1ERC20Bridge` Uses Unsafe Approvals - USDT won't work

Support

FAQs

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