A generic contract system for reliably refunding the gas costs of transactions. The purpose of the project is to:
- Enable Protocols to specify what contract calls they are willing to sponsor with a set of limitations (e.g gas price)
- Enable anyone to sumbit transactions that are eligible for refunding and get their transaction fee reimbursed in the range of 96% - 99% (more on the different in the range later)
- Provide a central registry for persisting all deployed refunders and their supported refundable transactions
Mainnet:
Registry: 0xAe23D33354bf2B7Df421D928Cdbb5aADFA9DFA16
Factory: 0x33DD37A160e7436B28B23FcE005a438A178316D7
Subgraph: https://api.thegraph.com/subgraphs/name/withtally/tally-gas-refunder-mainnet
- Refunder factory
- Refunder
- Registry
Factory contract used for the deployment of Refunder contracts. Anyone is able to deploy a refunder contract and configure it for its own needs.
On refunder deployment msg.sender is the initial owner of the Refunder contract.
Refunder contract represents the interest of a given protocol/entity that wants to sponsor a set of function calls.
The contract:
- is
ownable. By default set to the deployer - holds
ETHfor gas cost reimbursements - has a mapping of whitelisted
refundables
Each refundable has:
target- contract address (f.e Compound Governance Alpha)identifier- function identifier (f.ecastVoteBySig)validatingContract- Optional validation contract to call when determening whether to refund themsg.sendervalidatingIdentifier- Optional validati identifier to call when determening whether to refund themsg.sender
Important
If you want to execute any additional business logic check except for requiring the gas price to be lower than the maxGasPrice set, you can specify validatingContract and validatingIdentifier. The contract + identifier will be called on every relay and refund call.
The signature of the validatingIdentifier must be:
functionName(address,address,bytes4,bytes) where the first address is the msg.sender that will be refunded, second address is the target contract, bytes4 is the identifier to be called and the last are the arguments that will be passed to that function call.
The contract measures the net gas usage and reimburses the msg.sender for all of the gas costs except for the arguments provided to the relayAndRefund function. This is where the 96-99% fomes from. If the arguments gas costs are big, the refunding proportional to the transaction cost will be lower.
Note: Gas costs for the arguments are as follows:
16gas for each non-zero byte4gas for each zero byte
The registry contract stores all Refunders deployed and their supported targetContracts and identifiers. Anyone is able to:
- query all deployed refunder contracts
- query by a given pair of
(targetContract, identifierId)the list ofrefunders that are willing to refund themsg.sender
The project uses the hardhat framework.
In order to compile, one must execute:
npm run compile
In order to run the unit tests, one must execute: run test
npm run test
In order to run the tests with code coverage, one must execute:
npm run coverage
There are several deployment scripts defined in the ./scripts folder and referenced using hardhat tasks.
In order to deploy the registry:
npx hardhat deploy-registry --network MY_NETWORK_NAME
In order to deploy the factory:
npx hardhat deploy-factory --network MY_NETWORK_NAME --registry REGISTRY_ADDRESS
In Order to deploy refunder using the factory:
npx hardhat factory-deploy-refunder --network MY_NETWORK_NAME --factory FACTORY_ADDRESS
In Order to deploy refunder without factory:
npx hardhat deploy-refunder --network MY_NETWORK_NAME --registry REGISTRY_ADDRESS
Note: By default, the version of the refunder is 1