Skip to content

Commit b9638bc

Browse files
ecPablograham-chainlinkCopilot
authored
feat: deploy custom topology mcms [CLD-2766] (#100)
To be merged after: #99 Implements the deploy custom topology changeset and sequences for EVM which allows users to deploy custom mcms / timelock structures without custom coding topologies. ## AI Summary This pull request refactors the EVM operations code in the MCMS legacy changesets by consolidating and updating imports to use a newer, centralized `evm/operations` package. The changes primarily involve replacing references to the old `oputil` and legacy operation types with the new `evmops` types and functions, improving maintainability and consistency across the codebase. No functional logic is altered; this is a structural cleanup. **Refactoring and Codebase Cleanup:** * Replaced all imports of `oputil` and legacy operation types in multiple files (such as `deploy_mcms_with_timelock.go`, `grant_timelock.go`, and various operation and sequence files) with the new `evmops` package from `mcms/evm/operations` for EVM operation utilities and types. [[1]](diffhunk://#diff-b2398611f89ecae075cf3fa2ebc54fffdb5be3053e22ec48a758b897a3fe4f2eL24-R26) [[2]](diffhunk://#diff-d65ee785393e80500d9a9e10b6be88af9066f272f273b3a495ca51eb62bcf1caL14-R16) [[3]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L23-R24) [[4]](diffhunk://#diff-d06b9c5105af450ff38a3d1088e63930739725c5d769c418e049501f2a9ee774L12-R25) [[5]](diffhunk://#diff-bbc03c83b6d0480e7d8522c83792e93540a723fd77538ee68aa6f4680b91d026L14-R14) [[6]](diffhunk://#diff-2ba3562716d4f675ca494b4cdd289784a1a11084bf6819b9fe02e3b129822741L12-R20) [[7]](diffhunk://#diff-6e44b5b90b68ec00183f14c09ca6f134d53654e8ee03c3cfe811033a07ccdf1dL12-R12) [[8]](diffhunk://#diff-f7f4b27536717322f79551fe53d332068a4a60df6ec498e5b17a504932fe953cL12-R25) [[9]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L17-R18) [[10]](diffhunk://#diff-1fd84ce86f315635e347f82581e4070196a811f934685fa1a908b24d67089ffeL17-R18) * Updated all usages of EVM operation constructors and types (e.g., `NewEVMDeployOperation`, `NewEVMCallOperation`, `EVMDeployInput`, `RetryDeploymentWithGasBoost`, `EVMCallOutput`, etc.) to use the new `evmops` equivalents, ensuring type compatibility and consistency. [[1]](diffhunk://#diff-b2398611f89ecae075cf3fa2ebc54fffdb5be3053e22ec48a758b897a3fe4f2eL259-R259) [[2]](diffhunk://#diff-b2398611f89ecae075cf3fa2ebc54fffdb5be3053e22ec48a758b897a3fe4f2eL271-R271) [[3]](diffhunk://#diff-d65ee785393e80500d9a9e10b6be88af9066f272f273b3a495ca51eb62bcf1caL204-R208) [[4]](diffhunk://#diff-d65ee785393e80500d9a9e10b6be88af9066f272f273b3a495ca51eb62bcf1caL245-R249) [[5]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L41-R47) [[6]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L59-R68) [[7]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L122-R122) [[8]](diffhunk://#diff-d06b9c5105af450ff38a3d1088e63930739725c5d769c418e049501f2a9ee774L12-R25) [[9]](diffhunk://#diff-bbc03c83b6d0480e7d8522c83792e93540a723fd77538ee68aa6f4680b91d026L26-R32) [[10]](diffhunk://#diff-2ba3562716d4f675ca494b4cdd289784a1a11084bf6819b9fe02e3b129822741L12-R20) [[11]](diffhunk://#diff-6e44b5b90b68ec00183f14c09ca6f134d53654e8ee03c3cfe811033a07ccdf1dL22-R22) [[12]](diffhunk://#diff-f7f4b27536717322f79551fe53d332068a4a60df6ec498e5b17a504932fe953cL35-R41) [[13]](diffhunk://#diff-f7f4b27536717322f79551fe53d332068a4a60df6ec498e5b17a504932fe953cL51-R57) [[14]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L48-R53) [[15]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L83-R94) [[16]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L122-R122) * Adjusted function signatures and return types throughout the EVM operation and sequence logic to use the new types from `evmops`, removing all direct dependencies on the deprecated `oputil` package. [[1]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L41-R47) [[2]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L59-R68) [[3]](diffhunk://#diff-01347b473bc84fecfbfd6e74fc8d3ceab6f5f46df817b98912390a91abded6e9L122-R122) [[4]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L48-R53) [[5]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L83-R94) [[6]](diffhunk://#diff-af27581a8ad86d0f1ecc0da7328dd4557658d19be900e98f4cd95b8588c6b3f2L122-R122) This update is a non-functional, structural refactor that will make future maintenance and enhancements easier by consolidating EVM operation logic in a single, modern package. --------- Signed-off-by: Pablo Estrada <139084212+ecPablo@users.noreply.github.com> Co-authored-by: Graham Goh <graham.goh@smartcontract.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent f10f84c commit b9638bc

28 files changed

Lines changed: 2944 additions & 893 deletions

legacy/mcms/changesets/deploy_mcms_with_timelock.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ import (
2121
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
2222

2323
evmchangesets "github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/changesets"
24-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
2524
"github.com/smartcontractkit/cld-changesets/legacy/pkg/family/evm"
2625
solchangesets "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/solana/changesets"
26+
evmops "github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
2727
)
2828

2929
// migrateAddressBookWithQualifiers migrates an address book to a data store,
@@ -256,7 +256,7 @@ func grantRoleLogic(e cldf.Environment, cfg GrantRoleInput) (cldf.ChangesetOutpu
256256
}
257257

258258
out := cldf.ChangesetOutput{}
259-
gasBoostConfigs := oputil.GasBoostConfigsForChainMap(cfg.ExistingProposerByChain, cfg.GasBoostConfigPerChain)
259+
gasBoostConfigs := evmops.GasBoostConfigsForChainMap(cfg.ExistingProposerByChain, cfg.GasBoostConfigPerChain)
260260
for chain := range cfg.ExistingProposerByChain {
261261
stateForChain := mcmsState[chain]
262262
evmChains := e.BlockChains.EVMChains()
@@ -268,7 +268,7 @@ func grantRoleLogic(e cldf.Environment, cfg GrantRoleInput) (cldf.ChangesetOutpu
268268
Timelock: stateForChain.Timelock,
269269
CallProxy: stateForChain.CallProxy,
270270
}, false, gasBoostConfigs[chain])
271-
out, err = oputil.AddEVMCallSequenceToCSOutput(e, out, seqReport, err, mcmsStateForProposal, cfg.MCMS, fmt.Sprintf("GrantRolesForTimelock on %s", evmChains[chain]))
271+
out, err = evmops.AddEVMCallSequenceToCSOutput(e, out, seqReport, err, mcmsStateForProposal, cfg.MCMS, fmt.Sprintf("GrantRolesForTimelock on %s", evmChains[chain]))
272272
if err != nil {
273273
return out, fmt.Errorf("failed to grant roles for timelock on chain %d: %w", chain, err)
274274
}

legacy/mcms/internal/family/evm/changesets/deploy_mcms_with_timelock.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import (
1111
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
1212

1313
opevm "github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/operations"
14-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
1514
seqevm "github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/sequences"
1615
evmstate "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/evm"
16+
evmops "github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
1717
)
1818

1919
// DeployMCMSOption is a function that modifies a TypeAndVersion before or after deployment.
@@ -201,11 +201,11 @@ func DeployMCMSWithTimelockContracts(
201201
env.OperationsBundle,
202202
opevm.OpDeployTimelock,
203203
chain,
204-
oputil.EVMDeployInput[opevm.OpDeployTimelockInput]{
204+
evmops.EVMDeployInput[opevm.OpDeployTimelockInput]{
205205
ChainSelector: chain.Selector,
206206
DeployInput: opInput,
207207
},
208-
oputil.RetryDeploymentWithGasBoost[opevm.OpDeployTimelockInput](config.GasBoostConfig),
208+
evmops.RetryDeploymentWithGasBoost[opevm.OpDeployTimelockInput](config.GasBoostConfig),
209209
)
210210
execReports = append(execReports, report.ToGenericReport())
211211
if err != nil {
@@ -242,11 +242,11 @@ func DeployMCMSWithTimelockContracts(
242242
env.OperationsBundle,
243243
opevm.OpDeployCallProxy,
244244
chain,
245-
oputil.EVMDeployInput[opevm.OpDeployCallProxyInput]{
245+
evmops.EVMDeployInput[opevm.OpDeployCallProxyInput]{
246246
ChainSelector: chain.Selector,
247247
DeployInput: opInput,
248248
},
249-
oputil.RetryDeploymentWithGasBoost[opevm.OpDeployCallProxyInput](config.GasBoostConfig),
249+
evmops.RetryDeploymentWithGasBoost[opevm.OpDeployCallProxyInput](config.GasBoostConfig),
250250
)
251251
execReports = append(execReports, report.ToGenericReport())
252252
if err != nil {

legacy/mcms/internal/family/evm/changesets/grant_timelock.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import (
2020
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
2121

2222
"github.com/smartcontractkit/cld-changesets/internal/mcmsrole"
23-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
2423
seqevm "github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/sequences"
24+
evmops "github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
2525
)
2626

2727
// GrantRolesForTimelock grants RBACTimelock roles to the MCMS contracts in timelockContracts.
@@ -38,13 +38,13 @@ func GrantRolesForTimelock(
3838
timelockContracts *cldfproposalutils.MCMSWithTimelockContracts,
3939
skipIfDeployerKeyNotAdmin bool, // If true, skip role grants if the deployer key is not an admin.
4040
gasBoostConfig *cldfproposalutils.GasBoostConfig,
41-
) (operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]oputil.EVMCallOutput], error) {
41+
) (operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]evmops.EVMCallOutput], error) {
4242
lggr := env.Logger
4343
ctx := env.GetContext()
4444

4545
if timelockContracts == nil {
4646
lggr.Errorw("Timelock contracts not found", "chain", chain.String())
47-
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]oputil.EVMCallOutput]{}, fmt.Errorf("timelock contracts not found for chain %s", chain.String())
47+
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]evmops.EVMCallOutput]{}, fmt.Errorf("timelock contracts not found for chain %s", chain.String())
4848
}
4949

