Skip to content

Commit c36e912

Browse files
authored
ERC20 Paymaster v2 (#15)
* wip * forge install: account-abstraction develop * temp * forge install: openzeppelin-contracts v5.0.1 * wip * fix * wip * payer to guarantor * push * fix * fix * full coverage * fix * updates * fix * add natspec and comments * fix * custom errors * rename * delete sdk * comments * sub * forge install: account-abstraction v0.7.0 * update safetransferlib * fix comments * fixes * fix * update event * add more tests * fix * fix * forge install: halmos-cheatcodes * halmos * change license to MIT * readme changes wip * fix readme * fix * removing unused files and reorgnising repo * clarify * remove broken test * redo comments a bit * fix
1 parent 44f7ff3 commit c36e912

39 files changed

+1533
-27784
lines changed

.gitmodules

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
url = https://github.com/foundry-rs/forge-std
44
[submodule "lib/openzeppelin-contracts"]
55
path = lib/openzeppelin-contracts
6-
url = https://github.com/OpenZeppelin/openzeppelin-contracts
6+
url = https://github.com/openzeppelin/openzeppelin-contracts
77
[submodule "lib/account-abstraction"]
88
path = lib/account-abstraction
99
url = https://github.com/eth-infinitism/account-abstraction
10+
[submodule "lib/halmos-cheatcodes"]
11+
path = lib/halmos-cheatcodes
12+
url = https://github.com/a16z/halmos-cheatcodes

.solcover.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"solidity.compileUsingRemoteVersion": "v0.8.23+commit.f704f362",
3+
"coverage-gutters.coverageFileNames": [
4+
"lcov.info"
5+
]
6+
}

LICENSE

Lines changed: 21 additions & 674 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,49 @@
1-
# Pimlico ERC20 Paymaster
1+
# `ERC20Paymaster` contract
2+
23
## Overview
3-
PimlicoERC20Paymaster is an ERC-4337 Paymaster contract by Pimlico which is able to sponsor gas fees in exchange for ERC20 tokens. The contract refunds excess tokens if the actual gas cost is lower than the initially provided amount. It also allows updating price configuration and withdrawing tokens by the contract owner. The contract uses an Oracle to fetch the latest token prices.
4+
5+
This repository contains an ERC-4337 paymaster implementation allowing users to pay for gas fees with ERC-20 tokens, leveraging an oracle to fetch latest prices. The contract takes the max fee during the paymaster validation step, and refunds excess tokens if the actual gas cost is lower than the initially provided amount. It also allows updating price configuration and withdrawing tokens by the contract owner.
46

57
## Features
6-
- ERC20 token payments for transaction fees
7-
- Refunding excess tokens based on actual gas cost
8-
- Updating price configuration
9-
- Withdrawing tokens by contract owner
10-
- Fetching latest token prices using an Oracle
11-
12-
## Contract
13-
The PimlicoERC20Paymaster contract inherits from BasePaymaster.
14-
15-
### Functions
16-
- constructor: Initializes the PimlicoERC20Paymaster contract with the given parameters.
17-
- updateConfig: Updates the price markup and price update threshold configurations.
18-
- withdrawToken: Allows the contract owner to withdraw a specified amount of tokens from the contract.
19-
- updatePrice: Updates the token price by fetching the latest price from the Oracle.
20-
- _validatePaymasterUserOp: Validates a paymaster user operation and calculates the required token amount for the transaction.
21-
- _postOp: Performs post-operation tasks, such as updating the token price and refunding excess tokens.
22-
23-
### Events
24-
- ConfigUpdated: Emitted when the price markup and price update threshold configurations are updated.
8+
9+
- Users paying with ERC-20 tokens for transaction fees
10+
- Using guarantors to front gas fees to allow for token approvals during execution
11+
- Compatible with EntryPoint v0.7
12+
- Refunding excess tokens based on the actual user operation cost
13+
- Using oracles to fetch latest gas prices
14+
- Withdrawing accrued tokens by the contract owner
2515

2616
## Usage
27-
Deploy the PimlicoERC20Paymaster contract, providing the required parameters such as the ERC20 token, EntryPoint contract, and Oracle contract addresses.
28-
Update the price markup and price update threshold configurations if needed, using the updateConfig function.
29-
If necessary, the contract owner can withdraw tokens using the withdrawToken function.
30-
To update the token price, call the updatePrice function.
31-
For more information, please refer to the comments within the contract source code.
3217

