├── .gitattributes ├── contracts ├── 5 │ ├── test │ │ └── MockBasicMetaTxChild.sol │ ├── EternalStorage.sol │ ├── token │ │ ├── erc721 │ │ │ ├── IERC165.sol │ │ │ └── IERC721.sol │ │ └── erc20 │ │ │ └── IERC20.sol │ ├── RelayerManager.sol │ ├── libs │ │ ├── EIP712Base.sol │ │ ├── Ownable.sol │ │ ├── EIP712MetaTx.sol │ │ └── SafeMath.sol │ ├── ImplementationLogic.sol │ ├── IdentityProxy.sol │ ├── WETH9.sol │ ├── dsproxy │ │ ├── MexaDSProxyFactory.sol │ │ └── dsProxy.sol │ ├── BasicMetaTransaction.sol │ ├── ProxyManager.sol │ └── RelayHub.sol └── 6 │ ├── test │ ├── imports.sol │ ├── mockFaucet.sol │ ├── TestToken.sol │ ├── Token.sol │ ├── AggregatorInterface.sol │ ├── TestRecipient.sol │ ├── TestnetDAI.sol │ ├── MockActions.sol │ ├── MockFeeManager.sol │ └── Dai.sol │ ├── interfaces │ ├── IERC20Extented.sol │ ├── IFeeManager.sol │ ├── IERC20Permit.sol │ ├── IRelayRecipient.sol │ ├── IERC20.sol │ └── IERC20EIP2612.sol │ ├── forwarder │ ├── ERC20TransferHandler.sol │ ├── ERC20ForwarderStorage.sol │ ├── ERC20ForwardRequestTypes.sol │ ├── OracleAggregator.sol │ └── ERC20ForwarderProxy.sol │ ├── libs │ ├── Context.sol │ ├── BaseRelayRecipient.sol │ ├── Ownable.sol │ └── Pausable.sol │ ├── insta-swaps │ ├── faucetManager.sol │ ├── ReentrancyGuard.sol │ └── Address.sol │ ├── ExecutorManager.sol │ └── feeManager │ ├── CentralisedFeeManagerWithLimits.sol │ └── CentralisedFeeManager.sol ├── .solcover.js ├── scripts ├── ChangeTransferHandlerGas.js ├── Accounts.js ├── ERC20TransferHandlerDeployer.js ├── BasicMetaTxDeployer.js ├── ExchangeProxyDeployer.js ├── mexaExchangeProxyDeployer.js ├── sample-script.js ├── SetTransferHandlerFeeRinkeby.js ├── TrustedForwarderDeployer.js ├── TrustedForwarderDeployerMatic.js ├── gas-price │ └── get-gas-price.js ├── hyphen-prod-script │ ├── hyphenMatic.js │ └── hyphenEthereum.js ├── hyphen-test-scripts │ ├── InstaExitGoerli.js │ └── InstaExitMumbai.js ├── ForwarderDeployerBinanceTest.js ├── ERC20ForwardersDeployerRinkeby.js ├── ERC20ForwardersDeployerMainnet.js └── ERC20ForwardersDeployerKovan.js ├── LICENSE ├── test ├── helpers │ └── shouldFail.js ├── testRecipientTest.js ├── OracleAggregatorTest.js └── Executor-manager.js ├── package.json ├── .gitignore ├── walletUtils.js ├── README.md └── hardhat.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /contracts/6/test/imports.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2; 3 | 4 | import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mocha: { 3 | grep: "@skip-on-coverage", // Find everything with this tag 4 | invert: true // Run the grep's inverse set. 5 | } 6 | } -------------------------------------------------------------------------------- /contracts/6/interfaces/IERC20Extented.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.7.6; 2 | 3 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 4 | 5 | 6 | abstract contract IERC20Extented is IERC20 { 7 | function decimals() public virtual view returns (uint8); 8 | } -------------------------------------------------------------------------------- /contracts/6/test/mockFaucet.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.8; 3 | 4 | contract mockFaucet{ 5 | 6 | function payUp(address payable to,uint256 amount) external{ 7 | to.transfer(amount); 8 | } 9 | 10 | receive() external payable {} 11 | } -------------------------------------------------------------------------------- /contracts/6/interfaces/IFeeManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.7.6; 3 | 4 | interface IFeeManager{ 5 | function getFeeMultiplier(address user, address token) external view returns (uint16 basisPoints); //setting max multiplier at 6.5536 6 | function getTokenAllowed(address token) external view returns (bool allowed); 7 | } -------------------------------------------------------------------------------- /contracts/5/test/MockBasicMetaTxChild.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.12; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "../BasicMetaTransaction.sol"; 5 | 6 | contract MockBasicMetaTxChild is BasicMetaTransaction { 7 | 8 | uint256 called; 9 | 10 | event Call(bytes4 sig); 11 | 12 | function call() external { 13 | called++; 14 | emit Call(msg.sig); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /scripts/ChangeTransferHandlerGas.js: -------------------------------------------------------------------------------- 1 | async function main() { 2 | //0x78122426ee7a6D35f15c4095b4Aa72A2A6418202 3 | const bf = await ethers.getContractAt("ERC20FeeProxy","0x78122426ee7a6D35f15c4095b4Aa72A2A6418202"); 4 | await bf.setTransferHandlerGas(60000); 5 | } 6 | 7 | main() 8 | .then(() => process.exit(0)) 9 | .catch(error => { 10 | console.error(error); 11 | process.exit(1); 12 | }); -------------------------------------------------------------------------------- /scripts/Accounts.js: -------------------------------------------------------------------------------- 1 | async function main() { 2 | const accounts = await ethers.getSigners(); 3 | const data = await Promise.all(accounts.map(account => account.getAddress())) 4 | console.log(data); 5 | //just to verify 6 | const acc0Address = accounts[0].getAddress(); 7 | console.log("account0 address ",acc0Address); 8 | } 9 | 10 | main() 11 | .then(() => process.exit(0)) 12 | .catch(error => { 13 | console.error(error); 14 | process.exit(1); 15 | }); -------------------------------------------------------------------------------- /scripts/ERC20TransferHandlerDeployer.js: -------------------------------------------------------------------------------- 1 | async function main() { 2 | const ERC20TransferHandler = await hre.ethers.getContractFactory("ERC20TransferHandler"); 3 | const erc20TransferHandler = await ERC20TransferHandler.deploy("0xBFA21CD2F21a8E581E77942B2831B378d2378E69"); 4 | await erc20TransferHandler.deployed(); 5 | console.log("ERC20 Transfer Handler Address " + erc20TransferHandler.address); 6 | } 7 | 8 | 9 | main() 10 | .then(() => process.exit(0)) 11 | .catch(error => { 12 | console.error(error); 13 | process.exit(1); 14 | }); -------------------------------------------------------------------------------- /contracts/6/test/TestToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.8; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | // Mocks BPool by receiving tokenA in and minting tokenB 1:1 7 | 8 | contract TestToken is ERC20{ 9 | ERC20 internal WETH; 10 | 11 | constructor(address _WETH) public ERC20("TEST","TEST"){ 12 | WETH = ERC20(_WETH); 13 | } 14 | 15 | function mint(uint256 amount) public{ 16 | WETH.transferFrom(msg.sender,address(this),amount); 17 | _mint(msg.sender,amount); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /contracts/6/test/Token.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.8; 3 | 4 | // import "centre-tokens/contracts/v2/FiatTokenV2.sol"; 5 | 6 | /** 7 | * Basic token only for testing 8 | */ 9 | contract Token { 10 | constructor(string memory name, string memory symbol, uint256 initialBalance) public { 11 | 12 | // initialize(name, symbol, "USD", 18, msg.sender, msg.sender, msg.sender, msg.sender); 13 | // DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(name, "1"); 14 | //_initializedV2 = true; 15 | 16 | // balances[msg.sender] = initialBalance; 17 | } 18 | } -------------------------------------------------------------------------------- /contracts/6/test/AggregatorInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.0; 3 | 4 | //copied from chainlink 5 | 6 | interface AggregatorInterface { 7 | function latestAnswer() external view returns (int256); 8 | function latestTimestamp() external view returns (uint256); 9 | function latestRound() external view returns (uint256); 10 | function getAnswer(uint256 roundId) external view returns (int256); 11 | function getTimestamp(uint256 roundId) external view returns (uint256); 12 | 13 | event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); 14 | event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); 15 | } -------------------------------------------------------------------------------- /scripts/BasicMetaTxDeployer.js: -------------------------------------------------------------------------------- 1 | const bre = require("@nomiclabs/buidler"); 2 | 3 | //{gasLimit:"4000000"} 4 | 5 | async function main() { 6 | const BasicMetaTx = await ethers.getContractFactory("BasicMetaTransaction"); 7 | const basicMetaTx = await BasicMetaTx.deploy(); 8 | await basicMetaTx.deployed(); 9 | console.log("ExchangeProxy at ",basicMetaTx.address); 10 | const deploymentData = await basicMetaTx.deployTransaction.wait(); 11 | console.log(deploymentData); 12 | } 13 | 14 | // We recommend this pattern to be able to use async/await everywhere 15 | // and properly handle errors. 16 | main() 17 | .then(() => process.exit(0)) 18 | .catch(error => { 19 | console.error(error); 20 | process.exit(1); 21 | }); -------------------------------------------------------------------------------- /contracts/6/test/TestRecipient.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.7.6; 3 | 4 | import "../libs/BaseRelayRecipient.sol"; 5 | 6 | 7 | contract TestRecipient is BaseRelayRecipient{ 8 | 9 | mapping (address=>uint) public callsMade; 10 | 11 | constructor(address forwarder) public{ 12 | trustedForwarder = forwarder; 13 | } 14 | 15 | function doCall(address sender) external{ 16 | require(_msgSender() == sender); 17 | callsMade[sender]++; 18 | } 19 | 20 | function nada() external { 21 | 22 | } 23 | 24 | function nadaRevert() external { 25 | require(1 == 2,"custom force revert"); 26 | } 27 | 28 | function versionRecipient() external virtual override view returns (string memory){return "1";} 29 | 30 | } -------------------------------------------------------------------------------- /contracts/5/EternalStorage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.13; 2 | 3 | contract EternalStorage { 4 | event Forwarded(address indexed destination, uint256 amount, bytes data); 5 | event Received(address indexed sender, uint256 amount); 6 | event Withdraw(address indexed receiver, uint256 amount); 7 | 8 | mapping(uint256 => uint256) public batchNonce; 9 | address public creator; 10 | address public manager; 11 | address public implementation; 12 | 13 | /* Upgradable Storage */ 14 | mapping(bytes32 => uint256) uIntStorage; 15 | mapping(bytes32 => string) stringStorage; 16 | mapping(bytes32 => address) addressStorage; 17 | mapping(bytes32 => bytes) bytesStorage; 18 | mapping(bytes32 => bool) boolStorage; 19 | mapping(bytes32 => int256) intStorage; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /contracts/6/interfaces/IERC20Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity 0.7.6; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IERC20Detailed is IERC20 { 7 | function name() external view returns(string memory); 8 | function decimals() external view returns(uint256); 9 | } 10 | 11 | interface IERC20Nonces is IERC20Detailed { 12 | function nonces(address holder) external view returns(uint); 13 | } 14 | 15 | interface IERC20Permit is IERC20Nonces { 16 | function permit(address holder, address spender, uint256 nonce, uint256 expiry, 17 | bool allowed, uint8 v, bytes32 r, bytes32 s) external; 18 | 19 | function permit(address holder, address spender, uint256 value, uint256 expiry, 20 | uint8 v, bytes32 r, bytes32 s) external; 21 | } -------------------------------------------------------------------------------- /contracts/6/forwarder/ERC20TransferHandler.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.7.6; 3 | pragma experimental ABIEncoderV2; 4 | 5 | //to do, seperate into forwarderWithPersonalSign.sol and ERC20Forwarder.sol 6 | 7 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 8 | import "../libs/BaseRelayRecipient.sol"; 9 | import "@openzeppelin/contracts/math/SafeMath.sol"; 10 | 11 | contract ERC20TransferHandler is BaseRelayRecipient{ 12 | 13 | constructor(address _forwarder) public { 14 | trustedForwarder = _forwarder; 15 | } 16 | 17 | function versionRecipient() external virtual view override returns (string memory){ return "1";} 18 | 19 | function transfer(address token, address to, uint256 amount) external{ 20 | require(IERC20(token).transferFrom(_msgSender(),to,amount)); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /scripts/ExchangeProxyDeployer.js: -------------------------------------------------------------------------------- 1 | const bre = require("@nomiclabs/buidler"); 2 | 3 | //{gasLimit:"4000000"} 4 | 5 | async function main() { 6 | const ExchangeProxy = await ethers.getContractFactory("ExchangeProxy"); 7 | const exchangeProxy = await ExchangeProxy.deploy("0xd0a1e359811322d97991e03f863a0c30c2cf029c",{gasLimit:ethers.BigNumber.from("9500000")}); 8 | await exchangeProxy.deployed(); 9 | console.log("ExchangeProxy at ",exchangeProxy.address); 10 | const deploymentData = await exchangeProxy.deployTransaction.wait(); 11 | console.log(deploymentData); 12 | } 13 | 14 | // We recommend this pattern to be able to use async/await everywhere 15 | // and properly handle errors. 16 | main() 17 | .then(() => process.exit(0)) 18 | .catch(error => { 19 | console.error(error); 20 | process.exit(1); 21 | }); 22 | -------------------------------------------------------------------------------- /contracts/5/token/erc721/IERC165.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | /** 4 | * @dev Interface of the ERC165 standard, as defined in the 5 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 6 | * 7 | * Implementers can declare support of contract interfaces, which can then be 8 | * queried by others ({ERC165Checker}). 9 | * 10 | * For an implementation, see {ERC165}. 11 | */ 12 | interface IERC165 { 13 | /** 14 | * @dev Returns true if this contract implements the interface defined by 15 | * `interfaceId`. See the corresponding 16 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 17 | * to learn more about how these ids are created. 18 | * 19 | * This function call must use less than 30 000 gas. 20 | */ 21 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 22 | } -------------------------------------------------------------------------------- /contracts/6/test/TestnetDAI.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.8; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | /** 7 | * @title Testnet Dai 8 | * @dev ERC20 minting logic 9 | * Sourced from OpenZeppelin and thoroughly butchered to remove security guards. 10 | * Anybody can mint - STRICTLY FOR TEST PURPOSES 11 | */ 12 | contract TestnetDAI is ERC20{ 13 | 14 | constructor() public ERC20("TestnetDAI", "DAI") {} 15 | 16 | /** 17 | * @dev Function to mint tokens 18 | * @param to The address that will receive the minted tokens. 19 | * @param value The amount of tokens to mint. 20 | * @return A boolean that indicates if the operation was successful. 21 | */ 22 | function mint(address to, uint256 value) public returns (bool) { 23 | _mint(to, value); 24 | return true; 25 | } 26 | } -------------------------------------------------------------------------------- /contracts/5/token/erc20/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | /** 4 | * @title ERC20 interface 5 | * @dev see https://github.com/ethereum/EIPs/issues/20 6 | */ 7 | interface IERC20 { 8 | function totalSupply() external view returns (uint256); 9 | 10 | function balanceOf(address who) external view returns (uint256); 11 | 12 | function allowance(address owner, address spender) external view returns (uint256); 13 | 14 | function transfer(address to, uint256 value) external returns (bool); 15 | 16 | function approve(address spender, uint256 value) external returns (bool); 17 | 18 | function transferFrom(address from, address to, uint256 value) external returns (bool); 19 | 20 | event Transfer(address indexed from, address indexed to, uint256 value); 21 | 22 | event Approval(address indexed owner, address indexed spender, uint256 value); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/6/test/MockActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.8; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | import "./TestToken.sol"; 6 | 7 | // DON'T CALL THIS CONTRACT, USE DELEGATE CALL 8 | // DESIGNED TO BE CALLED BY DSProxy 9 | 10 | // Mock BActions 11 | // - transfers tokens from the forwarder to itself 12 | // - approves the bpoolMock to spend the received token 13 | // - calls bpoolMock 14 | // - receives bpoolMock tokens back 15 | // - transfers those tokens to the receiver 16 | 17 | contract MockActions{ 18 | IERC20 internal WETH; 19 | TestToken internal TokenB; 20 | 21 | constructor(address _WETH,address _TokenB) public{ 22 | WETH = IERC20(_WETH); 23 | TokenB = TestToken(_TokenB); 24 | } 25 | 26 | function joinPool(uint256 amount) public{ 27 | WETH.transferFrom(msg.sender,address(this),amount); 28 | TokenB.mint(amount); 29 | TokenB.transfer(msg.sender,amount); 30 | } 31 | } -------------------------------------------------------------------------------- /scripts/mexaExchangeProxyDeployer.js: -------------------------------------------------------------------------------- 1 | const bre = require("@nomiclabs/buidler"); 2 | 3 | //{gasLimit:"4000000"} 0xf5D53D5C38204b9dFbF68B780834e6c1e0FF5378 4 | 5 | async function main() { 6 | const MexaExchangeProxy = await ethers.getContractFactory("MexaExchangeProxy"); 7 | const mexaExchangeProxy = await MexaExchangeProxy.deploy("0xd0a1e359811322d97991e03f863a0c30c2cf029c",{gasLimit:ethers.BigNumber.from("9500000")}); 8 | await mexaExchangeProxy.deployed(); 9 | console.log("MexaExchangeProxy at ",mexaExchangeProxy.address); 10 | const deploymentData = await mexaExchangeProxy.deployTransaction.wait(); 11 | console.log(deploymentData); 12 | const chainId = await mexaExchangeProxy.getChainID(); 13 | console.log(chainId.toNumber()); 14 | } 15 | 16 | // We recommend this pattern to be able to use async/await everywhere 17 | // and properly handle errors. 18 | main() 19 | .then(() => process.exit(0)) 20 | .catch(error => { 21 | console.error(error); 22 | process.exit(1); 23 | }); 24 | -------------------------------------------------------------------------------- /contracts/6/libs/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.7.6; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Biconomy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /contracts/6/interfaces/IRelayRecipient.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier:MIT 2 | pragma solidity 0.7.6; 3 | 4 | /** 5 | * a contract must implement this interface in order to support relayed transaction. 6 | * It is better to inherit the BaseRelayRecipient as its implementation. 7 | */ 8 | abstract contract IRelayRecipient { 9 | 10 | /** 11 | * return if the forwarder is trusted to forward relayed transactions to us. 12 | * the forwarder is required to verify the sender's signature, and verify 13 | * the call is not a replay. 14 | */ 15 | function isTrustedForwarder(address forwarder) public virtual view returns(bool); 16 | 17 | /** 18 | * return the sender of this call. 19 | * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes 20 | * of the msg.data. 21 | * otherwise, return `msg.sender` 22 | * should be used in the contract anywhere instead of msg.sender 23 | */ 24 | function _msgSender() internal virtual view returns (address payable); 25 | 26 | function versionRecipient() external virtual view returns (string memory); 27 | } -------------------------------------------------------------------------------- /contracts/6/test/MockFeeManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.7.6; 3 | 4 | import "../interfaces/IFeeManager.sol"; 5 | import "@openzeppelin/contracts/access/Ownable.sol"; 6 | 7 | contract MockFeeManager is IFeeManager,Ownable{ 8 | 9 | uint16 bp; 10 | 11 | mapping(address => bool) public tokenAllowed; 12 | 13 | constructor(uint16 _bp) public{ 14 | bp = _bp; 15 | } 16 | 17 | function getFeeMultiplier(address user, address token) external override view returns (uint16 basisPoints){ 18 | basisPoints = bp; 19 | } 20 | 21 | function setFeeMultiplier(uint16 basisPoints) external onlyOwner{ 22 | bp = basisPoints; 23 | } 24 | 25 | function setTokenAllowed(address token,bool allowed) external onlyOwner{ 26 | tokenAllowed[token] = allowed; 27 | } 28 | 29 | function getTokenAllowed(address token) external override view returns (bool allowed){ 30 | allowed = tokenAllowed[token]; 31 | } 32 | 33 | function getPriceFeedAddress(address token) external view returns (address priceFeed){ 34 | priceFeed = address(0); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /test/helpers/shouldFail.js: -------------------------------------------------------------------------------- 1 | 2 | async function shouldFailWithMessage (promise, message) { 3 | try { 4 | await promise; 5 | } catch (error) { 6 | if (message) { 7 | assert.isTrue(error.message.includes(message),`Wrong failure type, expected '${message}' but got '${error.message}'`); 8 | } 9 | return; 10 | } 11 | 12 | assert.fail('Expected failure not received'); 13 | } 14 | 15 | async function reverting (promise) { 16 | await shouldFailWithMessage(promise, 'revert'); 17 | } 18 | 19 | async function throwing (promise) { 20 | await shouldFailWithMessage(promise, 'invalid opcode'); 21 | } 22 | 23 | async function outOfGas (promise) { 24 | await shouldFailWithMessage(promise, 'out of gas'); 25 | } 26 | 27 | async function shouldFail (promise) { 28 | await shouldFailWithMessage(promise); 29 | } 30 | 31 | async function revertWithMessage(promise, message) { 32 | await shouldFailWithMessage(promise, message); 33 | } 34 | 35 | shouldFail.reverting = reverting; 36 | shouldFail.throwing = throwing; 37 | shouldFail.outOfGas = outOfGas; 38 | shouldFail.revertWithMessage = revertWithMessage; 39 | 40 | module.exports = shouldFail; 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mexa", 3 | "version": "1.0.0", 4 | "description": "Mexa is Biconomy's implementation of meta transactions.", 5 | "main": "", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "npx hardhat test" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/bcnmy/mexa.git" 15 | }, 16 | "author": "", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/bcnmy/mexa/issues" 20 | }, 21 | "homepage": "https://github.com/bcnmy/mexa#readme", 22 | "devDependencies": { 23 | "@nomiclabs/hardhat-ethers": "^2.0.0", 24 | "@nomiclabs/hardhat-etherscan": "^2.0.0", 25 | "@nomiclabs/hardhat-waffle": "^2.0.0", 26 | "@openzeppelin/contracts": "^3.2.0", 27 | "ethereum-waffle": "^3.1.2", 28 | "hardhat": "^2.0.3", 29 | "hardhat-gas-reporter": "^1.0.0", 30 | "solidity-coverage": "^0.7.17" 31 | }, 32 | "dependencies": { 33 | "@nomiclabs/buidler": "^1.4.8", 34 | "@uniswap/v2-periphery": "^1.1.0-beta.0", 35 | "chai": "^4.3.4", 36 | "ethers": "^5.0.19", 37 | "openzeppelin-solidity": "3.3.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /scripts/sample-script.js: -------------------------------------------------------------------------------- 1 | // We require the Buidler Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node