Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
gitpusha committed Aug 24, 2022
1 parent 23618dc commit fc82e33
Show file tree
Hide file tree
Showing 20 changed files with 10,722 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cache
dist
typechain
83 changes: 83 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"env": {
"commonjs": true,
"es2021": true,
"node": true,
"mocha": true
},
"extends": ["eslint:recommended", "prettier"],
"parserOptions": {
"ecmaVersion": 12
},
// Typescript config
"overrides": [
{
"files": ["*.ts"],
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": "./tsconfig.json" },
"plugins": ["@typescript-eslint", "prettier"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"prettier"
],
"rules": {
"prettier/prettier": "error",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "default",
"format": ["camelCase"]
},
{
"selector": "variable",
"format": ["camelCase", "UPPER_CASE"]
},
{
"selector": "parameter",
"format": ["camelCase"],
"leadingUnderscore": "allow"
},
{
"selector": ["objectLiteralProperty"],
"format": ["camelCase", "PascalCase"]
},
{
"selector": ["classProperty"],
"modifiers": ["private", "static"],
"format": ["PascalCase", "UPPER_CASE"]
},
{
"selector": ["classProperty", "classMethod"],
"modifiers": ["private"],
"format": ["camelCase"],
"leadingUnderscore": "require"
},
{
"selector": ["classProperty", "classMethod"],
"modifiers": ["protected"],
"format": ["camelCase"],
"leadingUnderscore": "require"
},
{
"selector": "typeLike",
"format": ["PascalCase"]
},
{
"selector": ["enumMember"],
"format": ["camelCase", "PascalCase"]
},
{
"selector": "variable",
"types": ["boolean"],
"format": ["PascalCase"],
"prefix": ["is", "should", "has", "can", "did", "will"]
}
]
}
}
]
}
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sol linguist-language=Solidity
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Dependency directory
node_modules

# local env variables
.env

# coverage
coverage
.nyc_output

# cache
.eslintcache

# hardhat
artifacts
cache

# macOS
.DS_Store
*.icloud

# redis
dump.rdb

# typechain
typechain

# typescript
dist

# yarn
yarn-error.log

# VS Code
.vscode

4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

rm -rf node_modules && yarn install && yarn clean && yarn build && yarn lint-staged && yarn lint:sol
4 changes: 4 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# yarn test
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
artifacts
dist
cache
typechain
deployments
10 changes: 10 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"overrides": [
{
"files": "*.sol",
"options": {
"compiler": "0.8.16"
}
}
]
}
46 changes: 46 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"extends": "solhint:recommended",
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"code-complexity": ["error", 5],
"function-max-lines": ["error", 40],
"max-line-length": ["error", 100],
"max-states-count": ["error", 3],
"no-empty-blocks": "error",
"no-unused-vars": "error",
"payable-fallback": "off",
"reason-string": ["off", { "maxLength": 32 }],
"constructor-syntax": "off",
"comprehensive-interface": "off",
"quotes": ["error", "double"],
"const-name-snakecase": "error",
"contract-name-camelcase": "error",
"event-name-camelcase": "error",
"func-name-mixedcase": "error",
"func-param-name-mixedcase": "error",
"modifier-name-mixedcase": "error",
"private-vars-leading-underscore": ["error", { "strict": false }],
"var-name-mixedcase": "error",
"imports-on-top": "error",
"ordering": "error",
"visibility-modifier-order": "error",
"avoid-call-value": "off",
"avoid-low-level-calls": "off",
"avoid-sha3": "error",
"avoid-suicide": "error",
"avoid-throw": "error",
"avoid-tx-origin": "off",
"check-send-result": "error",
"compiler-version": ["error", "^0.8.1"],
"mark-callable-contracts": "off",
"func-visibility": ["error", { "ignoreConstructors": true }],
"multiple-sends": "error",
"no-complex-fallback": "error",
"no-inline-assembly": "off",
"not-rely-on-block-hash": "error",
"not-rely-on-time": "error",
"reentrancy": "error",
"state-visibility": "error"
}
}
4 changes: 4 additions & 0 deletions .solhintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
contracts/functions
contracts/vendor
contracts/interfaces
133 changes: 133 additions & 0 deletions contracts/RelayerFeeContext.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

