-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support zkSyncEra and zkSyndTestnet chains #1259
Changes from all commits
8834eb0
69d037a
e617b4d
b43b865
419bd9c
80979e9
fc9dbdf
c32363e
cee7716
c5c8bda
3ed4097
ee242bd
da521fc
2a262a3
6ec7bec
84eaa48
cc85517
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const chainId = 280; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const chainId = 324; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,7 @@ describe('erc777-stream', () => { | |
it.each([ | ||
{ network: 'goerli' }, | ||
{ network: 'matic' }, | ||
{ network: 'xdai' }, | ||
// { network: 'xdai' }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||
{ network: 'optimism' }, | ||
{ network: 'avalanche' }, | ||
{ network: 'arbitrum-one' }, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { erc20FeeProxyArtifact, ethereumFeeProxyArtifact } from '../src/lib'; | ||
import { deployContract } from './utils-zk'; | ||
import * as hre from 'hardhat'; | ||
import { CurrencyTypes } from '@requestnetwork/types'; | ||
|
||
/** | ||
* Deploys Batch payments contracts to zkSync network. | ||
* This script is supposed to be run with the deploy-zksync plugin | ||
* check zkSync section in smart-contracts/README file | ||
*/ | ||
export default async function () { | ||
const [deployer] = await hre.ethers.getSigners(); | ||
const constructorArguments = [ | ||
erc20FeeProxyArtifact.getAddress(hre.network.name as CurrencyTypes.EvmChainName), | ||
ethereumFeeProxyArtifact.getAddress(hre.network.name as CurrencyTypes.EvmChainName), | ||
hre.ethers.constants.AddressZero, | ||
hre.ethers.constants.AddressZero, | ||
hre.ethers.constants.AddressZero, | ||
deployer.address, | ||
]; | ||
console.log(`Deploying BatchConversionPayments to zkSync ...`); | ||
await deployContract('BatchConversionPayments', constructorArguments); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { deployContract } from './utils-zk'; | ||
|
||
/** | ||
* Deploys Proxy contracts to zkSync network. | ||
* This script is supposed to be run with the deploy-zksync plugin | ||
* check zkSync section in smart-contracts/README file | ||
*/ | ||
export default async function () { | ||
const deployList: string[] = ['ERC20FeeProxy', 'EthereumFeeProxy']; | ||
|
||
for (let index = 0; index < deployList.length; index++) { | ||
const contractName = deployList[index]; | ||
console.log(`Deploying ${contractName} to zkSync ...`); | ||
await deployContract(contractName, []); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { Provider, Wallet, Contract } from 'zksync-web3'; | ||
import * as hre from 'hardhat'; | ||
import { Deployer } from '@matterlabs/hardhat-zksync-deploy'; | ||
import { formatEther } from 'ethers/lib/utils'; | ||
import { BigNumberish } from 'ethers'; | ||
|
||
import { config } from 'dotenv'; | ||
import { networkRpcs } from '@requestnetwork/utils/dist/providers'; | ||
|
||
config(); | ||
|
||
const accounts = process.env.DEPLOYMENT_PRIVATE_KEY | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems weird, no? Don't we just have 1 PK for deployment/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just copied the logic from hardhat.config.ts file, we get the accounts the same way There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it can be simplified with the only key you need for deployment. For example the |
||
? [process.env.DEPLOYMENT_PRIVATE_KEY] | ||
: process.env.DEPLOYER_MASTER_KEY | ||
? [process.env.DEPLOYER_MASTER_KEY] | ||
: process.env.ADMIN_PRIVATE_KEY | ||
? [process.env.ADMIN_PRIVATE_KEY] | ||
: undefined; | ||
|
||
const WALLET_PRIVATE_KEY = (accounts || [])[0]; | ||
|
||
export const getProvider = () => { | ||
const rpcUrl = networkRpcs[hre.network.name]; | ||
if (!rpcUrl) | ||
throw `⛔️ RPC URL wasn't found in "${hre.network.name}"! Please add a "url" field to the network config in hardhat.config.ts`; | ||
|
||
// Initialize zkSync Provider | ||
const provider = new Provider(rpcUrl); | ||
|
||
return provider; | ||
}; | ||
|
||
export const getWallet = (privateKey?: string): Wallet => { | ||
if (!privateKey) { | ||
// Get wallet private key from .env file | ||
if (!WALLET_PRIVATE_KEY) throw "⛔️ Wallet private key wasn't found in .env file!"; | ||
} | ||
|
||
const provider = getProvider(); | ||
|
||
// Initialize zkSync Wallet | ||
const wallet = new Wallet(privateKey ?? WALLET_PRIVATE_KEY!, provider); | ||
|
||
return wallet; | ||
}; | ||
|
||
export const verifyEnoughBalance = async (wallet: Wallet, amount: BigNumberish) => { | ||
// Check if the wallet has enough balance | ||
const balance = await wallet.getBalance(); | ||
if (balance.lt(amount)) | ||
throw `⛔️ Wallet balance is too low! Required ${formatEther(amount)} ETH, but current ${ | ||
wallet.address | ||
} balance is ${formatEther(balance)} ETH`; | ||
}; | ||
|
||
/** | ||
* @param {string} data.contract The contract's path and name. E.g., "contracts/Greeter.sol:Greeter" | ||
*/ | ||
export const verifyContract = async (data: { | ||
address: string; | ||
contract: string; | ||
constructorArguments: string | []; | ||
bytecode: string; | ||
}) => { | ||
const verificationRequestId: number = await hre.run('verify:verify', { | ||
...data, | ||
noCompile: true, | ||
}); | ||
return verificationRequestId; | ||
}; | ||
|
||
type DeployContractOptions = { | ||
/** | ||
* If true, the deployment process will not print any logs | ||
*/ | ||
silent?: boolean; | ||
/** | ||
* If true, the contract will not be verified on Block Explorer | ||
*/ | ||
noVerify?: boolean; | ||
/** | ||
* If specified, the contract will be deployed using this wallet | ||
*/ | ||
wallet?: Wallet; | ||
}; | ||
|
||
export const verifyContractByName = async ( | ||
contractArtifactName: string, | ||
contractAddress: string, | ||
) => { | ||
const wallet = getWallet(); | ||
const deployer = new Deployer(hre, wallet); | ||
|
||
const artifact = await deployer.loadArtifact(contractArtifactName).catch((error) => { | ||
if (error?.message?.includes(`Artifact for contract "${contractArtifactName}" not found.`)) { | ||
console.error(error.message); | ||
throw `⛔️ Please make sure you have compiled your contracts or specified the correct contract name!`; | ||
} else { | ||
throw error; | ||
} | ||
}); | ||
|
||
const fullContractSource = `${artifact.sourceName}:${artifact.contractName}`; | ||
|
||
// Display contract deployment info | ||
console.log(`\n"${artifact.contractName}" was successfully deployed:`); | ||
console.log(` - Contract address: ${contractAddress}`); | ||
console.log(` - Contract source: ${fullContractSource}`); | ||
|
||
console.log(`Requesting contract verification...`); | ||
await verifyContract({ | ||
address: contractAddress, | ||
contract: fullContractSource, | ||
constructorArguments: [], | ||
bytecode: artifact.bytecode, | ||
}); | ||
}; | ||
|
||
export const deployContract = async ( | ||
contractArtifactName: string, | ||
constructorArguments?: any[], | ||
options?: DeployContractOptions, | ||
): Promise<Contract> => { | ||
const log = (message: string) => { | ||
if (!options?.silent) console.log(message); | ||
}; | ||
|
||
log(`\nStarting deployment process of "${contractArtifactName}"...`); | ||
|
||
const wallet = options?.wallet ?? getWallet(); | ||
const deployer = new Deployer(hre, wallet); | ||
|
||
const artifact = await deployer.loadArtifact(contractArtifactName).catch((error) => { | ||
if (error?.message?.includes(`Artifact for contract "${contractArtifactName}" not found.`)) { | ||
console.error(error.message); | ||
throw `⛔️ Please make sure you have compiled your contracts or specified the correct contract name!`; | ||
} else { | ||
throw error; | ||
} | ||
}); | ||
|
||
// Estimate contract deployment fee | ||
const deploymentFee = await deployer.estimateDeployFee(artifact, constructorArguments || []); | ||
log(`Estimated deployment cost: ${formatEther(deploymentFee)} ETH`); | ||
|
||
// Check if the wallet has enough balance | ||
await verifyEnoughBalance(wallet, deploymentFee); | ||
|
||
// Deploy the contract to zkSync | ||
const contract = await deployer.deploy(artifact, constructorArguments); | ||
|
||
const constructorArgs = contract.interface.encodeDeploy(constructorArguments); | ||
const fullContractSource = `${artifact.sourceName}:${artifact.contractName}`; | ||
|
||
// Display contract deployment info | ||
log(`\n"${artifact.contractName}" was successfully deployed:`); | ||
log(` - Contract address: ${contract.address}`); | ||
log(` - Contract source: ${fullContractSource}`); | ||
log(` - Encoded constructor arguments: ${constructorArgs}\n`); | ||
|
||
if (!options?.noVerify && hre.network.config.verifyURL) { | ||
log(`Requesting contract verification...`); | ||
await verifyContract({ | ||
address: contract.address, | ||
contract: fullContractSource, | ||
constructorArguments: constructorArgs, | ||
bytecode: artifact.bytecode, | ||
}); | ||
} | ||
|
||
return contract; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why we don't keep the usual format (
zk-sync-era-testnet
) ?