I have a GSN wrapped function which should charge a caller with ERC20 tokens using #transferFrom()
call and assumes that tokens are pre-approved by a caller.
function _preRelayedCall(bytes memory _context) internal returns (bytes32) {
(address from, bytes4 signature) = abi.decode(_context, (address,bytes4));
if (signature == ThisContract(0).myFunction.selector) {
IERC20(address(token)).transferFrom(from, address(this), gsnFee);
}
}
I see that there is a 100K limitation for _preRelayedCall()
method https://github.com/opengsn/gsn/blob/13fa9d029bfa8858519e25ca6f16e717d695bdab/contracts/RelayHub.sol#L48. But my ERC20 token is kind-of MiniMe token and caches balances within each call and has some additional logic. So my #transferFrom()
call consumes more than 100K gas. The fee is constant and doesn’t depend on gas consumed.
The only solution I have now is to charge a user inside the function being wrapped using GSN like this:
function myFunction() external {
if (msg.sender == getHubAddr()) {
IERC20(address(token)).transferFrom(from, address(this), gsnFee);
}
// Do the rest of its logic
}
Meanwhile, the existing GSNRecipientERC20Fee implementation charges fee inside _preRelayed/_postRelayed
hooks.
So the question is…
Is it safe to charge users inside a function being called by GSN, not inside _preRelayed/_postRelayed
and can there be any implications? Or maybe there is a way to provide a custom amount of gas for these hooks?