-
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.
- Loading branch information
1 parent
da63c60
commit e83b67c
Showing
19 changed files
with
667 additions
and
319 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 |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.20; | ||
|
||
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/access/Ownable.sol"; | ||
|
||
/// @author Matter Labs | ||
/// @notice This contract does not include any validations other than using the paymaster general flow. | ||
contract GeneralPaymaster is IPaymaster { | ||
modifier onlyBootloader() { | ||
require( | ||
msg.sender == BOOTLOADER_FORMAL_ADDRESS, | ||
"Only bootloader can call this method" | ||
); | ||
// Continue execution if called from the bootloader. | ||
_; | ||
} | ||
|
||
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] | ||
); | ||
if (paymasterInputSelector == IPaymasterFlow.general.selector) { | ||
// 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; | ||
|
||
// 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 in paymasterParams."); | ||
} | ||
} | ||
|
||
function postTransaction( | ||
bytes calldata _context, | ||
Transaction calldata _transaction, | ||
bytes32, | ||
bytes32, | ||
ExecutionResult _txResult, | ||
uint256 _maxRefundedGas | ||
) external payable override onlyBootloader {} | ||
|
||
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,31 @@ | ||
import { Wallet, Provider } from 'zksync-ethers'; | ||
import type { HardhatRuntimeEnvironment } from 'hardhat/types'; | ||
import { Deployer } from '@matterlabs/hardhat-zksync-deploy'; | ||
|
||
// load env file | ||
import dotenv from 'dotenv'; | ||
import { ethers } from 'ethers'; | ||
dotenv.config(); | ||
|
||
const DEPLOYER_PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || ''; | ||
|
||
export default async function (hre: HardhatRuntimeEnvironment) { | ||
// @ts-expect-error target config file which can be testnet or local | ||
const provider = new Provider(hre.network.config.url); | ||
const wallet = new Wallet(DEPLOYER_PRIVATE_KEY, provider); | ||
const deployer = new Deployer(hre, wallet); | ||
const artifact = await deployer.loadArtifact('GeneralPaymaster'); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const constructorArguments: any[] = []; | ||
const contract = await deployer.deploy(artifact, constructorArguments); | ||
const paymasterAddress = await contract.getAddress(); | ||
console.log('PAYMASTER CONTRACT ADDRESS: ', paymasterAddress); | ||
|
||
const tx = await wallet.sendTransaction({ | ||
to: paymasterAddress, | ||
value: ethers.parseEther('10'), | ||
}); | ||
|
||
await tx.wait(); | ||
console.log('DONE DEPLOYING & FUNDING PAYMASTER'); | ||
} |
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
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 |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import type { FC, ReactNode } from 'react'; | ||
import { createContext, useContext, useState } from 'react'; | ||
|
||
export type AccountContext = string | null; | ||
|
||
const AccountCtx = createContext<AccountContext>(null); | ||
const SetAccountCtx = createContext<(value: AccountContext) => void>(() => {}); | ||
|
||
export function useAccount() { | ||
return useContext(AccountCtx); | ||
} | ||
|
||
export function useSetAccount() { | ||
return useContext(SetAccountCtx); | ||
} | ||
|
||
interface AccountProviderProps { | ||
children: ReactNode; | ||
} | ||
|
||
const storageLabel = 'smart-account-address'; | ||
|
||
export const AccountProvider: FC<AccountProviderProps> = ({ children }) => { | ||
const [state, setState] = useState<AccountContext>(() => { | ||
if (typeof window !== 'undefined') { | ||
return (sessionStorage.getItem(storageLabel) as AccountContext) || null; | ||
} | ||
return null; | ||
}); | ||
|
||
const setAccount = (account: AccountContext) => { | ||
setState(account); | ||
if (typeof window !== 'undefined') { | ||
sessionStorage.setItem(storageLabel, account as string); | ||
} | ||
}; | ||
|
||
return ( | ||
<AccountCtx.Provider value={state}> | ||
<SetAccountCtx.Provider value={setAccount}>{children}</SetAccountCtx.Provider> | ||
</AccountCtx.Provider> | ||
); | ||
}; |
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,34 @@ | ||
import type { Wallet } from 'zksync-ethers'; | ||
import type { FC, ReactNode } from 'react'; | ||
import { createContext, useContext, useState } from 'react'; | ||
|
||
export type WalletContext = Wallet | null; | ||
|
||
const WalletCtx = createContext<WalletContext>(null); | ||
const SetWalletCtx = createContext<(value: WalletContext) => void>(() => {}); | ||
|
||
export function useWallet() { | ||
return useContext(WalletCtx); | ||
} | ||
|
||
export function useSetWallet() { | ||
return useContext(SetWalletCtx); | ||
} | ||
|
||
interface WalletProviderProps { | ||
children: ReactNode; | ||
} | ||
|
||
export const WalletProvider: FC<WalletProviderProps> = ({ children }) => { | ||
const [state, setState] = useState<WalletContext>(null); | ||
|
||
const setWallet = (wallet: WalletContext) => { | ||
setState(wallet); | ||
}; | ||
|
||
return ( | ||
<WalletCtx.Provider value={state}> | ||
<SetWalletCtx.Provider value={setWallet}>{children}</SetWalletCtx.Provider> | ||
</WalletCtx.Provider> | ||
); | ||
}; |
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 |
---|---|---|
@@ -1,6 +1,22 @@ | ||
import '@/styles/globals.css'; | ||
import type { AppProps } from 'next/app'; | ||
import { AccountProvider } from '../hooks/useAccount'; | ||
import { WalletProvider } from '../hooks/useWallet'; | ||
import { Provider } from 'zksync-ethers'; | ||
|
||
export default function App({ Component, pageProps }: AppProps) { | ||
return <Component {...pageProps} />; | ||
const networkProvider = new Provider('http://localhost:8011'); | ||
return ( | ||
<> | ||
<AccountProvider> | ||
<WalletProvider> | ||
<Component | ||
{...pageProps} | ||
provider={networkProvider} | ||
/> | ||
; | ||
</WalletProvider> | ||
</AccountProvider> | ||
</> | ||
); | ||
} |
Oops, something went wrong.