- The relay
- 0xaBcC9b596420A9E9172FD5938620E265a0f9Df92
- current implementation: 0xe20a2c705bfa7ba81ca3a00eb54c4f496c1e1f77
- 0xBf175FCC7086b4f9bd59d5EAE8eA67b8f940DE0d
- 0xaBcC9b596420A9E9172FD5938620E265a0f9Df92
- Contracts that inherited from
GelatoRelayContext
and use_transferRelayFee()
method to pay the relayer are vulnerable. - Similar issues may also occur with contracts inherited from
GelatoRelayContextERC2771
as it implements the fee payment in a similar way.
- ETH:0xf6f02e017870859e7265010bb6ffb0664747169f
- Polygon:0xfea5b6d5f990ebdff4e8b103eddeb4279f4efd51
- BSC:0xfc868f1d35a4a19a707c57519706fb72594176bd
- Arbitrum:0xf42647d472b6d2299eb283081714c8657e657295
The GelatoRelay is a trusted contract that could collect relay fee from clients' smart contract. It is designed to be trusted and thus the funds that are in the target contract is at GelatoRelay's disposal. As per design, callWithSyncFeeV2
in GelatoRelay.sol
is guarded by the onlyGelato
modifier.
As the target contract inherits from GelatoRelayContext
, the _transferRelayFee()
is called by the GelatoRelay.sol
. _getFeeCollector()
and _getFee()
We found it is possilbe to encode arbitrary feeCollector
, feeToken
,fee
in the calldata and have it relayed by the gelato relay through sponsoredCall
. Since sponsoredCall
transactions are also relayed from the same contract as the one for the callWithSyncFeeV2
, the smart contract can not distinguished whether the encoded fee parameters is from a legit callWithSyncFeeV2
call or a sponsoredCall
call with malacious fee parameters. Both types of transactions can pass the onlyGelato
modifier.
This allows exploiter to drain all the funds from contracts that implements _transferRelayFee()
.
Even though the target contract can cap the relay fee with _transferRelayFeeCapped(uint256 _maxFee)
, the exploiter may still be able to drain the contract with multiple transactions.
It's possible to trigger _transferRelayFee()
encoded with aribitray fee receipant and parameters with sponsoredCall()
with the Counter.sol
example provided on the Gelato's documentation. This is an actual relayed transaction on the mumbai testnet.
transaction: https://mumbai.polygonscan.com/tx/0x1e49767d4c5528f8b0dcd2602ba7210f99c80e236d448e2dbe40175a33006d49
We also simulated the transaction on one of the notable vulnerable contracts and showed it's possible drained the funds from the contract. In this example, 1000 USDC (It can be encoded to any number.) is drained by the exploiter.