-
Notifications
You must be signed in to change notification settings - Fork 75
feat: Implement ZkSync Adapter and SpokePool #180
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
Conversation
mrice32
left a comment
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.
LGTM! Just a few minor comments and nits. Nice work!!
| // On Ethereum, avoiding constructor parameters and putting them into constants reduces some of the gas cost | ||
| // upon contract deployment. On zkSync the opposite is true: deploying the same bytecode for contracts, | ||
| // while changing only constructor parameters can lead to substantial fee savings. So, the following params | ||
| // are all set by passing in constructor params where possible. |
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.
We don't expect to deploy many spoke pool contracts, right?
I think this mostly comes down to reads, since these values will be read for more than they will be deployed. Is reading directly from immutable bytecode cheaper or is reading from mutable storage cheaper? On ethereum mutable storage is far more expensive to read than immutable bytecode.
However, don't we typically make keep these bridge variables mutable to allow upgradability?
I guess I'm just a little confused about which variables this comment applies to.
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.
Yeah we typically keep these variables mutable but perhaps the comment is misleading. I only included it for now as a consideration but I agree this contract should be rarely re-redeployed so i'll add that note
contracts/ZkSync_SpokePool.sol
Outdated
| .withdraw( | ||
| hubPool, | ||
| // Note: If ETH, must use 0x0: https://github.com/matter-labs/v2-testnet-contracts/blob/3a0651357bb685751c2163e4cc65a240b0f602ef/l2/contracts/bridge/L2ETHBridge.sol#L57 | ||
| ( |
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.
nit: are these parens necessary?
contracts/ZkSync_SpokePool.sol
Outdated
| address public zkErc20Bridge; | ||
|
|
||
| // Bridge used to send ETH to L1: https://github.com/matter-labs/v2-testnet-contracts/blob/3a0651357bb685751c2163e4cc65a240b0f602ef/l2/contracts/bridge/L2ETHBridge.sol | ||
| address public zkEthBridge; |
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.
nit: do both of these conform to ZkBridgeLike? Might make the code below a little simpler if we stored them as ZkBridgeLike rather than addresses so we don't have to cast when using them.
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.
Great point!
| @@ -0,0 +1,40 @@ | |||
| import { HardhatRuntimeEnvironment } from "hardhat/types/runtime"; | |||
| import { Wallet } from "zksync-web3"; | |||
| import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; | |||
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.
Just to understand, hre does not contain getNamedAccounts like it does with normal hardhat-deploy?
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.
Yeah this isn't the hardhat-deploy we're ued to, its a special zksync version
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.
@matterlabs/hardhat-zksync-deploy pretty much only adds the deploy-zksync task
| const artifact = await deployer.loadArtifact("ZkSync_SpokePool"); | ||
| const args = [ | ||
| L2_ADDRESS_MAP[chainId].zkErc20Bridge, | ||
| L2_ADDRESS_MAP[chainId].zkEthBridge, | ||
| hubPool.address, // Set hub pool as cross domain admin since it delegatecalls the ZkSync_Adapter logic. | ||
| hubPool.address, | ||
| L2_ADDRESS_MAP[chainId].l2Weth, // l2Weth | ||
| "0x0000000000000000000000000000000000000000", // timer | ||
| ]; | ||
| const contract = await deployer.deploy(artifact, args); |
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.
Same as above, just want to double check -- we cannot just pass the name (ZkSync_SpokePool) directly into the deploy command like we do in other deployments?
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.
Yeah i don't think this script has access to hardhat-deploy at all but I haven't tried importing hardhat-deploy so i'll try that now
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.
Ah, so one complication is that the usual deploy command doesn't know to look in the artifacts-zk folder, instead it looks at the artifacts folder. So all of the tutorials use the deploy-zksync task
| }, | ||
| networks: { | ||
| hardhat: { accounts: { accountsBalance: "1000000000000000000000000" } }, | ||
| hardhat: { accounts: { accountsBalance: "1000000000000000000000000" }, zksync: compileZk }, |
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.
Does this overwrite the normal artifacts or does it output to a different directory?
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.
Outputs to artifacts-zk and cache-zk because the compiler is diff
scripts/zkSync.ts
Outdated
| // zksync block explorer does not have contract verification yet so calling contracts via GUI is impossible. This file | ||
| // contains useful scripts to interact with zksync goerli contracts. To run, run: | ||
| // yarn hardhat run ./scripts/zksync.ts --network zksync-goerli |
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.
nit: could you put this at the top of the file so it's more visible?
scripts/zkSync.ts
Outdated
| const execute = await spokePool.executeRelayerRefundLeaf( | ||
| config.rootBundleIdToExecute, | ||
| { | ||
| // Recreating leaf constructed in './buildSampleTree.ts' | ||
| amountToReturn: toBN("100000000000000000"), // 0.1 | ||
| chainId: originChainId, | ||
| refundAmounts: [toBN("100000000000000000")], // -0.1 | ||
| leafId: 0, | ||
| l2TokenAddress: erc20.address, | ||
| refundAddresses: ["0x9a8f92a830a5cb89a3816e3d267cb7791c16b04d"], | ||
| }, | ||
| [] | ||
| ); | ||
| const executeReceipt = await execute.wait(); |
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.
nit: should this be commented out with the other write transactions?
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.
good point
Co-authored-by: Matt Rice <matthewcrice32@gmail.com>
|
@mrice32 there are a lot of inconsistencies with the deployment scripts in this PR because we use the zksync tutorial's suggested I bumped |
Very cool! |
mrice32
left a comment
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.
LGTM! This looks great. Thanks for looking into the hardhat-deploy issue
|
|
||
| const chainId = parseInt(await getChainId()); | ||
|
|
||
| await deploy("ZkSync_SpokePool", { |
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.
👌
Implements https://linear.app/uma/issue/ACX-169/write-test-zk-sync-contracts
and adds helper scripts