33-
## SDK
34-
You can use permissionless.js to interact with an ERC20 Paymaster. Follow [this link](https://docs.pimlico.io/permissionless/tutorial/tutorial-3) to check out tutorial on how to submit user operation using with an ERC-20 Paymaster.
18+
This paymaster has four modes. It allows the user to be simply made to pay themselves, but also allows the selection of a guarnator who can front the ERC-20 token fees during validation, allowing the user to approve tokens to the paymaster or fetch / claim tokens if they do not already have any. For each mode, it is possible to set a ERC-20 token spend limit to protect against sudden price fluctuations or oracle manipulation.
3519

36-
Check out [these docs](https://docs.pimlico.io/permissionless/how-to/paymasters/use-custom-paymaster) if you're going to use a custom paymaster implementation.
20+
Mode 1:
21+
- The user (sender) pays for gas fees with the ERC-20 token.
22+
- `paymasterData` is empty
3723

38-
## Development setup
24+
Mode 2:
25+
- The user (sender) pays for gas fees with the ERC-20 token,
26+
- There is a limit to the amount of ERC-20 tokens that can be taken from the user for the user opertion.
27+
- `paymasterData`: "0x01" + token spend limit (32 bytes)
3928

40-
This repository uses both hardhat and foundry for development, and assumes you have already installed hardhat/foundry
29+
Mode 3:
30+
- A guarantor fronts the ERC-20 token gas fees during validation, and expects the user to be able to pay the actual cost during the postOp phase and get refunded. Otherwise the guarantor is liable.
31+
- `paymasterData`: "0x02" + guarantor address (20 bytes) + validUntil (6 bytes) + validAfter (6 bytes) + guarantor signature (dynamic bytes)
4132

42-
### hardhat
33+
Mode 4:
34+
- A guarantor fronts the ERC-20 token gas fees during validation, and expects the user to be able to pay the actual cost during the postOp phase and get refunded. Otherwise the guarantor is liable.
35+
- There is a limit to the amount of ERC-20 tokens that can be taken from the user/guarantor for the user opertion.
36+
- `paymasterData`: "0x03" + token spend limit (32 bytes) + guarantor address (20 bytes) + validUntil (6 bytes) + validAfter (6 bytes) + guarantor signature (dynamic bytes)
4337

44-
Hardhat is used for gas metering and developing sdk.
38+
## Development
4539

46-
1. install dependencies
47-
```shell
48-
npm install
49-
```
50-
2. run test
51-
```
52-
Npx hardhat test
53-
```
54-
This will show results for the gas metering on different modes based on 1) refund 2) token payment limit 3) price update
40+
This repository uses Foundry and Halmos for development.
5541

56-
*note* : first transaction is expensive because nonce increases 0 -> 1
42+
### Foundry
5743

58-
### foundry
44+
Run `foundryup` to make sure you have the latest foundry version.
5945

60-
Foundry is used for unit tests
46+
Foundry is used for unit tests.
6147

6248
1. install dependencies
6349
```shell
@@ -71,9 +57,24 @@ forge test
7157

7258
3. run coverage
7359
```shell
74-
forge coverage
60+
forge coverage --ir-minimum
7561
```
7662

63+
### Halmos
64+
65+
To install Halmos, run `pip install halmos` or follow [their detailed installation guide](https://github.com/a16z/halmos?tab=readme-ov-file#installation).
66+
67+
Halmos is used for symbolic tests.
68+
69+
1. install dependencies
70+
```shell
71+
forge install
72+
```
73+
74+
2. run tests
75+
```shell
76+
halmos
77+
```
7778

7879
## License
79-
This project is licensed under the GNU General Public License v3.0.
80+
This project is licensed under the MIT license.

foundry.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ out = 'out'
44
libs = ['node_modules', 'lib']
55
test = 'test'
66
#cache_path = 'cache_forge'
7-
solc = "0.8.19"
7+
solc = "0.8.23"
88
optimizer = true
99
optimizer_runs = 1000000
1010
gas_price = 1000000000
11+
ast = true

hardhat.config.ts

Lines changed: 0 additions & 74 deletions
This file was deleted.

lib/account-abstraction

Submodule account-abstraction updated 140 files

lib/halmos-cheatcodes

Submodule halmos-cheatcodes added at c0d8655

lib/openzeppelin-contracts

0 commit comments

Comments
 (0)