FuelLabs / fuel-bridge

The canonical Fuel bridge mono repo.

Home Page:https://app.fuel.network/portal/bridge

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TOB-FUEL-6: Unable to retrieve Ether from payable contracts

xgreenx opened this issue · comments

Description

The Fuel ERC20 gateway contracts are able to receive Ether without the possibility of retrieving it.
The deposit, depositWithData and finalizeWithdrawal functions of the ERC20 gateway are all marked as payable, accepting Ether as payment.

Figure 6.1: The deposit function in fuel-v2-contracts/contracts/messaging/gateway/FuelERC20Gateway.sol

106    /// @dev Made payable to reduce gas costs
107    function deposit(bytes32 to, address tokenId, bytes32 fuelTokenId, uint256
amount) external payable whenNotPaused {
108       bytes memory messageData = abi.encodePacked(
109           fuelTokenId,
110           bytes32(uint256(uint160(tokenId))),
111           bytes32(uint256(uint160(msg.sender))), //from
112           to,
113           bytes32(amount)
114       );
115       _deposit(tokenId, fuelTokenId, amount, messageData);
116    }

Even though the contracts are not designed to handle Ether payments, the comment suggests that this has been done for gas optimization purposes. However, there exists no logic that would allow Ether that was accidentally sent to the contract to be retrieved.

Exploit Scenario

Alice calls the deposit function to deposit 1 WETH to the Fuel chain, but she accidentally also sends 1 Ether with the transaction. The transaction succeeds, and her WETH will be bridged. However, Alice is unable to retrieve the 1 Ether.

Recommendations

Short term, mark the functions as non-payable or include logic that would allow Ether to be retrieved.

Long term, carefully weigh the use of gas cost saving mechanisms against the footguns that such optimizations introduce. Protecting the user should be given priority over saving a small amount of gas.