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 10 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.