import {TokenUtils} from "./lib/TokenUtils.sol";

/**
* @dev Context variant with RelayerFee support.
* Use RelayerFeeERC2771Context, if you need ERC2771 support.
* Expects calldata encoding:
* abi.encodePacked(bytes fnArgs, address feeCollectorAddress, address feeToken, uint256 fee)
* Therefore, we're expecting 3 * 32bytes (20hex) (60 hex total) to be appended to normal msgData
* 32bytes (20 hex) start offsets from calldatasize:
* feeCollector: -60
* feeToken: -40
* fee: -20
*/
abstract contract RelayerFeeContext {
using TokenUtils for address;

/// @dev Only use with a safe whitelisted trusted forwarder contract (e.g. GelatoRelay)
address public immutable trustedForwarder;

// RelayerFeeContext
uint256 internal constant _FEE_COLLECTOR_START = 60;
uint256 internal constant _FEE_TOKEN_START = 40;
uint256 internal constant _FEE_START = 20;

modifier isTrustedForwarder() {
require(
_isTrustedForwarder(msg.sender),
"RelayerFeeContextERC2771.isTrustedForwarder"
);
_;
}

constructor(address _trustedForwarder) {
trustedForwarder = _trustedForwarder;
}

function _transferFromThisToRelayerUncapped() internal isTrustedForwarder {
_getFeeTokenUnchecked().transfer(
_getFeeCollectorUnchecked(),
_getFeeUnchecked()
);
}

function _transferFromThisToRelayerCapped(uint256 _maxFee)
internal
isTrustedForwarder
{
uint256 fee = _getFeeUnchecked();
require(
fee <= _maxFee,
"RelayerFeeContextERC2771._transferFromThisToRelayerCapped: maxFee"
);
_getFeeTokenUnchecked().transfer(_getFeeCollectorUnchecked(), fee);
}

function _isTrustedForwarder(address _forwarder)
internal
view
virtual
returns (bool)
{
return _forwarder == trustedForwarder;
}

/// Use RelayerFeeERC2771Context if you expect the ERC2771 behavior.
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}

function _msgData() internal view returns (bytes calldata) {
return
_isTrustedForwarder(msg.sender)
? msg.data[:msg.data.length - _FEE_COLLECTOR_START]
: msg.data;
}

function _getFeeCollector()
internal
view
isTrustedForwarder
returns (address)
{
return
abi.decode(
msg.data[msg.data.length - _FEE_COLLECTOR_START:],
(address)
);
}

function _getFeeToken() internal view isTrustedForwarder returns (address) {
return
abi.decode(
msg.data[msg.data.length - _FEE_TOKEN_START:],
(address)
);
}

function _getFee() internal view isTrustedForwarder returns (uint256) {
return abi.decode(msg.data[msg.data.length - _FEE_START:], (uint256));
}

function _getFeeCollectorUnchecked() internal pure returns (address) {
return
abi.decode(
msg.data[msg.data.length - _FEE_COLLECTOR_START:],
(address)
);
}

function _getFeeTokenUnchecked() internal pure returns (address) {
return
abi.decode(
msg.data[msg.data.length - _FEE_TOKEN_START:],
(address)
);
}

function _getFeeUnchecked() internal pure returns (uint256) {
return abi.decode(msg.data[msg.data.length - _FEE_START:], (uint256));
}

function _encodeRelayerFeeContext(
bytes calldata _fnArgs,
address _feeCollector,
address _feeToken,
uint256 _fee
) internal pure returns (bytes memory) {
return abi.encodePacked(_fnArgs, _feeCollector, _feeToken, _fee);
}
}
Loading

0 comments on commit fc82e33

Please sign in to comment.