-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: update & test paymaster frontend tutorial (#91)
- fixes & updates the frontend paymaster tutorial - adds a test - adds synpress for metamask testing
- Loading branch information
1 parent
4016397
commit a8e7a6c
Showing
57 changed files
with
10,429 additions
and
361 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ logs | |
tests-output | ||
test-results | ||
playwright-report | ||
.cache-synpress | ||
|
||
# Local env files | ||
.env | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ node_modules | |
.idea | ||
public | ||
**/*.md | ||
tests-output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
WALLET_PRIVATE_KEY= | ||
ALLOWED_TOKEN= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
.vscode | ||
|
||
# hardhat artifacts | ||
artifacts | ||
cache | ||
|
||
# zksync artifacts | ||
artifacts-zk | ||
cache-zk | ||
deployments-zk | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# TypeScript v1 declaration files | ||
typings/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
.env.test | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
|
||
# Next.js build output | ||
.next | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
legacy-peer-deps=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//SPDX-License-Identifier: Unlicense | ||
pragma solidity ^0.8.0; | ||
|
||
contract Greeter { | ||
string private greeting; | ||
|
||
constructor(string memory _greeting) { | ||
greeting = _greeting; | ||
} | ||
|
||
function greet() public view returns (string memory) { | ||
return greeting; | ||
} | ||
|
||
function setGreeting(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
code/frontend-paymaster/contracts/contracts/erc20/MyERC20Token.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; | ||
|
||
/** | ||
* @title MyERC20Token | ||
* @dev This is a basic ERC20 token using the OpenZeppelin's ERC20PresetFixedSupply preset. | ||
* You can edit the default values as needed. | ||
*/ | ||
contract MyERC20Token is ERC20Burnable { | ||
|
||
/** | ||
* @dev Constructor to initialize the token with default values. | ||
* You can edit these values as needed. | ||
*/ | ||
constructor() ERC20("DefaultTokenName", "DTN") { | ||
// Default initial supply of 1 million tokens (with 18 decimals) | ||
uint256 initialSupply = 1_000_000 * (10 ** 18); | ||
|
||
// The initial supply is minted to the deployer's address | ||
_mint(msg.sender, initialSupply); | ||
} | ||
|
||
// Additional functions or overrides can be added here if needed. | ||
} |
126 changes: 126 additions & 0 deletions
126
code/frontend-paymaster/contracts/contracts/paymasters/ApprovalPaymaster.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {IPaymaster, ExecutionResult, PAYMASTER_VALIDATION_SUCCESS_MAGIC} from "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IPaymaster.sol"; | ||
import {IPaymasterFlow} from "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IPaymasterFlow.sol"; | ||
import {TransactionHelper, Transaction} from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/TransactionHelper.sol"; | ||
|
||
import "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
|
||
/// @author Matter Labs | ||
/// @notice This smart contract pays the gas fees for accounts with balance of a specific ERC20 token. It makes use of the approval-based flow paymaster. | ||
contract ApprovalPaymaster is IPaymaster, Ownable { | ||
uint256 constant PRICE_FOR_PAYING_FEES = 1; | ||
|
||
address public allowedToken; | ||
|
||
modifier onlyBootloader() { | ||
require( | ||
msg.sender == BOOTLOADER_FORMAL_ADDRESS, | ||
"Only bootloader can call this method" | ||
); | ||
// Continue execution if called from the bootloader. | ||
_; | ||
} | ||
|
||
constructor(address _erc20) { | ||
allowedToken = _erc20; | ||
} | ||
|
||
function validateAndPayForPaymasterTransaction( | ||
bytes32, | ||
bytes32, | ||
Transaction calldata _transaction | ||
) | ||
external | ||
payable | ||
onlyBootloader | ||
returns (bytes4 magic, bytes memory context) | ||
{ | ||
// By default we consider the transaction as accepted. | ||
magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; | ||
require( | ||
_transaction.paymasterInput.length >= 4, | ||
"The standard paymaster input must be at least 4 bytes long" | ||
); | ||
|
||
bytes4 paymasterInputSelector = bytes4( | ||
_transaction.paymasterInput[0:4] | ||
); | ||
// Approval based flow | ||
if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { | ||
// While the transaction data consists of address, uint256 and bytes data, | ||
// the data is not needed for this paymaster | ||
(address token, uint256 amount, bytes memory data) = abi.decode( | ||
_transaction.paymasterInput[4:], | ||
(address, uint256, bytes) | ||
); | ||
|
||
// Verify if token is the correct one | ||
require(token == allowedToken, "Invalid token"); | ||
|
||
// We verify that the user has provided enough allowance | ||
address userAddress = address(uint160(_transaction.from)); | ||
|
||
address thisAddress = address(this); | ||
|
||
uint256 providedAllowance = IERC20(token).allowance( | ||
userAddress, | ||
thisAddress | ||
); | ||
require( | ||
providedAllowance >= PRICE_FOR_PAYING_FEES, | ||
"Min allowance too low" | ||
); | ||
|
||
// Note, that while the minimal amount of ETH needed is tx.gasPrice * tx.gasLimit, | ||
// neither paymaster nor account are allowed to access this context variable. | ||
uint256 requiredETH = _transaction.gasLimit * | ||
_transaction.maxFeePerGas; | ||
|
||
try | ||
IERC20(token).transferFrom(userAddress, thisAddress, amount) | ||
{} catch (bytes memory revertReason) { | ||
// If the revert reason is empty or represented by just a function selector, | ||
// we replace the error with a more user-friendly message | ||
if (revertReason.length <= 4) { | ||
revert("Failed to transferFrom from users' account"); | ||
} else { | ||
assembly { | ||
revert(add(0x20, revertReason), mload(revertReason)) | ||
} | ||
} | ||
} | ||
|
||
// The bootloader never returns any data, so it can safely be ignored here. | ||
(bool success, ) = payable(BOOTLOADER_FORMAL_ADDRESS).call{ | ||
value: requiredETH | ||
}(""); | ||
require( | ||
success, | ||
"Failed to transfer tx fee to the bootloader. Paymaster balance might not be enough." | ||
); | ||
} else { | ||
revert("Unsupported paymaster flow"); | ||
} | ||
} | ||
|
||
function postTransaction( | ||
bytes calldata _context, | ||
Transaction calldata _transaction, | ||
bytes32, | ||
bytes32, | ||
ExecutionResult _txResult, | ||
uint256 _maxRefundedGas | ||
) external payable override onlyBootloader {} | ||
|
||
function withdraw(address _to) external onlyOwner { | ||
(bool success, ) = payable(_to).call{value: address(this).balance}(""); | ||
require(success, "Failed to withdraw funds from paymaster."); | ||
} | ||
|
||
receive() external payable {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { deployContract } from './utils'; | ||
|
||
// An example of a basic deploy script | ||
// It will deploy a Greeter contract to selected network | ||
// as well as verify it on Block Explorer if possible for the network | ||
export default async function () { | ||
const contractArtifactName = 'Greeter'; | ||
const constructorArguments = ['Hi there!']; | ||
await deployContract(contractArtifactName, constructorArguments); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { deployContract } from '../utils'; | ||
|
||
// This script is used to deploy an ERC20 token contract | ||
// as well as verify it on Block Explorer if possible for the network | ||
|
||
// Important: make sure to change contract name and symbol in contract source | ||
// at contracts/erc20/MyERC20Token.sol | ||
export default async function () { | ||
await deployContract('MyERC20Token'); | ||
} |
Oops, something went wrong.