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

Txfusion - ZKSync support #1

Open
wants to merge 70 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
91a2077
chore: add zksolc compiler for zksync
ljankovic-txfusion Sep 12, 2024
6fc9f02
update: make hardhat tests compatible with zksync
ljankovic-txfusion Sep 13, 2024
e5724aa
update: linking workspaces & contract compilation
ljankovic-txfusion Sep 16, 2024
0a692b3
chore: remove non-compatible zksync code from SDK
ljankovic-txfusion Sep 16, 2024
de77dba
feature: exporting zksync contract artifacts from core
ljankovic-txfusion Sep 17, 2024
1e1d748
feat: zksync deployer
ljankovic-txfusion Sep 18, 2024
2848efe
fix: artifacts compilation; add:typechain-types to .gitignore
ljankovic-txfusion Sep 18, 2024
79ceac4
update: wip deploying contracts via cli
ljankovic-txfusion Sep 18, 2024
04f390c
update: load artifacts from factory
ljankovic-txfusion Sep 18, 2024
e76bbf2
feat: cli bash script for automating core deployment
ljankovic-txfusion Sep 18, 2024
e1929f8
update: wip sdk hardhat test on zksync
ljankovic-txfusion Sep 19, 2024
8b2596a
update: wip making sdk tests compatible with zksync
ljankovic-txfusion Sep 19, 2024
e10d557
cleanup: minor test changes
ljankovic-txfusion Sep 19, 2024
e4cef73
cleanup: minor changes
ljankovic-txfusion Sep 19, 2024
2d2fb15
fix: should derive a token type from contract
ljankovic-txfusion Sep 19, 2024
a29df94
chore: refactoring multi provider
ljankovic-txfusion Sep 23, 2024
49c3812
feat: ProviderTypes for zksync
ljankovic-txfusion Sep 23, 2024
82e0938
refactor: deployment gasLimit for in memory node
ljankovic-txfusion Sep 23, 2024
53f8e61
feat: relaying messages locally
ljankovic-txfusion Sep 24, 2024
3022cd0
chore: remove gasLimit overrides for zksync
ljankovic-txfusion Sep 24, 2024
3e3637a
refactor: MultiProvider added defaultZKProviderBuilder in tryGetProvider
ljankovic-txfusion Sep 25, 2024
23f6e94
feat: singe cli/sdk to deploy to both evm and zkevm chains
ljankovic-txfusion Sep 27, 2024
733572a
feat: mutable storage multisig ISM
mortezashojaei Sep 30, 2024
629a4c8
fix: add missing addBufferToGasLimit function on utils
mortezashojaei Sep 30, 2024
2c0cb55
feat: compile contracts with solc & zksolc using single command
ljankovic-txfusion Sep 30, 2024
dcaecea
minor: cleanup
mortezashojaei Sep 30, 2024
36244c9
feature: support zksync protocol in addresses utils
mortezashojaei Sep 30, 2024
ecb3c49
minor: cleanup
mortezashojaei Sep 30, 2024
2b76f59
minot: revert back estimate handle in HyperlaneRelayer
mortezashojaei Sep 30, 2024
0ea4e51
feat: zksync support for TypedTransaction
ljankovic-txfusion Sep 30, 2024
74c3a67
Merge branch 'txfusion/sending-messages' of github.com:hyperlane-xyz/…
ljankovic-txfusion Sep 30, 2024
15de0ad
fix: prevent handle estimation on zksync protocol
mortezashojaei Sep 30, 2024
50903a6
feat: deploying StorageMerkleRootMultisigIsm
ljankovic-txfusion Oct 1, 2024
5e36ece
feat: deploying StorageMessageIdMultisigIsm
ljankovic-txfusion Oct 4, 2024
4273265
feat: refactor of contract deployment
ljankovic-txfusion Oct 4, 2024
d0fb3c8
chore: reverted & removed unused code
ljankovic-txfusion Oct 9, 2024
9bf46bc
chore: minor refactoring & adding types
ljankovic-txfusion Oct 9, 2024
8b5afe3
chore: minor changes & refactoring
ljankovic-txfusion Oct 9, 2024
0891c62
chore: minor refactoring
ljankovic-txfusion Oct 9, 2024
be23123
chore: minor cleanup
ljankovic-txfusion Oct 10, 2024
35260d6
minor refactor & cleanup
ljankovic-txfusion Oct 10, 2024
b8862ae
fix: yarn lock for cli e2e test
ljankovic-txfusion Oct 11, 2024
a432fbe
temp: testing verification
mortezashojaei Oct 8, 2024
b79b813
minor: revert contract verifier changes
mortezashojaei Oct 9, 2024
ccccce0
feat: zk verifier
mortezashojaei Oct 9, 2024
93af451
feat: verifying contract implementation on zksync explorer
ljankovic-txfusion Oct 10, 2024
6753e1f
fix: change the way load contract content
mortezashojaei Oct 10, 2024
4f39405
feat: verifying zksync contracts on block explorer
ljankovic-txfusion Oct 10, 2024
f44d3d3
minor: return verification id in zksync contract verification
mortezashojaei Oct 10, 2024
ac29b9d
feat: manage contract verification for both zksync and evm based chains
mortezashojaei Oct 11, 2024
b87cd54
minor: cleanup
mortezashojaei Oct 11, 2024
21add82
fix: support explorer just for etherum and zksync based chains
mortezashojaei Oct 11, 2024
1f0d464
minor: yarn lock
mortezashojaei Oct 11, 2024
9f98407
feat: handle verification on evm module deployer
mortezashojaei Oct 11, 2024
cb81ec7
feat: dynamic zksync artifact import
ljankovic-txfusion Oct 15, 2024
8383e95
chore: reverted/added comments
ljankovic-txfusion Oct 15, 2024
957375f
improvement: comments on zksync contract verifier
mortezashojaei Oct 15, 2024
eb79bea
fix: update hardat config type output directories
mortezashojaei Oct 15, 2024
cff1960
fix: update chain technical stack with latest values
mortezashojaei Oct 15, 2024
075f699
Merge remote-tracking branch 'origin/txfusion/sending-messages' into …
mortezashojaei Oct 15, 2024
52b221d
merge: latest main changes
mortezashojaei Oct 16, 2024
1c591a1
minor: yarn fix
mortezashojaei Oct 16, 2024
317f6d7
fix: add zksync address on explorer health test
mortezashojaei Oct 16, 2024
2f4cc62
naming: core/artifacts to core/zksync-artifacts
ljankovic-txfusion Oct 16, 2024
dec3ef4
feat: blacklist static contracts from being deployed on zksync on `hy…
ljankovic-txfusion Oct 18, 2024
8cc652d
test: e2e on zksync for warp read & apply
ljankovic-txfusion Oct 18, 2024
29205fb
feat: migrating from ProtocolType to chain technical stack for zksync
ljankovic-txfusion Oct 21, 2024
fbc7c31
feat: checking core config for Aggregation ISM on zksync core deployment
ljankovic-txfusion Oct 22, 2024
48c9b8c
merge: latest changes from root repo main
mortezashojaei Oct 22, 2024
570084a
minor: cleanup
mortezashojaei Oct 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"husky": "^8.0.0",
"lint-staged": "^12.4.3",
"prettier": "^2.8.8",
"tsx": "^4.7.1"
"tsx": "^4.7.1",
"zksync-ethers": "^5"
},
"dependencies": {
"@changesets/cli": "^2.26.2"
Expand Down
8 changes: 8 additions & 0 deletions solidity/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ docs
flattened/
buildArtifact.json
fixtures/


# zksync artifacts
artifacts-zk
cache-zk

.zksolc-libraries-cache/
typechain-types/
9 changes: 9 additions & 0 deletions solidity/contracts/interfaces/IThresholdAddressFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;

interface IThresholdAddressFactory {
function deploy(
address[] calldata _values,
uint8 _threshold
) external returns (address);
}
2 changes: 1 addition & 1 deletion solidity/contracts/isms/multisig/AbstractMultisigIsm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ abstract contract AbstractMultisig {
* @notice Manages per-domain m-of-n Validator sets of AbstractMultisig that are used to verify
* interchain messages.
*/
abstract contract AbstractMultisigIsm is AbstractMultisig {
abstract contract AbstractMultisigIsm is AbstractMultisig, IMultisigIsm {
// ============ Virtual Functions ============
// ======= OVERRIDE THESE TO IMPLEMENT =======

Expand Down
130 changes: 130 additions & 0 deletions solidity/contracts/isms/multisig/StorageMultisigIsm.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;

// ============ Internal Imports ============
import {AbstractMultisigIsm} from "./AbstractMultisigIsm.sol";
import {AbstractMerkleRootMultisigIsm} from "./AbstractMerkleRootMultisigIsm.sol";
import {AbstractMessageIdMultisigIsm} from "./AbstractMessageIdMultisigIsm.sol";
import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
import {IThresholdAddressFactory} from "../../interfaces/IThresholdAddressFactory.sol";
import {MinimalProxy} from "../../libs/MinimalProxy.sol";

// ============ External Imports ============
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

abstract contract AbstractStorageMultisigIsm is
AbstractMultisigIsm,
OwnableUpgradeable
{
address[] public validators;
uint8 public threshold;

event ValidatorsAndThresholdSet(address[] validators, uint8 threshold);

constructor(
address[] memory _validators,
uint8 _threshold
) OwnableUpgradeable() {
validators = _validators;
threshold = _threshold;
_disableInitializers();
}

function initialize(
address[] memory _validators,
uint8 _threshold
) external initializer {
__Ownable_init();
setValidatorsAndThreshold(_validators, _threshold);
}

function setValidatorsAndThreshold(
address[] memory _validators,
uint8 _threshold
) public onlyOwner {
require(_threshold <= _validators.length, "Invalid threshold");
validators = _validators;
threshold = _threshold;
emit ValidatorsAndThresholdSet(_validators, _threshold);
}

function validatorsAndThreshold(
bytes calldata /* _message */
) public view override returns (address[] memory, uint8) {
return (validators, threshold);
}
}

contract StorageMerkleRootMultisigIsm is
AbstractMerkleRootMultisigIsm,
AbstractStorageMultisigIsm
{
uint8 public constant moduleType =
uint8(IInterchainSecurityModule.Types.MERKLE_ROOT_MULTISIG);

constructor(
address[] memory _validators,
uint8 _threshold
) AbstractStorageMultisigIsm(_validators, _threshold) {}
}

contract StorageMessageIdMultisigIsm is
AbstractMessageIdMultisigIsm,
AbstractStorageMultisigIsm
{
uint8 public constant moduleType =
uint8(IInterchainSecurityModule.Types.MESSAGE_ID_MULTISIG);

constructor(
address[] memory _validators,
uint8 _threshold
) AbstractStorageMultisigIsm(_validators, _threshold) {}
}

abstract contract StorageMultisigIsmFactory is IThresholdAddressFactory {
/**
* @notice Emitted when a multisig module is deployed
* @param module The deployed ISM
*/
event ModuleDeployed(address module);

// ============ External Functions ============
function deploy(
address[] calldata _validators,
uint8 _threshold
) external returns (address ism) {
ism = MinimalProxy.create(implementation());
emit ModuleDeployed(ism);
AbstractStorageMultisigIsm(ism).initialize(_validators, _threshold);
}

function implementation() public view virtual returns (address);
}

contract StorageMerkleRootMultisigIsmFactory is StorageMultisigIsmFactory {
address internal immutable _implementation;

constructor() {
_implementation = address(
new StorageMerkleRootMultisigIsm(new address[](0), 0)
);
}

function implementation() public view override returns (address) {
return _implementation;
}
}

contract StorageMessageIdMultisigIsmFactory is StorageMultisigIsmFactory {
address internal immutable _implementation;

constructor() {
_implementation = address(
new StorageMessageIdMultisigIsm(new address[](0), 0)
);
}

function implementation() public view override returns (address) {
return _implementation;
}
}
3 changes: 2 additions & 1 deletion solidity/contracts/libs/StaticAddressSetFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";

// ============ Internal Imports ============
import {MetaProxy} from "./MetaProxy.sol";
import {IThresholdAddressFactory} from "../interfaces/IThresholdAddressFactory.sol";

abstract contract StaticThresholdAddressSetFactory {
abstract contract StaticThresholdAddressSetFactory is IThresholdAddressFactory {
// ============ Immutables ============
address public immutable implementation;

Expand Down
39 changes: 38 additions & 1 deletion solidity/exportBuildArtifact.sh
Copy link
Member

Choose a reason for hiding this comment

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

this is only used for verification btw

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yup, we are currently tackling verification (this code should belong to another branch)

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ outputFileJs="./dist/buildArtifact.js"
outputFileTsd="./dist/buildArtifact.d.ts"

# log that we're in the script
echo 'Finding and processing hardhat build artifact...'
echo 'Finding and processing hardhat build EVM artifact...'

# Find most recently modified JSON build artifact
if [ "$(uname)" = "Darwin" ]; then
Expand All @@ -37,3 +37,40 @@ else
echo 'Failed to process build artifact with jq'
exit 1
fi

# ZKSYNC

# Define the artifacts directory
artifactsDir="./artifacts-zk/build-info"
# Define the output file
outputFileJson="./dist/zksync/buildArtifact.json"
outputFileJs="./dist/zksync/buildArtifact.js"
outputFileTsd="./dist/zksync/buildArtifact.d.ts"

# log that we're in the script
echo 'Finding and processing hardhat build ZKSync artifact...'

# Find most recently modified JSON build artifact
if [ "$(uname)" = "Darwin" ]; then
# for local flow
jsonFiles=$(find "$artifactsDir" -type f -name "*.json" -exec stat -f "%m %N" {} \; | sort -rn | head -n 1 | cut -d' ' -f2-)
else
# for CI flow
jsonFiles=$(find "$artifactsDir" -type f -name "*.json" -exec stat -c "%Y %n" {} \; | sort -rn | head -n 1 | cut -d' ' -f2-)
fi

if [ ! -f "$jsonFiles" ]; then
echo 'Failed to find build artifact'
exit 1
fi
Comment on lines +53 to +65
Copy link
Contributor

Choose a reason for hiding this comment

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

would be nice to deduplicate this recently modified artifact finding/checking


# Extract required keys and write to outputFile
if jq -c '{input, solcLongVersion, zk_version: .output.zk_version}' "$jsonFiles" > "$outputFileJson"; then
echo "export const buildArtifact = " > "$outputFileJs"
cat "$outputFileJson" >> "$outputFileJs"
echo "export const buildArtifact: any" > "$outputFileTsd"
echo 'Finished processing build artifact.'
else
echo 'Failed to process build artifact with jq'
exit 1
fi
64 changes: 64 additions & 0 deletions solidity/generate-artifact-exports.mjs
Copy link
Member

Choose a reason for hiding this comment

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

not sure I totally understand why we need this
importing from JSON in TS is fine

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We use it in ZKDeployer class. Since the cli/sdk doesn't have access to hre that could fetch compiled artifacts from the root, we have to export all artifacts both as an array and by contract.

When we import all contracts as an array its much easier to sift through all of them, and then load the correct artifact for deployment.

I don't think this is optimal, need to find a better way.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { basename, dirname, join } from 'path';
import { glob } from 'typechain';
import { fileURLToPath } from 'url';

const cwd = process.cwd();

const zksyncArtifacts = glob(cwd, [
`!./artifacts-zk/contracts/**/*.dbg.json`,
`!./artifacts-zk/@openzeppelin/**/*.dbg.json`,
`./artifacts-zk/contracts/**/+([a-zA-Z0-9_]).json`,
`./artifacts-zk/@openzeppelin/**/+([a-zA-Z0-9_]).json`,
]);

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Directory containing your JSON files
const outputFile = join(__dirname, 'types/zksync/artifacts/index.ts');
const outputDir = join(__dirname, 'types/zksync/artifacts');

const zkSyncFileNames = new Set();

let zkSyncArtifactMap = {};

// Start building the TypeScript export string
let exportStatements = zksyncArtifacts
.map((file) => {
const fileContent = readFileSync(file, 'utf-8');
const jsonObject = JSON.parse(fileContent);
const contractName = jsonObject.contractName;
let fileName = `${basename(file, '.json')}__artifact`;

if (zkSyncFileNames.has(fileName)) {
return;
}
zkSyncFileNames.add(fileName);

// Add to artifact map
zkSyncArtifactMap[contractName] = fileName;

// Create a TypeScript object export statement
return `export const ${fileName} = ${JSON.stringify(
jsonObject,
null,
2,
)} as const;`;
})
.join('\n\n');

exportStatements += `\n\nexport const zksyncArtifacts : any[] = [\n${Array.from(
zkSyncFileNames,
).join(',\n')}\n] as const;`;

if (!existsSync(outputDir)) {
mkdirSync(outputDir, { recursive: true });
}

// Write the index.ts file
writeFileSync(outputFile, exportStatements);

console.log(
`Generated TypeScript object exports for ${zksyncArtifacts.length} JSON files in configs/`,
);
17 changes: 12 additions & 5 deletions solidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
"@layerzerolabs/lz-evm-oapp-v2": "2.0.2",
"@openzeppelin/contracts": "^4.9.3",
"@openzeppelin/contracts-upgradeable": "^v4.9.3",
"fx-portal": "^1.0.3"
"fx-portal": "^1.0.3",
"zksync-ethers": "^5"
},
"devDependencies": {
"@layerzerolabs/solidity-examples": "^1.1.0",
"@matterlabs/hardhat-zksync-deploy": "^0.7.0",
"@matterlabs/hardhat-zksync-solc": "^1.2.4",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-waffle": "^2.0.6",
"@typechain/ethers-v5": "^11.1.2",
Expand Down Expand Up @@ -45,12 +48,15 @@
"./mailbox": "./dist/contracts/Mailbox.js",
"./buildArtifact.js": "./dist/buildArtifact.js",
"./buildArtifact.json": "./dist/buildArtifact.json",
"./contracts": "./contracts"
"./contracts": "./contracts",
"./artifacts": "./dist/zksync/artifacts/index.js",
"./artifacts/*": "./dist/zksync/artifacts/*.js"
Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps ./artifacts -> ./zksync-artifacts/, to leave the door open for other types of VM artifacts

},
"types": "./dist/index.d.ts",
"files": [
"/dist",
"/contracts"
"/contracts",
"/dist/zksync/artifacts"
],
"engines": {
"node": ">=16"
Expand All @@ -63,13 +69,14 @@
],
"license": "Apache-2.0",
"scripts": {
"build": "yarn hardhat-esm compile && tsc && ./exportBuildArtifact.sh",
"build": "yarn hardhat-esm compile && yarn hardhat-zk compile && ts-node generate-artifact-exports.mjs && tsc && ./exportBuildArtifact.sh",
"lint": "solhint contracts/**/*.sol",
"clean": "yarn hardhat-esm clean && rm -rf ./dist ./cache ./types ./coverage ./out ./forge-cache ./fixtures",
"clean": "yarn hardhat-esm clean && yarn hardhat-zk clean && rm -rf ./dist ./cache ./cache-zk ./types ./coverage ./out ./forge-cache ./fixtures",
"coverage": "yarn fixtures && ./coverage.sh",
"docs": "forge doc",
"fixtures": "mkdir -p ./fixtures/aggregation ./fixtures/multisig",
"hardhat-esm": "NODE_OPTIONS='--experimental-loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' hardhat --config hardhat.config.cts",
"hardhat-zk": "NODE_OPTIONS='--experimental-loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' hardhat --config zk-hardhat.config.cts",
"prettier": "prettier --write ./contracts ./test",
"test": "yarn hardhat-esm test && yarn test:forge",
"test:hardhat": "yarn hardhat-esm test",
Expand Down
Loading
Loading