Skip to content
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: zksync support #4725

Open
wants to merge 159 commits into
base: main
Choose a base branch
from

Conversation

mshojaei-txfusion
Copy link

Description

This PR introduces a series of changes aimed at enhancing zkSync support within the codebase. Key updates include the addition of the zksolc compiler for zkSync, integration of contract artifacts, CLI automation for core deployment, and compatibility adjustments in tests for the zkSync environment. It also includes improvements in contract verification on zkSync explorer and handling gas limits for zkSync deployments.

Drive-by changes

  • Added support for the zksolc compiler.
  • Decoupled Hardhat configuration for EVM from zkSync.
  • Enabled the export of zkSync-related contract artifacts.
  • Verified compatibility of different deployment components based on the chain’s technical stack.
  • Integrated zkSync provider and signer.
  • Added support for contract verification on the zkSync explorer.
  • Blacklisted static contracts from deployment on zkSync, as they are not supported.

Related issues

No related issue

Backward compatibility

Yes

Testing

Manual testing and some automated tests were performed, including end-to-end tests on zkSync for warp read and apply functionalities.

Copy link
Contributor

@jmrossy jmrossy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of nice work here but I still have some concerns, please see comments :)

return false;
}

if (input.address === ethers.constants.AddressZero) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see isZeroishAddress in the utils package

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

import { ChainMap, ChainName } from '../../types.js';

import { ContractVerificationInput } from './types.js';

const { Interface } = await import('@ethersproject/abi');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you doing a dynamic import of this? Instead, import it directly from the ethers package like other imports above

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

@@ -99,12 +100,12 @@ export class MultiProtocolProvider<
const providers = objMap(
this.providers,
(_, typeToProviders) => typeToProviders[ProviderType.EthersV5]?.provider,
) as ChainMap<EthersV5Provider['provider'] | undefined>;
) as ChainMap<ZKSyncProvider['provider'] | undefined>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the concern I expressed above around the Wallet class, I disagree that ZKSyncProviders should replace Ethers V5 providers as the default provider type here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, this should not be here. Resolved

if (!provider) return signer;

// Handle ZKSync provider separately
if (signer instanceof ZKSyncWallet) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using instanceof this way has pitfalls and is generally a code smell. Is there a tangible property on the signer you can check instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your comment on removing ZKSyncWallet form ChainMap helped me resolve this. No longer need to check for instance of

Comment on lines 343 to 345
const metadata = this.tryGetChainMetadata(chainNameOrId);
if (!metadata) {
throw new Error('Chain metadata not found!');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use this.getChainMetadata(chainNameOrId); and it'll throw if if doesn't find it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

Comment on lines 131 to 132
// Kept for backwards compatibility
export function defaultZKProviderBuilder(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we need this for backwards compat when it doesn't currently exist? You can remove this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use it in MultiProvider, will remove this comment

@@ -43,7 +55,7 @@ export interface MultiProviderOptions {
export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
readonly providers: ChainMap<Provider>;
readonly providerBuilder: ProviderBuilderFn<Provider>;
signers: ChainMap<Signer>;
signers: ChainMap<ZKSyncWallet | Signer>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ZKSyncWallet doesn't implement the Signer interface? I'd expect that it would since an Ethers.js Wallet does implement it

Copy link
Contributor

@ljankovic-txfusion ljankovic-txfusion Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For types we can remove both ZKSyncWallet and ZKSyncProvider from ChainMap and type Provider ... but we need to be mindful that MultiProvider is also used for deploying contracts (& gas estimation...), and for that we use ZKSyncDeployer class, which strictly requires that the type of signer is ZKSyncWallet [extends Wallet base]. Meaning that type casting to ZKSyncWallet will still be required down in the code. We need to keep this in mind.

ljankovic-txfusion and others added 24 commits November 21, 2024 10:21
@sachanayush47
Copy link

I was trying this feature and I caught this error while deploying warp contracts: Error: Technical stack zksync is not compatible with staticAggregationIsm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

8 participants