5050
timelock := timelockContracts.Timelock
@@ -56,16 +56,16 @@ func GrantRolesForTimelock(
5656
// get admin addresses
5757
adminAddresses, err := getAdminAddresses(ctx, timelock)
5858
if err != nil {
59-
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]oputil.EVMCallOutput]{}, fmt.Errorf("failed to get admin addresses: %w", err)
59+
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]evmops.EVMCallOutput]{}, fmt.Errorf("failed to get admin addresses: %w", err)
6060
}
6161
isDeployerKeyAdmin := slices.Contains(adminAddresses, chain.DeployerKey.From.String())
6262
isTimelockAdmin := slices.Contains(adminAddresses, timelock.Address().String())
6363
if !isDeployerKeyAdmin && skipIfDeployerKeyNotAdmin {
6464
lggr.Infow("Deployer key is not admin, skipping role grants", "chain", chain.String())
65-
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]oputil.EVMCallOutput]{}, nil
65+
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]evmops.EVMCallOutput]{}, nil
6666
}
6767
if !isDeployerKeyAdmin && !isTimelockAdmin {
68-
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]oputil.EVMCallOutput]{}, errors.New("neither deployer key nor timelock is admin, cannot grant roles")
68+
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]evmops.EVMCallOutput]{}, errors.New("neither deployer key nor timelock is admin, cannot grant roles")
6969
}
7070

