diff --git a/.gitignore b/.gitignore index 93c3a26..650ca01 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ broadcast/ snapshots/ node_modules +data/ .DS_Store docs/superpowers/ diff --git a/config/deploy/mainnet/eth_config_input.json b/config/deploy/mainnet/eth_config_input.json new file mode 100644 index 0000000..7b4b29f --- /dev/null +++ b/config/deploy/mainnet/eth_config_input.json @@ -0,0 +1,13 @@ +{ + "vault_root_sender_adapter": { + "address": "0x0000000000000000000000000000000000000000", + "vault_root_sender": "0x5FDCCA53617f4d2b9134B29090C87D01058e27e9", + "root_receiver": "0x58b5484F489f7858DC83a5a677338074b57de806", + "root_receiver_chain": "immutable", + "axelar_gas_service": "0x2d5d7d31F671F86C782533cc367F14109a082712", + "axelar_gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5" + }, + "stark_exchange_migration": { + "implementation_address": "0x0000000000000000000000000000000000000000" + } +} diff --git a/config/deploy/mainnet/eth_deployed.json b/config/deploy/mainnet/eth_deployed.json new file mode 100644 index 0000000..aa4296d --- /dev/null +++ b/config/deploy/mainnet/eth_deployed.json @@ -0,0 +1,13 @@ +{ + "vault_root_sender_adapter": { + "address": "0x9Fabd9Cc71f15b9Cfd717E117FBb9cfD9fC7cd32", + "vault_root_sender": "0x5FDCCA53617f4d2b9134B29090C87D01058e27e9", + "root_receiver": "0x58b5484F489f7858DC83a5a677338074b57de806", + "root_receiver_chain": "immutable", + "axelar_gas_service": "0x2d5d7d31F671F86C782533cc367F14109a082712", + "axelar_gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5" + }, + "stark_exchange_migration": { + "implementation_address": "0x58b5484F489f7858DC83a5a677338074b57de806" + } +} \ No newline at end of file diff --git a/config/deploy/mainnet/zkevm_config_input.json b/config/deploy/mainnet/zkevm_config_input.json new file mode 100644 index 0000000..80e6d27 --- /dev/null +++ b/config/deploy/mainnet/zkevm_config_input.json @@ -0,0 +1,87 @@ +{ + "vault_escape_proof_verifier": { + "address": "0x0000000000000000000000000000000000000000", + "lookup_tables": [ + "0xB98CD7457BafA2B8F1bE10684A3ca7994A5F518b", + "0x16EA1DDf2f0569A9dfe79eEE8c80927941BEa818", + "0x675956E18A41172D32e03ab8c1C001F085eB605E", + "0xF9D0B099F8950054eaCc5511Bca7CCC38e37F47B", + "0x20b6C1e491ABB27914efAedd7253062B958dE8fE", + "0xB1f8636691bbb5A699B081f49e8a9f3E3342d6d8", + "0xAb618188BaF7191822A6C8f5beCaD5e52251fdB7", + "0x5C8E04129e22c0Ea89BE21f60aA39112284C1828", + "0xF4D63165ef738E9b824AB29D60868DE4106882F6", + "0x1dcC14B69603280C39b134a1e016081e894081aF", + "0xD7Fc22589EC43C9f6C01f204d83A2D2ad00B5675", + "0x40Bf22315AbFABB6a6CBDB2adA311BA5CB6Dc03C", + "0xA5833A592760564Df619013D1D193F7057C1320E", + "0xe75B35cBF59652AeB40E828eF0Fc53810A99333f", + "0x5906c7E81D44454ca93cb81b8A730e3e6f5c04Fb", + "0xf535E11bd0cD0BEe585674eD2b42a869A5D9A232", + "0x91B80204ab4D28A6B888086E4c35c6487e57E349", + "0x47d63A1Bc39E511360E84371A1b2E6Db3A042449", + "0xB4dE0D1C324333ad124bc6245a59339A4E002004", + "0x7586F2B9340a87EAC9c220678083d1541b247E78", + "0x17119e3E988092733e24Ef47aa6B6d4794820264", + "0x065Aa0C90e3CCAC367Ba47D138b2D344Da972C9a", + "0xAf98EB4e32446ff4B6cE80443C83373DB17dc506", + "0xF1428f263a666e6929dF7b056Dd399873e1d3542", + "0x8e84059D906dEF254E15a1eA9AeF5470C5458996", + "0x8EB4336B3bcE8DB209AC17DC2ea2BCF7D38C89F1", + "0x7A8DCB906cd7C54810a2C06634EA030F94594057", + "0x5f6813d68a44eD947Ed4aa64B10e262bB51Bb67a", + "0x5aE5ca6C29B022029EF49712CA959eb605dDF7c6", + "0xf5Aa18553E392f16ac646aefDAe2ABf3cE127B04", + "0x486fcd169e0C98633242F0058F9929E77c5177E9", + "0x2818ff7556FB634061385423f8794A858Fc656ae", + "0xC87A6ee0C5650A833b0F7b7C3D1f14ee66A99468", + "0xA07595Ee9D19d394374A80618807b9a5194EA30F", + "0x52281643ec5217e74e185c947A49782c73a53473", + "0x1284AE8100aAB81D0b0389Bef5B69C0C042c3dd2", + "0xA27070B4EBEd4C9D29E42ba2f0785e3A5CA23bce", + "0x9C8076146365ba1D006e23ce632C47b62a50339d", + "0x01945A3A917Bba28EAAc2928fa941706e27b86B6", + "0x50df2739C42942ea35f2d21bC293a7e9DeC73951", + "0x54CE367BD7dbDC1909209888737827513F0336F2", + "0x3e3CF0c49c6a56a7EbEeAac5f244F85c5A9ef482", + "0x495A6ffc902429f32394bCB8e29bae1E95934b3a", + "0x1c3b9a631B72236C8E91894Be504569BfAAC7b39", + "0xeF823B211f41a3a5EEF86425e5C7168F593B1c64", + "0xB6C53AE2771ee6e2Bc5e65eF6A6e9EC487A76CC5", + "0xc9486c1298dD3c8d59F2d0DeEa2DB4310641AFCE", + "0x2fEcABA0B477C9d4F30fd65670FF059876f844c2", + "0x3498311FC4D1D1AEa7c2BE9996fa9660e88B1EbE", + "0x3e14D5D611E6933d9c40d7bd51559409463af236", + "0xedaEB8eFc7270ed6CecfB2007719C602EfC0C114", + "0x6Cd4568077D1061BDEd7251bA20B3c7ebc2c9dB1", + "0xba89c843d304f127Ee225165AbAE9952844D1244", + "0xB35B64F23d343Bc1e6E06DB6FfdeAA80B62568E2", + "0x6d38dd682ff6e73625EaD7ed9F7420BBeA81153a", + "0x541e8a4Ef0a7c9A3361fBbaC1a1e1BB193e269be", + "0x3eF2C44bEd2003e7Eb5BD5b8EfEFF5F3af57F325", + "0xd78ef7B623d4E69ec0aBD749a930D2028Cd097aB", + "0x79f7957958A4770Afb7C283c7cBDDEe8bdf85a09", + "0x722Fbf18c2B2e4B7B74026B91A4006BA1C69e395", + "0x57911025A80E5726Aa5cf2956F81461891A7F303", + "0xc92C55B1AE8fF7C9E6Af81b75CbD950935881082", + "0x5b862467445Fa62ceB06a424E406ca9200cc052c" + ] + }, + "vault_root_receiver_adapter": { + "address": "0x0000000000000000000000000000000000000000", + "owner": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "axelar_gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31" + }, + "vault_withdrawal_processor": { + "address": "0x0000000000000000000000000000000000000000", + "allow_root_override": false, + "operators": { + "accountRootProvider": "0xd92D786a10585C1038E59c4804A90de942c9093D", + "tokenMappingManager": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "disburser": "0x848438c5586df38de277fc12884cd723cb830726", + "pauser": "0x0bB8BDC645821bf997e182647d86bb0bbcdC97bB", + "unpauser": "0xd92D786a10585C1038E59c4804A90de942c9093D", + "defaultAdmin": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915" + } + } +} diff --git a/config/deploy/mainnet/zkevm_deployed.json b/config/deploy/mainnet/zkevm_deployed.json new file mode 100644 index 0000000..bc4dfff --- /dev/null +++ b/config/deploy/mainnet/zkevm_deployed.json @@ -0,0 +1,87 @@ +{ + "vault_escape_proof_verifier": { + "address": "0x9Fabd9Cc71f15b9Cfd717E117FBb9cfD9fC7cd32", + "lookup_tables": [ + "0xB98CD7457BafA2B8F1bE10684A3ca7994A5F518b", + "0x16EA1DDf2f0569A9dfe79eEE8c80927941BEa818", + "0x675956E18A41172D32e03ab8c1C001F085eB605E", + "0xF9D0B099F8950054eaCc5511Bca7CCC38e37F47B", + "0x20b6C1e491ABB27914efAedd7253062B958dE8fE", + "0xB1f8636691bbb5A699B081f49e8a9f3E3342d6d8", + "0xAb618188BaF7191822A6C8f5beCaD5e52251fdB7", + "0x5C8E04129e22c0Ea89BE21f60aA39112284C1828", + "0xF4D63165ef738E9b824AB29D60868DE4106882F6", + "0x1dcC14B69603280C39b134a1e016081e894081aF", + "0xD7Fc22589EC43C9f6C01f204d83A2D2ad00B5675", + "0x40Bf22315AbFABB6a6CBDB2adA311BA5CB6Dc03C", + "0xA5833A592760564Df619013D1D193F7057C1320E", + "0xe75B35cBF59652AeB40E828eF0Fc53810A99333f", + "0x5906c7E81D44454ca93cb81b8A730e3e6f5c04Fb", + "0xf535E11bd0cD0BEe585674eD2b42a869A5D9A232", + "0x91B80204ab4D28A6B888086E4c35c6487e57E349", + "0x47d63A1Bc39E511360E84371A1b2E6Db3A042449", + "0xB4dE0D1C324333ad124bc6245a59339A4E002004", + "0x7586F2B9340a87EAC9c220678083d1541b247E78", + "0x17119e3E988092733e24Ef47aa6B6d4794820264", + "0x065Aa0C90e3CCAC367Ba47D138b2D344Da972C9a", + "0xAf98EB4e32446ff4B6cE80443C83373DB17dc506", + "0xF1428f263a666e6929dF7b056Dd399873e1d3542", + "0x8e84059D906dEF254E15a1eA9AeF5470C5458996", + "0x8EB4336B3bcE8DB209AC17DC2ea2BCF7D38C89F1", + "0x7A8DCB906cd7C54810a2C06634EA030F94594057", + "0x5f6813d68a44eD947Ed4aa64B10e262bB51Bb67a", + "0x5aE5ca6C29B022029EF49712CA959eb605dDF7c6", + "0xf5Aa18553E392f16ac646aefDAe2ABf3cE127B04", + "0x486fcd169e0C98633242F0058F9929E77c5177E9", + "0x2818ff7556FB634061385423f8794A858Fc656ae", + "0xC87A6ee0C5650A833b0F7b7C3D1f14ee66A99468", + "0xA07595Ee9D19d394374A80618807b9a5194EA30F", + "0x52281643ec5217e74e185c947A49782c73a53473", + "0x1284AE8100aAB81D0b0389Bef5B69C0C042c3dd2", + "0xA27070B4EBEd4C9D29E42ba2f0785e3A5CA23bce", + "0x9C8076146365ba1D006e23ce632C47b62a50339d", + "0x01945A3A917Bba28EAAc2928fa941706e27b86B6", + "0x50df2739C42942ea35f2d21bC293a7e9DeC73951", + "0x54CE367BD7dbDC1909209888737827513F0336F2", + "0x3e3CF0c49c6a56a7EbEeAac5f244F85c5A9ef482", + "0x495A6ffc902429f32394bCB8e29bae1E95934b3a", + "0x1c3b9a631B72236C8E91894Be504569BfAAC7b39", + "0xeF823B211f41a3a5EEF86425e5C7168F593B1c64", + "0xB6C53AE2771ee6e2Bc5e65eF6A6e9EC487A76CC5", + "0xc9486c1298dD3c8d59F2d0DeEa2DB4310641AFCE", + "0x2fEcABA0B477C9d4F30fd65670FF059876f844c2", + "0x3498311FC4D1D1AEa7c2BE9996fa9660e88B1EbE", + "0x3e14D5D611E6933d9c40d7bd51559409463af236", + "0xedaEB8eFc7270ed6CecfB2007719C602EfC0C114", + "0x6Cd4568077D1061BDEd7251bA20B3c7ebc2c9dB1", + "0xba89c843d304f127Ee225165AbAE9952844D1244", + "0xB35B64F23d343Bc1e6E06DB6FfdeAA80B62568E2", + "0x6d38dd682ff6e73625EaD7ed9F7420BBeA81153a", + "0x541e8a4Ef0a7c9A3361fBbaC1a1e1BB193e269be", + "0x3eF2C44bEd2003e7Eb5BD5b8EfEFF5F3af57F325", + "0xd78ef7B623d4E69ec0aBD749a930D2028Cd097aB", + "0x79f7957958A4770Afb7C283c7cBDDEe8bdf85a09", + "0x722Fbf18c2B2e4B7B74026B91A4006BA1C69e395", + "0x57911025A80E5726Aa5cf2956F81461891A7F303", + "0xc92C55B1AE8fF7C9E6Af81b75CbD950935881082", + "0x5b862467445Fa62ceB06a424E406ca9200cc052c" + ] + }, + "vault_root_receiver_adapter": { + "address": "0x58b5484F489f7858DC83a5a677338074b57de806", + "owner": "0xd92D786a10585C1038E59c4804A90de942c9093D", + "axelar_gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31" + }, + "vault_withdrawal_processor": { + "address": "0xCeA34C706C4A18E103575832Dd21fD3656026D1E", + "allow_root_override": false, + "operators": { + "accountRootProvider": "0xd92D786a10585C1038E59c4804A90de942c9093D", + "tokenMappingManager": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "disburser": "0x848438c5586df38de277fc12884cd723cb830726", + "pauser": "0x0bB8BDC645821bf997e182647d86bb0bbcdC97bB", + "unpauser": "0xd92D786a10585C1038E59c4804A90de942c9093D", + "defaultAdmin": "0xd92D786a10585C1038E59c4804A90de942c9093D" + } + } +} \ No newline at end of file diff --git a/config/deploy/sandbox/eth_config_input.json b/config/deploy/sandbox/eth_config_input.json new file mode 100644 index 0000000..4ff292d --- /dev/null +++ b/config/deploy/sandbox/eth_config_input.json @@ -0,0 +1,13 @@ +{ + "vault_root_sender_adapter": { + "address": "0x0000000000000000000000000000000000000000", + "vault_root_sender": "0x2d5C349fD8464DA06a3f90b4B0E9195F3d1b7F98", + "root_receiver": "0x58b5484F489f7858DC83a5a677338074b57de806", + "root_receiver_chain": "immutable", + "axelar_gas_service": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "axelar_gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31" + }, + "stark_exchange_migration": { + "implementation_address": "0x0000000000000000000000000000000000000000" + } +} diff --git a/config/deploy/sandbox/eth_deployed.json b/config/deploy/sandbox/eth_deployed.json new file mode 100644 index 0000000..f3dc81d --- /dev/null +++ b/config/deploy/sandbox/eth_deployed.json @@ -0,0 +1,13 @@ +{ + "vault_root_sender_adapter": { + "address": "0xCeA34C706C4A18E103575832Dd21fD3656026D1E", + "vault_root_sender": "0x2d5C349fD8464DA06a3f90b4B0E9195F3d1b7F98", + "root_receiver": "0x58b5484F489f7858DC83a5a677338074b57de806", + "root_receiver_chain": "immutable", + "axelar_gas_service": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "axelar_gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31" + }, + "stark_exchange_migration": { + "implementation_address": "0x9F9b4A495A62191A4225759Ae7C00906Cc6417B8" + } +} \ No newline at end of file diff --git a/config/deploy/sandbox/zkevm_config_input.json b/config/deploy/sandbox/zkevm_config_input.json new file mode 100644 index 0000000..01b6133 --- /dev/null +++ b/config/deploy/sandbox/zkevm_config_input.json @@ -0,0 +1,87 @@ +{ + "vault_escape_proof_verifier": { + "address": "0x0000000000000000000000000000000000000000", + "lookup_tables": [ + "0x2818ff7556fb634061385423f8794a858fc656ae", + "0xc87a6ee0c5650a833b0f7b7c3d1f14ee66a99468", + "0xa07595ee9d19d394374a80618807b9a5194ea30f", + "0x52281643ec5217e74e185c947a49782c73a53473", + "0x1284ae8100aab81d0b0389bef5b69c0c042c3dd2", + "0xa27070b4ebed4c9d29e42ba2f0785e3a5ca23bce", + "0x9c8076146365ba1d006e23ce632c47b62a50339d", + "0x01945a3a917bba28eaac2928fa941706e27b86b6", + "0x50df2739c42942ea35f2d21bc293a7e9dec73951", + "0x54ce367bd7dbdc1909209888737827513f0336f2", + "0x3e3cf0c49c6a56a7ebeeaac5f244f85c5a9ef482", + "0x495a6ffc902429f32394bcb8e29bae1e95934b3a", + "0x1c3b9a631b72236c8e91894be504569bfaac7b39", + "0xef823b211f41a3a5eef86425e5c7168f593b1c64", + "0xb6c53ae2771ee6e2bc5e65ef6a6e9ec487a76cc5", + "0xc9486c1298dd3c8d59f2d0deea2db4310641afce", + "0x2fecaba0b477c9d4f30fd65670ff059876f844c2", + "0x3498311fc4d1d1aea7c2be9996fa9660e88b1ebe", + "0x3e14d5d611e6933d9c40d7bd51559409463af236", + "0xedaeb8efc7270ed6cecfb2007719c602efc0c114", + "0x6cd4568077d1061bded7251ba20b3c7ebc2c9db1", + "0xba89c843d304f127ee225165abae9952844d1244", + "0xb35b64f23d343bc1e6e06db6ffdeaa80b62568e2", + "0x6d38dd682ff6e73625ead7ed9f7420bbea81153a", + "0x541e8a4ef0a7c9a3361fbbac1a1e1bb193e269be", + "0x3ef2c44bed2003e7eb5bd5b8efeff5f3af57f325", + "0xd78ef7b623d4e69ec0abd749a930d2028cd097ab", + "0x79f7957958a4770afb7c283c7cbddee8bdf85a09", + "0x722fbf18c2b2e4b7b74026b91a4006ba1c69e395", + "0x57911025a80e5726aa5cf2956f81461891a7f303", + "0xc92c55b1ae8ff7c9e6af81b75cbd950935881082", + "0x5b862467445fa62ceb06a424e406ca9200cc052c", + "0x2b99d57cfe79329f352089119f4054b5e1e6382e", + "0xc8a346c1a2b85f360f99d543d19f5bf3bd5ef47c", + "0x3d508ac6aa2cf90f5d17a9f0379bf40d669d9481", + "0x78d57d64df572b59f9e92cb9d923ced633d7e078", + "0x9969cf1dd14d1728351a47d9dc22ff7aa00b54ed", + "0xf1ab15f3d652e0f3e048a57fce2bdca30dc108d1", + "0x8480654be69ff985e3a292d514c1c44a27b93c85", + "0x8a01913a2f4691acd7a80a34f91851764ac3b43b", + "0xa701916cf4ccf17809207fe4665a4abc4d9e6b61", + "0x0377f94042d7798a70c753b05a0feeabb9a3e985", + "0x2217b9949dc07775336258cc28b499482c240041", + "0x69fbfee2c650eb6df3a346143a337399c2c547c4", + "0xf739568a3c7783211e36c95d41ee5beac493e7fd", + "0xe1faec4fcf4fc8654f924f93b520122e65ad9ae4", + "0x181e00ea7c1f6a1f786340dbe6858f8b9118446e", + "0xeecee92d924a54cddb90b35a7a4d3f5e721f59e5", + "0xabf8154e5e4b03340591c213aac0935d9ae5d055", + "0xcc7f5bd64536aadc4a045a7b2563ebfccc8ebbd5", + "0x5fad59be35015e6db6da347a6aa8b0c372b5d1f0", + "0xa27fb4d009d06020cedc58272af2d5ae49df69b8", + "0x7c44bca810623935022e1937f94c0b0e6de44b3a", + "0x69fc936a1503c851510435188ab9eb98c4176a47", + "0xde1fdd4ef2198b27ab2778337bb4bd2a99c52bc9", + "0x5e7650265f131b7712a78705921f6bae1f4d9d8f", + "0x6773940b4d2bf0541e015e3c9e2baf1b531ce9d8", + "0x39d1f70dc7336173c17ea67b4888af6227badce1", + "0xf55ac4c2181234b17c26d28623661ee3a9106424", + "0x5a3f65e07629ada8c59b8b7c96fc527e2ff982bb", + "0x183424c6ce378de5ad6cc3acd8846a62beed0311", + "0x49a7a5272a33f0e2639e9a5d1fd1cd2ceb92948f", + "0xa5c8cd4528478a8d9389aed62b9f175b1eb56997" + ] + }, + "vault_root_receiver_adapter": { + "address": "0x0000000000000000000000000000000000000000", + "owner": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "axelar_gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31" + }, + "vault_withdrawal_processor": { + "address": "0x0000000000000000000000000000000000000000", + "allow_root_override": true, + "operators": { + "accountRootProvider": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "tokenMappingManager": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "disburser": "0xeff042fd9bcfcd46d9f90eafcda69ba398b3748f", + "pauser": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "unpauser": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "defaultAdmin": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915" + } + } +} diff --git a/config/deploy/sandbox/zkevm_deployed.json b/config/deploy/sandbox/zkevm_deployed.json new file mode 100644 index 0000000..39bbde4 --- /dev/null +++ b/config/deploy/sandbox/zkevm_deployed.json @@ -0,0 +1,87 @@ +{ + "vault_escape_proof_verifier": { + "address": "0x9Fabd9Cc71f15b9Cfd717E117FBb9cfD9fC7cd32", + "lookup_tables": [ + "0x2818ff7556fb634061385423f8794a858fc656ae", + "0xc87a6ee0c5650a833b0f7b7c3d1f14ee66a99468", + "0xa07595ee9d19d394374a80618807b9a5194ea30f", + "0x52281643ec5217e74e185c947a49782c73a53473", + "0x1284ae8100aab81d0b0389bef5b69c0c042c3dd2", + "0xa27070b4ebed4c9d29e42ba2f0785e3a5ca23bce", + "0x9c8076146365ba1d006e23ce632c47b62a50339d", + "0x01945a3a917bba28eaac2928fa941706e27b86b6", + "0x50df2739c42942ea35f2d21bc293a7e9dec73951", + "0x54ce367bd7dbdc1909209888737827513f0336f2", + "0x3e3cf0c49c6a56a7ebeeaac5f244f85c5a9ef482", + "0x495a6ffc902429f32394bcb8e29bae1e95934b3a", + "0x1c3b9a631b72236c8e91894be504569bfaac7b39", + "0xef823b211f41a3a5eef86425e5c7168f593b1c64", + "0xb6c53ae2771ee6e2bc5e65ef6a6e9ec487a76cc5", + "0xc9486c1298dd3c8d59f2d0deea2db4310641afce", + "0x2fecaba0b477c9d4f30fd65670ff059876f844c2", + "0x3498311fc4d1d1aea7c2be9996fa9660e88b1ebe", + "0x3e14d5d611e6933d9c40d7bd51559409463af236", + "0xedaeb8efc7270ed6cecfb2007719c602efc0c114", + "0x6cd4568077d1061bded7251ba20b3c7ebc2c9db1", + "0xba89c843d304f127ee225165abae9952844d1244", + "0xb35b64f23d343bc1e6e06db6ffdeaa80b62568e2", + "0x6d38dd682ff6e73625ead7ed9f7420bbea81153a", + "0x541e8a4ef0a7c9a3361fbbac1a1e1bb193e269be", + "0x3ef2c44bed2003e7eb5bd5b8efeff5f3af57f325", + "0xd78ef7b623d4e69ec0abd749a930d2028cd097ab", + "0x79f7957958a4770afb7c283c7cbddee8bdf85a09", + "0x722fbf18c2b2e4b7b74026b91a4006ba1c69e395", + "0x57911025a80e5726aa5cf2956f81461891a7f303", + "0xc92c55b1ae8ff7c9e6af81b75cbd950935881082", + "0x5b862467445fa62ceb06a424e406ca9200cc052c", + "0x2b99d57cfe79329f352089119f4054b5e1e6382e", + "0xc8a346c1a2b85f360f99d543d19f5bf3bd5ef47c", + "0x3d508ac6aa2cf90f5d17a9f0379bf40d669d9481", + "0x78d57d64df572b59f9e92cb9d923ced633d7e078", + "0x9969cf1dd14d1728351a47d9dc22ff7aa00b54ed", + "0xf1ab15f3d652e0f3e048a57fce2bdca30dc108d1", + "0x8480654be69ff985e3a292d514c1c44a27b93c85", + "0x8a01913a2f4691acd7a80a34f91851764ac3b43b", + "0xa701916cf4ccf17809207fe4665a4abc4d9e6b61", + "0x0377f94042d7798a70c753b05a0feeabb9a3e985", + "0x2217b9949dc07775336258cc28b499482c240041", + "0x69fbfee2c650eb6df3a346143a337399c2c547c4", + "0xf739568a3c7783211e36c95d41ee5beac493e7fd", + "0xe1faec4fcf4fc8654f924f93b520122e65ad9ae4", + "0x181e00ea7c1f6a1f786340dbe6858f8b9118446e", + "0xeecee92d924a54cddb90b35a7a4d3f5e721f59e5", + "0xabf8154e5e4b03340591c213aac0935d9ae5d055", + "0xcc7f5bd64536aadc4a045a7b2563ebfccc8ebbd5", + "0x5fad59be35015e6db6da347a6aa8b0c372b5d1f0", + "0xa27fb4d009d06020cedc58272af2d5ae49df69b8", + "0x7c44bca810623935022e1937f94c0b0e6de44b3a", + "0x69fc936a1503c851510435188ab9eb98c4176a47", + "0xde1fdd4ef2198b27ab2778337bb4bd2a99c52bc9", + "0x5e7650265f131b7712a78705921f6bae1f4d9d8f", + "0x6773940b4d2bf0541e015e3c9e2baf1b531ce9d8", + "0x39d1f70dc7336173c17ea67b4888af6227badce1", + "0xf55ac4c2181234b17c26d28623661ee3a9106424", + "0x5a3f65e07629ada8c59b8b7c96fc527e2ff982bb", + "0x183424c6ce378de5ad6cc3acd8846a62beed0311", + "0x49a7a5272a33f0e2639e9a5d1fd1cd2ceb92948f", + "0xa5c8cd4528478a8d9389aed62b9f175b1eb56997" + ] + }, + "vault_root_receiver_adapter": { + "address": "0x58b5484F489f7858DC83a5a677338074b57de806", + "owner": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "axelar_gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31" + }, + "vault_withdrawal_processor": { + "address": "0xCeA34C706C4A18E103575832Dd21fD3656026D1E", + "allow_root_override": true, + "operators": { + "accountRootProvider": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "tokenMappingManager": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "disburser": "0xeff042fd9bcfcd46d9f90eafcda69ba398b3748f", + "pauser": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "unpauser": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915", + "defaultAdmin": "0x2E9EE2Df8037dE744C0b4D1b9A3aeE4E88816915" + } + } +} \ No newline at end of file diff --git a/config/devnet_config.json b/config/devnet_config.json deleted file mode 100644 index 0bcadcd..0000000 --- a/config/devnet_config.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "allow_root_override": true, - "vault_verifier": "0x3498311FC4D1D1AEa7c2BE9996fa9660e88B1EbE", - "vault_root_provider": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "operators": { - "pauser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "unpauser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "disburser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "defaultAdmin": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "accountRootManager": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "tokenMappingManager": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa" - }, - "lookup_tables": [ - "0x029d9879136ce8e827A682850922E7C9b13DD683", - "0x44A54af771E82EdCCC8156711645d3B818D2B5c3", - "0x4D2AFc71BA1a37317E40097fE397A8Ed6b603C5f", - "0x574e2F793aff1a809A9CC282f7ef9751Fedf444D", - "0x91F0690c5A6ABeEE8c29f66b194817032A79f303", - "0x4FF1D7cdF7Ae135C6186d2A384d88a2c932B209d", - "0x27795c4a55f30ce249ee2a7b1a156f5614F31cE4", - "0x609FccdbDbb3E038234a31DF76CC8cAe82E4530E", - "0x8651B41a049c547092eF233eccB39E4DfD59C341", - "0x0B914090a57854acC120940e1B132E1e6185E981", - "0xFf822faB6387aa6A49FB6475F86b3B77459cf49A", - "0xB71D4653a503368F29D1fA39d349619a8A42f1Af", - "0x4656b0634AAa5C6534038082364b292541b58D51", - "0x0038299b9e47722BB4eeB6a83256f0303Aa11b65", - "0xbdeeA03a2160A32a7ecf60bE4DB7Dd55f19019E3", - "0xA659C6457EDe2eD4152EB6611F52dbF1548F42B8", - "0x1293BD3F70B6090Aca46A0e2Fd5259d948190280", - "0x3d68250ffe4FE818A7aC5E0bf6f2D1C4443961f9", - "0x8b8FBAdF809A98f15Fa8f89929214a3034F7A615", - "0x7e5aB889045207051FB6030D8f7E8A43e21D8d4B", - "0x0A904eF7500980265de77B01aa1234cBA1C2712c", - "0xB98CD7457BafA2B8F1bE10684A3ca7994A5F518b", - "0x16EA1DDf2f0569A9dfe79eEE8c80927941BEa818", - "0x675956E18A41172D32e03ab8c1C001F085eB605E", - "0xF9D0B099F8950054eaCc5511Bca7CCC38e37F47B", - "0x20b6C1e491ABB27914efAedd7253062B958dE8fE", - "0xB1f8636691bbb5A699B081f49e8a9f3E3342d6d8", - "0xAb618188BaF7191822A6C8f5beCaD5e52251fdB7", - "0x5C8E04129e22c0Ea89BE21f60aA39112284C1828", - "0xF4D63165ef738E9b824AB29D60868DE4106882F6", - "0x1dcC14B69603280C39b134a1e016081e894081aF", - "0xD7Fc22589EC43C9f6C01f204d83A2D2ad00B5675", - "0x40Bf22315AbFABB6a6CBDB2adA311BA5CB6Dc03C", - "0xA5833A592760564Df619013D1D193F7057C1320E", - "0xe75B35cBF59652AeB40E828eF0Fc53810A99333f", - "0x5906c7E81D44454ca93cb81b8A730e3e6f5c04Fb", - "0xf535E11bd0cD0BEe585674eD2b42a869A5D9A232", - "0x91B80204ab4D28A6B888086E4c35c6487e57E349", - "0x47d63A1Bc39E511360E84371A1b2E6Db3A042449", - "0xB4dE0D1C324333ad124bc6245a59339A4E002004", - "0x7586F2B9340a87EAC9c220678083d1541b247E78", - "0x17119e3E988092733e24Ef47aa6B6d4794820264", - "0x065Aa0C90e3CCAC367Ba47D138b2D344Da972C9a", - "0xAf98EB4e32446ff4B6cE80443C83373DB17dc506", - "0xF1428f263a666e6929dF7b056Dd399873e1d3542", - "0x8e84059D906dEF254E15a1eA9AeF5470C5458996", - "0x8EB4336B3bcE8DB209AC17DC2ea2BCF7D38C89F1", - "0x7A8DCB906cd7C54810a2C06634EA030F94594057", - "0x5f6813d68a44eD947Ed4aa64B10e262bB51Bb67a", - "0x5aE5ca6C29B022029EF49712CA959eb605dDF7c6", - "0xf5Aa18553E392f16ac646aefDAe2ABf3cE127B04", - "0x486fcd169e0C98633242F0058F9929E77c5177E9", - "0x2818ff7556FB634061385423f8794A858Fc656ae", - "0xC87A6ee0C5650A833b0F7b7C3D1f14ee66A99468", - "0xA07595Ee9D19d394374A80618807b9a5194EA30F", - "0x52281643ec5217e74e185c947A49782c73a53473", - "0x1284AE8100aAB81D0b0389Bef5B69C0C042c3dd2", - "0xA27070B4EBEd4C9D29E42ba2f0785e3A5CA23bce", - "0x9C8076146365ba1D006e23ce632C47b62a50339d", - "0x01945A3A917Bba28EAAc2928fa941706e27b86B6", - "0x50df2739C42942ea35f2d21bC293a7e9DeC73951", - "0x54CE367BD7dbDC1909209888737827513F0336F2", - "0x3e3CF0c49c6a56a7EbEeAac5f244F85c5A9ef482" - ], - "asset_mappings": [ - { - "assetOnIMX": { - "id": 23718511493958177006583535789608930096011308449015670711204494372594274066, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x0000000000000000000000000000000000000FfF" - }, - { - "assetOnIMX": { - "id": 1103114524755001640548555873671808205895038091681120606634696969331999845790, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x2fEcABA0B477C9d4F30fd65670FF059876f844c2" - } - ] -} \ No newline at end of file diff --git a/config/tenderly_eth_mainnet_config.json b/config/operate/mainnet/eth_mainnet_config.json similarity index 92% rename from config/tenderly_eth_mainnet_config.json rename to config/operate/mainnet/eth_mainnet_config.json index ded4f18..9fbfbaa 100644 --- a/config/tenderly_eth_mainnet_config.json +++ b/config/operate/mainnet/eth_mainnet_config.json @@ -1,15 +1,5 @@ { - "allow_root_override": true, - "vault_verifier": "0x0000000000000000000000000000000000000000", - "vault_root_provider": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "operators": { - "pauser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "unpauser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "disburser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "defaultAdmin": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "accountRootManager": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "tokenMappingManager": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa" - }, + "withdrawal_processor": "0x0000000000000000000000000000000000000000", "lookup_tables": [ "0x3325e8C5d390AeC436Ff225779Dcdd4D12314f27", "0x5429509172710E58bb5BCACC550F3f980c992233", diff --git a/config/operate/mainnet/imx_tokens.json b/config/operate/mainnet/imx_tokens.json new file mode 100644 index 0000000..af0bac4 --- /dev/null +++ b/config/operate/mainnet/imx_tokens.json @@ -0,0 +1,182 @@ +[ + { + "token_int": 1015922532137787982946651776980869339398815931061497279724058213836132190095, + "token_hex": "0x023efde50c5bb32292bca9f847528b1c9eff10879048d6192f8aa9dd8fdc078f", + "token_address": "0x4d224452801aced8b2f0aebe155379bb5d594381", + "ticker_symbol": "APE", + "quantum": 100000000, + "eth_exchange_rate": 0.0001653, + "token_weight": 20 + }, + { + "token_int": 313505229384936965539156700002111859723492368677210314696313758091297420165, + "token_hex": "0x00b1700b40464e72a75e3583b68b0d6ba9037f0cbe6bf0a8cd9958181b4ff385", + "token_address": "0xe21363bf33620a291a6c354dc3bb99e40cb3086b", + "ticker_symbol": "BR", + "quantum": 100000000, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 1670413597475604293967066736840650619123375215270437228479873503062842925101, + "token_hex": "0x03b16babe64497b2831beb3590817ffe6da52c7664cd15ed8336a63b1a93e02d", + "token_address": "0xe910c2a090516fb7a7be07f96a464785f2d5dc18", + "ticker_symbol": "CMT", + "quantum": 100000000, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 990917105548321882863790743692016363780882772911795288852111915173114800720, + "token_hex": "0x0230d6d63a2a92dbd1b2bf589517b7823587dae986da2a63a8f11092ea4bea50", + "token_address": "0x90685e300a4c4532efcefe91202dfe1dfd572f47", + "ticker_symbol": "CTA", + "quantum": 100000000, + "eth_exchange_rate": 0.00001224, + "token_weight": 20 + }, + { + "token_int": 1707776506599369959662713172170118390106404453517106730194996143842397299232, + "token_hex": "0x03c69137390804d0bd32e452ae71ea42f236b74fb81da3106c6a7a3e1f50a220", + "token_address": "0xa3d59c6d24f428dcfedc09724869e7af4d281fdd", + "ticker_symbol": "DEV", + "quantum": 1, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 127313621446881611467827816653547345717404185327457088545463981166261510791, + "token_hex": "0x00480e94ad68296b0bd050666fa696219d667d8fcce307206af6af4679612287", + "token_address": "0x35f3bad2fcc8053869086885f7898a3d4309db4e", + "ticker_symbol": "EMBER", + "quantum": 100000000, + "eth_exchange_rate": 0.00000006869, + "token_weight": 20 + }, + { + "token_int": 1103114524755001640548555873671808205895038091681120606634696969331999845790, + "token_hex": "0x02705737cd248ac819034b5de474c8f0368224f72a0fda9e031499d519992d9e", + "token_address": "eth", + "ticker_symbol": "ETH", + "quantum": 100000000, + "eth_exchange_rate": 1, + "token_weight": 100 + }, + { + "token_int": 427042314744200788989839114132810697143887157126058739219120820878172477593, + "token_hex": "0x00f1b287cdf5aac7ceb8de77b253c60aa648c550460cf9adc63254649957d899", + "token_address": "0x19997289163ce4659d447617a0877da36770ab4d", + "ticker_symbol": "FGL", + "quantum": 100000000, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 636117700839179604858620718832286872417390350654465827892936533551518041557, + "token_hex": "0x016807a4e2986bc9d4c2c6a2fff6b2c6f351989c0f7a6d2164377848aac7c5d5", + "token_address": "0xccc8cb5229b0ac8069c51fd58367fd1e622afd97", + "ticker_symbol": "GODS", + "quantum": 100000000, + "eth_exchange_rate": 0.00003042, + "token_weight": 20 + }, + { + "token_int": 1125223003001074656178455529439603029082973884966680368655489058248875828864, + "token_hex": "0x027cda88d6158016cc3b1e489ab2733f1e22ff9803ee838963e0b88a4593e680", + "token_address": "0x9ab7bb7fdc60f4357ecfef43986818a2a3569c62", + "ticker_symbol": "GOG", + "quantum": 100000000, + "eth_exchange_rate": 0.000003253, + "token_weight": 20 + }, + { + "token_int": 634028667897844324040908450156043846954664548107344752361156161409532472444, + "token_hex": "0x0166d8f658c71f52c5ed1a120850a0a2141eb620ac766a4aa2dcb154d0d2ac7c", + "token_address": "0x767fe9edc9e0df98e07454847909b5e959d7ca0e", + "ticker_symbol": "ILV", + "quantum": 100000000, + "eth_exchange_rate": 0.003963, + "token_weight": 20 + }, + { + "token_int": 88914301944088089141574999348394996493546404963067902156417732601144566237, + "token_hex": "0x003252dec1ad51e115659dcfab7cbf9489e2ab1d7a81b747ec1a9e5daa0261dd", + "token_address": "0xf57e7e7c23978c3caec3c3548e3d615c346e79ff", + "ticker_symbol": "IMX", + "quantum": 100000000, + "eth_exchange_rate": 0.0001536, + "token_weight": 60 + }, + { + "token_int": 103129661469142187932697195709967826790010599230686898125218855467795622233, + "token_hex": "0x003a5e8bbf13d7ef6b65d7456b9c9d46562821012149e2fcf14b3710b6302959", + "token_address": "0x71854072ce51cc8859c8c178e33581034fa75753", + "ticker_symbol": "LOST", + "quantum": 100000000, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 881983512215682697930791077345670677400334790145955708894204513777355240488, + "token_hex": "0x01f32f5aaee31e3bca862904ba913222e307d33b00f2546f15fae9352fa6b428", + "token_address": "0xed35af169af46a02ee13b9d79eb57d6d68c1749e", + "ticker_symbol": "OMI", + "quantum": 100000000, + "eth_exchange_rate": 0.0000000504, + "token_weight": 20 + }, + { + "token_int": 525164948494449116421805041713913612934056483342602240145121349090983728353, + "token_hex": "0x01293b9a9220a3a4e6d2a947bd142c693b7e3e4664503baa7bab694ec58ad4e1", + "token_address": "0xed35af169af46a02ee13b9d79eb57d6d68c1749e", + "ticker_symbol": "OMI", + "quantum": 100000000000, + "eth_exchange_rate": 0.0000000504, + "token_weight": 20 + }, + { + "token_int": 227716095600406046651136589472266806698090667547081713813841569445055346153, + "token_hex": "0x0080e1fb6c92d583a9504b2aa9d1f665355f7a380c19fb64b8a2bc639f8cb5e9", + "token_address": "0x7e77dcb127f99ece88230a64db8d595f31f1b068", + "ticker_symbol": "SILV2", + "quantum": 100000000, + "eth_exchange_rate": 0.001856, + "token_weight": 20 + }, + { + "token_int": 1147032829293317481173155891309375254605214077236177772270270553197624560221, + "token_hex": "0x02893294412a4c8f915f75892b395ebbf6859ec246ec365c3b1f56f47c3a0a5d", + "token_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "ticker_symbol": "USDC", + "quantum": 1, + "eth_exchange_rate": 0.0002541, + "token_weight": 100 + }, + { + "token_int": 1485183671027309009439509871835489442660821279230223034298428454062208985878, + "token_hex": "0x0348958c1322d3fc34f89b91b0b6473594725847184ee590e990bb70ef322b16", + "token_address": "0x2caa4021e580b07d92adf8a40ec53b33a215d620", + "ticker_symbol": "VCO", + "quantum": 100000000, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 1796496801014838733778624354279754962911198551343321171219226048470100654417, + "token_hex": "0x03f8c7f9d713c0e2f8e049f3e9199667adc83a5e254a4142af43b82c2acab951", + "token_address": "0x733b5056a0697e7a4357305fe452999a0c409feb", + "ticker_symbol": "VCORE", + "quantum": 100000000, + "eth_exchange_rate": 0.00000000001, + "token_weight": 20 + }, + { + "token_int": 915177440183500088607294558883023442174593163187193385150232248105465289242, + "token_hex": "0x0205f8d9e6a74938443ec9e626b12d5d513c09ade66bd71642fcdc185e3c1a1a", + "token_address": "0x3b604747ad1720c01ded0455728b62c0d2f100f0", + "ticker_symbol": "WAGMI", + "quantum": 100000000, + "eth_exchange_rate": 0.000000001783, + "token_weight": 20 + } +] \ No newline at end of file diff --git a/config/operate/mainnet/token_mappings.json b/config/operate/mainnet/token_mappings.json new file mode 100644 index 0000000..89c61d4 --- /dev/null +++ b/config/operate/mainnet/token_mappings.json @@ -0,0 +1,138 @@ +{ + "withdrawal_processor": "0x0000000000000000000000000000000000000000", + "asset_mappings": [ + { + "tokenOnIMX": { + "id": 88914301944088089141574999348394996493546404963067902156417732601144566237, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x0000000000000000000000000000000000000FfF" + }, + { + "tokenOnIMX": { + "id": 103129661469142187932697195709967826790010599230686898125218855467795622233, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x201a5cC4C4cC21F9859D24e018e81487E6f48e9C" + }, + { + "tokenOnIMX": { + "id": 127313621446881611467827816653547345717404185327457088545463981166261510791, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xc4626318B3bECee9d50Df656C782c40252ED0f67" + }, + { + "tokenOnIMX": { + "id": 227716095600406046651136589472266806698090667547081713813841569445055346153, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x1d4115d22C6c6C8933d3708D492cD8038aa4fF61" + }, + { + "tokenOnIMX": { + "id": 313505229384936965539156700002111859723492368677210314696313758091297420165, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x9754A6939Eb529E44a42Fd54db27bAAF29F7b164" + }, + { + "tokenOnIMX": { + "id": 525164948494449116421805041713913612934056483342602240145121349090983728353, + "quantum": 100000000000 + }, + "tokenOnZKEVM": "0xA1cD1f0801DbCdD9DC945D028f3961c1aA63aC7E" + }, + { + "tokenOnIMX": { + "id": 634028667897844324040908450156043846954664548107344752361156161409532472444, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x4e55C0c55830252A293EbBAE090B1a4d00A2D0e0" + }, + { + "tokenOnIMX": { + "id": 636117700839179604858620718832286872417390350654465827892936533551518041557, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xE0e0981D19eF2E0a57Cc48CA60D9454eD2D53fEB" + }, + { + "tokenOnIMX": { + "id": 881983512215682697930791077345670677400334790145955708894204513777355240488, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xA1cD1f0801DbCdD9DC945D028f3961c1aA63aC7E" + }, + { + "tokenOnIMX": { + "id": 915177440183500088607294558883023442174593163187193385150232248105465289242, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xf23470043011b747250EC0FeFFc43C5ab09bE306" + }, + { + "tokenOnIMX": { + "id": 990917105548321882863790743692016363780882772911795288852111915173114800720, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xcee79B4dA47f149c35C584a0780578CBa4398610" + }, + { + "tokenOnIMX": { + "id": 1015922532137787982946651776980869339398815931061497279724058213836132190095, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x5674cC415897ee922A45fbBC4598F8FC4c064878" + }, + { + "tokenOnIMX": { + "id": 1103114524755001640548555873671808205895038091681120606634696969331999845790, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x52A6c53869Ce09a731CD772f245b97A4401d3348" + }, + { + "tokenOnIMX": { + "id": 1125223003001074656178455529439603029082973884966680368655489058248875828864, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xb00ed913aAFf8280C17BfF33CcE82fE6D79e85e8" + }, + { + "tokenOnIMX": { + "id": 1147032829293317481173155891309375254605214077236177772270270553197624560221, + "quantum": 1 + }, + "tokenOnZKEVM": "0x6de8aCC0D406837030CE4dd28e7c08C5a96a30d2" + }, + { + "tokenOnIMX": { + "id": 1485183671027309009439509871835489442660821279230223034298428454062208985878, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x979084A06dAa9064B532214AeA71024517A99fF9" + }, + { + "tokenOnIMX": { + "id": 1670413597475604293967066736840650619123375215270437228479873503062842925101, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x2Ad1F875539A8081E00d4835621771155A58bD86" + }, + { + "tokenOnIMX": { + "id": 1707776506599369959662713172170118390106404453517106730194996143842397299232, + "quantum": 1 + }, + "tokenOnZKEVM": "0x5407795A261955F69641bC9751F4ffedF0E0F42A" + }, + { + "tokenOnIMX": { + "id": 1796496801014838733778624354279754962911198551343321171219226048470100654417, + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x6454A4d1a7e050D966F9Aa21C4eefb1a6c92FB4C" + } + ] +} diff --git a/config/operate/sandbox/imx_tokens.json b/config/operate/sandbox/imx_tokens.json new file mode 100644 index 0000000..64986ac --- /dev/null +++ b/config/operate/sandbox/imx_tokens.json @@ -0,0 +1,317 @@ +[ + { + "token_int": 1530984830380564117086548947741263773510366505132298518074070101164820062630, + "token_hex": "0x036281b77e9bf5e957c1dbc6f38ebb755bf188c2bbe3b08564a410bb7818e1a6", + "token_address": "0x00e49f72e3ff96f50e98d8533f2eb5a9b69b002f", + "ticker_symbol": "ARG", + "quantum": 100000000 + }, + { + "token_int": 1073653178426466786182623804251028445438158097414716880341181592411393923116, + "token_hex": "0x025faa89bb32e7b75c263d500d177753fad1250006e8d75a09e40dbd013e982c", + "token_address": "0xc7bc6619082b8cced2cc936203eff41891edb76b", + "ticker_symbol": "BR", + "quantum": 100000000 + }, + { + "token_int": 469541149215236994106312323274306218924367273999532936226373165480865072166, + "token_hex": "0x0109c0392fcb91c8c35ac2634cfabd2b26661624b926e5a06a3e7a7b04ae8426", + "token_address": "0x655dfe9d7ec1a74d45841f79ec6b4f6160a4c031", + "ticker_symbol": "CRYPI", + "quantum": 100000000 + }, + { + "token_int": 1800070639292759431876200506148529988822384962475997258171744591397001372553, + "token_hex": "0x03facdcade8ebb6ead84e24f16253999268b5517fdab65f8404a587463202389", + "token_address": "0xf82dbf105e144f7219b089fb2790f3faf19b676e", + "ticker_symbol": "CRYPI", + "quantum": 1 + }, + { + "token_int": 278583067383992383480264268372737502031925467588718654218074253480841633548, + "token_hex": "0x009dac24452a9073dccaf51b1e6d651f262c3272c124820fcf405b6432cedf0c", + "token_address": "0x1d30db727c18f6d8c3318deda7d3cd8a689ce935", + "ticker_symbol": "CRYPT", + "quantum": 1 + }, + { + "token_int": 855696249333702326166027625093829385191505517726423367160505816117313720239, + "token_hex": "0x01e44e91e9573aa3377516854657fb47aaf26ba9d5f710a78acfe5a32706cfaf", + "token_address": "0x40d3e56ddfcd6b98b41439f9d98eb7a42804249a", + "ticker_symbol": "CRYPT", + "quantum": 100000000 + }, + { + "token_int": 45817669857783943078259039040823645909482319712107577790906451611064669921, + "token_hex": "0x0019ee8fd41662bd7afea3b333596f0614303dc1233768cf7d89bf12abcf16e1", + "token_address": "0xed398bfdde93056c4dd61e2503816587aa80c346", + "ticker_symbol": "CRYPU", + "quantum": 1 + }, + { + "token_int": 1796911963631684152130514622551639338427318256305213492458648234201659064961, + "token_hex": "0x03f9042113d4b778ba1932153a38f9fac9539da1530b1dad53c91ee71a8dc281", + "token_address": "0x8122c8f02f1e586f166dcb6a6de3b5c0fd3e48ca", + "ticker_symbol": "CRYPU", + "quantum": 100000000 + }, + { + "token_int": 1205801016002269626459263468621484672253654502893679938994915767141360433198, + "token_hex": "0x02aa758d735b0516fa059e40882d9a90447a4cf56a62d5c7eee0005f6d4b782e", + "token_address": "0x6da2a4d37259439c7ddcddb55cd0ef2033fe1e8f", + "ticker_symbol": "CTA", + "quantum": 100000000 + }, + { + "token_int": 1697937671430045510303887649398941342205203259071938147663058327235194893000, + "token_hex": "0x03c0ffa88b24427590ec073c8da64e9ba7073779397de048c9d643861261b2c8", + "token_address": "0xbe7be8d5f99b16b2f29007d9eb08ed49f73d05d6", + "ticker_symbol": "EST", + "quantum": 100000000 + }, + { + "token_int": 1103114524755001640548555873671808205895038091681120606634696969331999845790, + "token_hex": "0x02705737cd248ac819034b5de474c8f0368224f72a0fda9e031499d519992d9e", + "token_address": "eth", + "ticker_symbol": "ETH", + "quantum": 100000000 + }, + { + "token_int": 958749024699050137966222344651071737385564981318518993053819450292484749550, + "token_hex": "0x021ea1f9cb3601cf8f4f4056b305a6fe916e3d6e070f8c737fadb82472f8b8ee", + "token_address": "0xf9c16d203b6d67c5943de257fff1ab2e5dc52f73", + "ticker_symbol": "EVM", + "quantum": 100000000 + }, + { + "token_int": 140045364627528196345084413227318657255889301714016666850545170669121136724, + "token_hex": "0x004f434b474ce23a7ed2ba98084190cebd039520d5ed2ca701c16d6d21356854", + "token_address": "0x5c9f1680bb6a4b4fc698e0cf702e0cc34aed91b7", + "ticker_symbol": "GODS", + "quantum": 100000000 + }, + { + "token_int": 288497620338891181002256043717214864459537182795830852149172946884830468774, + "token_hex": "0x00a348ab7a6b1e4e96eafba1b92d6795e4b72c4f41acf5eeb83eb927d3089aa6", + "token_address": "0xfe9df9ebe5fbd94b00247613b6cf7629891954e2", + "ticker_symbol": "GOG", + "quantum": 100000000 + }, + { + "token_int": 1782613318986674861730994617630569436938103649781060793390626353255201116359, + "token_hex": "0x03f0ec62deee8373379d9aa8dcd6ee3b13634a19385c888023b3909af42410c7", + "token_address": "0x040b46e6f5fb6d21e5e117b2cc6a8490bd13bdd8", + "ticker_symbol": "HYPEI", + "quantum": 1 + }, + { + "token_int": 1100051021863410963740714092430936399472019405492900761810892193340061133175, + "token_hex": "0x026e9b5829e574b996fbd4cc5e4972772962c959d40a485c8d9bdf8d31582977", + "token_address": "0xb239c8e5c119f231151791fface0bf634670f27a", + "ticker_symbol": "HYPEI", + "quantum": 100000000 + }, + { + "token_int": 1730268361872681930365892179602415294747249511559951801222868962857887087074, + "token_hex": "0x03d34c148081c305f44bed7d09c7f0695b5d92f89764bf593fb46ac5adb639e2", + "token_address": "0x17eae1f5d6c6dba5a8fc68789ad8bb6531b1c5ce", + "ticker_symbol": "HYPER", + "quantum": 1 + }, + { + "token_int": 133566068527828825746133918188608556461795710960217173451759027761417430363, + "token_hex": "0x004b9880d43da4b30f564481a5e908c0ef16f4271bc4268a5ef160508e3e255b", + "token_address": "0xbd8172ab5f2d4b068f8865ed527c3427cb998678", + "ticker_symbol": "HYPER", + "quantum": 100000000 + }, + { + "token_int": 279228093087404724401986225486636769487846954176324340679736210809311495, + "token_hex": "0x0000287525464118634e83b0125c1c556cdb2fa803a16d333b4ddd104d925107", + "token_address": "0x64f78605852706da360457c64267a0b7da77f0e9", + "ticker_symbol": "HYPEU", + "quantum": 100000000 + }, + { + "token_int": 278218763421750168916729775629218233399649390895347468260686151792906842745, + "token_hex": "0x009d775b7c3676966ddcbf9510dab3a21e32a1d7383f8848202a364c6745b279", + "token_address": "0xb79a155c97a21fb0630b6094d8cd90c3d32790d6", + "ticker_symbol": "HYPEU", + "quantum": 1 + }, + { + "token_int": 1118767138481389624672377790657114412417202583785801293058102967449208440552, + "token_hex": "0x02793323832e0bed01953f6d62bc030d44cb8a6bbcba426d30d6a4391c4746e8", + "token_address": "0x886dd14dcc6caed09a3e4d01d489673a84dd8f16", + "ticker_symbol": "ILV", + "quantum": 100000000 + }, + { + "token_int": 246687233301300469710108727028426484184902991299048503161524411000024849494, + "token_hex": "0x008b9eba07d398dcfbe9f53293e494fd7c8632e596542bdf315e2806470ddc56", + "token_address": "0xf444a3355e4624f7b2c532557420e9c01ced499f", + "ticker_symbol": "ILVI", + "quantum": 100000000 + }, + { + "token_int": 620001226371989005351249404877383874184100034181679496390579996208319954842, + "token_hex": "0x015ee8839f78292d8f5a0f1bc03aad3d83c17e722b2200c8ea08d3656753ff9a", + "token_address": "0xc65f3e4d8edda3ee80cf7f98b0b0c9f208c33c9e", + "ticker_symbol": "ILVU", + "quantum": 100000000 + }, + { + "token_int": 774695052920335475148844746909925970695317951232942764061726388365724651811, + "token_hex": "0x01b6763c8d4f5d55a9af0da888a3aab2602244fd49ac1e58ae0a295072529123", + "token_address": "0x2fa06c6672ddcc066ab04631192738799231de4a", + "ticker_symbol": "IMX", + "quantum": 100000000 + }, + { + "token_int": 1079365209654237028653623629764958016172582949813253986541136037171578617505, + "token_hex": "0x0262e628beb02321b2ec900b4901d91a74b7b6a30ef0d01f7d8967fa8fc53ea1", + "token_address": "0xf674d458575c1b659da24a60add8a4f68cd7fb19", + "ticker_symbol": "MTK", + "quantum": 10 + }, + { + "token_int": 889491635621296293428570805285996100526088113454814524032053738967908687010, + "token_hex": "0x01f76f3675542641b1726cfd40853f5c677823c566592e00f63f9716b6cb1ca2", + "token_address": "0x174ce99c5a5407b2e7101e5a743f28936f2f0c69", + "ticker_symbol": "MZD", + "quantum": 1 + }, + { + "token_int": 1541893324194556794018922586922863773169005377082433218256783405946955321773, + "token_hex": "0x0368ae42049fcaee0cf99c3244ef433aa29737bc22d61fad6ddeca5fb87351ad", + "token_address": "0x02f80da373021e0b6a0a00470f82b55d4830a724", + "ticker_symbol": "OMI", + "quantum": 100000000 + }, + { + "token_int": 508896894519199837882532718821198929536057284631686405901881975310756808819, + "token_hex": "0x01200682e9838b0cd66780a2ede3e844cfc18a8b3db2cc2a6e9e3032e6670873", + "token_address": "0x3b1b47bdaeb409a1ed64a13d856bd0ca1f718be5", + "ticker_symbol": "OMI", + "quantum": 100000000 + }, + { + "token_int": 1713273459042363589671903409735439653127748941717893520188565250123836559922, + "token_hex": "0x03c9adac8559575d2f5fb290542d6f93c0a8fd130d32c9bffda5c60eeff61232", + "token_address": "0x2711f4f362dc6c3da2fce3e021170b033b7df7fc", + "ticker_symbol": "OMI", + "quantum": 100000000 + }, + { + "token_int": 1007429852875183837711381425904397530529430287830771091622498485479621080033, + "token_hex": "0x023a2f621113bf203ee0789aae1e31c1891b079551690bf56e759a5bbd5933e1", + "token_address": "0x312674a822a337bc50d4fdf465781079760a6729", + "ticker_symbol": "SDK", + "quantum": 100000000 + }, + { + "token_int": 1026459113228997553038702658409951763724108387124859616632951167746600061279, + "token_hex": "0x0244f48c8feb2121ebbff33e0b9e237b08879f0bbe283e1fcde67e9df4c7c95f", + "token_address": "0x82475443f1075bc571a552cbdab1f49b24e1c47a", + "ticker_symbol": "SILV2", + "quantum": 100000000 + }, + { + "token_int": 224326615647497430209000540151115974094010699057468868354504375901667258695, + "token_hex": "0x007ef6e0a00ece137332cd5f3b5b13cb2c46d009d200163040d96a64deecf147", + "token_address": "0x387798f984091808e266dcb7f3fd306e18d71904", + "ticker_symbol": "SILVI", + "quantum": 100000000 + }, + { + "token_int": 14406987772269190202869751597715327602721087011555776736463891281797319454, + "token_hex": "0x00082770e06766fb8946372dc848003cc29dc0d3fa2e04e3cbb997a5916e0b1e", + "token_address": "0x6bdefb9b62444c99999682a2076841b47a4cab9c", + "ticker_symbol": "SILVU", + "quantum": 100000000 + }, + { + "token_int": 1074694638794775585034847784496210938495869105762602294578446735922582865903, + "token_hex": "0x0260416fa4ae3ef88f51b8101b16830395a08fd38e76500d22eaf5df6b7d47ef", + "token_address": "0xbb864c80cb6e263c34c325f51544e8d0b9e9455c", + "ticker_symbol": "SOLOI", + "quantum": 100000000 + }, + { + "token_int": 1789880607087655497383974216548231163506506920581499066660700239294810361138, + "token_hex": "0x03f50959916c298c491b05ae0d4276c77ccb94d43749bdc769c0ba4207010d32", + "token_address": "0xb13477b46fbcb878b496ca511018801e45cfc846", + "ticker_symbol": "SOLOI", + "quantum": 1 + }, + { + "token_int": 1142780287754666633490319950078041001437265973993631920364116058229405481176, + "token_hex": "0x0286ca6cb8e4b039c1d6e8f92cb1b8a70437e4e1148f476f28b4c459512978d8", + "token_address": "0xedc2e5600ac2ae5c79cb68114e4ca6cb3360ee51", + "ticker_symbol": "SOLON", + "quantum": 1 + }, + { + "token_int": 1304335111848845550036725670378237818351850476608607454929125615580280114750, + "token_hex": "0x02e23a3e31bbe0b19a3d20cb4f4ce3f57b98efbda3a637b5ef4e645a697dce3e", + "token_address": "0x3701c15dd3b155d96d02d4eeec6cadc387af767d", + "ticker_symbol": "SOLON", + "quantum": 100000000 + }, + { + "token_int": 584818264821865309529860137527490043841291606793888110511892289381889046142, + "token_hex": "0x014afed30c92df172300841b588eeba2a8847c6f69eb6369099304fa85b5767e", + "token_address": "0x8db3294ac60ec3462d846a090e1f4348e29d8d8d", + "ticker_symbol": "SOLOU", + "quantum": 1 + }, + { + "token_int": 21498777723544896979545581006810717137381075370112586295636297534407605532, + "token_hex": "0x000c2af9fc5330112b2b1903a31fbdf1831696c3199a712778fba2c27c4e7d1c", + "token_address": "0x73d859408b80c395f97232dff990b86f3c51aff6", + "ticker_symbol": "SOLOU", + "quantum": 100000000 + }, + { + "token_int": 1694009098181558118158615594769574705969634676578372970032421836083086133628, + "token_hex": "0x03bec671a9b76918fa48522c9393f8812ce939f2989c36cd428b1a17f88a897c", + "token_address": "0x5b56a1a6e46e799c5ca87b37f9896902f541afc8", + "ticker_symbol": "TRDS", + "quantum": 100000000 + }, + { + "token_int": 540062279147817096126692697840181823459298758504720034739181724881731629294, + "token_hex": "0x0131aa174693d972c69769b40661e38a0a299a22f771ff02430ad7600562b0ee", + "token_address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "ticker_symbol": "UNI", + "quantum": 100000000 + }, + { + "token_int": 661141420868150794624283883274270269479864861417174829821648462727047715204, + "token_hex": "0x0176315a3f61a48b81f3cf31f54ec78571898e60b71001ac6d4c4c1675969984", + "token_address": "0xca6c31cc71fb8f00dc2c465299f605039e0e1f4b", + "ticker_symbol": "USDC", + "quantum": 1 + }, + { + "token_int": 1529047011282119779666243264336891129455481470106617051357049340145514211869, + "token_hex": "0x036168f1ca14b6e3d32589c2f88617f9d91d1f3b13a3830002fc654a37de6a1d", + "token_address": "0xec0ed56027f7896fe11309de6dacf95b786924d3", + "ticker_symbol": "VCOIN", + "quantum": 100000000 + }, + { + "token_int": 937627426884687223015650826300942653066238230804307701105682811511494029416, + "token_hex": "0x0212ada6304417eb3ea3f5a8887388bb30fe5230fe3166410e679e982e4a3068", + "token_address": "0xc7d4cd5bc9da8a5f77718f6851f3df6f79a13293", + "ticker_symbol": "VCOIN", + "quantum": 100000000 + }, + { + "token_int": 701992353264593934042630901537572119762294448768089561198251820694421559230, + "token_hex": "0x018d50478b6de660778b9c7b2d1b178cfcd7df6978ba472886395b07ab0ed7be", + "token_address": "0x315061da0f44527eb0c534b62df4e5cefc0d5cdb", + "ticker_symbol": "VCORE", + "quantum": 100000000 + } +] \ No newline at end of file diff --git a/config/operate/sandbox/token_mappings.json b/config/operate/sandbox/token_mappings.json new file mode 100644 index 0000000..9fa30d0 --- /dev/null +++ b/config/operate/sandbox/token_mappings.json @@ -0,0 +1,320 @@ +{ + "withdrawal_processor": "0xCeA34C706C4A18E103575832Dd21fD3656026D1E", + "asset_mappings": [ + { + "tokenOnIMX": { + "id": "1530984830380564117086548947741263773510366505132298518074070101164820062630", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xa9fAB8761c583563B2DeA14b696011fd0a810b8C" + }, + { + "tokenOnIMX": { + "id": "1073653178426466786182623804251028445438158097414716880341181592411393923116", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xe5D62376e16915278d2C02441B468c04081299eC" + }, + { + "tokenOnIMX": { + "id": "469541149215236994106312323274306218924367273999532936226373165480865072166", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x641315EB5b773FA539c3930521B8C947092c4998" + }, + { + "tokenOnIMX": { + "id": "1800070639292759431876200506148529988822384962475997258171744591397001372553", + "quantum": 1 + }, + "tokenOnZKEVM": "0x1Fd936B1eE64Fb1b0b0D4A7f72559cB6130690E5" + }, + { + "tokenOnIMX": { + "id": "278583067383992383480264268372737502031925467588718654218074253480841633548", + "quantum": 1 + }, + "tokenOnZKEVM": "0x5Ca77Ed943885Ff7a4AE379eff185Ec8C7812511" + }, + { + "tokenOnIMX": { + "id": "855696249333702326166027625093829385191505517726423367160505816117313720239", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x06efA06E5129E80cd729B99113fd157c9081385c" + }, + { + "tokenOnIMX": { + "id": "45817669857783943078259039040823645909482319712107577790906451611064669921", + "quantum": 1 + }, + "tokenOnZKEVM": "0x3775caf3E5654dEfC7c77Fc887e99C0BD1270cfC" + }, + { + "tokenOnIMX": { + "id": "1796911963631684152130514622551639338427318256305213492458648234201659064961", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xD7C6Cf64CA16d9d48458d69bFdBB1be0eA8f744A" + }, + { + "tokenOnIMX": { + "id": "1205801016002269626459263468621484672253654502893679938994915767141360433198", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x545AA0D76e89102CF71F223295431f4CaE1F15AD" + }, + { + "tokenOnIMX": { + "id": "1697937671430045510303887649398941342205203259071938147663058327235194893000", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xB01058f4729CF657527ACE0C2049509Ebded9cD5" + }, + { + "tokenOnIMX": { + "id": "1103114524755001640548555873671808205895038091681120606634696969331999845790", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xe9E96d1aad82562b7588F03f49aD34186f996478" + }, + { + "tokenOnIMX": { + "id": "958749024699050137966222344651071737385564981318518993053819450292484749550", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x558397dCa21504c05E6C7302845FEBBAb6a89836" + }, + { + "tokenOnIMX": { + "id": "140045364627528196345084413227318657255889301714016666850545170669121136724", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xD4739008AB13B594a1574401e9B99852361d2494" + }, + { + "tokenOnIMX": { + "id": "288497620338891181002256043717214864459537182795830852149172946884830468774", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xB8EE289C64C1A0DC0311364721aDA8c3180D838C" + }, + { + "tokenOnIMX": { + "id": "1782613318986674861730994617630569436938103649781060793390626353255201116359", + "quantum": 1 + }, + "tokenOnZKEVM": "0x79b4e9647cf3964f3afb6fB1d91D881Cb56CA365" + }, + { + "tokenOnIMX": { + "id": "1100051021863410963740714092430936399472019405492900761810892193340061133175", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xAaF67BbC04D0ebD8ddfaC65c3a45BdBef8F2b55f" + }, + { + "tokenOnIMX": { + "id": "1730268361872681930365892179602415294747249511559951801222868962857887087074", + "quantum": 1 + }, + "tokenOnZKEVM": "0x109bC6507b0A86077D6cdC1f404B965ED1495574" + }, + { + "tokenOnIMX": { + "id": "133566068527828825746133918188608556461795710960217173451759027761417430363", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x2FdEDeFECDe9000720A826803AB0c02cC5511c88" + }, + { + "tokenOnIMX": { + "id": "279228093087404724401986225486636769487846954176324340679736210809311495", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xf7318F48cAA65c76239968156E415a4A30538D4d" + }, + { + "tokenOnIMX": { + "id": "278218763421750168916729775629218233399649390895347468260686151792906842745", + "quantum": 1 + }, + "tokenOnZKEVM": "0x036637bdb7Af827F33C4B124b76dd5741F6334Ce" + }, + { + "tokenOnIMX": { + "id": "1118767138481389624672377790657114412417202583785801293058102967449208440552", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x51B536AD0D0ABF775d4bcA5e5f1Bd40Bab377F73" + }, + { + "tokenOnIMX": { + "id": "246687233301300469710108727028426484184902991299048503161524411000024849494", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x8e3f8DbF143e512b68Ed675527A60E87c14805f1" + }, + { + "tokenOnIMX": { + "id": "620001226371989005351249404877383874184100034181679496390579996208319954842", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xAD17dFFf57d5150bFBB25eBA5964279285E061ab" + }, + { + "tokenOnIMX": { + "id": "774695052920335475148844746909925970695317951232942764061726388365724651811", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x7Ec22dF6fDADEaDF84770E8E1c88A619CCd9Db85" + }, + { + "tokenOnIMX": { + "id": "1079365209654237028653623629764958016172582949813253986541136037171578617505", + "quantum": 10 + }, + "tokenOnZKEVM": "0xB070a17CEAf343782D17F2667700158aeEe4c9Bb" + }, + { + "tokenOnIMX": { + "id": "889491635621296293428570805285996100526088113454814524032053738967908687010", + "quantum": 1 + }, + "tokenOnZKEVM": "0xe8AAc312f348A5530A7EbdA3a976e05Fb33479a5" + }, + { + "tokenOnIMX": { + "id": "1541893324194556794018922586922863773169005377082433218256783405946955321773", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xA05F0FB7825c52996d05c7CE8D520831bd459528" + }, + { + "tokenOnIMX": { + "id": "508896894519199837882532718821198929536057284631686405901881975310756808819", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x5c9b349DD47973DdE6771330dac98F54B5261E44" + }, + { + "tokenOnIMX": { + "id": "1713273459042363589671903409735439653127748941717893520188565250123836559922", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xf7F2708EAC0De61d6eeB9662B00c0a6E36A13e12" + }, + { + "tokenOnIMX": { + "id": "1007429852875183837711381425904397530529430287830771091622498485479621080033", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x4BCF536761C28748C6154E158EE2adADA5452D03" + }, + { + "tokenOnIMX": { + "id": "1026459113228997553038702658409951763724108387124859616632951167746600061279", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xEd7E8a30D54928845C16d72B9Eb6f3e3e866d505" + }, + { + "tokenOnIMX": { + "id": "224326615647497430209000540151115974094010699057468868354504375901667258695", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xF184E2B0FEADC3398A593211A33647D9A2e3D97b" + }, + { + "tokenOnIMX": { + "id": "14406987772269190202869751597715327602721087011555776736463891281797319454", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xe1F177209f82Cf7f346570b480c899FdC3A5BCDA" + }, + { + "tokenOnIMX": { + "id": "1074694638794775585034847784496210938495869105762602294578446735922582865903", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x2113Bc67396Ce7C12B02fb0678d8bDa12cE17929" + }, + { + "tokenOnIMX": { + "id": "1789880607087655497383974216548231163506506920581499066660700239294810361138", + "quantum": 1 + }, + "tokenOnZKEVM": "0x8FDFb77aD068f68d365Bf47A57b4BFf7AFC6e28B" + }, + { + "tokenOnIMX": { + "id": "1142780287754666633490319950078041001437265973993631920364116058229405481176", + "quantum": 1 + }, + "tokenOnZKEVM": "0x643A7775BA10D776c6484473859ce49f6688564e" + }, + { + "tokenOnIMX": { + "id": "1304335111848845550036725670378237818351850476608607454929125615580280114750", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xB92ccC5519f9d39EcBbB9F03f8E5e5AE856CfE14" + }, + { + "tokenOnIMX": { + "id": "584818264821865309529860137527490043841291606793888110511892289381889046142", + "quantum": 1 + }, + "tokenOnZKEVM": "0x25b11E2c7BeF5ED3Ba40b11c7581Da80A6D6fe57" + }, + { + "tokenOnIMX": { + "id": "21498777723544896979545581006810717137381075370112586295636297534407605532", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x7C663Af67772c01E79A08442e22eC5454B22e2C9" + }, + { + "tokenOnIMX": { + "id": "1694009098181558118158615594769574705969634676578372970032421836083086133628", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xa8c45CCa65090581a86Fc101D9Cba535dBaD66E6" + }, + { + "tokenOnIMX": { + "id": "540062279147817096126692697840181823459298758504720034739181724881731629294", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xB13632fC7b2c323Ead333FD9c947d05e0aFBA4C7" + }, + { + "tokenOnIMX": { + "id": "661141420868150794624283883274270269479864861417174829821648462727047715204", + "quantum": 1 + }, + "tokenOnZKEVM": "0x465b3f4279986CbF3D11A37B88Aa2eb61c139cbD" + }, + { + "tokenOnIMX": { + "id": "1529047011282119779666243264336891129455481470106617051357049340145514211869", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0xC2Ae33691C2eA55937e515fB80c7E0E2D7D5c219" + }, + { + "tokenOnIMX": { + "id": "937627426884687223015650826300942653066238230804307701105682811511494029416", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x1eA04F4425F6f1ce7D2a73C2D3D05bf69E7475bF" + }, + { + "tokenOnIMX": { + "id": "701992353264593934042630901537572119762294448768089561198251820694421559230", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x910A607CDcc24726506947EA147F7a7274161B77" + } + ] +} diff --git a/config/operate/sandbox/token_phases.json b/config/operate/sandbox/token_phases.json new file mode 100644 index 0000000..6d5ba01 --- /dev/null +++ b/config/operate/sandbox/token_phases.json @@ -0,0 +1,422 @@ +[ + { + "phase": 0, + "token_address": "0x1d30db727c18f6d8c3318deda7d3cd8a689ce935", + "ticker_symbol": "CRYPT", + "unquantised_sum": 76179 + }, + { + "phase": 0, + "token_address": "0x17eae1f5d6c6dba5a8fc68789ad8bb6531b1c5ce", + "ticker_symbol": "HYPER", + "unquantised_sum": 60 + }, + { + "phase": 0, + "token_address": "0xedc2e5600ac2ae5c79cb68114e4ca6cb3360ee51", + "ticker_symbol": "SOLON", + "unquantised_sum": 52 + }, + { + "phase": 1, + "token_address": "eth", + "ticker_symbol": "ETH", + "unquantised_sum": 23781888054718900000000 + }, + { + "phase": 2, + "token_address": "0x655dfe9d7ec1a74d45841f79ec6b4f6160a4c031", + "ticker_symbol": "CRYPI", + "unquantised_sum": 9770927499999848000000000 + }, + { + "phase": 2, + "token_address": "0x40d3e56ddfcd6b98b41439f9d98eb7a42804249a", + "ticker_symbol": "CRYPT", + "unquantised_sum": 1016534089000000000000000000 + }, + { + "phase": 2, + "token_address": "0x8122c8f02f1e586f166dcb6a6de3b5c0fd3e48ca", + "ticker_symbol": "CRYPU", + "unquantised_sum": 9894953000000000000000000 + }, + { + "phase": 2, + "token_address": "0x6da2a4d37259439c7ddcddb55cd0ef2033fe1e8f", + "ticker_symbol": "CTA", + "unquantised_sum": 736034961316709300000000 + }, + { + "phase": 2, + "token_address": "0xbe7be8d5f99b16b2f29007d9eb08ed49f73d05d6", + "ticker_symbol": "EST", + "unquantised_sum": 203455719350000200000000 + }, + { + "phase": 2, + "token_address": "eth", + "ticker_symbol": "ETH", + "unquantised_sum": 129954660554974100000000 + }, + { + "phase": 2, + "token_address": "0xf9c16d203b6d67c5943de257fff1ab2e5dc52f73", + "ticker_symbol": "EVM", + "unquantised_sum": 49951315268647000000000000 + }, + { + "phase": 2, + "token_address": "0x5c9f1680bb6a4b4fc698e0cf702e0cc34aed91b7", + "ticker_symbol": "GODS", + "unquantised_sum": 8418693400865496300000000 + }, + { + "phase": 2, + "token_address": "0xb239c8e5c119f231151791fface0bf634670f27a", + "ticker_symbol": "HYPEI", + "unquantised_sum": 8773639000000000000000000 + }, + { + "phase": 2, + "token_address": "0xbd8172ab5f2d4b068f8865ed527c3427cb998678", + "ticker_symbol": "HYPER", + "unquantised_sum": 798423728000000000000000000 + }, + { + "phase": 2, + "token_address": "0xf444a3355e4624f7b2c532557420e9c01ced499f", + "ticker_symbol": "ILVI", + "unquantised_sum": 59642795564470000000000 + }, + { + "phase": 2, + "token_address": "0x2711f4f362dc6c3da2fce3e021170b033b7df7fc", + "ticker_symbol": "OMI", + "unquantised_sum": 100000100000000000000000000 + }, + { + "phase": 2, + "token_address": "0x82475443f1075bc571a552cbdab1f49b24e1c47a", + "ticker_symbol": "SILV2", + "unquantised_sum": 97900000000000000000000 + }, + { + "phase": 3, + "token_address": "0x00e49f72e3ff96f50e98d8533f2eb5a9b69b002f", + "ticker_symbol": "ARG", + "unquantised_sum": 710000000000000000000 + }, + { + "phase": 3, + "token_address": "0x655dfe9d7ec1a74d45841f79ec6b4f6160a4c031", + "ticker_symbol": "CRYPI", + "unquantised_sum": 856712499999858000000000 + }, + { + "phase": 3, + "token_address": "0xf82dbf105e144f7219b089fb2790f3faf19b676e", + "ticker_symbol": "CRYPI", + "unquantised_sum": 8588018 + }, + { + "phase": 3, + "token_address": "0x1d30db727c18f6d8c3318deda7d3cd8a689ce935", + "ticker_symbol": "CRYPT", + "unquantised_sum": 9054039537 + }, + { + "phase": 3, + "token_address": "0x40d3e56ddfcd6b98b41439f9d98eb7a42804249a", + "ticker_symbol": "CRYPT", + "unquantised_sum": 145542911000000000000000000 + }, + { + "phase": 3, + "token_address": "0x8122c8f02f1e586f166dcb6a6de3b5c0fd3e48ca", + "ticker_symbol": "CRYPU", + "unquantised_sum": 91197000000000000000000 + }, + { + "phase": 3, + "token_address": "0xed398bfdde93056c4dd61e2503816587aa80c346", + "ticker_symbol": "CRYPU", + "unquantised_sum": 109413035 + }, + { + "phase": 3, + "token_address": "0x6da2a4d37259439c7ddcddb55cd0ef2033fe1e8f", + "ticker_symbol": "CTA", + "unquantised_sum": 266798038683290700000000 + }, + { + "phase": 3, + "token_address": "0xbe7be8d5f99b16b2f29007d9eb08ed49f73d05d6", + "ticker_symbol": "EST", + "unquantised_sum": 9844280649999800000000 + }, + { + "phase": 3, + "token_address": "eth", + "ticker_symbol": "ETH", + "unquantised_sum": 16280312507311300000000 + }, + { + "phase": 3, + "token_address": "0xf9c16d203b6d67c5943de257fff1ab2e5dc52f73", + "ticker_symbol": "EVM", + "unquantised_sum": 1048694731353000000000000 + }, + { + "phase": 3, + "token_address": "0x5c9f1680bb6a4b4fc698e0cf702e0cc34aed91b7", + "ticker_symbol": "GODS", + "unquantised_sum": 478605599134503700000000 + }, + { + "phase": 3, + "token_address": "0xfe9df9ebe5fbd94b00247613b6cf7629891954e2", + "ticker_symbol": "GOG", + "unquantised_sum": 1062333000000000000000 + }, + { + "phase": 3, + "token_address": "0x040b46e6f5fb6d21e5e117b2cc6a8490bd13bdd8", + "ticker_symbol": "HYPEI", + "unquantised_sum": 7271887 + }, + { + "phase": 3, + "token_address": "0xb239c8e5c119f231151791fface0bf634670f27a", + "ticker_symbol": "HYPEI", + "unquantised_sum": 1297911000000000000000000 + }, + { + "phase": 3, + "token_address": "0x17eae1f5d6c6dba5a8fc68789ad8bb6531b1c5ce", + "ticker_symbol": "HYPER", + "unquantised_sum": 19014808467 + }, + { + "phase": 3, + "token_address": "0xbd8172ab5f2d4b068f8865ed527c3427cb998678", + "ticker_symbol": "HYPER", + "unquantised_sum": 268277822000000000000000000 + }, + { + "phase": 3, + "token_address": "0x64f78605852706da360457c64267a0b7da77f0e9", + "ticker_symbol": "HYPEU", + "unquantised_sum": 9994000000000000000000000 + }, + { + "phase": 3, + "token_address": "0xb79a155c97a21fb0630b6094d8cd90c3d32790d6", + "ticker_symbol": "HYPEU", + "unquantised_sum": 108644847 + }, + { + "phase": 3, + "token_address": "0x886dd14dcc6caed09a3e4d01d489673a84dd8f16", + "ticker_symbol": "ILV", + "unquantised_sum": 190000000000000000000 + }, + { + "phase": 3, + "token_address": "0xf444a3355e4624f7b2c532557420e9c01ced499f", + "ticker_symbol": "ILVI", + "unquantised_sum": 2353704134530000000000 + }, + { + "phase": 3, + "token_address": "0xc65f3e4d8edda3ee80cf7f98b0b0c9f208c33c9e", + "ticker_symbol": "ILVU", + "unquantised_sum": 50000000000000000000000 + }, + { + "phase": 3, + "token_address": "0x2fa06c6672ddcc066ab04631192738799231de4a", + "ticker_symbol": "IMX", + "unquantised_sum": 12516121608010300000000 + }, + { + "phase": 3, + "token_address": "0xf674d458575c1b659da24a60add8a4f68cd7fb19", + "ticker_symbol": "MTK", + "unquantised_sum": 92233720368547750070 + }, + { + "phase": 3, + "token_address": "0x174ce99c5a5407b2e7101e5a743f28936f2f0c69", + "ticker_symbol": "MZD", + "unquantised_sum": 9222148664817921026 + }, + { + "phase": 3, + "token_address": "0x2711f4f362dc6c3da2fce3e021170b033b7df7fc", + "ticker_symbol": "OMI", + "unquantised_sum": 7196890000000000000000 + }, + { + "phase": 3, + "token_address": "0x3b1b47bdaeb409a1ed64a13d856bd0ca1f718be5", + "ticker_symbol": "OMI", + "unquantised_sum": 5200000000000000000000 + }, + { + "phase": 3, + "token_address": "0x312674a822a337bc50d4fdf465781079760a6729", + "ticker_symbol": "SDK", + "unquantised_sum": 100000000000000000000000 + }, + { + "phase": 3, + "token_address": "0x82475443f1075bc571a552cbdab1f49b24e1c47a", + "ticker_symbol": "SILV2", + "unquantised_sum": 3229811433362500000000 + }, + { + "phase": 3, + "token_address": "0x387798f984091808e266dcb7f3fd306e18d71904", + "ticker_symbol": "SILVI", + "unquantised_sum": 706175899770000000000000 + }, + { + "phase": 3, + "token_address": "0x6bdefb9b62444c99999682a2076841b47a4cab9c", + "ticker_symbol": "SILVU", + "unquantised_sum": 7721000000000000000000 + }, + { + "phase": 3, + "token_address": "0xb13477b46fbcb878b496ca511018801e45cfc846", + "ticker_symbol": "SOLOI", + "unquantised_sum": 7603463 + }, + { + "phase": 3, + "token_address": "0xbb864c80cb6e263c34c325f51544e8d0b9e9455c", + "ticker_symbol": "SOLOI", + "unquantised_sum": 10966150000000000000000000 + }, + { + "phase": 3, + "token_address": "0x3701c15dd3b155d96d02d4eeec6cadc387af767d", + "ticker_symbol": "SOLON", + "unquantised_sum": 1099723950000000000000000000 + }, + { + "phase": 3, + "token_address": "0xedc2e5600ac2ae5c79cb68114e4ca6cb3360ee51", + "ticker_symbol": "SOLON", + "unquantised_sum": 7338674508 + }, + { + "phase": 3, + "token_address": "0x73d859408b80c395f97232dff990b86f3c51aff6", + "ticker_symbol": "SOLOU", + "unquantised_sum": 10000000000000000000000000 + }, + { + "phase": 3, + "token_address": "0x5b56a1a6e46e799c5ca87b37f9896902f541afc8", + "ticker_symbol": "TRDS", + "unquantised_sum": 10000000000000000000000 + }, + { + "phase": 3, + "token_address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "ticker_symbol": "UNI", + "unquantised_sum": 64489000000000000 + }, + { + "phase": 3, + "token_address": "0xca6c31cc71fb8f00dc2c465299f605039e0e1f4b", + "ticker_symbol": "USDC", + "unquantised_sum": 152933552441 + }, + { + "phase": 3, + "token_address": "0xc7d4cd5bc9da8a5f77718f6851f3df6f79a13293", + "ticker_symbol": "VCOIN", + "unquantised_sum": 1000000000000000000000000 + }, + { + "phase": 3, + "token_address": "0x315061da0f44527eb0c534b62df4e5cefc0d5cdb", + "ticker_symbol": "VCORE", + "unquantised_sum": 1000000001018000000000000 + }, + { + "phase": 4, + "token_address": "0xf82dbf105e144f7219b089fb2790f3faf19b676e", + "ticker_symbol": "CRYPI", + "unquantised_sum": 870012 + }, + { + "phase": 4, + "token_address": "0x1d30db727c18f6d8c3318deda7d3cd8a689ce935", + "ticker_symbol": "CRYPT", + "unquantised_sum": 187148881 + }, + { + "phase": 4, + "token_address": "0xed398bfdde93056c4dd61e2503816587aa80c346", + "ticker_symbol": "CRYPU", + "unquantised_sum": 291965 + }, + { + "phase": 4, + "token_address": "0x040b46e6f5fb6d21e5e117b2cc6a8490bd13bdd8", + "ticker_symbol": "HYPEI", + "unquantised_sum": 1852913 + }, + { + "phase": 4, + "token_address": "0x17eae1f5d6c6dba5a8fc68789ad8bb6531b1c5ce", + "ticker_symbol": "HYPER", + "unquantised_sum": 605119712 + }, + { + "phase": 4, + "token_address": "0xb79a155c97a21fb0630b6094d8cd90c3d32790d6", + "ticker_symbol": "HYPEU", + "unquantised_sum": 997568 + }, + { + "phase": 4, + "token_address": "0xf674d458575c1b659da24a60add8a4f68cd7fb19", + "ticker_symbol": "MTK", + "unquantised_sum": 9610 + }, + { + "phase": 4, + "token_address": "0x174ce99c5a5407b2e7101e5a743f28936f2f0c69", + "ticker_symbol": "MZD", + "unquantised_sum": 44 + }, + { + "phase": 4, + "token_address": "0xb13477b46fbcb878b496ca511018801e45cfc846", + "ticker_symbol": "SOLOI", + "unquantised_sum": 1837627 + }, + { + "phase": 4, + "token_address": "0xedc2e5600ac2ae5c79cb68114e4ca6cb3360ee51", + "ticker_symbol": "SOLON", + "unquantised_sum": 2684483020 + }, + { + "phase": 4, + "token_address": "0x8db3294ac60ec3462d846a090e1f4348e29d8d8d", + "ticker_symbol": "SOLOU", + "unquantised_sum": 109889085 + }, + { + "phase": 4, + "token_address": "0xca6c31cc71fb8f00dc2c465299f605039e0e1f4b", + "ticker_symbol": "USDC", + "unquantised_sum": 13655 + } +] \ No newline at end of file diff --git a/config/tenderly_zkevm_mainnet_config.json b/config/tenderly_zkevm_mainnet_config.json deleted file mode 100644 index 53ba51a..0000000 --- a/config/tenderly_zkevm_mainnet_config.json +++ /dev/null @@ -1,213 +0,0 @@ -{ - "allow_root_override": true, - "vault_verifier": "0x0000000000000000000000000000000000000000", - "vault_root_provider": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "operators": { - "pauser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "unpauser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "disburser": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "defaultAdmin": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "accountRootManager": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa", - "tokenMappingManager": "0xBc6E5103D599FaEC8f4D2911efAEb98814cb5Aaa" - }, - "lookup_tables": [ - "0xB98CD7457BafA2B8F1bE10684A3ca7994A5F518b", - "0x16EA1DDf2f0569A9dfe79eEE8c80927941BEa818", - "0x675956E18A41172D32e03ab8c1C001F085eB605E", - "0xF9D0B099F8950054eaCc5511Bca7CCC38e37F47B", - "0x20b6C1e491ABB27914efAedd7253062B958dE8fE", - "0xB1f8636691bbb5A699B081f49e8a9f3E3342d6d8", - "0xAb618188BaF7191822A6C8f5beCaD5e52251fdB7", - "0x5C8E04129e22c0Ea89BE21f60aA39112284C1828", - "0xF4D63165ef738E9b824AB29D60868DE4106882F6", - "0x1dcC14B69603280C39b134a1e016081e894081aF", - "0xD7Fc22589EC43C9f6C01f204d83A2D2ad00B5675", - "0x40Bf22315AbFABB6a6CBDB2adA311BA5CB6Dc03C", - "0xA5833A592760564Df619013D1D193F7057C1320E", - "0xe75B35cBF59652AeB40E828eF0Fc53810A99333f", - "0x5906c7E81D44454ca93cb81b8A730e3e6f5c04Fb", - "0xf535E11bd0cD0BEe585674eD2b42a869A5D9A232", - "0x91B80204ab4D28A6B888086E4c35c6487e57E349", - "0x47d63A1Bc39E511360E84371A1b2E6Db3A042449", - "0xB4dE0D1C324333ad124bc6245a59339A4E002004", - "0x7586F2B9340a87EAC9c220678083d1541b247E78", - "0x17119e3E988092733e24Ef47aa6B6d4794820264", - "0x065Aa0C90e3CCAC367Ba47D138b2D344Da972C9a", - "0xAf98EB4e32446ff4B6cE80443C83373DB17dc506", - "0xF1428f263a666e6929dF7b056Dd399873e1d3542", - "0x8e84059D906dEF254E15a1eA9AeF5470C5458996", - "0x8EB4336B3bcE8DB209AC17DC2ea2BCF7D38C89F1", - "0x7A8DCB906cd7C54810a2C06634EA030F94594057", - "0x5f6813d68a44eD947Ed4aa64B10e262bB51Bb67a", - "0x5aE5ca6C29B022029EF49712CA959eb605dDF7c6", - "0xf5Aa18553E392f16ac646aefDAe2ABf3cE127B04", - "0x486fcd169e0C98633242F0058F9929E77c5177E9", - "0x2818ff7556FB634061385423f8794A858Fc656ae", - "0xC87A6ee0C5650A833b0F7b7C3D1f14ee66A99468", - "0xA07595Ee9D19d394374A80618807b9a5194EA30F", - "0x52281643ec5217e74e185c947A49782c73a53473", - "0x1284AE8100aAB81D0b0389Bef5B69C0C042c3dd2", - "0xA27070B4EBEd4C9D29E42ba2f0785e3A5CA23bce", - "0x9C8076146365ba1D006e23ce632C47b62a50339d", - "0x01945A3A917Bba28EAAc2928fa941706e27b86B6", - "0x50df2739C42942ea35f2d21bC293a7e9DeC73951", - "0x54CE367BD7dbDC1909209888737827513F0336F2", - "0x3e3CF0c49c6a56a7EbEeAac5f244F85c5A9ef482", - "0x495A6ffc902429f32394bCB8e29bae1E95934b3a", - "0x1c3b9a631B72236C8E91894Be504569BfAAC7b39", - "0xeF823B211f41a3a5EEF86425e5C7168F593B1c64", - "0xB6C53AE2771ee6e2Bc5e65eF6A6e9EC487A76CC5", - "0xc9486c1298dD3c8d59F2d0DeEa2DB4310641AFCE", - "0x2fEcABA0B477C9d4F30fd65670FF059876f844c2", - "0x3498311FC4D1D1AEa7c2BE9996fa9660e88B1EbE", - "0x3e14D5D611E6933d9c40d7bd51559409463af236", - "0xedaEB8eFc7270ed6CecfB2007719C602EfC0C114", - "0x6Cd4568077D1061BDEd7251bA20B3c7ebc2c9dB1", - "0xba89c843d304f127Ee225165AbAE9952844D1244", - "0xB35B64F23d343Bc1e6E06DB6FfdeAA80B62568E2", - "0x6d38dd682ff6e73625EaD7ed9F7420BBeA81153a", - "0x541e8a4Ef0a7c9A3361fBbaC1a1e1BB193e269be", - "0x3eF2C44bEd2003e7Eb5BD5b8EfEFF5F3af57F325", - "0xd78ef7B623d4E69ec0aBD749a930D2028Cd097aB", - "0x79f7957958A4770Afb7C283c7cBDDEe8bdf85a09", - "0x722Fbf18c2B2e4B7B74026B91A4006BA1C69e395", - "0x57911025A80E5726Aa5cf2956F81461891A7F303", - "0xc92C55B1AE8fF7C9E6Af81b75CbD950935881082", - "0x5b862467445Fa62ceB06a424E406ca9200cc052c" - ], - "asset_mappings": [ - { - "assetOnIMX": { - "id": 88914301944088089141574999348394996493546404963067902156417732601144566237, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x0000000000000000000000000000000000000FfF" - }, - { - "assetOnIMX": { - "id": 103129661469142187932697195709967826790010599230686898125218855467795622233, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x201a5cC4C4cC21F9859D24e018e81487E6f48e9C" - }, - { - "assetOnIMX": { - "id": 127313621446881611467827816653547345717404185327457088545463981166261510791, - "quantum": 100000000 - }, - "assetOnZKEVM": "0xc4626318B3bECee9d50Df656C782c40252ED0f67" - }, - { - "assetOnIMX": { - "id": 227716095600406046651136589472266806698090667547081713813841569445055346153, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x1d4115d22C6c6C8933d3708D492cD8038aa4fF61" - }, - { - "assetOnIMX": { - "id": 313505229384936965539156700002111859723492368677210314696313758091297420165, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x9754A6939Eb529E44a42Fd54db27bAAF29F7b164" - }, - { - "assetOnIMX": { - "id": 525164948494449116421805041713913612934056483342602240145121349090983728353, - "quantum": 100000000000 - }, - "assetOnZKEVM": "0xA1cD1f0801DbCdD9DC945D028f3961c1aA63aC7E" - }, - { - "assetOnIMX": { - "id": 634028667897844324040908450156043846954664548107344752361156161409532472444, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x4e55C0c55830252A293EbBAE090B1a4d00A2D0e0" - }, - { - "assetOnIMX": { - "id": 636117700839179604858620718832286872417390350654465827892936533551518041557, - "quantum": 100000000 - }, - "assetOnZKEVM": "0xE0e0981D19eF2E0a57Cc48CA60D9454eD2D53fEB" - }, - { - "assetOnIMX": { - "id": 881983512215682697930791077345670677400334790145955708894204513777355240488, - "quantum": 100000000 - }, - "assetOnZKEVM": "0xA1cD1f0801DbCdD9DC945D028f3961c1aA63aC7E" - }, - { - "assetOnIMX": { - "id": 915177440183500088607294558883023442174593163187193385150232248105465289242, - "quantum": 100000000 - }, - "assetOnZKEVM": "0xf23470043011b747250EC0FeFFc43C5ab09bE306" - }, - { - "assetOnIMX": { - "id": 990917105548321882863790743692016363780882772911795288852111915173114800720, - "quantum": 100000000 - }, - "assetOnZKEVM": "0xcee79B4dA47f149c35C584a0780578CBa4398610" - }, - { - "assetOnIMX": { - "id": 1015922532137787982946651776980869339398815931061497279724058213836132190095, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x5674cC415897ee922A45fbBC4598F8FC4c064878" - }, - { - "assetOnIMX": { - "id": 1103114524755001640548555873671808205895038091681120606634696969331999845790, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x52A6c53869Ce09a731CD772f245b97A4401d3348" - }, - { - "assetOnIMX": { - "id": 1125223003001074656178455529439603029082973884966680368655489058248875828864, - "quantum": 100000000 - }, - "assetOnZKEVM": "0xb00ed913aAFf8280C17BfF33CcE82fE6D79e85e8" - }, - { - "assetOnIMX": { - "id": 1147032829293317481173155891309375254605214077236177772270270553197624560221, - "quantum": 1 - }, - "assetOnZKEVM": "0x6de8aCC0D406837030CE4dd28e7c08C5a96a30d2" - }, - { - "assetOnIMX": { - "id": 1485183671027309009439509871835489442660821279230223034298428454062208985878, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x979084A06dAa9064B532214AeA71024517A99fF9" - }, - { - "assetOnIMX": { - "id": 1670413597475604293967066736840650619123375215270437228479873503062842925101, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x2Ad1F875539A8081E00d4835621771155A58bD86" - }, - { - "assetOnIMX": { - "id": 1707776506599369959662713172170118390106404453517106730194996143842397299232, - "quantum": 1 - }, - "assetOnZKEVM": "0x5407795A261955F69641bC9751F4ffedF0E0F42A" - }, - { - "assetOnIMX": { - "id": 1796496801014838733778624354279754962911198551343321171219226048470100654417, - "quantum": 100000000 - }, - "assetOnZKEVM": "0x6454A4d1a7e050D966F9Aa21C4eefb1a6c92FB4C" - } - ] -} \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 19d381a..a2e1fbc 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,11 +2,11 @@ src = "src" out = "out" libs = ["lib"] +fs_permissions = [{ access = "read-write", path = "./config" }] via_ir = true gas_reports = ["VaultWithdrawalProcessor", "VaultEscapeProofVerifier", "AccountProofVerifier"] gas_snapshot_check = true cbor_metadata = true # Enabled for Tenderly source verification -fs_permissions = [{ access = "read", path = "./config" }] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options [lint] diff --git a/script/DeployEthContracts.s.sol b/script/DeployEthContracts.s.sol new file mode 100644 index 0000000..d4fba6a --- /dev/null +++ b/script/DeployEthContracts.s.sol @@ -0,0 +1,138 @@ +// Copyright Immutable Pty Ltd 2018 - 2025 +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {VaultRootSenderAdapter} from "../src/bridge/messaging/VaultRootSenderAdapter.sol"; +import {StarkExchangeMigration} from "../src/bridge/starkex/StarkExchangeMigration.sol"; + +/** + * @title DeployEthContracts + * @notice Deploys the migration contracts on Ethereum: + * 1. VaultRootSenderAdapter + * 2. StarkExchangeMigration (implementation only, no proxy) + * + * @dev The StarkExchangeMigration is deployed as an implementation contract only. + * The existing StarkEx bridge proxy on-chain will be upgraded to point to this + * implementation separately (e.g., via governance), at which point `initialize` + * will be called with the appropriate parameters. + * + * @dev This script should be run AFTER DeployZkEVMContracts.s.sol, since the + * VaultRootSenderAdapter requires the VaultRootReceiverAdapter address from zkEVM. + * + * @dev After deployment, this script writes an updated config file with the deployed addresses. + * + * Required env vars: + * - DEPLOYMENT_CONFIG_FILE: Path to input config (see config/sample_eth_config.json) + * - DEPLOYMENT_OUTPUT_FILE: Path to write output config with deployed addresses + */ +contract DeployEthContracts is Script { + // VaultRootSenderAdapter + address private senderAdapter; + address private vaultRootSender; + string private rootReceiver; + string private rootReceiverChain; + address private axelarGasService; + address private axelarGateway; + + // StarkExchangeMigration + address private migrationImpl; + + string private configFilePath; + string private outputFilePath; + + function setUp() external { + configFilePath = vm.envString("DEPLOYMENT_CONFIG_FILE"); + outputFilePath = vm.envString("DEPLOYMENT_OUTPUT_FILE"); + + string memory config = vm.readFile(configFilePath); + + // --- VaultRootSenderAdapter --- + senderAdapter = vm.parseJsonAddress(config, "$.vault_root_sender_adapter.address"); + vaultRootSender = vm.parseJsonAddress(config, "$.vault_root_sender_adapter.vault_root_sender"); + rootReceiverChain = vm.parseJsonString(config, "$.vault_root_sender_adapter.root_receiver_chain"); + axelarGasService = vm.parseJsonAddress(config, "$.vault_root_sender_adapter.axelar_gas_service"); + axelarGateway = vm.parseJsonAddress(config, "$.vault_root_sender_adapter.axelar_gateway"); + + // root_receiver is the VaultRootReceiverAdapter address on zkEVM, stored as a string + // since Axelar uses string addresses for cross-chain messaging + address rootReceiverAddr = vm.parseJsonAddress(config, "$.vault_root_sender_adapter.root_receiver"); + rootReceiver = vm.toString(rootReceiverAddr); + + // --- StarkExchangeMigration --- + migrationImpl = vm.parseJsonAddress(config, "$.stark_exchange_migration.implementation_address"); + } + + /// @notice Deploys the Ethereum contracts. + /// @dev Use --slow or --batch-size 1 when running on Tenderly to avoid out-of-order deployments. + function run() external { + _validateConfig(); + + vm.startBroadcast(); + + // 1. Deploy VaultRootSenderAdapter (if not already deployed) + if (senderAdapter == address(0)) { + senderAdapter = address( + new VaultRootSenderAdapter( + vaultRootSender, rootReceiver, rootReceiverChain, axelarGasService, axelarGateway + ) + ); + console.log("Deployed VaultRootSenderAdapter:", senderAdapter); + } else { + console.log("Using existing VaultRootSenderAdapter:", senderAdapter); + } + + // 2. Deploy StarkExchangeMigration implementation (if not already deployed) + // The constructor only calls _disableInitializers(). No proxy is deployed here. + // The existing StarkEx bridge proxy will be upgraded separately via governance. + if (migrationImpl == address(0)) { + migrationImpl = address(new StarkExchangeMigration()); + console.log("Deployed StarkExchangeMigration implementation:", migrationImpl); + } else { + console.log("Using existing StarkExchangeMigration implementation:", migrationImpl); + } + + vm.stopBroadcast(); + + _writeDeploymentOutput(); + _logSummary(); + } + + /** + * @dev Validates that all required config addresses are non-zero for contracts being deployed. + * Only checks constructor params for contracts where address == 0 (i.e., will be deployed). + */ + function _validateConfig() private view { + // VaultRootSenderAdapter: validate all constructor params if deploying + if (senderAdapter == address(0)) { + require(vaultRootSender != address(0), "vault_root_sender_adapter.vault_root_sender is zero address"); + require(bytes(rootReceiver).length > 0, "vault_root_sender_adapter.root_receiver is empty"); + require(bytes(rootReceiverChain).length > 0, "vault_root_sender_adapter.root_receiver_chain is empty"); + require(axelarGasService != address(0), "vault_root_sender_adapter.axelar_gas_service is zero address"); + require(axelarGateway != address(0), "vault_root_sender_adapter.axelar_gateway is zero address"); + } + + // StarkExchangeMigration: no constructor params to validate (only calls _disableInitializers) + } + + /** + * @dev Writes an updated config file with the deployed contract addresses. + * Copies the original config and updates the address fields. + */ + function _writeDeploymentOutput() private { + string memory config = vm.readFile(configFilePath); + vm.writeFile(outputFilePath, config); + + vm.writeJson(vm.toString(senderAdapter), outputFilePath, ".vault_root_sender_adapter.address"); + vm.writeJson(vm.toString(migrationImpl), outputFilePath, ".stark_exchange_migration.implementation_address"); + + console.log("Deployment output written to:", outputFilePath); + } + + function _logSummary() private view { + console.log("--- Ethereum Deployment Summary ---"); + console.log("VaultRootSenderAdapter:", senderAdapter); + console.log("StarkExchangeMigration (impl):", migrationImpl); + } +} diff --git a/script/DeployZkEVMContracts.s.sol b/script/DeployZkEVMContracts.s.sol new file mode 100644 index 0000000..c55d4a0 --- /dev/null +++ b/script/DeployZkEVMContracts.s.sol @@ -0,0 +1,180 @@ +// Copyright Immutable Pty Ltd 2018 - 2025 +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {VaultEscapeProofVerifier} from "../src/verifiers/vaults/VaultEscapeProofVerifier.sol"; +import {VaultRootReceiverAdapter} from "../src/bridge/messaging/VaultRootReceiverAdapter.sol"; +import {VaultWithdrawalProcessor} from "../src/withdrawals/VaultWithdrawalProcessor.sol"; +import {ProcessorAccessControl} from "../src/withdrawals/ProcessorAccessControl.sol"; + +/** + * @title DeployZkEVMContracts + * @notice Deploys the migration contracts on Immutable zkEVM: + * 1. VaultEscapeProofVerifier + * 2. VaultRootReceiverAdapter + * 3. VaultWithdrawalProcessor + * + * @dev Deployment ordering matters: VaultWithdrawalProcessor depends on the addresses of + * VaultEscapeProofVerifier (as its proof verifier) and VaultRootReceiverAdapter (as its + * vault root provider). These are wired automatically within the script. + * + * @dev For each contract, if its `address` field in the config is non-zero, the script skips + * deployment and uses the provided address instead. This allows partial re-runs. + * + * @dev After deployment, this script writes an updated config file with the deployed addresses. + * Token mapping registration is handled separately by RegisterTokenMappings.s.sol. + * + * Required env vars: + * - DEPLOYMENT_CONFIG_FILE: Path to input config (see config/sample_zkevm_config.json) + * - DEPLOYMENT_OUTPUT_FILE: Path to write output config with deployed addresses + */ +contract DeployZkEVMContracts is Script { + // VaultEscapeProofVerifier + address private vaultVerifier; + address[63] private lookupTables; + + // VaultRootReceiverAdapter + address private receiverAdapter; + address private receiverAdapterOwner; + address private receiverAdapterAxelarGateway; + + // VaultWithdrawalProcessor + address private withdrawalProcessor; + bool private allowRootOverride; + ProcessorAccessControl.RoleOperators private operators; + + string private configFilePath; + string private outputFilePath; + + function setUp() external { + configFilePath = vm.envString("DEPLOYMENT_CONFIG_FILE"); + outputFilePath = vm.envString("DEPLOYMENT_OUTPUT_FILE"); + + string memory config = vm.readFile(configFilePath); + + // --- VaultEscapeProofVerifier --- + vaultVerifier = vm.parseJsonAddress(config, "$.vault_escape_proof_verifier.address"); + address[] memory _lookupTables = vm.parseJsonAddressArray(config, "$.vault_escape_proof_verifier.lookup_tables"); + require(_lookupTables.length == 63, "Lookup tables must contain exactly 63 addresses"); + for (uint256 i = 0; i < _lookupTables.length; i++) { + lookupTables[i] = _lookupTables[i]; + } + + // --- VaultRootReceiverAdapter --- + receiverAdapter = vm.parseJsonAddress(config, "$.vault_root_receiver_adapter.address"); + receiverAdapterOwner = vm.parseJsonAddress(config, "$.vault_root_receiver_adapter.owner"); + receiverAdapterAxelarGateway = vm.parseJsonAddress(config, "$.vault_root_receiver_adapter.axelar_gateway"); + + // --- VaultWithdrawalProcessor --- + withdrawalProcessor = vm.parseJsonAddress(config, "$.vault_withdrawal_processor.address"); + allowRootOverride = vm.parseJsonBool(config, "$.vault_withdrawal_processor.allow_root_override"); + + // Parse operators individually to avoid alphabetical key ordering issues with abi.decode + operators.accountRootProvider = + vm.parseJsonAddress(config, "$.vault_withdrawal_processor.operators.accountRootProvider"); + operators.tokenMappingManager = + vm.parseJsonAddress(config, "$.vault_withdrawal_processor.operators.tokenMappingManager"); + operators.disburser = vm.parseJsonAddress(config, "$.vault_withdrawal_processor.operators.disburser"); + operators.pauser = vm.parseJsonAddress(config, "$.vault_withdrawal_processor.operators.pauser"); + operators.unpauser = vm.parseJsonAddress(config, "$.vault_withdrawal_processor.operators.unpauser"); + operators.defaultAdmin = vm.parseJsonAddress(config, "$.vault_withdrawal_processor.operators.defaultAdmin"); + } + + /// @notice Deploys all zkEVM contracts in dependency order. + /// @dev Use --slow or --batch-size 1 when running on Tenderly to avoid out-of-order deployments. + function run() external { + _validateConfig(); + + vm.startBroadcast(); + + // 1. Deploy VaultEscapeProofVerifier (if not already deployed) + if (vaultVerifier == address(0)) { + vaultVerifier = address(new VaultEscapeProofVerifier(lookupTables)); + console.log("Deployed VaultEscapeProofVerifier:", vaultVerifier); + } else { + console.log("Using existing VaultEscapeProofVerifier:", vaultVerifier); + } + + // 2. Deploy VaultRootReceiverAdapter (if not already deployed) + if (receiverAdapter == address(0)) { + receiverAdapter = address(new VaultRootReceiverAdapter(receiverAdapterOwner, receiverAdapterAxelarGateway)); + console.log("Deployed VaultRootReceiverAdapter:", receiverAdapter); + } else { + console.log("Using existing VaultRootReceiverAdapter:", receiverAdapter); + } + + // 3. Deploy VaultWithdrawalProcessor (if not already deployed) + // - _vaultProofVerifier = VaultEscapeProofVerifier from step 1 + // - _vaultRootProvider = VaultRootReceiverAdapter from step 2 + if (withdrawalProcessor == address(0)) { + withdrawalProcessor = + address(new VaultWithdrawalProcessor(vaultVerifier, receiverAdapter, operators, allowRootOverride)); + console.log("Deployed VaultWithdrawalProcessor:", withdrawalProcessor); + } else { + console.log("Using existing VaultWithdrawalProcessor:", withdrawalProcessor); + } + + vm.stopBroadcast(); + + _writeDeploymentOutput(); + _logSummary(); + } + + /** + * @dev Validates that all required config addresses are non-zero for contracts being deployed. + * Only checks constructor params for contracts where address == 0 (i.e., will be deployed). + */ + function _validateConfig() private view { + // VaultEscapeProofVerifier: validate lookup tables if deploying + if (vaultVerifier == address(0)) { + for (uint256 i = 0; i < lookupTables.length; i++) { + require( + lookupTables[i] != address(0), + string.concat("Lookup table at index ", vm.toString(i), " is zero address") + ); + } + } + + // VaultRootReceiverAdapter: validate owner and gateway if deploying + if (receiverAdapter == address(0)) { + require(receiverAdapterOwner != address(0), "vault_root_receiver_adapter.owner is zero address"); + require( + receiverAdapterAxelarGateway != address(0), "vault_root_receiver_adapter.axelar_gateway is zero address" + ); + } + + // VaultWithdrawalProcessor: validate operators if deploying + if (withdrawalProcessor == address(0)) { + require(operators.accountRootProvider != address(0), "operators.accountRootProvider is zero address"); + require(operators.tokenMappingManager != address(0), "operators.tokenMappingManager is zero address"); + require(operators.disburser != address(0), "operators.disburser is zero address"); + require(operators.pauser != address(0), "operators.pauser is zero address"); + require(operators.unpauser != address(0), "operators.unpauser is zero address"); + require(operators.defaultAdmin != address(0), "operators.defaultAdmin is zero address"); + } + } + + /** + * @dev Writes an updated config file with the deployed contract addresses. + * Copies the original config and updates the address fields. + */ + function _writeDeploymentOutput() private { + string memory config = vm.readFile(configFilePath); + vm.writeFile(outputFilePath, config); + + vm.writeJson(vm.toString(vaultVerifier), outputFilePath, ".vault_escape_proof_verifier.address"); + vm.writeJson(vm.toString(receiverAdapter), outputFilePath, ".vault_root_receiver_adapter.address"); + vm.writeJson(vm.toString(withdrawalProcessor), outputFilePath, ".vault_withdrawal_processor.address"); + + console.log("Deployment output written to:", outputFilePath); + } + + function _logSummary() private view { + console.log("--- zkEVM Deployment Summary ---"); + console.log("VaultEscapeProofVerifier:", vaultVerifier); + console.log("VaultRootReceiverAdapter:", receiverAdapter); + console.log("VaultWithdrawalProcessor:", withdrawalProcessor); + } +} diff --git a/script/GenerateAssetMappings.s.sol b/script/GenerateAssetMappings.s.sol new file mode 100644 index 0000000..d70a05a --- /dev/null +++ b/script/GenerateAssetMappings.s.sol @@ -0,0 +1,186 @@ +// Copyright Immutable Pty Ltd 2018 - 2025 +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {BridgedTokenMapping} from "../src/assets/BridgedTokenMapping.sol"; + +/** + * @title GenerateAssetMappings + * @notice Generates asset_mappings config by reading tokens and querying a bridge contract. + * @dev This script reads tokens from a JSON file, queries rootTokenToChildToken() on a bridge + * contract to get zkEVM addresses, and updates the asset_mappings in the config file in place. + * + * Required env vars: + * - TOKENS_FILE: Path to JSON file with token list (e.g., sandbox tokens.json) + * - DEPLOYMENT_CONFIG_FILE: Path to config file (will be updated in place) + * - BRIDGE_CONTRACT: Address of contract with rootTokenToChildToken(address) function + * - ETH_MAPPING: Address of the ETH ERC20 token on zkEVM (varies by network) + * + * Special cases: + * - token_address "eth" → tokenOnZKEVM = ETH_MAPPING (provided via env var) + * - ticker_symbol "IMX" → tokenOnZKEVM = 0x0000000000000000000000000000000000000FfF + */ +interface IRootTokenMapper { + function rootTokenToChildToken(address rootToken) external view returns (address); +} + +contract GenerateAssetMappings is Script { + /// @dev Special address for native IMX on zkEVM + address constant NATIVE_IMX_ADDRESS = 0x0000000000000000000000000000000000000FfF; + + string private tokensFilePath; + string private configFilePath; + address private bridgeContract; + address private ethMapping; + + BridgedTokenMapping.TokenMapping[] private assetMappings; + + function setUp() external { + tokensFilePath = vm.envString("TOKENS_FILE"); + configFilePath = vm.envString("DEPLOYMENT_CONFIG_FILE"); + bridgeContract = vm.envAddress("BRIDGE_CONTRACT"); + ethMapping = vm.envAddress("ETH_MAPPING"); + } + + function run() external { + // Read the tokens file + string memory tokensJson = vm.readFile(tokensFilePath); + + // Count tokens in the JSON array + uint256 tokenCount = _countJsonArrayElements(tokensJson); + + console.log("Processing %d tokens...", tokenCount); + + IRootTokenMapper bridge = IRootTokenMapper(bridgeContract); + + // Process each token by parsing individual fields + uint256 mappedCount = 0; + for (uint256 i = 0; i < tokenCount; i++) { + // Parse individual fields using JSON path + string memory basePath = string(abi.encodePacked("$[", vm.toString(i), "]")); + + uint256 tokenInt = vm.parseJsonUint(tokensJson, string(abi.encodePacked(basePath, ".token_int"))); + uint256 quantum = vm.parseJsonUint(tokensJson, string(abi.encodePacked(basePath, ".quantum"))); + string memory tokenAddress = + vm.parseJsonString(tokensJson, string(abi.encodePacked(basePath, ".token_address"))); + string memory tickerSymbol = + vm.parseJsonString(tokensJson, string(abi.encodePacked(basePath, ".ticker_symbol"))); + + address tokenOnZKEVM; + + // Check for special cases + if (_isEthToken(tokenAddress)) { + tokenOnZKEVM = ethMapping; + console.log(" [%d] %s (ETH) -> %s", i, tickerSymbol, vm.toString(ethMapping)); + } else if (_isImxToken(tickerSymbol)) { + tokenOnZKEVM = NATIVE_IMX_ADDRESS; + console.log(" [%d] %s (IMX) -> 0xFfF", i, tickerSymbol); + } else { + // Query the bridge contract + address rootToken = vm.parseAddress(tokenAddress); + tokenOnZKEVM = bridge.rootTokenToChildToken(rootToken); + + if (tokenOnZKEVM == address(0)) { + console.log(" [%d] %s -> SKIPPED (not mapped)", i, tickerSymbol); + continue; + } + console.log(" [%d] %s -> %s", i, tickerSymbol, vm.toString(tokenOnZKEVM)); + } + + // Add to mappings + assetMappings.push( + BridgedTokenMapping.TokenMapping({ + tokenOnIMX: BridgedTokenMapping.ImmutableXToken({id: tokenInt, quantum: quantum}), + tokenOnZKEVM: tokenOnZKEVM + }) + ); + mappedCount++; + } + + console.log("Generated %d asset mappings", mappedCount); + + // Write output + _writeOutput(); + } + + function _countJsonArrayElements(string memory json) private pure returns (uint256) { + bytes memory jsonBytes = bytes(json); + uint256 count = 0; + uint256 depth = 0; + bool inString = false; + + for (uint256 i = 0; i < jsonBytes.length; i++) { + bytes1 c = jsonBytes[i]; + + if (c == '"' && (i == 0 || jsonBytes[i - 1] != "\\")) { + inString = !inString; + } + + if (!inString) { + if (c == "[") { + depth++; + } else if (c == "]") { + depth--; + } else if (c == "{" && depth == 1) { + count++; + } + } + } + + return count; + } + + function _isEthToken(string memory tokenAddress) private pure returns (bool) { + return keccak256(bytes(tokenAddress)) == keccak256(bytes("eth")); + } + + function _isImxToken(string memory tickerSymbol) private pure returns (bool) { + return keccak256(bytes(tickerSymbol)) == keccak256(bytes("IMX")); + } + + function _writeOutput() private { + // Build the asset_mappings JSON array + string memory mappingsJson = _serializeAssetMappings(); + + // Update the asset_mappings in the config file in place + vm.writeJson(mappingsJson, configFilePath, ".asset_mappings"); + + console.log("Updated asset_mappings in: ", configFilePath); + } + + function _serializeAssetMappings() private returns (string memory) { + // Serialize each mapping + string[] memory items = new string[](assetMappings.length); + for (uint256 i = 0; i < assetMappings.length; i++) { + string memory itemKey = string(abi.encodePacked("item_", vm.toString(i))); + + // Serialize tokenOnIMX + string memory tokenOnIMXKey = string(abi.encodePacked("tokenOnIMX_", vm.toString(i))); + vm.serializeUint(tokenOnIMXKey, "id", assetMappings[i].tokenOnIMX.id); + string memory tokenOnIMXJson = + vm.serializeUint(tokenOnIMXKey, "quantum", assetMappings[i].tokenOnIMX.quantum); + + // Serialize the full mapping object + vm.serializeString(itemKey, "tokenOnIMX", tokenOnIMXJson); + items[i] = vm.serializeAddress(itemKey, "tokenOnZKEVM", assetMappings[i].tokenOnZKEVM); + } + + // Combine into array - we need to manually build the JSON array + if (items.length == 0) { + return "[]"; + } + + bytes memory result = "["; + for (uint256 i = 0; i < items.length; i++) { + if (i > 0) { + result = abi.encodePacked(result, ","); + } + result = abi.encodePacked(result, items[i]); + } + result = abi.encodePacked(result, "]"); + + return string(result); + } +} diff --git a/script/MigrateHoldings.s.sol b/script/MigrateHoldings.s.sol new file mode 100644 index 0000000..52dabf2 --- /dev/null +++ b/script/MigrateHoldings.s.sol @@ -0,0 +1,191 @@ +// Copyright Immutable Pty Ltd 2018 - 2025 +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {IStarkExchangeMigration} from "../src/bridge/starkex/IStarkExchangeMigration.sol"; + +/** + * @title MigrateHoldings + * @notice Calls migrateHoldings() on the StarkExchangeMigration contract for a given phase. + * @dev Reads token_phases config, aggregates amounts per token address for the specified phase, + * and invokes migrateHoldings(). Simulates by default; add --broadcast to send on-chain. + * + * Required env vars: + * - PHASES_FILE: Path to token_phases JSON file + * - PHASE: The phase number to migrate + * - BRIDGE_FEE: The bridge fee (in wei) to use for each token + * - MIGRATION_CONTRACT: Address of the StarkExchangeMigration contract + * + * Usage (simulate): + * PHASES_FILE=config/operate/sandbox/token_phases.json \ + * PHASE=2 \ + * BRIDGE_FEE=100000000000000 \ + * MIGRATION_CONTRACT=0x... \ + * forge script script/MigrateHoldings.s.sol --rpc-url $RPC_URL + * + * Usage (broadcast): + * PHASES_FILE=config/operate/sandbox/token_phases.json \ + * PHASE=2 \ + * BRIDGE_FEE=100000000000000 \ + * MIGRATION_CONTRACT=0x... \ + * forge script script/MigrateHoldings.s.sol --rpc-url $RPC_URL --broadcast + */ +contract MigrateHoldings is Script { + /// @dev Reference to native ETH, matching StarkExchangeMigration.NATIVE_ETH + address constant NATIVE_ETH = address(0xeee); + + address[] private aggTokens; + uint256[] private aggAmounts; + string[] private aggTickers; + + function setUp() external {} + + function run() external { + uint256 phase = vm.envUint("PHASE"); + uint256 bridgeFee = vm.envUint("BRIDGE_FEE"); + string memory phasesFilePath = vm.envString("PHASES_FILE"); + address migrationContract = vm.envAddress("MIGRATION_CONTRACT"); + + string memory json = vm.readFile(phasesFilePath); + uint256 entryCount = _countJsonArrayElements(json); + + console.log("========================================"); + console.log(" migrateHoldings() "); + console.log("========================================"); + console.log(""); + console.log("Phases file: %s", phasesFilePath); + console.log("Phase: %d", phase); + console.log("Bridge fee/tok: %s wei", vm.toString(bridgeFee)); + console.log("Target: %s", vm.toString(migrationContract)); + console.log(""); + + // Filter by phase, log each raw entry, and aggregate by token_address + console.log("--- Raw entries for phase %d ---", phase); + console.log(""); + uint256 rawCount = 0; + for (uint256 i = 0; i < entryCount; i++) { + string memory basePath = string(abi.encodePacked("$[", vm.toString(i), "]")); + + uint256 entryPhase = vm.parseJsonUint(json, string(abi.encodePacked(basePath, ".phase"))); + if (entryPhase != phase) continue; + + string memory tokenAddressStr = + vm.parseJsonString(json, string(abi.encodePacked(basePath, ".token_address"))); + string memory ticker = vm.parseJsonString(json, string(abi.encodePacked(basePath, ".ticker_symbol"))); + uint256 amount = vm.parseJsonUint(json, string(abi.encodePacked(basePath, ".unquantised_sum"))); + + address tokenAddr; + if (_isEth(tokenAddressStr)) { + tokenAddr = NATIVE_ETH; + } else { + tokenAddr = vm.parseAddress(tokenAddressStr); + } + + console.log(" [%d] %s %s", rawCount, ticker, vm.toString(tokenAddr)); + console.log(" amount: %s", vm.toString(amount)); + rawCount++; + + // Aggregate: find existing entry or create new one + bool found = false; + for (uint256 j = 0; j < aggTokens.length; j++) { + if (aggTokens[j] == tokenAddr) { + aggAmounts[j] += amount; + found = true; + break; + } + } + if (!found) { + aggTokens.push(tokenAddr); + aggAmounts.push(amount); + aggTickers.push(ticker); + } + } + + uint256 numTokens = aggTokens.length; + require(numTokens > 0, "No tokens found for the specified phase"); + + uint256 totalMsgValue = bridgeFee * numTokens; + + // Build TokenMigrationDetails array and show aggregated results + IStarkExchangeMigration.TokenMigrationDetails[] memory details = + new IStarkExchangeMigration.TokenMigrationDetails[](numTokens); + + console.log(""); + console.log("--- Aggregated tokens (%d unique from %d entries) ---", numTokens, rawCount); + console.log(""); + for (uint256 i = 0; i < numTokens; i++) { + details[i] = IStarkExchangeMigration.TokenMigrationDetails({ + token: aggTokens[i], amount: aggAmounts[i], bridgeFee: bridgeFee + }); + + console.log(" [%d] %s", i, aggTickers[i]); + console.log(" token: %s", vm.toString(aggTokens[i])); + console.log(" amount: %s", vm.toString(aggAmounts[i])); + console.log(" bridgeFee: %s", vm.toString(bridgeFee)); + } + + // Encode the full calldata + bytes memory callData = abi.encodeCall(IStarkExchangeMigration.migrateHoldings, (details)); + + // Transaction summary + console.log(""); + console.log("=== Transaction to be sent ==="); + console.log(""); + console.log(" to: %s", vm.toString(migrationContract)); + console.log(" function: migrateHoldings(TokenMigrationDetails[])"); + console.log(" selector: 0x701f9fae"); + console.log(" msg.value: %s wei", vm.toString(totalMsgValue)); + console.log(" = %d tokens x %s fee per token", numTokens, vm.toString(bridgeFee)); + console.log(""); + console.log(" calldata (%d bytes):", callData.length); + console.log(" %s", vm.toString(callData)); + console.log(""); + console.log(" calldata hash (keccak256):"); + console.log(" %s", vm.toString(keccak256(callData))); + console.log(""); + console.log("========================================"); + + // Execute the call (simulated unless --broadcast is passed) + vm.startBroadcast(); + IStarkExchangeMigration(migrationContract).migrateHoldings{value: totalMsgValue}(details); + vm.stopBroadcast(); + + console.log(""); + console.log("migrateHoldings() executed successfully"); + console.log("========================================"); + } + + function _isEth(string memory tokenAddress) private pure returns (bool) { + return keccak256(bytes(tokenAddress)) == keccak256(bytes("eth")); + } + + /// @dev Count top-level objects in a JSON array. + function _countJsonArrayElements(string memory json) private pure returns (uint256) { + bytes memory jsonBytes = bytes(json); + uint256 count = 0; + uint256 depth = 0; + bool inString = false; + + for (uint256 i = 0; i < jsonBytes.length; i++) { + bytes1 c = jsonBytes[i]; + + if (c == '"' && (i == 0 || jsonBytes[i - 1] != "\\")) { + inString = !inString; + } + + if (!inString) { + if (c == "[") { + depth++; + } else if (c == "]") { + depth--; + } else if (c == "{" && depth == 1) { + count++; + } + } + } + + return count; + } +} diff --git a/script/README.md b/script/README.md new file mode 100644 index 0000000..06c63ae --- /dev/null +++ b/script/README.md @@ -0,0 +1,378 @@ +# Forge Scripts + +Solidity scripts for deploying and configuring the migration contracts using Foundry. + +## Scripts Overview + +| Script | Chain | Purpose | Executed By | +|--------|-------|---------|-------------| +| `DeployZkEVMContracts.s.sol` | zkEVM | Deploy VaultEscapeProofVerifier, VaultRootReceiverAdapter, VaultWithdrawalProcessor | Deployer | +| `DeployEthContracts.s.sol` | Ethereum | Deploy VaultRootSenderAdapter and StarkExchangeMigration implementation | Deployer | +| `GenerateAssetMappings.s.sol` | - | Generate asset mappings by querying bridge contract | Utility (offline) | +| `VerifyAssetMappings.s.sol` | - | Verify asset mappings against bridge contract | Utility (read-only) | +| `RegisterTokenMappings.s.sol` | zkEVM | Register token mappings on the processor | TOKEN_MAPPING_MANAGER | +| `MigrateHoldings.s.sol` | Ethereum | Migrate token holdings for a given phase via `migrateHoldings()` | Migration Manager | + +### Legacy + +| Script | Purpose | +|--------|---------| +| `DeployL2Contracts.s.sol` | (Superseded by `DeployZkEVMContracts.s.sol`) Deploys VaultWithdrawalProcessor and VaultEscapeProofVerifier only | + +## Cross-Chain Deployment Workflow + +Deployment spans two chains with cross-chain dependencies. **zkEVM must be deployed first** since Ethereum contracts reference zkEVM addresses. + +```mermaid +flowchart TD + subgraph zkEVM ["Step 1: zkEVM"] + A[zkevm_config.json] --> B[DeployZkEVMContracts] + B --> C[zkevm_deployed.json] + C --> D[GenerateAssetMappings] + D --> E[config with asset_mappings] + E --> F[RegisterTokenMappings] + F --> G[zkEVM Ready] + end + + subgraph Ethereum ["Step 2: Ethereum"] + H[eth_config.json] --> I[DeployEthContracts] + I --> J[eth_deployed.json] + J --> K["Upgrade proxy via governance"] + end + + C -.->|"populate root_receiver + zkevm_withdrawal_processor"| H +``` + +### Step 1: Deploy zkEVM Contracts + +Deploy `VaultEscapeProofVerifier`, `VaultRootReceiverAdapter`, and `VaultWithdrawalProcessor`. + +The script automatically wires intra-chain dependencies: +- `VaultWithdrawalProcessor._vaultProofVerifier` = deployed `VaultEscapeProofVerifier` address +- `VaultWithdrawalProcessor._vaultRootProvider` = deployed `VaultRootReceiverAdapter` address + +```bash +DEPLOYMENT_CONFIG_FILE=config/zkevm_config.json \ +DEPLOYMENT_OUTPUT_FILE=config/zkevm_deployed.json \ +forge script script/DeployZkEVMContracts.s.sol \ + --rpc-url $ZKEVM_RPC_URL \ + --broadcast \ + --slow +``` + +**Output:** Creates `config/zkevm_deployed.json` with deployed addresses populated in: +- `vault_escape_proof_verifier.address` +- `vault_root_receiver_adapter.address` +- `vault_withdrawal_processor.address` + +### Step 2: Populate Ethereum Config with zkEVM Addresses + +Before deploying Ethereum contracts, update the Ethereum config with addresses from the zkEVM deployment: + +- `vault_root_sender_adapter.root_receiver` = `vault_root_receiver_adapter.address` from zkEVM output +- (For governance upgrade) `VaultWithdrawalProcessor` address from zkEVM output will be needed when calling `StarkExchangeMigration.initialize` + +### Step 3: Deploy Ethereum Contracts + +Deploy `VaultRootSenderAdapter` and the `StarkExchangeMigration` implementation. + +```bash +DEPLOYMENT_CONFIG_FILE=config/eth_config.json \ +DEPLOYMENT_OUTPUT_FILE=config/eth_deployed.json \ +forge script script/DeployEthContracts.s.sol \ + --rpc-url $ETH_RPC_URL \ + --broadcast \ + --slow +``` + +**Output:** Creates `config/eth_deployed.json` with deployed addresses populated in: +- `vault_root_sender_adapter.address` +- `stark_exchange_migration.implementation_address` + +**Note:** The `StarkExchangeMigration` is deployed as an implementation only. The existing StarkEx bridge proxy on-chain must be upgraded to point to this implementation separately (e.g., via governance), at which point `initialize` is called with the migration parameters. + +### Step 4: Generate Asset Mappings (zkEVM) + +Query the bridge contract to populate `asset_mappings` in the zkEVM config. + +```bash +TOKENS_FILE=config/tokens.json \ +DEPLOYMENT_CONFIG_FILE=config/zkevm_deployed.json \ +BRIDGE_CONTRACT=0x... \ +ETH_MAPPING=0x... \ +forge script script/GenerateAssetMappings.s.sol \ + --rpc-url $ZKEVM_RPC_URL +``` + +**Output:** Updates `asset_mappings` in the config file in place. + +### Step 5: Register Token Mappings (zkEVM) + +Register the token mappings on the deployed processor (requires `TOKEN_MAPPING_MANAGER` role). + +```bash +DEPLOYMENT_CONFIG_FILE=config/zkevm_deployed.json \ +forge script script/RegisterTokenMappings.s.sol \ + --rpc-url $ZKEVM_RPC_URL \ + --broadcast +``` + +--- + +## Script Details + +### DeployZkEVMContracts.s.sol + +Deploys the zkEVM contracts for the migration system. + +**Environment Variables:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `DEPLOYMENT_CONFIG_FILE` | Yes | Path to input config JSON (see `config/sample_zkevm_config.json`) | +| `DEPLOYMENT_OUTPUT_FILE` | Yes | Path to write output config with deployed addresses | + +**Config File Structure** (see `config/sample_zkevm_config.json`): + +```json +{ + "vault_escape_proof_verifier": { + "address": "0x0000...", + "lookup_tables": ["0x...", "...63 addresses..."] + }, + "vault_root_receiver_adapter": { + "address": "0x0000...", + "owner": "0x...", + "axelar_gateway": "0x..." + }, + "vault_withdrawal_processor": { + "address": "0x0000...", + "allow_root_override": true, + "operators": { + "accountRootProvider": "0x...", + "tokenMappingManager": "0x...", + "disburser": "0x...", + "pauser": "0x...", + "unpauser": "0x...", + "defaultAdmin": "0x..." + } + } +} +``` + +**Notes:** +- Set any contract's `address` to the zero address (`0x0000...`) to deploy a new instance +- Set a non-zero `address` to skip deployment and use the existing contract +- Use `--slow` or `--batch-size 1` for Tenderly to ensure correct deployment order + +--- + +### DeployEthContracts.s.sol + +Deploys the Ethereum contracts for the migration system. + +**Environment Variables:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `DEPLOYMENT_CONFIG_FILE` | Yes | Path to input config JSON (see `config/sample_eth_config.json`) | +| `DEPLOYMENT_OUTPUT_FILE` | Yes | Path to write output config with deployed addresses | + +**Config File Structure** (see `config/sample_eth_config.json`): + +```json +{ + "vault_root_sender_adapter": { + "address": "0x0000...", + "vault_root_sender": "0x...", + "root_receiver": "0x...", + "root_receiver_chain": "immutable", + "axelar_gas_service": "0x...", + "axelar_gateway": "0x..." + }, + "stark_exchange_migration": { + "implementation_address": "0x0000..." + } +} +``` + +**Config fields:** +- `vault_root_sender`: The existing StarkEx bridge proxy address on Ethereum +- `root_receiver`: The `VaultRootReceiverAdapter` address on zkEVM (from zkEVM deployment output) +- `root_receiver_chain`: The Axelar chain identifier for zkEVM (e.g., `"immutable"`) +- `axelar_gas_service`: The Axelar gas service contract on Ethereum +- `axelar_gateway`: The Axelar gateway contract on Ethereum + +**Notes:** +- Run this script **after** `DeployZkEVMContracts.s.sol` +- The `StarkExchangeMigration` is deployed as implementation only (no proxy deployment) +- Use `--slow` or `--batch-size 1` for Tenderly to ensure correct deployment order + +--- + +### GenerateAssetMappings.s.sol + +Generates the `asset_mappings` array by querying a bridge contract for zkEVM token addresses. + +**Environment Variables:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `TOKENS_FILE` | Yes | Path to JSON file with token list | +| `DEPLOYMENT_CONFIG_FILE` | Yes | Path to config file (updated in place) | +| `BRIDGE_CONTRACT` | Yes | Address of contract with `rootTokenToChildToken(address)` | +| `ETH_MAPPING` | Yes | zkEVM address for ETH ERC20 (network-specific) | + +**Tokens File Format:** + +```json +[ + { + "token_int": 123..., + "quantum": 100000000, + "token_address": "0x...", + "ticker_symbol": "TOKEN" + } +] +``` + +**Special Cases:** +- `token_address: "eth"` → Uses `ETH_MAPPING` env var +- `ticker_symbol: "IMX"` → Uses `0x0000000000000000000000000000000000000FfF` + +--- + +### RegisterTokenMappings.s.sol + +Registers token mappings on an existing `VaultWithdrawalProcessor`. + +**Environment Variables:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `DEPLOYMENT_CONFIG_FILE` | Yes | Path to config with `withdrawal_processor` and `asset_mappings` | + +**Requirements:** +- The signing account must have the `TOKEN_MAPPING_MANAGER` role on the processor +- Config must contain a valid `withdrawal_processor` address +- Config must contain at least one entry in `asset_mappings` + +**Config File Requirements:** + +```json +{ + "withdrawal_processor": "0x...", + "asset_mappings": [ + { + "tokenOnIMX": { + "id": "123...", + "quantum": 100000000 + }, + "tokenOnZKEVM": "0x..." + } + ] +} +``` + +--- + +### VerifyAssetMappings.s.sol + +Verifies that the `asset_mappings` in a token mappings config file are consistent with the bridge contract's `rootTokenToChildToken()` results. + +For each token in the tokens file, the script: +1. Finds the matching entry in `asset_mappings` (by `token_int` == `tokenOnIMX.id`) +2. Queries `rootTokenToChildToken(token_address)` on the bridge contract +3. Compares the bridge result with `tokenOnZKEVM` in the config + +**Environment Variables:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `TOKENS_FILE` | Yes | Path to imx_tokens JSON file | +| `DEPLOYMENT_CONFIG_FILE` | Yes | Path to token_mappings JSON file (with `asset_mappings` array) | +| `BRIDGE_CONTRACT` | Yes | Address of contract with `rootTokenToChildToken(address)` | +| `ETH_MAPPING` | Yes | zkEVM address for ETH ERC20 (for the special `"eth"` token) | + +**Usage:** + +```bash +TOKENS_FILE=config/operate/sandbox/imx_tokens.json \ +DEPLOYMENT_CONFIG_FILE=config/operate/sandbox/token_mappings.json \ +BRIDGE_CONTRACT=0x... \ +ETH_MAPPING=0x... \ +forge script script/VerifyAssetMappings.s.sol \ + --rpc-url $RPC_URL +``` + +**Output:** Prints `PASS`, `FAIL`, or `MISSING` for each token and a summary. This is a read-only script (no broadcast needed). + +**Special Cases:** +- `token_address: "eth"` → Expected zkEVM address is `ETH_MAPPING` +- `ticker_symbol: "IMX"` → Expected zkEVM address is `0x0000000000000000000000000000000000000FfF` + +--- + +### MigrateHoldings.s.sol + +Calls `migrateHoldings()` on the `StarkExchangeMigration` contract for a given phase. Reads a token phases config, filters by phase number, aggregates amounts for duplicate token addresses, and invokes the migration. + +The script simulates by default. Add `--broadcast` to send the transaction on-chain. + +**Environment Variables:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `PHASES_FILE` | Yes | Path to token phases JSON file | +| `PHASE` | Yes | The phase number to migrate | +| `BRIDGE_FEE` | Yes | Bridge fee in wei to use for each token | +| `MIGRATION_CONTRACT` | Yes | Address of the `StarkExchangeMigration` contract | + +**Phases File Format:** + +```json +[ + { + "phase": 2, + "token_address": "0x...", + "ticker_symbol": "TOKEN", + "unquantised_sum": 1000000000000000000 + } +] +``` + +**Special Cases:** +- `token_address: "eth"` → Mapped to `address(0xeee)` (native ETH on the migration contract) +- Duplicate `token_address` entries within the same phase are aggregated (amounts summed) + +**Usage (simulate):** + +```bash +PHASES_FILE=config/operate/sandbox/token_phases.json \ +PHASE=2 \ +BRIDGE_FEE=100000000000000 \ +MIGRATION_CONTRACT=0x... \ +forge script script/MigrateHoldings.s.sol \ + --rpc-url $ETH_RPC_URL +``` + +**Usage (broadcast):** + +```bash +PHASES_FILE=config/operate/sandbox/token_phases.json \ +PHASE=2 \ +BRIDGE_FEE=100000000000000 \ +MIGRATION_CONTRACT=0x... \ +forge script script/MigrateHoldings.s.sol \ + --rpc-url $ETH_RPC_URL \ + --broadcast +``` + +**Output:** Before executing, the script logs: +1. Every raw entry from the phases file for the selected phase +2. The aggregated `TokenMigrationDetails[]` (unique tokens with summed amounts) +3. The full transaction details: target address, `msg.value`, calldata (hex), and calldata keccak256 hash + +**Requirements:** +- The signing account must be the `migrationManager` on the `StarkExchangeMigration` contract +- The signer must have sufficient ETH to cover `BRIDGE_FEE * num_tokens` diff --git a/script/RegisterTokenMappings.s.sol b/script/RegisterTokenMappings.s.sol new file mode 100644 index 0000000..53cba02 --- /dev/null +++ b/script/RegisterTokenMappings.s.sol @@ -0,0 +1,49 @@ +// Copyright Immutable Pty Ltd 2018 - 2025 +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +import "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {VaultWithdrawalProcessor} from "../src/withdrawals/VaultWithdrawalProcessor.sol"; +import {BridgedTokenMapping} from "../src/assets/BridgedTokenMapping.sol"; + +/** + * @title RegisterTokenMappings + * @notice Registers token mappings on an existing VaultWithdrawalProcessor. + * @dev This script is separate from deployment since token registration is typically + * executed by a different account (TOKEN_MAPPING_MANAGER role). + * + * Required env vars: + * - DEPLOYMENT_CONFIG_FILE: Path to input config with withdrawal_processor and asset_mappings + */ +contract RegisterTokenMappings is Script { + VaultWithdrawalProcessor private withdrawalProcessor; + BridgedTokenMapping.TokenMapping[] private assetMappings; + + function setUp() external { + string memory config = vm.readFile(vm.envString("DEPLOYMENT_CONFIG_FILE")); + + address processorAddress = vm.parseJsonAddress(config, "$.withdrawal_processor"); + require(processorAddress != address(0), "Withdrawal processor address must be provided"); + withdrawalProcessor = VaultWithdrawalProcessor(payable(processorAddress)); + + BridgedTokenMapping.TokenMapping[] memory assetMappingsMem = + abi.decode(vm.parseJson(config, "$.asset_mappings"), (BridgedTokenMapping.TokenMapping[])); + for (uint256 i = 0; i < assetMappingsMem.length; i++) { + assetMappings.push(assetMappingsMem[i]); + } + require(assetMappings.length > 0, "At least one asset mapping must be provided"); + } + + function run() external { + console.log( + "Registering %d token mappings on processor: %s", assetMappings.length, address(withdrawalProcessor) + ); + + vm.startBroadcast(); + withdrawalProcessor.registerTokenMappings(assetMappings); + vm.stopBroadcast(); + + console.log("Successfully registered %d token mappings", assetMappings.length); + } +} diff --git a/script/VerifyAssetMappings.s.sol b/script/VerifyAssetMappings.s.sol new file mode 100644 index 0000000..e6695d5 --- /dev/null +++ b/script/VerifyAssetMappings.s.sol @@ -0,0 +1,259 @@ +// Copyright Immutable Pty Ltd 2018 - 2025 +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +import "forge-std/Script.sol"; +import "forge-std/console.sol"; + +/** + * @title VerifyAssetMappings + * @notice Verifies that asset_mappings in the token_mappings config match the bridge contract's + * rootTokenToChildToken() results for every token in the imx_tokens file. + * @dev For each token in the tokens file, this script: + * 1. Finds the matching entry in asset_mappings (by token_int == tokenOnIMX.id) + * 2. Queries rootTokenToChildToken(token_address) on the bridge contract + * 3. Compares the bridge result with the tokenOnZKEVM in the config + * + * Required env vars: + * - TOKENS_FILE: Path to imx_tokens JSON file + * - DEPLOYMENT_CONFIG_FILE: Path to token_mappings JSON file (with asset_mappings array) + * - BRIDGE_CONTRACT: Address of contract with rootTokenToChildToken(address) function + * - ETH_MAPPING: Address of the ETH ERC20 token on zkEVM (for the special "eth" token) + * + * Usage: + * TOKENS_FILE=config/operate/sandbox/imx_tokens.json \ + * DEPLOYMENT_CONFIG_FILE=config/operate/sandbox/token_mappings.json \ + * BRIDGE_CONTRACT=0x... \ + * ETH_MAPPING=0x... \ + * forge script script/VerifyAssetMappings.s.sol --rpc-url $RPC_URL + */ +interface ITokenMapper { + function rootTokenToChildToken(address rootToken) external view returns (address); +} + +contract VerifyAssetMappings is Script { + /// @dev Special address for native IMX on zkEVM + address constant NATIVE_IMX_ADDRESS = 0x0000000000000000000000000000000000000FfF; + + string private tokensFilePath; + string private configFilePath; + address private bridgeContract; + address private ethMapping; + + function setUp() external { + tokensFilePath = vm.envString("TOKENS_FILE"); + configFilePath = vm.envString("DEPLOYMENT_CONFIG_FILE"); + bridgeContract = vm.envAddress("BRIDGE_CONTRACT"); + ethMapping = vm.envAddress("ETH_MAPPING"); + } + + function run() external view { + string memory tokensJson = vm.readFile(tokensFilePath); + string memory configJson = vm.readFile(configFilePath); + + uint256 tokenCount = _countJsonArrayElements(tokensJson); + uint256 mappingCount = _countJsonArrayElements2(configJson); + + console.log("=== Asset Mapping Verification ==="); + console.log("Tokens file: %s (%d tokens)", tokensFilePath, tokenCount); + console.log("Config file: %s (%d mappings)", configFilePath, mappingCount); + console.log("Bridge: %s", vm.toString(bridgeContract)); + console.log("ETH mapping: %s", vm.toString(ethMapping)); + console.log(""); + + ITokenMapper bridge = ITokenMapper(bridgeContract); + + uint256 passCount = 0; + uint256 failCount = 0; + uint256 missingCount = 0; + + for (uint256 i = 0; i < tokenCount; i++) { + string memory basePath = string(abi.encodePacked("$[", vm.toString(i), "]")); + + uint256 tokenInt = vm.parseJsonUint(tokensJson, string(abi.encodePacked(basePath, ".token_int"))); + string memory tokenAddress = + vm.parseJsonString(tokensJson, string(abi.encodePacked(basePath, ".token_address"))); + string memory tickerSymbol = + vm.parseJsonString(tokensJson, string(abi.encodePacked(basePath, ".ticker_symbol"))); + uint256 quantum = vm.parseJsonUint(tokensJson, string(abi.encodePacked(basePath, ".quantum"))); + + // Find matching entry in asset_mappings by tokenOnIMX.id + (bool found, address configZkevmAddr) = _findMappingById(configJson, mappingCount, tokenInt); + + if (!found) { + console.log( + " [%d] MISSING %s (token_int: %s) - not found in asset_mappings", + i, + tickerSymbol, + vm.toString(tokenInt) + ); + missingCount++; + continue; + } + + // Get expected zkEVM address from bridge + address bridgeZkevmAddr; + + if (_isEthToken(tokenAddress)) { + bridgeZkevmAddr = ethMapping; + } else if (_isImxToken(tickerSymbol)) { + bridgeZkevmAddr = NATIVE_IMX_ADDRESS; + } else { + address rootToken = vm.parseAddress(tokenAddress); + bridgeZkevmAddr = bridge.rootTokenToChildToken(rootToken); + } + + // Compare + if (bridgeZkevmAddr == configZkevmAddr) { + console.log(" [%d] PASS %s root=%s", i, tickerSymbol, _formatAddress(tokenAddress)); + console.log(" zkEVM=%s quantum=%d", vm.toString(configZkevmAddr), quantum); + passCount++; + } else { + console.log(" [%d] FAIL %s root=%s", i, tickerSymbol, _formatAddress(tokenAddress)); + console.log(" config tokenOnZKEVM = %s", vm.toString(configZkevmAddr)); + console.log(" bridge rootToChild = %s", vm.toString(bridgeZkevmAddr)); + failCount++; + } + } + + // Summary + console.log(""); + console.log("=== Summary ==="); + console.log(" Total tokens: %d", tokenCount); + console.log(" PASS: %d", passCount); + console.log(" FAIL: %d", failCount); + console.log(" MISSING: %d", missingCount); + + if (failCount > 0 || missingCount > 0) { + console.log(""); + console.log("VERIFICATION FAILED"); + } else { + console.log(""); + console.log("ALL CHECKS PASSED"); + } + } + + /// @dev Find the tokenOnZKEVM address in asset_mappings where tokenOnIMX.id matches the given id. + function _findMappingById(string memory configJson, uint256 mappingCount, uint256 targetId) + private + pure + returns (bool found, address tokenOnZKEVM) + { + for (uint256 j = 0; j < mappingCount; j++) { + string memory mappingBase = string(abi.encodePacked("$.asset_mappings[", vm.toString(j), "]")); + + uint256 mappingId = vm.parseJsonUint(configJson, string(abi.encodePacked(mappingBase, ".tokenOnIMX.id"))); + + if (mappingId == targetId) { + tokenOnZKEVM = vm.parseJsonAddress(configJson, string(abi.encodePacked(mappingBase, ".tokenOnZKEVM"))); + return (true, tokenOnZKEVM); + } + } + + return (false, address(0)); + } + + /// @dev Count top-level objects in a JSON array (for the tokens file which is a plain array). + function _countJsonArrayElements(string memory json) private pure returns (uint256) { + bytes memory jsonBytes = bytes(json); + uint256 count = 0; + uint256 depth = 0; + bool inString = false; + + for (uint256 i = 0; i < jsonBytes.length; i++) { + bytes1 c = jsonBytes[i]; + + if (c == '"' && (i == 0 || jsonBytes[i - 1] != "\\")) { + inString = !inString; + } + + if (!inString) { + if (c == "[") { + depth++; + } else if (c == "]") { + depth--; + } else if (c == "{" && depth == 1) { + count++; + } + } + } + + return count; + } + + /// @dev Count elements in the asset_mappings array inside a JSON object. + /// Finds the asset_mappings key and counts objects at the appropriate depth. + function _countJsonArrayElements2(string memory json) private pure returns (uint256) { + bytes memory jsonBytes = bytes(json); + uint256 count = 0; + + // Find the "asset_mappings" key and then count objects in its array + bytes memory key = bytes('"asset_mappings"'); + uint256 keyStart = _findSubstring(jsonBytes, key); + if (keyStart == type(uint256).max) return 0; + + // Find the opening '[' after the key + uint256 arrStart = keyStart + key.length; + while (arrStart < jsonBytes.length && jsonBytes[arrStart] != "[") { + arrStart++; + } + if (arrStart >= jsonBytes.length) return 0; + + // Count objects at depth 1 within this array. Track both '[' and '{' in + // depth so nested objects inside each mapping (e.g. tokenOnIMX) are not + // double-counted. + uint256 depth = 0; + bool inString = false; + for (uint256 i = arrStart; i < jsonBytes.length; i++) { + bytes1 c = jsonBytes[i]; + + if (c == '"' && (i == 0 || jsonBytes[i - 1] != "\\")) { + inString = !inString; + } + + if (!inString) { + if (c == "[") { + depth++; + } else if (c == "]") { + if (depth == 1) break; + depth--; + } else if (c == "{") { + if (depth == 1) count++; + depth++; + } else if (c == "}") { + depth--; + } + } + } + + return count; + } + + function _findSubstring(bytes memory haystack, bytes memory needle) private pure returns (uint256) { + if (needle.length > haystack.length) return type(uint256).max; + for (uint256 i = 0; i <= haystack.length - needle.length; i++) { + bool found = true; + for (uint256 j = 0; j < needle.length; j++) { + if (haystack[i + j] != needle[j]) { + found = false; + break; + } + } + if (found) return i; + } + return type(uint256).max; + } + + function _isEthToken(string memory tokenAddress) private pure returns (bool) { + return keccak256(bytes(tokenAddress)) == keccak256(bytes("eth")); + } + + function _isImxToken(string memory tickerSymbol) private pure returns (bool) { + return keccak256(bytes(tickerSymbol)) == keccak256(bytes("IMX")); + } + + function _formatAddress(string memory addr) private pure returns (string memory) { + if (_isEthToken(addr)) return "eth (native)"; + return addr; + } +} diff --git a/script/DeployL2Contracts.s.sol b/script/legacy/DeployL2Contracts.s.sol similarity index 54% rename from script/DeployL2Contracts.s.sol rename to script/legacy/DeployL2Contracts.s.sol index 637f4ed..2ff362a 100644 --- a/script/DeployL2Contracts.s.sol +++ b/script/legacy/DeployL2Contracts.s.sol @@ -2,14 +2,23 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.28; -import "../src/verifiers/accounts/AccountProofVerifier.sol"; -import "../src/verifiers/vaults/VaultEscapeProofVerifier.sol"; +import "../../src/verifiers/vaults/VaultEscapeProofVerifier.sol"; import "forge-std/Script.sol"; import "forge-std/console.sol"; -import {VaultWithdrawalProcessor} from "../src/withdrawals/VaultWithdrawalProcessor.sol"; -import {BridgedTokenMapping} from "../src/assets/BridgedTokenMapping.sol"; +import {VaultWithdrawalProcessor} from "../../src/withdrawals/VaultWithdrawalProcessor.sol"; import {ProcessorAccessControl} from "@src/withdrawals/ProcessorAccessControl.sol"; +/** + * @title DeployL2Contracts + * @notice Deploys the VaultWithdrawalProcessor and optionally the VaultEscapeProofVerifier. + * @dev Token mapping registration is handled separately by RegisterTokenMappings.s.sol + * since it will typically be executed by a different account (TOKEN_MAPPING_MANAGER). + * + * @dev After deployment, this script writes an updated config file with the deployed addresses. + * Required env vars: + * - DEPLOYMENT_CONFIG_FILE: Path to input config + * - DEPLOYMENT_OUTPUT_FILE: Path to write output config with deployed addresses + */ contract DeployL2Contracts is Script { bool private allowRootOverride; address private vaultVerifier; @@ -17,10 +26,15 @@ contract DeployL2Contracts is Script { address[63] private lookupTables; VaultWithdrawalProcessor private withdrawalProcessor; VaultWithdrawalProcessor.RoleOperators private operators; - BridgedTokenMapping.TokenMapping[] private assetMappings; + + string private configFilePath; + string private outputFilePath; function setUp() external { - string memory config = vm.readFile(vm.envString("DEPLOYMENT_CONFIG_FILE")); + configFilePath = vm.envString("DEPLOYMENT_CONFIG_FILE"); + outputFilePath = vm.envString("DEPLOYMENT_OUTPUT_FILE"); + + string memory config = vm.readFile(configFilePath); allowRootOverride = vm.parseJsonBool(config, "$.allow_root_override"); vaultVerifier = vm.parseJsonAddress(config, "$.vault_verifier"); @@ -33,29 +47,40 @@ contract DeployL2Contracts is Script { for (uint256 i = 0; i < _lookupTables.length; i++) { lookupTables[i] = _lookupTables[i]; } - - BridgedTokenMapping.TokenMapping[] memory assetMappingsMem = - abi.decode(vm.parseJson(config, "$.asset_mappings"), (BridgedTokenMapping.TokenMapping[])); - for (uint256 i = 0; i < assetMappingsMem.length; i++) { - assetMappings.push(assetMappingsMem[i]); - } - require(assetMappings.length > 0, "At least one asset mapping must be provided"); } // NOTE: Make sure to use either --slow or -batch-size 1 when running this script for Tenderly to avoid out of order deployments of contracts and incorrect addresses. function run() external { - // Deploy vault verifier if not provided vm.startBroadcast(); + + // Deploy vault verifier if not provided if (vaultVerifier == address(0)) { vaultVerifier = address(new VaultEscapeProofVerifier(lookupTables)); } withdrawalProcessor = new VaultWithdrawalProcessor(vaultVerifier, vaultRootProvider, operators, allowRootOverride); - withdrawalProcessor.registerTokenMappings(assetMappings); - _logDeploymentDetails(); vm.stopBroadcast(); + + _writeDeploymentOutput(); + _logDeploymentDetails(); + } + + /** + * @dev Writes an updated config file with the deployed contract addresses. + * This output can be used directly as input for RegisterTokenMappings.s.sol + */ + function _writeDeploymentOutput() private { + // Copy the original config to output file + string memory config = vm.readFile(configFilePath); + vm.writeFile(outputFilePath, config); + + // Update with deployed addresses + vm.writeJson(vm.toString(vaultVerifier), outputFilePath, ".vault_verifier"); + vm.writeJson(vm.toString(address(withdrawalProcessor)), outputFilePath, ".withdrawal_processor"); + + console.log("Deployment output written to: ", outputFilePath); } function _logDeploymentDetails() private view { diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..5cff45b --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,138 @@ +# Anvil Scripts + +Shell scripts for local development and testing on **Anvil fork chains only**. + +These scripts use Anvil-specific RPC methods (`anvil_setBalance`, `anvil_impersonateAccount`) that are not available on real networks. They are intended for local testing and sandbox environments. + +## Prerequisites + +- [Foundry](https://book.getfoundry.sh/) installed (`cast` CLI) +- `jq` for JSON processing +- A running **Anvil** instance (forked or standalone) + +## Scripts + +| Script | Purpose | +|--------|---------| +| `anvil_mint_tokens.sh` | Mint tokens to the withdrawal processor by impersonating the bridge | +| `anvil_setup_disbursers.sh` | Fund accounts and grant DISBURSER_ROLE | + +--- + +### anvil_mint_tokens.sh + +Mints tokens to the withdrawal processor for testing. Uses Anvil's account impersonation to mint tokens as if the bridge were calling. + +**Usage:** + +```bash +./scripts/anvil_mint_tokens.sh \ + --rpc-url http://localhost:8545 \ + --bridge 0xBa5E35E26Ae59c7aea6F029B68c6460De2d13eB6 \ + --config config/sandbox/anvil/anvil_zkevm_testnet_config_deployed.json \ + --tokens config/sandbox/imx_token_amounts.json +``` + +**Arguments:** + +| Argument | Required | Description | +|----------|----------|-------------| +| `--rpc-url` | Yes | Anvil RPC endpoint | +| `--bridge` | Yes | Bridge address to impersonate (must have mint rights on tokens) | +| `--config` | Yes | Path to deployed config with `withdrawal_processor` and `asset_mappings` | +| `--tokens` | Yes | Path to JSON file with token amounts | +| `--private-key` | No | Private key (alternative to impersonation) | + +**Behavior:** + +- Reads `withdrawal_processor` from config as the beneficiary +- For each token in the amounts file: + - Matches `token_int` to `tokenOnIMX.id` in `asset_mappings` + - **IMX tokens**: Uses `anvil_setBalance` to set native balance + - **Other tokens**: Impersonates bridge and calls `mint(address,uint256)` +- Skips tokens without a matching asset mapping + +**Anvil-Specific Features Used:** +- `anvil_impersonateAccount` / `anvil_stopImpersonatingAccount` +- `anvil_setBalance` (for IMX native token) + +--- + +### anvil_setup_disbursers.sh + +Sets up disburser accounts by funding them with native tokens and granting the `DISBURSER_ROLE` on the withdrawal processor contract. + +**Usage:** + +```bash +./scripts/anvil_setup_disbursers.sh \ + --rpc-url http://localhost:8545 \ + --contract 0xA15BB66138824a1c7167f5E85b957d04Dd34E468 \ + --disbursers config/sandbox/disbursers.txt \ + --admin-key $ADMIN_PRIVATE_KEY +``` + +**Arguments:** + +| Argument | Required | Description | +|----------|----------|-------------| +| `--rpc-url` | Yes | Anvil RPC endpoint | +| `--contract` | Yes | Withdrawal processor contract address | +| `--disbursers` | Yes | Path to file with comma-separated addresses | +| `--admin-key` | Yes | Private key of account with DEFAULT_ADMIN_ROLE | +| `--balance` | No | Amount to fund in hex (default: 100 ETH = `0x56bc75e2d63100000`) | + +**Behavior:** + +- Reads comma-separated addresses from the disbursers file +- For each address: + - Funds with native tokens via `anvil_setBalance` + - Grants `DISBURSER_ROLE` (`0x83b1a44decfa848e00bb3100d7cc1596f7f72453e6ae10ceea99dc7cd75046f0`) + +**Anvil-Specific Features Used:** +- `anvil_setBalance` + +**Disbursers File Format:** + +``` +0xAddress1, 0xAddress2, 0xAddress3 +``` + +--- + +## Example Workflow + +```bash +# 1. Start Anvil fork +anvil --fork-url $ZKEVM_RPC_URL + +# 2. Deploy contracts (see script/README.md) +DEPLOYMENT_CONFIG_FILE=config/sandbox/anvil/anvil_zkevm_testnet_config.json \ +DEPLOYMENT_OUTPUT_FILE=config/sandbox/anvil/anvil_zkevm_testnet_config_deployed.json \ +forge script script/DeployL2Contracts.s.sol --rpc-url http://localhost:8545 --broadcast + +# 3. Setup disbursers +./scripts/anvil_setup_disbursers.sh \ + --rpc-url http://localhost:8545 \ + --contract $WITHDRAWAL_PROCESSOR \ + --disbursers config/sandbox/disbursers.txt \ + --admin-key $ADMIN_KEY + +# 4. Mint tokens to withdrawal processor +./scripts/anvil_mint_tokens.sh \ + --rpc-url http://localhost:8545 \ + --bridge $BRIDGE_ADDRESS \ + --config config/sandbox/anvil/anvil_zkevm_testnet_config_deployed.json \ + --tokens config/sandbox/imx_token_amounts.json +``` + +## Why Anvil-Only? + +These scripts rely on Anvil's special RPC methods: + +| Method | Purpose | +|--------|---------| +| `anvil_setBalance` | Set arbitrary ETH/native token balance | +| `anvil_impersonateAccount` | Send transactions as any address without private key | + +These methods don't exist on real networks (mainnet, testnets, Tenderly, etc.). diff --git a/scripts/anvil_mint_tokens.sh b/scripts/anvil_mint_tokens.sh new file mode 100755 index 0000000..06a49a9 --- /dev/null +++ b/scripts/anvil_mint_tokens.sh @@ -0,0 +1,181 @@ +#!/bin/bash +# Copyright Immutable Pty Ltd 2018 - 2025 +# SPDX-License-Identifier: MIT +# +# Mint tokens to the withdrawal processor for testing purposes. +# This script reads token amounts from a JSON file, matches them to zkEVM addresses, +# and mints the tokens by impersonating the bridge. +# +# Usage: +# ./scripts/mint_tokens.sh \ +# --rpc-url http://localhost:8545 \ +# --bridge 0xBa5E35E26Ae59c7aea6F029B68c6460De2d13eB6 \ +# --config config/sandbox/anvil/anvil_zkevm_testnet_config_deployed.json \ +# --tokens config/sandbox/imx_token_amounts.json +# +# Options: +# --rpc-url RPC endpoint for the zkEVM network +# --bridge Bridge address to impersonate (must have mint rights on tokens) +# --config Path to deployed config with withdrawal_processor and asset_mappings +# --tokens Path to JSON file with token amounts +# --private-key Optional: Private key for signing (if not using Anvil impersonation) + +set -e + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --rpc-url) + RPC_URL="$2" + shift 2 + ;; + --bridge) + BRIDGE_ADDRESS="$2" + shift 2 + ;; + --config) + CONFIG_FILE="$2" + shift 2 + ;; + --tokens) + TOKENS_FILE="$2" + shift 2 + ;; + --private-key) + PRIVATE_KEY="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +# Validate required arguments +if [ -z "$RPC_URL" ]; then + echo "Error: --rpc-url is required" + exit 1 +fi + +if [ -z "$BRIDGE_ADDRESS" ]; then + echo "Error: --bridge is required" + exit 1 +fi + +if [ -z "$CONFIG_FILE" ]; then + echo "Error: --config is required" + exit 1 +fi + +if [ -z "$TOKENS_FILE" ]; then + echo "Error: --tokens is required" + exit 1 +fi + +# Check files exist +if [ ! -f "$CONFIG_FILE" ]; then + echo "Error: Config file not found: $CONFIG_FILE" + exit 1 +fi + +if [ ! -f "$TOKENS_FILE" ]; then + echo "Error: Tokens file not found: $TOKENS_FILE" + exit 1 +fi + +# Read withdrawal_processor from config (beneficiary) +BENEFICIARY=$(jq -r '.withdrawal_processor' "$CONFIG_FILE") +echo "Beneficiary (withdrawal_processor): $BENEFICIARY" +echo "Bridge address: $BRIDGE_ADDRESS" +echo "" + +# If no private key, use Anvil impersonation +if [ -z "$PRIVATE_KEY" ]; then + echo "Using Anvil impersonation mode..." + cast rpc anvil_impersonateAccount "$BRIDGE_ADDRESS" --rpc-url "$RPC_URL" || { + echo "Warning: Failed to impersonate account. If not using Anvil, provide --private-key" + } +fi + +# Count tokens +TOKEN_COUNT=$(jq 'length' "$TOKENS_FILE") +echo "Processing $TOKEN_COUNT tokens..." +echo "" + +# Process each token +SUCCESS_COUNT=0 +SKIP_COUNT=0 +FAIL_COUNT=0 + +while read -r token; do + TOKEN_INT=$(echo "$token" | jq -r '.token_int') + AMOUNT=$(echo "$token" | jq -r '.unquantised_sum') + TICKER=$(echo "$token" | jq -r '.ticker_symbol') + + # Find matching tokenOnZKEVM in asset_mappings + # Note: token_int is a large number, need to match as string + ZKEVM_ADDR=$(jq -r --arg id "$TOKEN_INT" \ + '.asset_mappings[] | select(.tokenOnIMX.id == $id) | .tokenOnZKEVM' "$CONFIG_FILE") + + if [ -z "$ZKEVM_ADDR" ] || [ "$ZKEVM_ADDR" == "null" ]; then + echo "[$TICKER] SKIPPED - No matching asset mapping found for token_int: $TOKEN_INT" + ((SKIP_COUNT++)) || true + continue + fi + + echo -n "[$TICKER] Minting $AMOUNT to $BENEFICIARY via $ZKEVM_ADDR... " + + # Handle IMX specially (native asset on zkEVM) + if [ "$TICKER" == "IMX" ]; then + # Convert amount to hex for anvil_setBalance + AMOUNT_HEX=$(printf '0x%x' "$AMOUNT" 2>/dev/null || echo "0x0") + + if cast rpc anvil_setBalance "$BENEFICIARY" "$AMOUNT_HEX" --rpc-url "$RPC_URL" 2>/dev/null; then + echo "OK (native IMX)" + ((SUCCESS_COUNT++)) || true + else + echo "FAILED" + ((FAIL_COUNT++)) || true + fi + else + # Mint ERC20 token + if [ -n "$PRIVATE_KEY" ]; then + # Use private key + if cast send "$ZKEVM_ADDR" "mint(address,uint256)" "$BENEFICIARY" "$AMOUNT" \ + --private-key "$PRIVATE_KEY" \ + --rpc-url "$RPC_URL" \ + --quiet 2>/dev/null; then + echo "OK" + ((SUCCESS_COUNT++)) || true + else + echo "FAILED" + ((FAIL_COUNT++)) || true + fi + else + # Use unlocked account (Anvil impersonation) + if cast send "$ZKEVM_ADDR" "mint(address,uint256)" "$BENEFICIARY" "$AMOUNT" \ + --from "$BRIDGE_ADDRESS" \ + --unlocked \ + --rpc-url "$RPC_URL" \ + --quiet 2>/dev/null; then + echo "OK" + ((SUCCESS_COUNT++)) || true + else + echo "FAILED" + ((FAIL_COUNT++)) || true + fi + fi + fi +done < <(jq -c '.[]' "$TOKENS_FILE") + +# Stop impersonation if we started it +if [ -z "$PRIVATE_KEY" ]; then + cast rpc anvil_stopImpersonatingAccount "$BRIDGE_ADDRESS" --rpc-url "$RPC_URL" 2>/dev/null || true +fi + +echo "" +echo "Done!" +echo " Success: $SUCCESS_COUNT" +echo " Skipped: $SKIP_COUNT" +echo " Failed: $FAIL_COUNT" diff --git a/scripts/anvil_setup_disbursers.sh b/scripts/anvil_setup_disbursers.sh new file mode 100755 index 0000000..f8460f6 --- /dev/null +++ b/scripts/anvil_setup_disbursers.sh @@ -0,0 +1,145 @@ +#!/bin/bash +# Copyright Immutable Pty Ltd 2018 - 2025 +# SPDX-License-Identifier: MIT +# +# Setup disbursers by funding them and granting DISBURSER_ROLE. +# This script reads addresses from a file, funds them via Anvil, +# and grants them the DISBURSER_ROLE on the specified contract. +# +# Usage: +# ./scripts/setup_disbursers.sh \ +# --rpc-url http://localhost:8545 \ +# --contract 0xA15BB66138824a1c7167f5E85b957d04Dd34E468 \ +# --disbursers config/sandbox/disbursers.txt \ +# --admin-key $ADMIN_PRIVATE_KEY +# +# Options: +# --rpc-url RPC endpoint (Anvil) +# --contract Contract address to call grantRole on (e.g., withdrawal_processor) +# --disbursers Path to file with comma-separated addresses +# --admin-key Private key of account with admin rights to grant roles +# --balance Optional: Amount of native tokens to fund in hex (default: 100 ETH) + +set -e + +# DISBURSER_ROLE hash +DISBURSER_ROLE="0x83b1a44decfa848e00bb3100d7cc1596f7f72453e6ae10ceea99dc7cd75046f0" + +# Default balance: 100 ETH in wei (hex) +DEFAULT_BALANCE="0x56bc75e2d63100000" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --rpc-url) + RPC_URL="$2" + shift 2 + ;; + --contract) + CONTRACT="$2" + shift 2 + ;; + --disbursers) + DISBURSERS_FILE="$2" + shift 2 + ;; + --admin-key) + ADMIN_KEY="$2" + shift 2 + ;; + --balance) + BALANCE="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +# Use default balance if not provided +BALANCE="${BALANCE:-$DEFAULT_BALANCE}" + +# Validate required arguments +if [ -z "$RPC_URL" ]; then + echo "Error: --rpc-url is required" + exit 1 +fi + +if [ -z "$CONTRACT" ]; then + echo "Error: --contract is required" + exit 1 +fi + +if [ -z "$DISBURSERS_FILE" ]; then + echo "Error: --disbursers is required" + exit 1 +fi + +if [ -z "$ADMIN_KEY" ]; then + echo "Error: --admin-key is required" + exit 1 +fi + +# Check file exists +if [ ! -f "$DISBURSERS_FILE" ]; then + echo "Error: Disbursers file not found: $DISBURSERS_FILE" + exit 1 +fi + +echo "Contract: $CONTRACT" +echo "Disbursers file: $DISBURSERS_FILE" +echo "Balance to set: $BALANCE" +echo "" + +# Read addresses from file (comma-space separated, convert to newline-separated) +ADDRESSES=$(cat "$DISBURSERS_FILE" | tr ',' '\n' | tr -d ' ' | tr -d '\n' | tr -s '\n') + +# Count addresses +ADDRESS_COUNT=$(echo "$ADDRESSES" | grep -c . || echo 0) +echo "Processing $ADDRESS_COUNT disbursers..." +echo "" + +# Process each address +SUCCESS_COUNT=0 +FAIL_COUNT=0 + +for addr in $(cat "$DISBURSERS_FILE" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'); do + # Skip empty lines + if [ -z "$addr" ]; then + continue + fi + + echo -n "[$addr] " + + # 1. Fund the address + echo -n "Funding... " + if cast rpc anvil_setBalance "$addr" "$BALANCE" --rpc-url "$RPC_URL" 2>/dev/null; then + echo -n "OK. " + else + echo "FAILED to fund" + ((FAIL_COUNT++)) || true + continue + fi + + # 2. Grant DISBURSER_ROLE + echo -n "Granting DISBURSER_ROLE... " + if cast send "$CONTRACT" "grantRole(bytes32,address)" \ + "$DISBURSER_ROLE" \ + "$addr" \ + --private-key "$ADMIN_KEY" \ + --rpc-url "$RPC_URL" \ + --quiet 2>/dev/null; then + echo "OK" + ((SUCCESS_COUNT++)) || true + else + echo "FAILED to grant role" + ((FAIL_COUNT++)) || true + fi +done + +echo "" +echo "Done!" +echo " Success: $SUCCESS_COUNT" +echo " Failed: $FAIL_COUNT" diff --git a/test/integration/bridge/starkex/StarkExchangeMigration.t.sol b/test/integration/bridge/starkex/StarkExchangeMigration.t.sol index 77109cf..22bc43b 100644 --- a/test/integration/bridge/starkex/StarkExchangeMigration.t.sol +++ b/test/integration/bridge/starkex/StarkExchangeMigration.t.sol @@ -5,13 +5,14 @@ import "@src/bridge/starkex/StarkExchangeMigration.sol"; import "forge-std/Test.sol"; import {IStarkExchangeMigration} from "../../../../src/bridge/starkex/IStarkExchangeMigration.sol"; import {MockVaultRootSenderAdapter} from "../../../common/MockVaultRootSenderAdapter.sol"; +import {IAxelarGateway} from "@axelar-gmp-sdk-solidity/interfaces/IAxelarGateway.sol"; +import {IAxelarGasService} from "@axelar-gmp-sdk-solidity/interfaces/IAxelarGasService.sol"; interface IStarkExchangeProxy is IStarkExchangeMigration { event ImplementationAdded(address indexed implementation, bytes initData, bool finalize); event Upgraded(address indexed implementation); function vaultRoot() external view returns (uint256 vaultRoot); - function addImplementation(address newImplementation, bytes calldata initData, bool finalized) external; function upgradeTo(address newImplementation, bytes calldata initData, bool finalized) external payable; function implementation() external view returns (address implementation); @@ -19,14 +20,19 @@ interface IStarkExchangeProxy is IStarkExchangeMigration { } contract StarkExchangeMigrationTest is Test { - uint256 private constant BRIDGE_FEE = 0.001 ether; - IStarkExchangeProxy public constant starkExProxy = IStarkExchangeProxy(0x5FDCCA53617f4d2b9134B29090C87D01058e27e9); - address private constant ZKEVM_BRIDGE = 0xBa5E35E26Ae59c7aea6F029B68c6460De2d13eB6; // Bridge address + IStarkExchangeProxy public constant STARKEX_PROXY = IStarkExchangeProxy(0x5FDCCA53617f4d2b9134B29090C87D01058e27e9); address private constant STARKEX_PROXY_OWNER = 0xD2C37fC6fD89563187f3679304975655e448D192; - address private constant L2VAULT_PROCESSOR = 0x5Ffb1b3C4D6E8B7A9c1E8d3f2b5e6f7a8B9C0d1E; // L2 Vault Processor address address private constant STARKEX_MIGRATION_MANAGER = STARKEX_PROXY_OWNER; - address private mockVaultRootSender; + address private constant ZKEVM_BRIDGE = 0xBa5E35E26Ae59c7aea6F029B68c6460De2d13eB6; // Bridge address + address private constant VAULT_ROOT_SENDER_ADAPTER = 0x9Fabd9Cc71f15b9Cfd717E117FBb9cfD9fC7cd32; // L1 Root Sender adapter address + address private constant AXELAR_GATEWAY = 0x4F4495243837681061C4743b74B3eEdf548D56A5; + address private constant AXELAR_GAS_SERVICE = 0x2d5d7d31F671F86C782533cc367F14109a082712; + string private constant L2RECEIVER_ADAPTER = "0x58b5484F489f7858DC83a5a677338074b57de806"; + address private constant L2VAULT_PROCESSOR = 0xCeA34C706C4A18E103575832Dd21fD3656026D1E; // L2 Vault Processor address + bytes private constant INIT_DATA = + hex"000000000000000000000000d2c37fc6fd89563187f3679304975655e448d192000000000000000000000000ba5e35e26ae59c7aea6f029b68c6460de2d13eb60000000000000000000000009fabd9cc71f15b9cfd717e117fbb9cfd9fc7cd32000000000000000000000000cea34c706c4a18e103575832dd21fd3656026d1e"; // INIT_DATA already supplied in the upgrade proposal + uint256 private constant BRIDGE_FEE = 0.001 ether; address[] private tokens = [ 0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF, // IMX @@ -38,25 +44,28 @@ contract StarkExchangeMigrationTest is Test { function setUp() public { string memory RPC_URL = vm.envString("ETH_RPC_URL"); vm.createSelectFork(RPC_URL); - mockVaultRootSender = address(new MockVaultRootSenderAdapter()); } function _upgradeStarkExchange() internal returns (address) { vm.startPrank(STARKEX_PROXY_OWNER); address starkExchange = address(new StarkExchangeMigration()); + + // sanity check that the INIT_DATA is derived from other parameters bytes memory initData = - abi.encode(STARKEX_MIGRATION_MANAGER, ZKEVM_BRIDGE, mockVaultRootSender, L2VAULT_PROCESSOR); + abi.encode(STARKEX_MIGRATION_MANAGER, ZKEVM_BRIDGE, VAULT_ROOT_SENDER_ADAPTER, L2VAULT_PROCESSOR); + + assertEq(initData, INIT_DATA, "Init Data does not match expected"); vm.expectEmit(true, true, true, true); emit IStarkExchangeProxy.ImplementationAdded(starkExchange, initData, false); - starkExProxy.addImplementation(starkExchange, initData, false); + STARKEX_PROXY.addImplementation(starkExchange, initData, false); - skip(15 days); + skip(14 days); vm.expectEmit(true, true, true, true); emit IStarkExchangeProxy.Upgraded(starkExchange); - starkExProxy.upgradeTo(starkExchange, initData, false); + STARKEX_PROXY.upgradeTo(starkExchange, initData, false); - assertTrue(starkExProxy.isNotFinalized(), "Implementation should not be finalized through this upgrade"); + assertTrue(STARKEX_PROXY.isNotFinalized(), "Implementation should not be finalized through this upgrade"); vm.stopPrank(); return starkExchange; @@ -64,20 +73,20 @@ contract StarkExchangeMigrationTest is Test { function test_UpgradeStarkExchange() public { address newImpl = _upgradeStarkExchange(); - assertEq(starkExProxy.implementation(), newImpl, "Implementation should be updated"); + assertEq(STARKEX_PROXY.implementation(), newImpl, "Implementation should be updated"); } function test_UpgradeStarkExchange_VaultRootPreserved() public { - uint256 initialVaultRoot = uint256(vm.load(address(starkExProxy), bytes32(uint256(13)))); + uint256 initialVaultRoot = uint256(vm.load(address(STARKEX_PROXY), bytes32(uint256(13)))); assertNotEq(initialVaultRoot, 0, "Vault root should not be zero"); _upgradeStarkExchange(); - uint256 vaultRoot = starkExProxy.vaultRoot(); + uint256 vaultRoot = STARKEX_PROXY.vaultRoot(); assertEq(vaultRoot, initialVaultRoot, "Vault root should remain the same after upgrade"); } function test_migrate_ETHHoldings() public { - uint256 initStarkExBal = address(starkExProxy).balance; + uint256 initStarkExBal = address(STARKEX_PROXY).balance; console.log("Initial ETH balance on StarkEx bridge: %s", initStarkExBal); assertGt(initStarkExBal, 0, "Initial ETH balance should be greater than zero"); @@ -98,9 +107,9 @@ contract StarkExchangeMigrationTest is Test { token: address(0xeee), amount: migrateAmount, bridgeFee: BRIDGE_FEE }); - starkExProxy.migrateHoldings{value: bridgeFee}(asset); + STARKEX_PROXY.migrateHoldings{value: bridgeFee}(asset); - uint256 finStarkExBal = address(starkExProxy).balance; + uint256 finStarkExBal = address(STARKEX_PROXY).balance; assertEq(finStarkExBal, 0, "Final ETH balance on StarkEx bridge should be zero after migration"); uint256 finzkEVMBal = address(ZKEVM_BRIDGE).balance; @@ -118,7 +127,7 @@ contract StarkExchangeMigrationTest is Test { for (uint256 i = 0; i < tokens.length; i++) { IERC20Metadata token = IERC20Metadata(tokens[i]); - uint256 initStarkExBal = token.balanceOf(address(starkExProxy)); + uint256 initStarkExBal = token.balanceOf(address(STARKEX_PROXY)); console.log("Initial balance of %s on StarkEx bridge: %s", tokens[i], initStarkExBal); assertGt(initStarkExBal, 0, "Initial balance should be greater than zero"); @@ -131,9 +140,9 @@ contract StarkExchangeMigrationTest is Test { token: address(token), amount: initStarkExBal, bridgeFee: bridgeFee }); - starkExProxy.migrateHoldings{value: bridgeFee}(assets); + STARKEX_PROXY.migrateHoldings{value: bridgeFee}(assets); - uint256 finStarkExBal = token.balanceOf(address(starkExProxy)); + uint256 finStarkExBal = token.balanceOf(address(STARKEX_PROXY)); assertEq(finStarkExBal, 0, "Final balance on StarkEx bridge should be zero after migration"); uint256 finzkEVMBal = token.balanceOf(ZKEVM_BRIDGE); @@ -148,21 +157,43 @@ contract StarkExchangeMigrationTest is Test { _upgradeStarkExchange(); vm.startPrank(STARKEX_MIGRATION_MANAGER); - uint256 vaultRoot = starkExProxy.vaultRoot(); + uint256 vaultRoot = STARKEX_PROXY.vaultRoot(); assertGt(vaultRoot, 0, "Vault root should be greater than zero"); uint256 bridgeFee = 0.001 ether; // Example bridge fee vm.deal(STARKEX_MIGRATION_MANAGER, bridgeFee); + bytes memory payload = abi.encode(keccak256("SET_VAULT_ROOT"), vaultRoot); + vm.expectCall( - mockVaultRootSender, + VAULT_ROOT_SENDER_ADAPTER, abi.encodeCall( - VaultRootSenderAdapter(mockVaultRootSender).sendVaultRoot, (vaultRoot, STARKEX_MIGRATION_MANAGER) + VaultRootSenderAdapter(VAULT_ROOT_SENDER_ADAPTER).sendVaultRoot, (vaultRoot, STARKEX_MIGRATION_MANAGER) ) ); - starkExProxy.migrateVaultRoot{value: bridgeFee}(); + vm.expectCall( + AXELAR_GATEWAY, + abi.encodeCall(IAxelarGateway(AXELAR_GATEWAY).callContract, ("immutable", L2RECEIVER_ADAPTER, payload)) + ); + vm.expectCall( + AXELAR_GAS_SERVICE, + abi.encodeCall( + IAxelarGasService(AXELAR_GAS_SERVICE).payNativeGasForContractCall, + ( + address(VAULT_ROOT_SENDER_ADAPTER), + "immutable", + L2RECEIVER_ADAPTER, + payload, + STARKEX_MIGRATION_MANAGER + ) + ) + ); + vm.expectEmit(true, true, true, true); + emit VaultRootSenderAdapter.VaultRootSent("immutable", L2RECEIVER_ADAPTER, payload); + + STARKEX_PROXY.migrateVaultRoot{value: bridgeFee}(); - uint256 newVaultRoot = starkExProxy.vaultRoot(); + uint256 newVaultRoot = STARKEX_PROXY.vaultRoot(); assertEq(newVaultRoot, vaultRoot, "Vault root should remain the same after migration"); vm.stopPrank(); diff --git a/test/integration/proofs/withdrawals/VaultWithdrawalProcessor.t.sol b/test/integration/proofs/withdrawals/VaultWithdrawalProcessor.t.sol index c118083..b5dccab 100644 --- a/test/integration/proofs/withdrawals/VaultWithdrawalProcessor.t.sol +++ b/test/integration/proofs/withdrawals/VaultWithdrawalProcessor.t.sol @@ -90,6 +90,8 @@ contract VaultWithdrawalProcessorIntegrationTest is abi.encode(rootReceiver.SET_VAULT_ROOT(), fixVaultEscapes[0].root) ); + assertEq(vaultProcessor.vaultRoot(), fixVaultEscapes[0].root, "Vault root not correctly set"); + address vaultProcessorAddr = address(vaultProcessor); AccountAssociation memory account = fixAccounts[fixVaultEscapes[2].vault.starkKey]; @@ -124,6 +126,8 @@ contract VaultWithdrawalProcessorIntegrationTest is abi.encode(rootReceiver.SET_VAULT_ROOT(), fixVaultEscapes[1].root) ); + assertEq(vaultProcessor.vaultRoot(), fixVaultEscapes[1].root, "Vault root not correctly set"); + address vaultProcessorAddr = address(vaultProcessor); // Fund some USDC