Skip to content

Commit

Permalink
Allow fee transfer from user to fee collector (#19)
Browse files Browse the repository at this point in the history
* allow fee transfer from user to fee collector

* add support for ERC2771

* rename

* update dependency

* implemented audit recommendations
  • Loading branch information
bennoprice authored Sep 4, 2023
1 parent af36ab7 commit c8e5771
Show file tree
Hide file tree
Showing 4 changed files with 401 additions and 202 deletions.
43 changes: 43 additions & 0 deletions contracts/GelatoRelayContextERC2771.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,49 @@ abstract contract GelatoRelayContextERC2771 is GelatoRelayERC2771Base {
_getFeeToken().transfer(_getFeeCollector(), fee);
}

// DANGER! Only use with onlyGelatoRelayERC2771, onlyGelatoRelayConcurrentERC2771,
// `_isGelatoRelayERC2771` or `_isGelatoRelayConcurrentERC2771` checks
function _transferFromRelayFee() internal {
_getFeeToken().transferFrom(
_getMsgSender(),
_getFeeCollector(),
_getFee()
);
}

// DANGER! Only use with onlyGelatoRelayERC2771, onlyGelatoRelayConcurrentERC2771,
// `_isGelatoRelayERC2771` or `_isGelatoRelayConcurrentERC2771` checks
function _transferFromRelayFeeCapped(uint256 _maxFee) internal {
uint256 fee = _getFee();
require(
fee <= _maxFee,
"GelatoRelayContextERC2771._transferFromRelayFeeCapped: maxFee"
);
_getFeeToken().transferFrom(_getMsgSender(), _getFeeCollector(), fee);
}

// DANGER! Only use with onlyGelatoRelayERC2771, onlyGelatoRelayConcurrentERC2771,
// `_isGelatoRelayERC2771` or `_isGelatoRelayConcurrentERC2771` checks
function _transferFromRelayFeeCappedWithPermit(
uint256 _maxFee,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) internal {
uint256 fee = _getFee();
require(
fee <= _maxFee,
"GelatoRelayContextERC2771._transferFromRelayFeeCappedWithPermit: maxFee"
);

address from = _getMsgSender();
address token = _getFeeToken();

token.permit(from, address(this), _maxFee, _deadline, _v, _r, _s);
token.transferFrom(from, _getFeeCollector(), fee);
}

function _getMsgData() internal view virtual returns (bytes calldata) {
return
_isGelatoRelayERC2771(msg.sender)
Expand Down
27 changes: 26 additions & 1 deletion contracts/lib/TokenUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,45 @@
pragma solidity ^0.8.1;

import {NATIVE_TOKEN} from "../constants/Tokens.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {
IERC20Permit
} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import {
SafeERC20
} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

library TokenUtils {
using SafeERC20 for IERC20;
using SafeERC20 for IERC20Permit;

modifier onlyERC20(address _token) {
require(_token != NATIVE_TOKEN, "TokenUtils.onlyERC20");
_;
}

function permit(
address _token,
address _owner,
address _spender,
uint256 _value,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) internal onlyERC20(_token) {
IERC20Permit(_token).safePermit(
_owner,
_spender,
_value,
_deadline,
_v,
_r,
_s
);
}

function transfer(
address _token,
address _to,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
},
"license": "MIT",
"dependencies": {
"@openzeppelin/contracts": "4.8.3"
"@openzeppelin/contracts": "4.9.3"
},
"devDependencies": {
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
Expand All @@ -57,7 +57,7 @@
"eslint-plugin-prettier": "4.2.1",
"ethereum-waffle": "3.4.4",
"ethers": "5.7.0",
"hardhat": "2.11.1",
"hardhat": "2.17.1",
"hardhat-deploy": "0.11.14",
"husky": "8.0.1",
"lint-staged": "13.0.3",
Expand Down
Loading

0 comments on commit c8e5771

Please sign in to comment.