7171
seqDeps := seqevm.SeqGrantRolesTimelockDeps{
@@ -119,7 +119,7 @@ func GrantRolesForTimelock(
119119
)
120120
if err != nil {
121121
lggr.Errorw("Failed to grant roles for timelock", "chain", chain.String(), "err", err)
122-
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]oputil.EVMCallOutput]{}, err
122+
return operations.SequenceReport[seqevm.SeqGrantRolesTimelockInput, map[uint64][]evmops.EVMCallOutput]{}, err
123123
}
124124

125125
return report, nil

legacy/mcms/internal/family/evm/operations/op_deploy_call_proxy.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ import (
99
zkbindings "github.com/smartcontractkit/mcms/sdk/zksync/bindings"
1010

1111
"github.com/smartcontractkit/cld-changesets/internal/semvers"
12-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
12+
"github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
1313
)
1414

1515
type OpDeployCallProxyInput struct {
1616
Timelock common.Address `json:"timelock"`
1717
}
1818

19-
var OpDeployCallProxy = oputil.NewEVMDeployOperation(
19+
var OpDeployCallProxy = operations.NewEVMDeployOperation(
2020
"evm-call-proxy-deploy",
2121
semver.MustParse("1.0.0"),
2222
"Deploys CallProxy contract on the specified EVM chains",
2323
mcmscontracts.CallProxy,
2424
bindings.CallProxyMetaData,
25-
&oputil.ContractOpts{
25+
&operations.ContractOpts{
2626
Version: &semvers.V1_0_0,
2727
EVMBytecode: common.FromHex(bindings.CallProxyBin),
2828
ZkSyncVMBytecode: zkbindings.CallProxyZkBytecode,

legacy/mcms/internal/family/evm/operations/op_deploy_timelock.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
zkbindings "github.com/smartcontractkit/mcms/sdk/zksync/bindings"
1212

1313
"github.com/smartcontractkit/cld-changesets/internal/semvers"
14-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
14+
"github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
1515
)
1616

1717
type OpDeployTimelockInput struct {
@@ -23,13 +23,13 @@ type OpDeployTimelockInput struct {
2323
Bypassers []common.Address `json:"bypassers"` // Bypasser of the timelock contract, usually the deployer key
2424
}
2525

26-
var OpDeployTimelock = oputil.NewEVMDeployOperation(
26+
var OpDeployTimelock = operations.NewEVMDeployOperation(
2727
"evm-timelock-deploy",
2828
semver.MustParse("1.0.0"),
2929
"Deploys Timelock contract on the specified EVM chains",
3030
mcmscontracts.RBACTimelock,
3131
bindings.RBACTimelockMetaData,
32-
&oputil.ContractOpts{
32+
&operations.ContractOpts{
3333
Version: &semvers.V1_0_0,
3434
EVMBytecode: common.FromHex(bindings.RBACTimelockBin),
3535
ZkSyncVMBytecode: zkbindings.RBACTimelockZkBytecode,

legacy/mcms/internal/family/evm/operations/op_grant_role.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@ package operations
22

33
import (
44
"github.com/Masterminds/semver/v3"
5-
"github.com/ethereum/go-ethereum/accounts/abi/bind/v2"
5+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
66
"github.com/ethereum/go-ethereum/common"
77
"github.com/ethereum/go-ethereum/core/types"
88

99
mcmscontracts "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/contracts/mcms"
1010
"github.com/smartcontractkit/mcms/sdk/evm/bindings"
1111

12-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
12+
"github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
1313
)
1414

1515
type OpGrantRoleInput struct {
1616
Account common.Address `json:"account"`
1717
RoleID [32]byte `json:"roleID"`
1818
}
1919

20-
var OpGrantRole = oputil.NewEVMCallOperation(
20+
var OpGrantRole = operations.NewEVMCallOperation(
2121
"evm-timelock-grant-role",
2222
semver.MustParse("1.0.0"),
2323
"Grants specified role to the ManyChainMultiSig contract on the EVM Timelock contract",

legacy/mcms/internal/family/evm/operations/op_set_config_mcm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
bindings "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers"
1010
mcmscontracts "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/contracts/mcms"
1111

12-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
12+
"github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
1313
)
1414

1515
type OpEVMSetConfigMCMInput struct {
@@ -19,7 +19,7 @@ type OpEVMSetConfigMCMInput struct {
1919
GroupParents [32]uint8 `json:"groupParents"`
2020
}
2121

22-
var OpEVMSetConfigMCM = oputil.NewEVMCallOperation(
22+
var OpEVMSetConfigMCM = operations.NewEVMCallOperation(
2323
"evm-mcm-set-config",
2424
semver.MustParse("1.0.0"),
2525
"Sets Config on the deployed MCM contract",

legacy/mcms/internal/family/evm/operations/ops_deploy_mcm.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ import (
99
zkbindings "github.com/smartcontractkit/mcms/sdk/zksync/bindings"
1010

1111
"github.com/smartcontractkit/cld-changesets/internal/semvers"
12-
"github.com/smartcontractkit/cld-changesets/legacy/mcms/internal/family/evm/oputil"
12+
"github.com/smartcontractkit/cld-changesets/mcms/evm/operations"
1313
)
1414

1515
type OpEVMDeployMCMOutput struct {
1616
Address common.Address `json:"address"`
1717
}
1818

19-
var OpDeployProposerMCM = oputil.NewEVMDeployOperation(
19+
var OpDeployProposerMCM = operations.NewEVMDeployOperation(
2020
"evm-proposer-mcm-deploy",
2121
semver.MustParse("1.0.0"),
2222
"Deploys Proposer MCM contract",
2323
mcmscontracts.ProposerManyChainMultisig,
2424
bindings.ManyChainMultiSigMetaData,
25-
&oputil.ContractOpts{
25+
&operations.ContractOpts{
2626
Version: &semvers.V1_0_0,
2727
EVMBytecode: common.FromHex(bindings.ManyChainMultiSigBin),
2828
ZkSyncVMBytecode: zkbindings.ManyChainMultiSigZkBytecode,
@@ -32,13 +32,13 @@ var OpDeployProposerMCM = oputil.NewEVMDeployOperation(
3232
},
3333
)
3434

35-
var OpDeployBypasserMCM = oputil.NewEVMDeployOperation(
35+
var OpDeployBypasserMCM = operations.NewEVMDeployOperation(
3636
"evm-bypasser-mcm-deploy",
3737
semver.MustParse("1.0.0"),
3838
"Deploys Bypasser MCM contract",
3939
mcmscontracts.BypasserManyChainMultisig,
4040
bindings.ManyChainMultiSigMetaData,
41-
&oputil.ContractOpts{
41+
&operations.ContractOpts{
4242
Version: &semvers.V1_0_0,
4343
EVMBytecode: common.FromHex(bindings.ManyChainMultiSigBin),
4444
ZkSyncVMBytecode: zkbindings.ManyChainMultiSigZkBytecode,
@@ -48,13 +48,13 @@ var OpDeployBypasserMCM = oputil.NewEVMDeployOperation(
4848
},
4949
)
5050

51-
var OpDeployCancellerMCM = oputil.NewEVMDeployOperation(
51+
var OpDeployCancellerMCM = operations.NewEVMDeployOperation(
5252
"evm-canceller-mcm-deploy",
5353
semver.MustParse("1.0.0"),
5454
"Deploys Canceller MCM contract",
5555
mcmscontracts.CancellerManyChainMultisig,
5656
bindings.ManyChainMultiSigMetaData,
57-
&oputil.ContractOpts{
57+
&operations.ContractOpts{
5858
Version: &semvers.V1_0_0,
5959
EVMBytecode: common.FromHex(bindings.ManyChainMultiSigBin),
6060
ZkSyncVMBytecode: zkbindings.ManyChainMultiSigZkBytecode,

0 commit comments

Comments
 (0)