From ef31d15fb1f66b4a68e51f455778aefb639ebc6a Mon Sep 17 00:00:00 2001 From: Richard Watts Date: Fri, 30 Aug 2024 10:56:34 +0100 Subject: [PATCH 1/4] (feat) Block following mode for when ZQ1 loses access to eth_getLogs() (fix) Fix history replays (feat) Legacy gas estimation overage mode - for preventing subtransactions from reverting due to lack of gas. --- .gitignore | 1 + bridge-validators/.gitignore | 1 + bridge-validators/Cargo.lock | 1438 ++++++++++---------- bridge-validators/README.md | 31 +- bridge-validators/config.toml | 33 +- bridge-validators/infra/config-leader.toml | 5 +- bridge-validators/infra/config.toml | 5 +- bridge-validators/src/block.rs | 215 ++- bridge-validators/src/bridge_node.rs | 32 +- bridge-validators/src/client.rs | 40 +- bridge-validators/src/main.rs | 9 +- bridge-validators/src/message.rs | 1 + bridge-validators/src/p2p_node.rs | 39 +- bridge-validators/src/validator_node.rs | 23 +- 14 files changed, 1050 insertions(+), 823 deletions(-) create mode 100644 bridge-validators/.gitignore diff --git a/.gitignore b/.gitignore index 23d4a5e..2185bf6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ Debug/ .trunk/** !.trunk/trunk.yaml +**/.env diff --git a/bridge-validators/.gitignore b/bridge-validators/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/bridge-validators/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/bridge-validators/Cargo.lock b/bridge-validators/Cargo.lock index 22f960a..0b3345a 100644 --- a/bridge-validators/Cargo.lock +++ b/bridge-validators/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -64,74 +64,75 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -139,18 +140,18 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" dependencies = [ "backtrace", ] [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -169,9 +170,9 @@ dependencies = [ [[package]] name = "asn1-rs" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -185,32 +186,32 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", "synstructure", ] [[package]] name = "asn1-rs-impl" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "async-io" -version = "2.2.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ "async-lock", "cfg-if", @@ -227,9 +228,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ "event-listener", "event-listener-strategy", @@ -255,18 +256,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -306,27 +307,26 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -357,9 +357,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -396,9 +402,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -453,9 +459,9 @@ dependencies = [ [[package]] name = "bs58" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ "sha2", "tinyvec", @@ -463,9 +469,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -481,9 +487,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" dependencies = [ "serde", ] @@ -511,18 +517,18 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -543,9 +549,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -583,9 +589,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "num-traits", ] @@ -603,9 +609,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -613,9 +619,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstream", "anstyle", @@ -625,21 +631,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "coins-bip32" @@ -679,7 +685,7 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bech32", "bs58", "digest", @@ -695,24 +701,24 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] [[package]] name = "const-hex" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -723,9 +729,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" @@ -760,53 +766,46 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", ] [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -848,16 +847,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -871,20 +869,20 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-encoding-macro" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -892,9 +890,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" dependencies = [ "data-encoding", "syn 1.0.109", @@ -902,9 +900,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -912,9 +910,9 @@ dependencies = [ [[package]] name = "der-parser" -version = "8.2.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ "asn1-rs", "displaydoc", @@ -926,30 +924,24 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "digest" version = "0.10.7" @@ -1006,13 +998,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1053,9 +1045,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", @@ -1068,9 +1060,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1093,29 +1085,29 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "enr" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "hex", "k256", @@ -1133,10 +1125,10 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1147,9 +1139,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1227,9 +1219,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1243,9 +1235,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c405f24ea3a517899ba7985385c43dc4a7eb1209af3b1e0a1a32d7dcc7f8d09" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" dependencies = [ "ethers-core", "once_cell", @@ -1255,9 +1247,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1274,9 +1266,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51258120c6b47ea9d9bec0d90f9e8af71c977fbefbef8213c91bfed385fe45eb" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" dependencies = [ "Inflector", "const-hex", @@ -1291,16 +1283,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.48", + "syn 2.0.72", "toml", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936e7a0f1197cee2b62dc89f63eff3201dbf87c283ff7e18d86d38f83b845483" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" dependencies = [ "Inflector", "const-hex", @@ -1309,14 +1301,14 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "ethers-core" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f03e0bdc216eeb9e355b90cf610ef6c5bb8aca631f97b5ae9980ce34ea7878d" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ "arrayvec", "bytes", @@ -1335,7 +1327,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.48", + "syn 2.0.72", "tempfile", "thiserror", "tiny-keccak", @@ -1344,9 +1336,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abbac2c890bdbe0f1b8e549a53b00e2c4c1de86bb077c1094d1f38cdf9381a56" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ "chrono", "ethers-core", @@ -1360,9 +1352,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" dependencies = [ "async-trait", "auto_impl", @@ -1387,13 +1379,13 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" dependencies = [ "async-trait", "auto_impl", - "base64 0.21.5", + "base64 0.21.7", "bytes", "const-hex", "enr", @@ -1425,9 +1417,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" dependencies = [ "async-trait", "coins-bip32", @@ -1444,9 +1436,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64f710586d147864cff66540a6d64518b9ff37d73ef827fee430538265b595f" +checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ "cfg-if", "const-hex", @@ -1476,9 +1468,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "4.0.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1487,9 +1479,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ "event-listener", "pin-project-lite", @@ -1497,9 +1489,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.9" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1507,9 +1499,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "ff" @@ -1523,9 +1515,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "fixed-hash" @@ -1547,9 +1539,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1588,9 +1580,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1603,9 +1595,9 @@ dependencies = [ [[package]] name = "futures-bounded" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e2774cc104e198ef3d3e1ff4ab40f86fa3245d6cb6a3a46174f21463cee173" +checksum = "91f328e7fb845fc832912fb6a34f40cf6d1888c92f974d1893a54e97b5ff542e" dependencies = [ "futures-timer", "futures-util", @@ -1613,9 +1605,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1623,15 +1615,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1641,15 +1633,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ "futures-core", "pin-project-lite", @@ -1667,36 +1659,37 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "futures-rustls" -version = "0.24.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls", + "rustls 0.23.12", + "rustls-pki-types", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-ticker" @@ -1711,9 +1704,9 @@ dependencies = [ [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", "send_wrapper 0.4.0", @@ -1721,9 +1714,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1759,9 +1752,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1770,9 +1763,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -1780,9 +1773,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -1815,9 +1808,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1834,9 +1827,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -1857,11 +1850,23 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -1877,9 +1882,9 @@ checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" [[package]] name = "hickory-proto" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091a6fbccf4860009355e3efc52ff4acf37a63489aad7435372d44ceeb6fbbcf" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" dependencies = [ "async-trait", "cfg-if", @@ -1892,7 +1897,7 @@ dependencies = [ "ipnet", "once_cell", "rand", - "socket2 0.5.5", + "socket2", "thiserror", "tinyvec", "tokio", @@ -1902,9 +1907,9 @@ dependencies = [ [[package]] name = "hickory-resolver" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" dependencies = [ "cfg-if", "futures-util", @@ -1941,11 +1946,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1961,9 +1966,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1983,9 +1988,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1995,9 +2000,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -2010,7 +2015,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", @@ -2026,7 +2031,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls", + "rustls 0.21.12", "tokio", "tokio-rustls", ] @@ -2082,9 +2087,9 @@ dependencies = [ [[package]] name = "igd-next" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e065e90a518ab5fedf79aa1e4b784e10f8e484a834f6bda85c42633a2cb7af" +checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ "async-trait", "attohttpc", @@ -2145,9 +2150,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown", @@ -2164,9 +2169,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2177,7 +2182,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.5", + "socket2", "widestring", "windows-sys 0.48.0", "winreg", @@ -2190,24 +2195,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -2220,24 +2211,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2248,7 +2239,7 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "pem 1.1.1", "ring 0.16.20", "serde", @@ -2258,9 +2249,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -2272,52 +2263,54 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] [[package]] name = "lalrpop" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", - "diff", "ena", - "is-terminal", - "itertools 0.10.5", + "itertools", "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.7.5", + "regex-syntax 0.8.4", "string_cache", "term", "tiny-keccak", "unicode-xid", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata 0.4.7", +] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -2386,15 +2379,14 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.41.2" +version = "0.41.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8130a8269e65a2554d55131c770bdf4bcd94d2b8d4efb24ca23699be65066c05" +checksum = "a5a8920cbd8540059a01950c1e5c96ea8d89eb50c51cd366fc18bdf540a6e48f" dependencies = [ "either", "fnv", "futures", "futures-timer", - "instant", "libp2p-identity", "multiaddr", "multihash", @@ -2411,6 +2403,7 @@ dependencies = [ "tracing", "unsigned-varint 0.8.0", "void", + "web-time", ] [[package]] @@ -2436,7 +2429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d665144a616dadebdc5fff186b1233488cdcd8bfb1223218ff084b6d052c94f7" dependencies = [ "asynchronous-codec", - "base64 0.21.5", + "base64 0.21.7", "byteorder", "bytes", "either", @@ -2463,9 +2456,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.44.1" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20499a945d2f0221fdc6269b3848892c0f370d2ee3e19c7f65a29d8f860f6126" +checksum = "b5d635ebea5ca0c3c3e77d414ae9b67eccf2a822be06091b9c1a0d13029a1e2f" dependencies = [ "asynchronous-codec", "either", @@ -2486,9 +2479,9 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999ec70441b2fb35355076726a6bc466c932e9bdc66f6a11c6c0aa17c7ab9be0" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" dependencies = [ "bs58", "ed25519-dalek", @@ -2548,7 +2541,7 @@ dependencies = [ "libp2p-swarm", "rand", "smallvec", - "socket2 0.5.5", + "socket2", "tokio", "tracing", "void", @@ -2600,9 +2593,9 @@ dependencies = [ [[package]] name = "libp2p-quic" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0375cdfee57b47b313ef1f0fdb625b78aed770d33a40cf1c294a371ff5e6666" +checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" dependencies = [ "bytes", "futures", @@ -2614,9 +2607,9 @@ dependencies = [ "parking_lot", "quinn", "rand", - "ring 0.16.20", - "rustls", - "socket2 0.5.5", + "ring 0.17.8", + "rustls 0.23.12", + "socket2", "thiserror", "tokio", "tracing", @@ -2624,9 +2617,9 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12823250fe0c45bdddea6eefa2be9a609aff1283ff4e1d8a294fdbb89572f6f" +checksum = "c314fe28368da5e3a262553fb0ad575c1c8934c461e10de10265551478163836" dependencies = [ "async-trait", "futures", @@ -2646,9 +2639,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.44.1" +version = "0.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e92532fc3c4fb292ae30c371815c9b10103718777726ea5497abc268a4761866" +checksum = "80cae6cb75f89dbca53862f9ebe0b9f463aa7b302762fcfaafb9e51dcc9b0f7e" dependencies = [ "either", "fnv", @@ -2658,6 +2651,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm-derive", + "lru", "multistream-select", "once_cell", "rand", @@ -2669,14 +2663,14 @@ dependencies = [ [[package]] name = "libp2p-swarm-derive" -version = "0.34.1" +version = "0.34.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b644268b4acfdaa6a6100b31226ee7a36d96ab4c43287d113bfd2308607d8b6f" +checksum = "5daceb9dd908417b6dfcfe8e94098bc4aac54500c282e78120b885dadc09b999" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2691,25 +2685,25 @@ dependencies = [ "libc", "libp2p-core", "libp2p-identity", - "socket2 0.5.5", + "socket2", "tokio", "tracing", ] [[package]] name = "libp2p-tls" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ce7e3c2e7569d685d08ec795157981722ff96e9e9f9eae75df3c29d02b07a5" +checksum = "72b7b831e55ce2aa6c354e6861a85fdd4dd0a2b97d5e276fabac0e4810a71776" dependencies = [ "futures", "futures-rustls", "libp2p-core", "libp2p-identity", "rcgen", - "ring 0.16.20", - "rustls", - "rustls-webpki", + "ring 0.17.8", + "rustls 0.23.12", + "rustls-webpki 0.101.7", "thiserror", "x509-parser", "yasna", @@ -2717,9 +2711,9 @@ dependencies = [ [[package]] name = "libp2p-upnp" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963eb8a174f828f6a51927999a9ab5e45dfa9aa2aa5fed99aa65f79de6229464" +checksum = "cccf04b0e3ff3de52d07d5fd6c3b061d0e7f908ffc683c32d9638caedce86fc8" dependencies = [ "futures", "futures-timer", @@ -2743,18 +2737,17 @@ dependencies = [ "thiserror", "tracing", "yamux 0.12.1", - "yamux 0.13.1", + "yamux 0.13.3", ] [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "libc", - "redox_syscall", ] [[package]] @@ -2765,15 +2758,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2781,15 +2774,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.12.1" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" dependencies = [ "hashbrown", ] @@ -2830,18 +2823,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -2857,22 +2841,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2985,9 +2970,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ "bytes", "futures", @@ -2998,9 +2983,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" @@ -3041,30 +3026,34 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -3076,45 +3065,45 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_enum" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "object" -version = "0.32.1" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] [[package]] name = "oid-registry" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" dependencies = [ "asn1-rs", ] @@ -3127,9 +3116,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "open-fastrlp" @@ -3170,9 +3159,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -3184,11 +3173,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3202,9 +3191,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -3212,15 +3201,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -3236,9 +3225,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-slash" @@ -3279,11 +3268,11 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.21.5", + "base64 0.22.1", "serde", ] @@ -3295,9 +3284,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap", @@ -3343,7 +3332,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -3366,29 +3355,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3408,24 +3397,19 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "platforms" -version = "3.2.0" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polling" -version = "3.3.1" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", "rustix", "tracing", @@ -3445,9 +3429,9 @@ dependencies = [ [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -3463,9 +3447,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy 0.6.6", +] [[package]] name = "precomputed-hash" @@ -3475,12 +3462,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -3499,61 +3486,27 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.2", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "toml_edit 0.21.1", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus-client" -version = "0.22.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510c4f1c9d81d556458f94c98f857748130ea9737bbd6053da497503b26ea63c" +checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", @@ -3569,22 +3522,22 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", "unarray", ] @@ -3618,9 +3571,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.10.2" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" dependencies = [ "bytes", "futures-io", @@ -3628,7 +3581,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.23.12", "thiserror", "tokio", "tracing", @@ -3636,15 +3589,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.6" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" dependencies = [ "bytes", "rand", - "ring 0.16.20", + "ring 0.17.8", "rustc-hash", - "rustls", + "rustls 0.23.12", "slab", "thiserror", "tinyvec", @@ -3653,22 +3606,21 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.4.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" dependencies = [ - "bytes", "libc", - "socket2 0.5.5", - "tracing", - "windows-sys 0.48.0", + "once_cell", + "socket2", + "windows-sys 0.52.0", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3720,9 +3672,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3730,9 +3682,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3744,7 +3696,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" dependencies = [ - "pem 3.0.3", + "pem 3.0.4", "ring 0.16.20", "time", "yasna", @@ -3752,18 +3704,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -3772,14 +3724,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -3793,13 +3745,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] @@ -3810,23 +3762,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -3843,11 +3789,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.21.12", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls", @@ -3897,16 +3844,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3957,9 +3905,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3993,11 +3941,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -4006,40 +3954,71 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.7", - "rustls-webpki", + "ring 0.17.8", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +dependencies = [ + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.6", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rw-stream-sink" @@ -4054,9 +4033,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -4078,9 +4057,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", "derive_more", @@ -4090,11 +4069,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -4124,7 +4103,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -4144,9 +4123,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -4165,40 +4144,41 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4258,18 +4238,18 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "signature" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", "rand_core", @@ -4304,9 +4284,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snow" @@ -4319,7 +4299,7 @@ dependencies = [ "chacha20poly1305", "curve25519-dalek", "rand_core", - "ring 0.17.7", + "ring 0.17.8", "rustc_version", "sha2", "subtle", @@ -4327,22 +4307,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4351,7 +4321,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" dependencies = [ - "itertools 0.11.0", + "itertools", "lalrpop", "lalrpop-util", "phf", @@ -4402,43 +4372,43 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "svm-rs" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", @@ -4467,25 +4437,30 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "unicode-xid", + "syn 2.0.72", ] [[package]] @@ -4517,15 +4492,14 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4541,29 +4515,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -4571,12 +4545,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4591,10 +4566,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4609,9 +4585,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4624,31 +4600,30 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4657,15 +4632,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -4680,7 +4655,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.21.12", "tokio", "tokio-rustls", "tungstenite", @@ -4689,72 +4664,60 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.8" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.18", ] [[package]] @@ -4782,7 +4745,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4866,7 +4829,7 @@ dependencies = [ "httparse", "log", "rand", - "rustls", + "rustls 0.21.12", "sha1", "thiserror", "url", @@ -4899,9 +4862,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4911,9 +4874,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -4960,9 +4923,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna 0.5.0", @@ -4977,9 +4940,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -4999,9 +4962,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" @@ -5011,9 +4974,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -5036,9 +4999,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5046,24 +5009,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -5073,9 +5036,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5083,28 +5046,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -5112,15 +5085,15 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -5140,11 +5113,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -5187,7 +5160,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -5207,17 +5180,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5228,9 +5202,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5240,9 +5214,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5252,9 +5226,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5264,9 +5244,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5276,9 +5256,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5288,9 +5268,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5300,15 +5280,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.28" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -5353,9 +5342,9 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", "rand_core", @@ -5365,9 +5354,9 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ "asn1-rs", "data-encoding", @@ -5382,9 +5371,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" [[package]] name = "xmltree" @@ -5412,18 +5401,18 @@ dependencies = [ [[package]] name = "yamux" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1d0148b89300047e72994bee99ecdabd15a9166a7b70c8b8c37c314dcc9002" +checksum = "a31b5e376a8b012bee9c423acdbb835fc34d45001cfa3106236a624e4b738028" dependencies = [ "futures", - "instant", "log", "nohash-hasher", "parking_lot", "pin-project", "rand", "static_assertions", + "web-time", ] [[package]] @@ -5443,29 +5432,50 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive 0.6.6", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" dependencies = [ - "zerocopy-derive", + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5478,7 +5488,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5522,9 +5532,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.12+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" dependencies = [ "cc", "pkg-config", diff --git a/bridge-validators/README.md b/bridge-validators/README.md index 166ac07..a761e09 100644 --- a/bridge-validators/README.md +++ b/bridge-validators/README.md @@ -1,4 +1,33 @@ -# Testing information +# The bridge validator + +This directory contains software that acts as a trivial bridge validator. It +accepts a configuration file - of which there is an example in +`config.toml` - and listens on the configured chains, relaying events +from the configured chain gateways. + +The configuration is defined in `src/main.rs`. + +There are a few options you can pass: + +```sh +--config-file : Use this config file. + +--is-leader : if true, we will be the validator node that + sends transactions to the target chain. + +--dispatch-history : if true, we will go through all of history from + chain_gateway_block_deployed and dispatch all relay + transactions, to make sure we don't miss any in + the gap between a previous instance dying and this + instance starting. If false, we start at the current + block. + +--help : help text. +``` + +## Testing information + +You can generate log data using `RUST_LOG=info`. 1.Run two anvil chains: diff --git a/bridge-validators/config.toml b/bridge-validators/config.toml index 5180b45..81994ca 100644 --- a/bridge-validators/config.toml +++ b/bridge-validators/config.toml @@ -5,9 +5,36 @@ # BSC Testnet [[chain_configs]] +## The block at which history replay should start. chain_gateway_block_deployed = 36696045 +## RPC URL to talk to for this chain. rpc_url = "https://bsc-prebsc-dataseed.bnbchain.org" -chain_gateway_address = "0x72B9B59e48779A8b64554A3e2bC8b5297A04c68a" +## The (EVM) address of the chain gateway contract +## - events from anywhere else will be ignored. +## - relay requests for this chain id will be relayed to this contract. +chain_gateway_address = "0xa9A14C90e53EdCD89dFd201A3bF94D867f8098fE" +## If this key is absent, we submit relay transactions with "enough" gas per eth_estimateGas(). +## Most chains seem to have problems with this, and so this key exists to allow you to +## submit legacy_gas_estimation_percent percent of the estimated gas, so as to ensure that +## relay txns don't run out of gas. A value of 130-150 seems to work for coin transfers. +legacy_gas_estimation_percent = 130 +## If this key is present, we delay scanning a block until N blocks ahead of it have been +## produced, to give some chains time to propagate block data to the nodes from which we are +## attempting to read them. +## scan_behind_blocks = 1 + +## If this is set true (Zilliqa 1 again!), we assume that any block we see is final. +## Otherwise (every other chain), we ask for the latest finalized block and scan that. +## block_instant_finality = true + +## Normally, we use eth_getFilterLogs() to fetch relay events for processing. +## Some chains (Zilliqa 1) will sometimes get into a state where they return [] for eth_getFilterLogs() +## regardless of the actual emitted logs for a block. This obviously confuses us. +## Worse, eth_getBlockReceipts() has the same problem. +## So, if you set this to true, we will call eth_getBlock() and then iterate through each transaction +## fetching the receipt and scanning it for relevant logs. This is slow, but at least it works .. +## use_get_transactions = true + # BSC Mainnet # [[chain_configs]] @@ -27,9 +54,9 @@ chain_gateway_address = "0x72B9B59e48779A8b64554A3e2bC8b5297A04c68a" [[chain_configs]] chain_gateway_block_deployed = 6542681 rpc_url = "https://dev-api.zilliqa.com" -chain_gateway_address = "0x10917A34FE60eE8364a401a6b1d3adaf80D84eb6" +chain_gateway_address = "0x7370e69565BB2313C4dA12F9062C282513919230" block_instant_finality = true -legacy_gas_estimation = true +legacy_gas_estimation_percent = 130 # Zilliqa Mainnet # [[chain_configs]] diff --git a/bridge-validators/infra/config-leader.toml b/bridge-validators/infra/config-leader.toml index 57c5008..596fa29 100644 --- a/bridge-validators/infra/config-leader.toml +++ b/bridge-validators/infra/config-leader.toml @@ -2,7 +2,8 @@ [[chain_configs]] chain_gateway_block_deployed = 36696045 rpc_url = "https://bsc-prebsc-dataseed.bnbchain.org" -chain_gateway_address = "0x72B9B59e48779A8b64554A3e2bC8b5297A04c68a" +chain_gateway_address = "0xa9A14C90e53EdCD89dFd201A3bF94D867f8098fE" +legacy_gas_estimation_percent = 150 # BSC Mainnet # [[chain_configs]] @@ -24,7 +25,7 @@ chain_gateway_block_deployed = 6542681 rpc_url = "https://evm-api-xbridge.testnet.zilliqa.com" chain_gateway_address = "0x10917A34FE60eE8364a401a6b1d3adaf80D84eb6" block_instant_finality = true -legacy_gas_estimation = true +legacy_gas_estimation_percent = 130 # Zilliqa Mainnet # [[chain_configs]] diff --git a/bridge-validators/infra/config.toml b/bridge-validators/infra/config.toml index 2d93c94..c950ee0 100644 --- a/bridge-validators/infra/config.toml +++ b/bridge-validators/infra/config.toml @@ -7,7 +7,8 @@ [[chain_configs]] chain_gateway_block_deployed = 36696045 rpc_url = "https://bsc-prebsc-dataseed.bnbchain.org" -chain_gateway_address = "0x72B9B59e48779A8b64554A3e2bC8b5297A04c68a" +chain_gateway_address = "0xa9A14C90e53EdCD89dFd201A3bF94D867f8098fE" +legacy_gas_estimation_percent = 150 # BSC Mainnet # [[chain_configs]] @@ -29,7 +30,7 @@ chain_gateway_block_deployed = 6542681 rpc_url = "https://evm-api-xbridge.testnet.zilliqa.com" chain_gateway_address = "0x10917A34FE60eE8364a401a6b1d3adaf80D84eb6" block_instant_finality = true -legacy_gas_estimation = true +legacy_gas_estimation_percent = 130 # Zilliqa Mainnet # [[chain_configs]] diff --git a/bridge-validators/src/block.rs b/bridge-validators/src/block.rs index a65e0ca..daf95a3 100644 --- a/bridge-validators/src/block.rs +++ b/bridge-validators/src/block.rs @@ -3,33 +3,117 @@ use std::{marker::PhantomData, time::Duration}; use async_stream::try_stream; use async_trait::async_trait; -use anyhow::Result; +use anyhow::{anyhow, Result}; use ethers::{ providers::Middleware, - types::{BlockNumber, Filter, Log, U64}, + types::{Address, Block, BlockNumber, Filter, Log, TxHash, ValueOrArray, U64}, }; use ethers_contract::{parse_log, EthEvent}; use futures::{Stream, StreamExt, TryStreamExt}; use tokio::time::interval; use tracing::{debug, info, warn}; -use crate::client::ChainClient; +use crate::client::{ChainClient, LogStrategy}; #[async_trait] pub trait BlockPolling { + #[allow(dead_code)] async fn stream_finalized_blocks(&mut self) -> Result<()>; + #[allow(dead_code)] async fn get_historic_blocks(&self, from: u64, to: u64) -> Result<()>; - async fn get_events( - &self, - event: Filter, - from_block: BlockNumber, - to_block: BlockNumber, - ) -> Result> + async fn get_events(&self, event: Filter, from_block: u64, to_block: u64) -> Result> where D: EthEvent; } +impl ChainClient { + async fn get_logs_from_blocks(&self, event: Filter) -> Result> { + // Fetch transactions for all the blocks in Filter. + let mut result: Vec = Vec::new(); + let from_block: u64 = event + .get_from_block() + .ok_or(anyhow!( + "from_block is not present in get_logs_from_blocks()" + ))? + .as_u64(); + let to_block: u64 = event + .get_to_block() + .ok_or(anyhow!("to_block is not present in get_logs_from_blocks()"))? + .as_u64(); + for block_number in from_block..to_block + 1 { + // eth_GetBlockReceipts is as broken as eth_getLogs, so we need to check each transaction + // individually. Joy! + let the_block: Option> = + self.client.provider().get_block(block_number).await?; + if let Some(block) = the_block { + // go through all the transactions + for txn_hash in block.transactions { + // We have a transaction. Did it have any logs? + debug!("block {} txn {:#x}", block_number, txn_hash); + // Get the receipt + let maybe_receipt = self + .client + .provider() + .get_transaction_receipt(txn_hash) + .await?; + if let Some(receipt) = maybe_receipt { + // Yay! + info!("Got receipt for txn {:#x}", txn_hash); + for log in receipt.logs { + // Because FML, the filter doesn't actually include the address. + if log.address != self.chain_gateway_address { + info!( + "[1] event from {0:#x} != chain_gateway({1:#x})", + log.address, self.chain_gateway_address + ); + continue; + } + let mut matches: bool = true; + for topic_idx in 0..event.topics.len() { + if let Some(x) = &event.topics[topic_idx] { + if let Some(y) = &log.topics.get(topic_idx) { + let match_this_topic = match x { + ValueOrArray::Value(xv) => { + if let Some(xxv) = xv { + xxv == *y + } else { + true + } + } + ValueOrArray::Array(xvs) => xvs.iter().any(|cand| { + if let Some(xcand) = cand { + *xcand == **y + } else { + false + } + }), + }; + if !match_this_topic { + matches = false; + break; + } + } else { + matches = false; + break; + } + } + // If there's no filter element for this topic, we're fine. + } + if matches { + result.push(log); + } + } + } else { + warn!("WARNING: txn {:#x} has no receipt", txn_hash); + } + } + } + } + Ok(result) + } +} + #[async_trait] impl BlockPolling for ChainClient { async fn stream_finalized_blocks(&mut self) -> Result<()> { @@ -38,9 +122,7 @@ impl BlockPolling for ChainClient { async fn get_historic_blocks(&self, from: u64, to: u64) -> Result<()> { let concurrent_requests = futures::stream::iter( - (from..to) - .into_iter() - .map(|block_number| self.client.get_block(block_number)), + (from..to).map(|block_number| self.client.get_block(block_number)), ) .buffer_unordered(3) .map(|r| { @@ -54,38 +136,56 @@ impl BlockPolling for ChainClient { Ok(()) } - async fn get_events( - &self, - event: Filter, - from_block: BlockNumber, - to_block: BlockNumber, - ) -> Result> + async fn get_events(&self, event: Filter, from_block: u64, to_block: u64) -> Result> where D: EthEvent, { - let event = event.from_block(from_block).to_block(to_block); - - let logs: Vec = self - .client - .provider() - .request("eth_getLogs", [event]) - .await?; + let event = event + .from_block(from_block) + .to_block(to_block) + .address(self.chain_gateway_address); - let logs = logs - .into_iter() - .map(|log| { - // Parse log values - let mut log = log; - match log["removed"].as_str() { - Some("true") => log["removed"] = serde_json::Value::Bool(true), - Some("false") => log["removed"] = serde_json::Value::Bool(false), - Some(&_) => warn!("invalid parsing"), - None => (), - }; - let log: Log = serde_json::from_value(log)?; - Ok(log) - }) - .collect::>>()?; + let logs: Vec = match self.log_strategy { + LogStrategy::GetLogs => { + let logs: Vec = self + .client + .provider() + .request("eth_getLogs", [event]) + .await?; + logs.into_iter() + .filter(|log| { + log.get("address") + .and_then(|val| val.as_str()) + .and_then(|val| val.parse::
().ok()) + .map(|from_address| { + if from_address == self.chain_gateway_address { + true + } else { + info!( + "event from {0:#x} , chain gateway {1:#x}", + from_address, self.chain_gateway_address + ); + false + } + }) + .unwrap_or(false) + }) + .map(|log| { + // Parse log values + let mut log = log; + match log["removed"].as_str() { + Some("true") => log["removed"] = serde_json::Value::Bool(true), + Some("false") => log["removed"] = serde_json::Value::Bool(false), + Some(&_) => warn!("invalid parsing"), + None => (), + }; + let log: Log = serde_json::from_value(log)?; + Ok(log) + }) + .collect::>>()? + } + LogStrategy::GetTransactions => self.get_logs_from_blocks(event).await?, + }; let events: Vec = logs .into_iter() @@ -131,41 +231,54 @@ impl EventListener { where D: EthEvent, { + // Some chains (Zilliqa!) can't get it together to broadcast events at the block they are + // currently at, so there is an option to deliberately delay checking back a few blocks, + // until the node we are pointed at has the logs for the block and can therefore reply + // correctly. + let scan_behind_blocks = self.chain_client.scan_behind_blocks; let new_block: U64 = match self.get_block_number().await { Err(e) => { warn!(?e); let vec = Ok(vec![]); return vec; } - // Return early if smaller block - Ok(block) if block <= self.current_block => return Ok(vec![]), Ok(block) => block, }; + // Don't worry about blocks we've already scanned. + let min_block = self.current_block + 1; + // Don't worry about blocks which are too recent for us to care about. + let max_block = new_block - scan_behind_blocks; + if max_block <= min_block { + // No point in checking, return early + return Ok(vec![]); + } // `eth_getLogs`'s block_number is inclusive, so `current_block` is already retrieved let events = match self .chain_client - .get_events( - self.event.clone(), - (self.current_block + 1).into(), - new_block.into(), - ) + .get_events(self.event.clone(), min_block.as_u64(), max_block.as_u64()) .await { Err(err) => { + warn!( + "Failed to fetch events on {} from {} to {}", + self.chain_client, + (self.current_block + 1), + new_block + ); warn!(?err); vec![] } Ok(events) => events, }; - debug!( + info!( "{} Getting from {} to {}, events gathered {:?}", self.chain_client.chain_id, (self.current_block + 1), new_block, events.len(), ); - if events.len() > 0 { + if !events.is_empty() { info!( "Getting from {} to {}, events gathered {:?}", (self.current_block + 1), @@ -183,7 +296,9 @@ impl EventListener { let stream = try_stream! { // TODO: update block interval on config let mut interval = interval(Duration::from_secs(3)); - self.current_block = self.chain_client.client.get_block_number().await?; + // Set this down 1 because we (almost) certainly haven't scanned this block + // yet... + self.current_block = self.chain_client.client.get_block_number().await? - 1; loop { interval.tick().await; diff --git a/bridge-validators/src/bridge_node.rs b/bridge-validators/src/bridge_node.rs index a9a0041..24233d7 100644 --- a/bridge-validators/src/bridge_node.rs +++ b/bridge-validators/src/bridge_node.rs @@ -69,7 +69,7 @@ impl BridgeNode { async fn get_historic_events( &self, event: Event, Client, D>, - to_block: BlockNumber, + to_block: u64, ) -> Result> where D: EthEvent, @@ -91,7 +91,10 @@ impl BridgeNode { } else { BlockNumber::Finalized }; - info!("Getting Historic Events {}", to_block); + info!( + "Getting Historic Events for chainId#{}: {}", + self.chain_client.chain_id, to_block + ); let to_block_number = self .chain_client @@ -109,10 +112,10 @@ impl BridgeNode { let dispatch_events = self .get_historic_events( chain_gateway.event::(), - BlockNumber::Number(to_block_number.into()), + to_block_number.as_u64(), ) .await?; - dbg!(dispatch_events.len()); + info!(" .. dispatch_events: {}", dispatch_events.len()); for dispatch in dispatch_events { self.handle_dispatch_event(dispatch)?; @@ -121,21 +124,21 @@ impl BridgeNode { let relay_events = self .get_historic_events( chain_gateway.event::(), - BlockNumber::Number(to_block_number.into()), + to_block_number.as_u64(), ) .await?; - dbg!(relay_events.len()); + info!(" .. relay_events: {}", relay_events.len()); for relay in relay_events { self.handle_relay_event(relay)?; } - unimplemented!(); + Ok(()) } pub async fn listen_events(&mut self) -> Result<()> { - println!("Start Listening: {:?}", self.chain_client.chain_id); + info!("Start Listening: {:?}", self.chain_client.chain_id); let chain_gateway: ChainGateway = self.chain_client.get_contract(); @@ -218,11 +221,6 @@ impl BridgeNode { return Ok(()); } - info!( - "Chain: {} event found to be broadcasted: {}", - self.chain_client.chain_id, event - ); - if let Some(RelayEventSignatures { dispatched: true, .. }) = self.event_signatures.get(&event.nonce) @@ -286,7 +284,7 @@ impl BridgeNode { let Relay { signature, event } = echo; let nonce = event.nonce; let event_hash = event.hash(); - + info!("handling relay {:?}", echo); let signature = Signature::try_from(signature.to_vec().as_slice())?; // update validator set in case it has changed @@ -337,9 +335,11 @@ impl BridgeNode { }; info!( - "Handling received: {:?}, collected: {:?}", + "Handling received: {:?}, collected: {:?}, is_leader {:?}, has_supermajority {:?}", &echo, - event_signatures.signatures.len() + event_signatures.signatures.len(), + self.is_leader, + self.has_supermajority(event_signatures.signatures.len()) ); // if leader and majority, create request to dispatch diff --git a/bridge-validators/src/client.rs b/bridge-validators/src/client.rs index 69d8976..65009b5 100644 --- a/bridge-validators/src/client.rs +++ b/bridge-validators/src/client.rs @@ -8,11 +8,21 @@ use ethers::{ signers::{LocalWallet, Signer}, types::{Address, U256}, }; +use std::fmt; +use tracing::info; use crate::ChainConfig; pub type Client = NonceManagerMiddleware, LocalWallet>>; +#[derive(Debug, Clone)] +pub enum LogStrategy { + // use eth_getLogs() + GetLogs, + // scan every transaction individually + GetTransactions, +} + #[derive(Debug, Clone)] pub struct ChainClient { pub client: Arc, @@ -22,25 +32,43 @@ pub struct ChainClient { pub wallet: LocalWallet, pub chain_gateway_block_deployed: u64, pub block_instant_finality: bool, - pub legacy_gas_estimation: bool, + pub legacy_gas_estimation_percent: Option, + pub scan_behind_blocks: u64, + pub log_strategy: LogStrategy, +} + +impl fmt::Display for ChainClient { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "chainid#{}", self.chain_id) + } } impl ChainClient { pub async fn new(config: &ChainConfig, wallet: LocalWallet) -> Result { + info!( + "initialising chain client for URL {0} with gateway {1:#x} ... ", + config.rpc_url.as_str(), + config.chain_gateway_address + ); let provider = Provider::::try_from(config.rpc_url.as_str())?; // let provider = Provider::::connect(&config.rpc_url).await?; let chain_id = provider.get_chainid().await?; - let client: Arc = Arc::new( provider .with_signer(wallet.clone().with_chain_id(chain_id.as_u64())) .nonce_manager(wallet.address()), ); - // TODO: get the validator_manager_address from chain_gateway itself let chain_gateway = ChainGateway::new(config.chain_gateway_address, client.clone()); let validator_manager_address: Address = chain_gateway.validator_manager().call().await?; - + let strategy = match config.use_get_transactions { + None => LogStrategy::GetLogs, + Some(v) => match v { + false => LogStrategy::GetLogs, + true => LogStrategy::GetTransactions, + }, + }; + info!("... success!"); Ok(ChainClient { client, validator_manager_address, @@ -49,7 +77,9 @@ impl ChainClient { wallet, chain_gateway_block_deployed: config.chain_gateway_block_deployed, block_instant_finality: config.block_instant_finality.unwrap_or_default(), - legacy_gas_estimation: config.legacy_gas_estimation.unwrap_or_default(), + legacy_gas_estimation_percent: config.legacy_gas_estimation_percent, + scan_behind_blocks: config.scan_behind_blocks.unwrap_or_default(), + log_strategy: strategy, }) } } diff --git a/bridge-validators/src/main.rs b/bridge-validators/src/main.rs index 7df8db4..de381c8 100644 --- a/bridge-validators/src/main.rs +++ b/bridge-validators/src/main.rs @@ -31,7 +31,9 @@ pub struct ChainConfig { pub chain_gateway_address: Address, pub chain_gateway_block_deployed: u64, pub block_instant_finality: Option, - pub legacy_gas_estimation: Option, + pub legacy_gas_estimation_percent: Option, + pub scan_behind_blocks: Option, + pub use_get_transactions: Option, } #[derive(Debug, Clone, Deserialize)] @@ -49,6 +51,8 @@ struct Args { config_file: PathBuf, #[clap(long)] is_leader: bool, + #[clap(long)] + dispatch_history: bool, } #[tokio::main] @@ -77,8 +81,7 @@ async fn main() -> Result<()> { bootstrap_address: config.bootstrap_address, }; - let mut node = P2pNode::new(args.secret_key, config).await?; - + let mut node = P2pNode::new(args.secret_key, config, args.dispatch_history).await?; node.start().await?; Ok(()) diff --git a/bridge-validators/src/message.rs b/bridge-validators/src/message.rs index 5ec74f3..a51c8d7 100644 --- a/bridge-validators/src/message.rs +++ b/bridge-validators/src/message.rs @@ -17,6 +17,7 @@ pub enum ExternalMessage { } impl ExternalMessage { + #[allow(dead_code)] pub fn name(&self) -> &'static str { match self { ExternalMessage::BridgeEcho(_) => "BridgeEcho", diff --git a/bridge-validators/src/p2p_node.rs b/bridge-validators/src/p2p_node.rs index 0eff790..63cd31e 100644 --- a/bridge-validators/src/p2p_node.rs +++ b/bridge-validators/src/p2p_node.rs @@ -1,18 +1,15 @@ // ! taken from ZQ2 //! A node in the Zilliqa P2P network. May coordinate multiple shard nodes. -use anyhow::{anyhow, Result}; +use anyhow::Result; use libp2p::{ - core::upgrade, futures::StreamExt, - gossipsub::{self, IdentTopic, MessageAuthenticity}, + gossipsub::{self}, identify, kad::{self, store::MemoryStore}, mdns, - multiaddr::Multiaddr, - noise, - swarm::{self, NetworkBehaviour, SwarmEvent}, - tcp, yamux, PeerId, Swarm, Transport, + swarm::NetworkBehaviour, + PeerId, }; use tokio::{ select, @@ -20,7 +17,7 @@ use tokio::{ task::JoinHandle, }; use tokio_stream::wrappers::UnboundedReceiverStream; -use tracing::{debug, error, info}; +use tracing::{error, info}; use crate::{ crypto::SecretKey, @@ -29,6 +26,7 @@ use crate::{ }; #[derive(NetworkBehaviour)] +#[allow(unused)] struct Behaviour { gossipsub: gossipsub::Behaviour, mdns: mdns::tokio::Behaviour, @@ -42,6 +40,7 @@ pub struct P2pNode { /// Forward messages to the bridge validators. Only initialised once BridgeNode is created bridge_inbound_message_sender: UnboundedSender, /// Bridge nodes get a copy of these senders to propagate messages across the network. + #[allow(dead_code)] bridge_outbound_message_sender: UnboundedSender, /// The p2p node keeps a handle to these receivers, to obtain messages from bridge nodes and propagate /// them as necessary. @@ -50,7 +49,11 @@ pub struct P2pNode { } impl P2pNode { - pub async fn new(secret_key: SecretKey, config: ValidatorNodeConfig) -> Result { + pub async fn new( + secret_key: SecretKey, + config: ValidatorNodeConfig, + dispatch_history: bool, + ) -> Result { let (bridge_outbound_message_sender, bridge_outbound_message_receiver) = mpsc::unbounded_channel(); let bridge_outbound_message_receiver = @@ -93,10 +96,14 @@ impl P2pNode { // let topic = IdentTopic::new("bridge"); // TODO: change to more specific bridge chains // self.swarm.behaviour_mut().gossipsub.subscribe(&topic)?; - // Initialise bridge node - let mut validator_node = - ValidatorNode::new(config, bridge_outbound_message_sender.clone()).await?; + + let mut validator_node = ValidatorNode::new( + config, + bridge_outbound_message_sender.clone(), + dispatch_history, + ) + .await?; let bridge_inbound_message_sender = validator_node.get_bridge_inbound_message_sender(); @@ -137,8 +144,6 @@ impl P2pNode { // self.swarm.listen_on(addr)?; - println!("Started"); - loop { select! { // event = self.swarm.select_next_some() => match event { @@ -186,8 +191,8 @@ impl P2pNode { // }, message = self.bridge_outbound_message_receiver.next() => { let message = message.expect("message stream should be infinite"); - let message_type = message.name(); - let data = serde_json::to_vec(&message).unwrap(); + // let message_type = message.name(); + // let data = serde_json::to_vec(&message).unwrap(); let from = self.peer_id; // let topic = IdentTopic::new("bridge"); @@ -214,10 +219,12 @@ impl P2pNode { Ok(Ok(())) => unreachable!(), Ok(Err(e)) => { error!(%e); + #[allow(clippy::useless_conversion)] return Err(e.into()) } Err(e) =>{ error!(%e); + #[allow(clippy::useless_conversion)] return Err(e.into()) } } diff --git a/bridge-validators/src/validator_node.rs b/bridge-validators/src/validator_node.rs index 6da4f0b..9e382db 100644 --- a/bridge-validators/src/validator_node.rs +++ b/bridge-validators/src/validator_node.rs @@ -27,6 +27,7 @@ pub struct ValidatorNodeConfig { pub chain_configs: Vec, pub private_key: SecretKey, pub is_leader: bool, + #[allow(dead_code)] pub bootstrap_address: Option<(PeerId, Multiaddr)>, } @@ -47,18 +48,16 @@ impl ValidatorNode { pub async fn new( config: ValidatorNodeConfig, bridge_outbound_message_sender: UnboundedSender, + dispatch_history: bool, ) -> Result { let mut chain_node_senders = HashMap::new(); let mut chain_clients = HashMap::new(); let wallet = config.private_key.as_wallet()?; println!("Node address is: {:?}", wallet.address()); - let (bridge_message_sender, bridge_message_receiver) = mpsc::unbounded_channel(); let bridge_message_receiver = UnboundedReceiverStream::new(bridge_message_receiver); - let mut bridge_node_threads: JoinSet> = JoinSet::new(); - for chain_config in config.chain_configs { let chain_client = ChainClient::new(&chain_config, wallet.clone()).await?; @@ -72,12 +71,12 @@ impl ValidatorNode { validator_chain_node.chain_client.chain_id, validator_chain_node.get_inbound_message_sender(), ); - chain_clients.insert(validator_chain_node.chain_client.chain_id, chain_client); - bridge_node_threads.spawn(async move { // Fill all historic events first - // validator_chain_node.sync_historic_events().await + if dispatch_history { + validator_chain_node.sync_historic_events().await?; + } // Then start listening to new ones validator_chain_node.listen_events().await }); @@ -140,10 +139,12 @@ impl ValidatorNode { Ok(Ok(())) => unreachable!(), Ok(Err(e)) => { error!(%e); + #[allow(clippy::useless_conversion)] return Err(e.into()) } Err(e) =>{ error!(%e); + #[allow(clippy::useless_conversion)] return Err(e.into()) } } @@ -180,7 +181,7 @@ impl ValidatorNode { event.target_chain_id, event.nonce ); - let function_call = if client.legacy_gas_estimation { + let function_call = if client.legacy_gas_estimation_percent.is_some() { function_call.legacy() } else { function_call @@ -191,7 +192,7 @@ impl ValidatorNode { // Get gas estimate // TODO: refactor configs specifically for zilliqa - let _function_call = if client.legacy_gas_estimation { + let _function_call = if let Some(percent) = client.legacy_gas_estimation_percent { let gas_estimate = match function_call.estimate_gas().await { Ok(estimate) => estimate, Err(err) => { @@ -199,8 +200,8 @@ impl ValidatorNode { return Ok(()); } }; - info!("Gas estimate {:?}", gas_estimate); - function_call.clone().gas(gas_estimate * 130 / 100) // Apply multiplier + info!("Legacy gas estimation: estimate {:?}", gas_estimate); + function_call.clone().gas(gas_estimate * percent / 100) // Apply multiplier } else { let function_call = function_call.clone(); // `eth_call` does not seem to work on ZQ so it had to be skipped @@ -231,7 +232,7 @@ impl ValidatorNode { // Make the actual call match _function_call.send().await { Ok(tx) => { - println!( + info!( "Transaction Sent {}.{} {:?}", event.target_chain_id, event.nonce, From b6eb330faf949fb174f7741328822f64871b4de5 Mon Sep 17 00:00:00 2001 From: Richard Watts Date: Fri, 30 Aug 2024 18:02:41 +0100 Subject: [PATCH 2/4] (feat) Zilbridge compatibility contracts. (feat) Documentation for zilbridge compatibility contracts. (feat) Scilla deployment scripts for zilbridge compatibility contracts. --- docs/test_1a000b82.md | 16 + docs/todo.md | 14 + docs/zilbridge.md | 292 + docs/zilbridge_test_template.md | 16 + scilla-contracts/.gitignore | 17 + scilla-contracts/README.md | 15 + .../contracts/FungibleToken.scilla | 195 + .../contracts/ScillaConnector.sol | 238 + .../contracts/SwitcheoTokenZRC2.scilla | 373 + .../contracts/ZRC2ProxyForZRC2.sol | 116 + scilla-contracts/hardhat.config.js | 24 + scilla-contracts/hardhat.config.ts | 25 + scilla-contracts/ignition/modules/Lock.js | 14 + scilla-contracts/ignition/modules/Lock.ts | 17 + scilla-contracts/package-lock.json | 8113 +++++++++++++++++ scilla-contracts/package.json | 19 + scilla-contracts/pnpm-lock.yaml | 4449 +++++++++ scilla-contracts/scripts/debug.ts | 32 + scilla-contracts/scripts/deploy.ts | 68 + scilla-contracts/scripts/transfer.ts | 28 + scilla-contracts/tsconfig.json | 11 + smart-contracts/README.md | 5 + .../LockProxyTokenManagerStorage.sol | 38 + .../LockProxyTokenManagerUpgradeable.sol | 54 + ...leaseOrNativeTokenManagerUpgradeableV3.sol | 82 + .../LockProxyTokenManagerUpgradeableV3.sol | 77 + .../ZilBridge/ccmCrossChainManager.sol | 1618 ++++ .../ZilBridge/ccmExtendCrossChainManager.sol | 72 + .../script/bsc-testnet/bridgeTokens.s.sol | 9 +- .../script/bsc-testnet/deployBridge.s.sol | 9 +- .../bsc-testnet/deployBridgeToken.s.sol | 11 +- .../bsc-testnet/deployCoreUpgradeable.s.sol | 9 +- .../bsc-testnet/deployMockZilBridge.s.sol | 46 + .../deployXBridgeOverMockZilBridge.s.sol | 39 + .../deployZilBridgeTokenManagers.s.sol | 53 + .../bsc-testnet/deployZilBridgeTokens.s.sol | 50 + .../script/bsc-testnet/pauseBridge.s.sol | 22 +- .../setChainGatewayOnTokenManager.s.sol | 7 +- .../bsc-testnet/setZilBridgeRouting.s.sol | 58 + .../script/bsc-testnet/unpauseBridge.s.sol | 33 +- .../bsc-testnet/upgradeTokenManagerV2.s.sol | 5 +- .../bsc-testnet/upgradeTokenManagerV3.s.sol | 5 +- .../bsc-testnet/zilBridgeTransferERC20.s.sol | 24 + smart-contracts/script/config.ts | 4 + smart-contracts/script/testnetConfig.s.sol | 52 + .../script/zq-testnet/bridgeTokens.s.sol | 9 +- .../zq-testnet/deployChainGateway.s.sol | 7 +- .../zq-testnet/deployCoreUpgradeable.s.sol | 11 +- .../deployNativeTokenManagerV3.s.sol | 42 + .../zq-testnet/deployTokenManager.s.sol | 8 +- .../script/zq-testnet/deployZRC2ERC20.s.sol | 35 + .../script/zq-testnet/dispatchRelay.s.sol | 6 +- .../script/zq-testnet/pauseBridge.s.sol | 37 +- .../script/zq-testnet/registerToken.s.sol | 5 +- .../setChainGatewayOnTokenManager.s.sol | 21 +- .../zq-testnet/setZilBridgeRouting.s.sol | 57 + .../script/zq-testnet/unpauseBridge.s.sol | 34 +- .../zq-testnet/upgradeTokenManagerV2.s.sol | 5 +- .../zq-testnet/upgradeTokenManagerV3.s.sol | 5 +- .../script/zq-testnet/zilBridgeDebug.s.sol | 39 + .../zq-testnet/zilBridgeTransferERC20.s.sol | 22 + .../test/periphery/TokenBridge.native.t.sol | 225 + ...AndReleaseOrNativeTokenManagerDeployer.sol | 36 + .../test/zilbridge/DeployZilBridge.t.sol | 124 + .../test/zilbridge/MockLockProxy.sol | 311 + .../test/zilbridge/TestingLockProxy.sol | 1896 ++++ .../LockProxyTokenManagerDeployer.sol | 34 + .../ZilBridgeTokenBridge.compat.t.sol | 224 + .../ZilBridgeTokenBridge.integration.t.sol | 240 + .../ZilBridgeTokenIntegrationFixture.t.sol | 152 + .../test/zilbridge/ZilBridgeTransfer.t.sol | 19 + .../ccmExtendCrossChainManager.t.sol | 79 + .../infrastructure/ccmCrossChainManager.sol | 1618 ++++ .../zilbridge/infrastructure/ccmProxy.sol | 265 + .../infrastructure/ethCrossChainData.sol | 316 + .../zilbridge/infrastructure/lockProxy.sol | 1884 ++++ .../zilbridge/tokens/switcheo/libs/LICENSE | 22 + .../zilbridge/tokens/switcheo/libs/README.md | 3 + .../tokens/switcheo/libs/math/SafeMath.sol | 152 + .../switcheo/libs/token/ERC20/ERC20.sol | 230 + .../libs/token/ERC20/ERC20Detailed.sol | 54 + .../switcheo/libs/token/ERC20/IERC20.sol | 77 + .../switcheo/tokens/SwitcheoTokenETH.sol | 48 + .../tokens/zrc2erc20/ScillaConnector.sol | 238 + .../tokens/zrc2erc20/ZRC2ProxyForZRC2.sol | 116 + 85 files changed, 25109 insertions(+), 71 deletions(-) create mode 100644 docs/test_1a000b82.md create mode 100644 docs/todo.md create mode 100644 docs/zilbridge.md create mode 100644 docs/zilbridge_test_template.md create mode 100644 scilla-contracts/.gitignore create mode 100644 scilla-contracts/README.md create mode 100644 scilla-contracts/contracts/FungibleToken.scilla create mode 100644 scilla-contracts/contracts/ScillaConnector.sol create mode 100644 scilla-contracts/contracts/SwitcheoTokenZRC2.scilla create mode 100644 scilla-contracts/contracts/ZRC2ProxyForZRC2.sol create mode 100644 scilla-contracts/hardhat.config.js create mode 100644 scilla-contracts/hardhat.config.ts create mode 100644 scilla-contracts/ignition/modules/Lock.js create mode 100644 scilla-contracts/ignition/modules/Lock.ts create mode 100644 scilla-contracts/package-lock.json create mode 100644 scilla-contracts/package.json create mode 100644 scilla-contracts/pnpm-lock.yaml create mode 100644 scilla-contracts/scripts/debug.ts create mode 100644 scilla-contracts/scripts/deploy.ts create mode 100644 scilla-contracts/scripts/transfer.ts create mode 100644 scilla-contracts/tsconfig.json create mode 100644 smart-contracts/contracts/periphery/LockProxyTokenManagerStorage.sol create mode 100644 smart-contracts/contracts/periphery/LockProxyTokenManagerUpgradeable.sol create mode 100644 smart-contracts/contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol create mode 100644 smart-contracts/contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol create mode 100644 smart-contracts/contracts/periphery/ZilBridge/ccmCrossChainManager.sol create mode 100644 smart-contracts/contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol create mode 100644 smart-contracts/script/bsc-testnet/deployMockZilBridge.s.sol create mode 100644 smart-contracts/script/bsc-testnet/deployXBridgeOverMockZilBridge.s.sol create mode 100644 smart-contracts/script/bsc-testnet/deployZilBridgeTokenManagers.s.sol create mode 100644 smart-contracts/script/bsc-testnet/deployZilBridgeTokens.s.sol create mode 100644 smart-contracts/script/bsc-testnet/setZilBridgeRouting.s.sol create mode 100644 smart-contracts/script/bsc-testnet/zilBridgeTransferERC20.s.sol create mode 100644 smart-contracts/script/testnetConfig.s.sol create mode 100644 smart-contracts/script/zq-testnet/deployNativeTokenManagerV3.s.sol create mode 100644 smart-contracts/script/zq-testnet/deployZRC2ERC20.s.sol create mode 100644 smart-contracts/script/zq-testnet/setZilBridgeRouting.s.sol create mode 100644 smart-contracts/script/zq-testnet/zilBridgeDebug.s.sol create mode 100644 smart-contracts/script/zq-testnet/zilBridgeTransferERC20.s.sol create mode 100644 smart-contracts/test/periphery/TokenBridge.native.t.sol create mode 100644 smart-contracts/test/periphery/TokenManagerDeployers/LockAndReleaseOrNativeTokenManagerDeployer.sol create mode 100644 smart-contracts/test/zilbridge/DeployZilBridge.t.sol create mode 100644 smart-contracts/test/zilbridge/MockLockProxy.sol create mode 100644 smart-contracts/test/zilbridge/TestingLockProxy.sol create mode 100644 smart-contracts/test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol create mode 100644 smart-contracts/test/zilbridge/ZilBridgeTokenBridge.compat.t.sol create mode 100644 smart-contracts/test/zilbridge/ZilBridgeTokenBridge.integration.t.sol create mode 100644 smart-contracts/test/zilbridge/ZilBridgeTokenIntegrationFixture.t.sol create mode 100644 smart-contracts/test/zilbridge/ZilBridgeTransfer.t.sol create mode 100644 smart-contracts/test/zilbridge/ccmExtendCrossChainManager.t.sol create mode 100644 smart-contracts/test/zilbridge/infrastructure/ccmCrossChainManager.sol create mode 100644 smart-contracts/test/zilbridge/infrastructure/ccmProxy.sol create mode 100644 smart-contracts/test/zilbridge/infrastructure/ethCrossChainData.sol create mode 100644 smart-contracts/test/zilbridge/infrastructure/lockProxy.sol create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/libs/LICENSE create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/libs/README.md create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/libs/math/SafeMath.sol create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20.sol create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20Detailed.sol create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/IERC20.sol create mode 100644 smart-contracts/test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol create mode 100644 smart-contracts/test/zilbridge/tokens/zrc2erc20/ScillaConnector.sol create mode 100644 smart-contracts/test/zilbridge/tokens/zrc2erc20/ZRC2ProxyForZRC2.sol diff --git a/docs/test_1a000b82.md b/docs/test_1a000b82.md new file mode 100644 index 0000000..1fb4651 --- /dev/null +++ b/docs/test_1a000b82.md @@ -0,0 +1,16 @@ +# Test run for 1a000b82 + +Test cases: + +| Number | Token | From | To | Result | Remarks | +| ------ | ----- | ---- | --- | ------ | ------- | +| IT001 | xTST | BSC | ZQ | Pass | | +| IT002 | xTST | ZQ | BSC | Pass | | +| IT003 | ZBTST | ZQ | BSC | Pass | | +| IT004 | ZBTST | BSC | ZQ | Pass | | +| IT005 | zBNB | BSC | ZQ | Pass | | +| IT006 | zBNB | ZQ | BSC | Pass | | +| IT007 | eZIL | ZQ | BSC | Pass | | +| IT008 | eZIL | BSC | ZQ | Pass | | + +Result is Pass/Fail/Other. diff --git a/docs/todo.md b/docs/todo.md new file mode 100644 index 0000000..994b00b --- /dev/null +++ b/docs/todo.md @@ -0,0 +1,14 @@ +# TODOs + +1. Refactor SafeMath out of all the zilbridge takeover contracts; less + conformant, but it's the default in 0.8.x and above. + +2. The validator should check whether the transaction it proxied ran + out of gas (meter the gas used by the subtransaction and if the + subtxn failed and it has < 15/16, say, gas left, it probably ran + out - try again with more gas). + +3. We don't cope well when (as quite often happens) a chain (usually BSC) + simply never confirms receipt of a transaction and we need to send it + again (or just assume it succeeded, because although it has run, the + chain isn't prepared to tell us this). diff --git a/docs/zilbridge.md b/docs/zilbridge.md new file mode 100644 index 0000000..a33f265 --- /dev/null +++ b/docs/zilbridge.md @@ -0,0 +1,292 @@ +# Zilbridge/XBridge integration + +Note that this work was done referencing the ZilBridge 1 contracts +available on Ethereum Mainnet (which have been verified - hence the +rather horrid source). + +Other contracts on the other correspondent chains of ZilBridge are +only patchily verified, and the ones that are verified are different +from those on Ethereum; the same approach should work, but I can't +guarantee it. Proceed with caution. + +## CrossChainManager extensions + +The currently deployed CCM on Ethereum does not contain functions to +register lockProxy extensions. + +These can be run remotely from the `counterpartChainId` (in +`lockProxy`), currently set to 5 (which is presumably Carbon). + +This means we need to either proxy or replace it. + +Replacing it is undesirable, because the address of the CCM is baked +into the configuration files for the relayers. + +My first attempt was to proxy it with a `CCMExtendProxy`, but this +doesn't work, because: + +- To upgrade you have to call `ccmProxy::upgradeEthCrossChainManager()` +- (side-note: this calls the _current_ `eccm.upgradeToNew()` which + hands ownership of the CCM data (proxied by the CCM contract) to + the CCMExtendProxty, which now needs to hand it back to the old + `ccm`) +- Subsequent calls through the `CCMExtendProxy` need to use the + original `ccm` state, and therefore have the `CCMExtendProxy` as + `msg.sender`. +- But there is no way to make the `CCMExtendProxy` an owner of the + `ccm`. + +The second attempt is to write a new CCM contract which duplicates the +original CCM and contains the new functions. Sadly, this means that +someone needs to remember what the whitelist parameters were, because +it is a map that does not emit events and we thus can't work out what +is in it. + +If we have the ability to register extensions directly over the +bridge, then all the faff with `CCMExtendProxy` is unnecessary and we +can directly register `LockProxyTokenManager` as an extension. + +If we do have to use `CCMExtendProxy`, it might be wise to remove the +bridge functions for release, to exclude any bugs in them from our +security perimeter. + +We'll have to discuss this when we come to migrate ZilBridge. + +## LockProxyTokenManager + +There is a `LockProxyTokenManager` which is registered as an extension +and interacts with the lock proxy to bridge tokens. + +zilBridge itself doesn't know which tokens are mint/burn and which are +lock/release - the lockproxy simply transfers tokens to and from +itself and the contracts it talks to either mint and burn, or don't, +when they spot that it's the lock proxy asking. + +We test it against a stubbed out LockProxyTokenManager which apes what the +Scilla side will do eventually, but with stubbed interop calls. + +## Current outstanding issues + +### Parallel ZilBridge operations + +If we can't get someone (Polynet?) to install our extension remotely, +we will have to replace the non-Zilliqa `ccm` and this will break +ZilBridge. Polynet will have to reset their `ccm` address to recover +functionality. + +If we do replace the non-Zilliqa `ccm`, I suggest that we do so with a +CCM that doesn't accept cross-chain events; this will make sure that +old keys from zilbridge/polynet can't compromise us in the future. + +## Testnet Deployment with Zilliqa Testnet and BSC testnet + +There are a group of scripts that allow you to deploy the EVM half of +the ZilBridge transition code into BSC Testnet. + +The `smart-contracts/README.md` contains predeployed addresses; if you +decide to redeploy you will need to change the constants in the ` +scripts, since this is how the addresses of previous contracts are +baked in (sorry!). + +Set `PRIVATE_KEY_TESTNET` to the validator privkey, and +`PRIVATE_KEY_ZILBRIDGE` to the zilbridge owner privkey. + +After each step (each script run) in the below, you will need to: + +- Verify the contracts you just deployed. +- Update the `testnet_config.s.sol` file with the addresses of the + contracts you just deployed. + +In most cases, the script will give you the name of the +`testnet_config.s.sol` constant to update. + +Run with: + +```sh +forge script script/bsc-testnet/deployMockZilBridge.s.sol \ + --rpc-url https://bsc-testnet.bnbchain.org --broadcast + +forge verify-contract
--rpc-url https://bsc-testnet.bnbchain.org \ + --chain-id 97 +# Now fill in the data to test_config.s.sol +forge script script/bsc-testnet/deployXBridgeOverMockZilBridge.s.sol \ + --rpc-url https://bsc-testnet.bnbchain.org --broadcast +forge verify-contract
--rpc-url https://bsc-testnet.bnbchain.org \ + --chain-id 97 +# and again .. +forge script scripts/bsc-testnet/deployZilBridgeTokenManagers.s.sol \ + --rpc-url https://bsc-testnet.bnbchain.org --broadcast +forge verify-contract
--rpc-url https://bsc-testnet.bnbchain.org \ + --chain-id 97 + +``` + +Remember to verify all your contracts on BSC, or you will get +hopelessly confused later. + +Now we need to deploy some contracts on the Zilliqa testnet. You can +verify on Zilliqa via sourcify: + +```sh +forge verify-contract
--rpc-url https://dev-api.zilliqa.com \ + --chain-id 33101 --verifier sourcify +``` + +We'll need our own token manager. This is identical to the +`LockAndReleaseTokenManager`, but contains some additional +functionality to deal with bridging native tokens (so that bridged ZIL +can be made to work). + +```sh +forge script script/zq-testnet/deployNativeTokenManagerV3.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +forge script script/zq-testnet/setChainGatewayOnTokenManager.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +``` + +Now we can deploy some contracts to the BNB testnet: + +```sh +forge script script/bsc-testnet/deployZilBridgeTokens.s.sol \ + --tc Deployment --rpc-url https://bsc-testnet.bnbchain.org \ + --broadcast +forge verify-contract
--rpc-url https://bsc-testnet.bnbchain.org \ + --chain-id 97 +``` + +And the corresponding tokens to the Zilliqa testnet: + +```sh +cd scilla-contracts +pnpm i +export TOKEN_MANAGER_ADDRESS=(value of zq_lockAndReleaseOrNativeTokenManager) +# NOW EDIT scripts/deploy.ts for the address of the Zilliqa testnet token manager. +npx hardhat run scripts/deploy.ts --network zq_testnet +``` + +And now we ship an ERC20 proxy for our ZRC2 and switcheo tokens. + +```sh +forge script script/zq-testnet/deployZRC2ERC20.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +``` + +And now we can set up routing for the tokens we just deployed. This is +"just" calls, so + +```sh +forge script script/bsc-testnet/setZilBridgeRouting.s.sol \ + --rpc-url https://bsc-testnet.bnbchain.org --broadcast +forge script script/zq-testnet/setZilBridgeRouting.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +``` + +### Testing + +The CI/CD'd testnet relayer will work for you. + +You can run the web interface with the instructions in [bridge-web/README.md](bridge-web/README.md). + +To avoid running into CORS problems, you will need to: + +```sh +export VITE_BSC_TESTNET_API=http://localhost:6128 +export VITE_BSC_TESTNET_KEY="" +``` + +Remember to omit the trailing '/' from `VITE_BSC_TESTNET_API` or you +will get CORS errors. + +And run: + +```sh +mitmweb --mode reverse:https://data-seed-prebsc-1-s1.binance.org:8545/ \ + --no-web-open-browser --listen-port 6128 --web-port 6001 +``` + +Put the token and token manager addresses from `testnet_config.s.sol` +into `bridge-web/src/config/config.ts` . + +You can transfer yourself some tokens by setting +`ZILBRIDGE_TEST_ADDRESS` and `ZILBRIDGE_TEST_AMOUNT` and running: + +```sh +forge script script/bsc-testnet/zilBridgeTransferERC20.s.sol \ + --rpc-url https://bsc-testnet.bnbchain.org --broadcast +``` + +And, setting `ZILBRIDGE_SCILLA_TOKEN_ADDRESS` to the Scilla token address: + +```sh +npx hardhat run scripts/transfer.ts +``` + +The ZQ transfer needs to be ZRC-2 because the initial funds holder is +the Zilliqa account associated with `PRIVATE_KEY_ZILBRIDGE` and we +therefore need a Scilla transition to transfer them. + +There is a test case template in +`docs/zilbridge_test_template.md`. Copy it for your commit and fill it +in. + +### Debugging from-zilliqa transfers + +Since Zilliqa testnet doesn't support tracing, this is done by +bisection. You only need one way, since we only care about the sending +txn working. + +- Redeploy the token manager on ZQ: + +```sh +forge script script/zq-testnet/deployNativeTokenManagerV3.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy + +forge script script/zq-testnet/setChainGatewayOnTokenManager.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +forge verify-contract
--rpc-url https://dev-api.zilliqa.com \ + --chain-id 33101 +``` + +Now write some routing - it actually doesn't matter that the routing +gets messed up, because we're only testing Zilliqa ZRC2 out, and the +native ZRC2 doesn't care what the token manager is: + +```sh +forge script script/zq-testnet/setZilBridgeRouting.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +``` + +- Run `transfer.ts` to transfer some `ZBTEST` to the wallet you want to test. +- List the new token manager in `config.ts` in `bridge-web` + +Now you can send a `transfer()` request and see if it works .. you'll +need to redeploy the test token contracts and rerun routing setup +(from both sides!) to fix the bridge when the bugs are sorted. + +When you're done, you'll need to redeploy the rest of the tokens, so +that the bridged ZRC2 has the right token manager set, then set up +routing again: + +```sh +cd scilla-contracts +pnpm i +export TOKEN_MANAGER_ADDRESS=(value of + zq_lockAndReleaseOrNativeTokenManager WITHOUT 0x prefix) + +# NOW EDIT scripts/deploy.ts for the address of the +# Zilliqa testnet token manager. +npx hardhat run scripts/deploy.ts --network zq_testnet +``` + +Remember to update `testnet_config.sol`, then: + +```sh +forge script script/zq-testnet/deployZRC2ERC20.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +forge script script/bsc-testnet/setZilBridgeRouting.s.sol \ + --rpc-url https://bsc-testnet.bnbchain.org --broadcast +forge script script/zq-testnet/setZilBridgeRouting.s.sol \ + --rpc-url https://dev-api.zilliqa.com --broadcast --legacy +``` + +And you can now get testing again. diff --git a/docs/zilbridge_test_template.md b/docs/zilbridge_test_template.md new file mode 100644 index 0000000..1338022 --- /dev/null +++ b/docs/zilbridge_test_template.md @@ -0,0 +1,16 @@ +# Test run for 3aa537f4e + +Test cases: + +| Number | Token | From | To | Result | Remarks | +| ------ | ----- | ---- | --- | ------ | ------- | +| IT001 | xTST | BSC | ZQ | Pass | | +| IT002 | xTST | ZQ | BSC | Pass | | +| IT003 | ZBTST | ZQ | BSC | | | +| IT004 | ZBTST | BSC | ZQ | | | +| IT005 | zBNB | BSC | ZQ | | | +| IT006 | zBNB | ZQ | BSC | | | +| IT007 | eZIL | ZQ | BSC | | | +| IT008 | eZIL | BSC | ZQ | | | + +Result is Pass/Fail/Other. diff --git a/scilla-contracts/.gitignore b/scilla-contracts/.gitignore new file mode 100644 index 0000000..e8c12ff --- /dev/null +++ b/scilla-contracts/.gitignore @@ -0,0 +1,17 @@ +node_modules +.env + +# Hardhat files +/cache +/artifacts + +# TypeChain files +/typechain +/typechain-types + +# solidity-coverage files +/coverage +/coverage.json + +# Hardhat Ignition default folder for deployments against a local node +ignition/deployments/chain-31337 diff --git a/scilla-contracts/README.md b/scilla-contracts/README.md new file mode 100644 index 0000000..f81610d --- /dev/null +++ b/scilla-contracts/README.md @@ -0,0 +1,15 @@ +# Sample Hardhat Project + +This project demonstrates a basic Hardhat use case. It comes with a +sample contract, a test for that contract, and a Hardhat Ignition +module that deploys that contract. + +Try running some of the following tasks: + +```shell +npx hardhat help +npx hardhat test +REPORT_GAS=true npx hardhat test +npx hardhat node +npx hardhat ignition deploy ./ignition/modules/Lock.ts +``` diff --git a/scilla-contracts/contracts/FungibleToken.scilla b/scilla-contracts/contracts/FungibleToken.scilla new file mode 100644 index 0000000..5ef0e14 --- /dev/null +++ b/scilla-contracts/contracts/FungibleToken.scilla @@ -0,0 +1,195 @@ +scilla_version 0 + +(***************************************************) +(* Associated library *) +(***************************************************) +import IntUtils +library FungibleToken + +let one_msg = + fun (msg : Message) => + let nil_msg = Nil {Message} in + Cons {Message} msg nil_msg + +let two_msgs = +fun (msg1 : Message) => +fun (msg2 : Message) => + let msgs_tmp = one_msg msg2 in + Cons {Message} msg1 msgs_tmp + +(* Error events *) +type Error = +| CodeIsSender +| CodeInsufficientFunds +| CodeInsufficientAllowance + +let make_error = + fun (result : Error) => + let result_code = + match result with + | CodeIsSender => Int32 -1 + | CodeInsufficientFunds => Int32 -2 + | CodeInsufficientAllowance => Int32 -3 + end + in + { _exception : "Error"; code : result_code } + +let zero = Uint128 0 + +(* Dummy user-defined ADT *) +type Unit = +| Unit + +let get_val = + fun (some_val: Option Uint128) => + match some_val with + | Some val => val + | None => zero + end + +(***************************************************) +(* The contract definition *) +(***************************************************) + +contract FungibleToken +( + contract_owner: ByStr20, + name : String, + symbol: String, + decimals: Uint32, + init_supply : Uint128 +) + +(* Mutable fields *) + +field total_supply : Uint128 = init_supply + +field balances: Map ByStr20 Uint128 + = let emp_map = Emp ByStr20 Uint128 in + builtin put emp_map contract_owner init_supply + +field allowances: Map ByStr20 (Map ByStr20 Uint128) + = Emp ByStr20 (Map ByStr20 Uint128) + +(**************************************) +(* Procedures *) +(**************************************) + +procedure ThrowError(err : Error) + e = make_error err; + throw e +end + +procedure IsNotSender(address: ByStr20) + is_sender = builtin eq _sender address; + match is_sender with + | True => + err = CodeIsSender; + ThrowError err + | False => + end +end + +procedure AuthorizedMoveIfSufficientBalance(from: ByStr20, to: ByStr20, amount: Uint128) + o_from_bal <- balances[from]; + bal = get_val o_from_bal; + can_do = uint128_le amount bal; + match can_do with + | True => + (* Subtract amount from from and add it to to address *) + new_from_bal = builtin sub bal amount; + balances[from] := new_from_bal; + (* Adds amount to to address *) + get_to_bal <- balances[to]; + new_to_bal = match get_to_bal with + | Some bal => builtin add bal amount + | None => amount + end; + balances[to] := new_to_bal + | False => + (* Balance not sufficient *) + err = CodeInsufficientFunds; + ThrowError err + end +end + +(***************************************) +(* Transitions *) +(***************************************) + +(* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be increased as allowance for the approved_spender. *) +transition IncreaseAllowance(spender: ByStr20, amount: Uint128) + IsNotSender spender; + some_current_allowance <- allowances[_sender][spender]; + current_allowance = get_val some_current_allowance; + new_allowance = builtin add current_allowance amount; + allowances[_sender][spender] := new_allowance; + e = {_eventname : "IncreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + event e +end + +(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) +transition DecreaseAllowance(spender: ByStr20, amount: Uint128) + IsNotSender spender; + some_current_allowance <- allowances[_sender][spender]; + current_allowance = get_val some_current_allowance; + new_allowance = + let amount_le_allowance = uint128_le amount current_allowance in + match amount_le_allowance with + | True => builtin sub current_allowance amount + | False => zero + end; + allowances[_sender][spender] := new_allowance; + e = {_eventname : "DecreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + event e +end + +(* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) +(* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be sent. *) +transition Transfer(to: ByStr20, amount: Uint128) + AuthorizedMoveIfSufficientBalance _sender to amount; + e = {_eventname : "TransferSuccess"; sender : _sender; recipient : to; amount : amount}; + event e; + (* Prevent sending to a contract address that does not support transfers of token *) + msg_to_recipient = {_tag : "RecipientAcceptTransfer"; _recipient : to; _amount : zero; + sender : _sender; recipient : to; amount : amount}; + msg_to_sender = {_tag : "TransferSuccessCallBack"; _recipient : _sender; _amount : zero; + sender : _sender; recipient : to; amount : amount}; + msgs = two_msgs msg_to_recipient msg_to_sender; + send msgs +end + +(* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param from: Address of the token_owner whose balance is decreased. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be transferred. *) +transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) + o_spender_allowed <- allowances[from][_sender]; + allowed = get_val o_spender_allowed; + can_do = uint128_le amount allowed; + match can_do with + | True => + AuthorizedMoveIfSufficientBalance from to amount; + e = {_eventname : "TransferFromSuccess"; initiator : _sender; sender : from; recipient : to; amount : amount}; + event e; + new_allowed = builtin sub allowed amount; + allowances[from][_sender] := new_allowed; + (* Prevent sending to a contract address that does not support transfers of token *) + msg_to_recipient = {_tag: "RecipientAcceptTransferFrom"; _recipient : to; _amount: zero; + initiator: _sender; sender : from; recipient: to; amount: amount}; + msg_to_sender = {_tag: "TransferFromSuccessCallBack"; _recipient: _sender; _amount: zero; + initiator: _sender; sender: from; recipient: to; amount: amount}; + msgs = two_msgs msg_to_recipient msg_to_sender; + send msgs + | False => + err = CodeInsufficientAllowance; + ThrowError err + end +end diff --git a/scilla-contracts/contracts/ScillaConnector.sol b/scilla-contracts/contracts/ScillaConnector.sol new file mode 100644 index 0000000..63f86ca --- /dev/null +++ b/scilla-contracts/contracts/ScillaConnector.sol @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +library ScillaConnector { + uint private constant CALL_SCILLA_WITH_THE_SAME_SENDER = 1; + uint private constant SCILLA_CALL_PRECOMPILE_ADDRESS = 0x5a494c53; + uint private constant SCILLA_STATE_READ_PRECOMPILE_ADDRESS = 0x5a494c92; + + /** + * @dev Calls a ZRC2 contract function with two arguments + * @param target The address of the ZRC2 contract + * @param tran_name The name of the function to call + * @param arg1 The first argument to the function + * @param arg2 The second argument to the function + */ + function call( + address target, + string memory tran_name, + address arg1, + uint128 arg2 + ) internal { + bytes memory encodedArgs = abi.encode( + target, + tran_name, + CALL_SCILLA_WITH_THE_SAME_SENDER, + arg1, + arg2 + ); + uint256 argsLength = encodedArgs.length; + + assembly { + let alwaysSuccessForThisPrecompile := call( + 21000, + SCILLA_CALL_PRECOMPILE_ADDRESS, + 0, + add(encodedArgs, 0x20), + argsLength, + 0x20, + 0 + ) + } + } + + /** + * @dev Calls a ZRC2 contract function with three arguments + * @param target The address of the ZRC2 contract + * @param tran_name The name of the function to call on the ZRC2 contract + * @param arg1 The first argument to the function + * @param arg2 The second argument to the function + * @param arg3 The third argument to the function + */ + function call( + address target, + string memory tran_name, + address arg1, + address arg2, + uint128 arg3 + ) internal { + bytes memory encodedArgs = abi.encode( + target, + tran_name, + CALL_SCILLA_WITH_THE_SAME_SENDER, + arg1, + arg2, + arg3 + ); + uint256 argsLength = encodedArgs.length; + + assembly { + let alwaysSuccessForThisPrecompile := call( + 21000, + SCILLA_CALL_PRECOMPILE_ADDRESS, + 0, + add(encodedArgs, 0x20), + argsLength, + 0x20, + 0 + ) + } + } + + /** + * @dev Reads a 128 bit integer from a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the variable to read from the ZRC2 contract + * @return The value of the variable + */ + function readUint128( + address target, + string memory variable_name + ) internal view returns (uint128) { + bytes memory encodedArgs = abi.encode(target, variable_name); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint128)); + } + + /** + * @dev Reads a 32 bit integer from a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the variable to read from the ZRC2 contract + * @return The value of the variable + */ + function readUint32( + address target, + string memory variable_name + ) internal view returns (uint32) { + bytes memory encodedArgs = abi.encode(target, variable_name); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint32)); + } + + /** + * @dev Reads a string from a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the variable to read from the ZRC2 contract + * @return retVal The value of the variable + */ + function readString( + address target, + string memory variable_name + ) internal view returns (string memory retVal) { + bytes memory encodedArgs = abi.encode(target, variable_name); + uint256 argsLength = encodedArgs.length; + bool success; + bytes memory output = new bytes(128); + uint256 output_len = output.length - 4; + assembly { + success := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + output_len + ) + } + require(success); + + (retVal) = abi.decode(output, (string)); + return retVal; + } + + /** + * @dev Reads a 128 bit integer from a map in a ZRC2 contract + * @param variable_name The name of the map in the ZRC2 contract + * @param addressMapKey The key to the map + * @return The value associated with the key in the map + */ + function readMapUint128( + address target, + string memory variable_name, + address addressMapKey + ) internal view returns (uint128) { + bytes memory encodedArgs = abi.encode( + target, + variable_name, + addressMapKey + ); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint128)); + } + + /** + * @dev Reads a 128 bit integer from a nested map in a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the map in the ZRC2 contract + * @param firstMapKey The first key to the map + * @param secondMapKey The second key to the map + * @return The value associated with the keys in the map + */ + function readNestedMapUint128( + address target, + string memory variable_name, + address firstMapKey, + address secondMapKey + ) internal view returns (uint128) { + bytes memory encodedArgs = abi.encode( + target, + variable_name, + firstMapKey, + secondMapKey + ); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint128)); + } +} diff --git a/scilla-contracts/contracts/SwitcheoTokenZRC2.scilla b/scilla-contracts/contracts/SwitcheoTokenZRC2.scilla new file mode 100644 index 0000000..4476e9f --- /dev/null +++ b/scilla-contracts/contracts/SwitcheoTokenZRC2.scilla @@ -0,0 +1,373 @@ +scilla_version 0 + +(***************************************************) +(* Associated library *) +(***************************************************) +import IntUtils BoolUtils +library FungibleToken + +let one_msg = + fun (msg : Message) => + let nil_msg = Nil {Message} in + Cons {Message} msg nil_msg + +let two_msgs = +fun (msg1 : Message) => +fun (msg2 : Message) => + let msgs_tmp = one_msg msg2 in + Cons {Message} msg1 msgs_tmp + +(* Error events *) +type Error = +| CodeIsSender +| CodeInsufficientFunds +| CodeInsufficientAllowance +| CodeIsNotOwner +| CodeInvalidAddress +| CodeIsNotSelf +| StagingOwnerValidationFailed +| StagingOwnerNotExist + +let make_error = + fun (result : Error) => + let result_code = + match result with + | CodeIsSender => Int32 -1 + | CodeInsufficientFunds => Int32 -2 + | CodeInsufficientAllowance => Int32 -3 + | CodeIsNotOwner => Int32 -4 + | CodeInvalidAddress => Int32 -5 + | CodeIsNotSelf => Int32 -6 + | StagingOwnerValidationFailed => Int32 -7 + | StagingOwnerNotExist => Int32 -8 + end + in + { _exception : "Error"; code : result_code } + +let zero = Uint128 0 +let zero_addr = 0x0000000000000000000000000000000000000000 +let true = True + +(* Dummy user-defined ADT *) +type Unit = +| Unit + +let get_val = + fun (some_val: Option Uint128) => + match some_val with + | Some val => val + | None => zero + end + +let some_addr = + fun (addr: ByStr20) => + Some {ByStr20} addr + +(***************************************************) +(* The contract definition *) +(***************************************************) + +contract SwitcheoTokenZRC2 +( + name: String, + symbol: String, + contract_owner: ByStr20, + decimals: Uint32, + init_supply: Uint128, + init_lockproxy: ByStr20 +) +with + (* init supply should be zero *) + let a = builtin eq init_supply zero in + let b = builtin eq init_lockproxy zero_addr in + (* lock proxy address should not be zero address *) + let c = negb b in + andb a c +=> + +(* Mutable fields *) + +field total_supply : Uint128 = init_supply + +field balances: Map ByStr20 Uint128 = Emp ByStr20 Uint128 + +field allowances: Map ByStr20 (Map ByStr20 Uint128) + = Emp ByStr20 (Map ByStr20 Uint128) + +field lock_proxy: ByStr20 = init_lockproxy + +field contractowner: ByStr20 = contract_owner + +field stagingcontractowner: Option ByStr20 = None {ByStr20} + +(**************************************) +(* Procedures *) +(**************************************) + +procedure ThrowError(err : Error) + e = make_error err; + throw e +end + +procedure IsNotSender(address: ByStr20) + is_sender = builtin eq _sender address; + match is_sender with + | True => + err = CodeIsSender; + ThrowError err + | False => + end +end + +procedure IsOwner() + owner <- contractowner; + is_owner = builtin eq _sender owner; + match is_owner with + | True => + | False => + err = CodeIsNotOwner; + ThrowError err + end +end + + +procedure AuthorizedMoveIfSufficientBalance(from: ByStr20, to: ByStr20, amount: Uint128) + o_from_bal <- balances[from]; + bal = get_val o_from_bal; + can_do = uint128_le amount bal; + match can_do with + | True => + (* Subtract amount from from and add it to to address *) + new_from_bal = builtin sub bal amount; + balances[from] := new_from_bal; + (* Adds amount to to address *) + get_to_bal <- balances[to]; + new_to_bal = match get_to_bal with + | Some bal => builtin add bal amount + | None => amount + end; + balances[to] := new_to_bal + | False => + (* Balance not sufficient *) + err = CodeInsufficientFunds; + ThrowError err + end +end + +procedure validateAddress(address: ByStr20) + is_zero_addr = builtin eq address zero_addr; + match is_zero_addr with + | True => + err = CodeInvalidAddress; + ThrowError err + | False => + end +end + +procedure isSelf() + is_self = builtin eq _sender _this_address; + match is_self with + | True => + | False => + err = CodeIsNotSelf; + ThrowError err + end +end + +(* @dev Creates amount tokens and assigns them to account, increasing the tital supply *) +procedure mint(address: ByStr20, amount: Uint128) + validateAddress address; + current_supply <- total_supply; + new_supply = builtin add current_supply amount; + total_supply := new_supply; + + get_bal <- balances[address]; + new_bal = match get_bal with + | Some bal => builtin add bal amount + | None => amount + end; + balances[address] := new_bal +end + +(* @dev Destorys amount token from address, reducing the total supply *) +procedure burn(address: ByStr20, amount: Uint128) + validateAddress address; + current_supply <- total_supply; + new_supply = builtin sub current_supply amount; + total_supply := new_supply; + + o_from_bal <- balances[address]; + bal = get_val o_from_bal; + can_do = uint128_le amount bal; + match can_do with + | True => + new_from_bal = builtin sub bal amount; + balances[address] := new_from_bal + | False => + err = CodeInsufficientFunds; + ThrowError err + end +end + +procedure handleMint(address: ByStr20, amount: Uint128) + lp <- lock_proxy; + is_lp = builtin eq lp address; + match is_lp with + | True => + mint address amount + | False => + end + +end + +procedure handleBurn(address: ByStr20, amount: Uint128) + lp <- lock_proxy; + is_lp = builtin eq lp address; + match is_lp with + | True => + msg_to_burn = {_tag : "Burn"; _recipient : _this_address; _amount : zero; + burn_account : address; amount : amount}; + msgs = one_msg msg_to_burn; + send msgs + | False => + end +end + + +(***************************************) +(* Transitions *) +(***************************************) + +transition UpdateOwner(newOwner: ByStr20) + IsOwner; + sco = Some {ByStr20} newOwner; + stagingcontractowner := sco +end + +transition ClaimOwner() + stagingOwner <- stagingcontractowner; + match stagingOwner with + | Some owner => + is_valid = builtin eq _sender owner; + match is_valid with + | True => + contractowner := owner; + nonOwner = None {ByStr20}; + stagingcontractowner := nonOwner; + e = { _eventname: "ClaimOwner"; new_owner: owner }; + event e + | False => + e = StagingOwnerValidationFailed; + ThrowError e + end + | None => + e = StagingOwnerNotExist; + ThrowError e + end +end + +(* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be increased as allowance for the approved_spender. *) +transition IncreaseAllowance(spender: ByStr20, amount: Uint128) + IsNotSender spender; + some_current_allowance <- allowances[_sender][spender]; + current_allowance = get_val some_current_allowance; + new_allowance = builtin add current_allowance amount; + allowances[_sender][spender] := new_allowance; + e = {_eventname : "IncreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + event e +end + +(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) +transition DecreaseAllowance(spender: ByStr20, amount: Uint128) + IsNotSender spender; + some_current_allowance <- allowances[_sender][spender]; + current_allowance = get_val some_current_allowance; + new_allowance = + let amount_le_allowance = uint128_le amount current_allowance in + match amount_le_allowance with + | True => builtin sub current_allowance amount + | False => zero + end; + allowances[_sender][spender] := new_allowance; + e = {_eventname : "DecreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + event e +end + +(* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) +(* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be sent. *) +transition Transfer(to: ByStr20, amount: Uint128) + handleMint _sender amount; + AuthorizedMoveIfSufficientBalance _sender to amount; + handleBurn to amount; + e = {_eventname : "TransferSuccess"; sender : _sender; recipient : to; amount : amount}; + event e; + (* Prevent sending to a contract address that does not support transfers of token *) + msg_to_recipient = {_tag : "RecipientAcceptTransfer"; _recipient : to; _amount : zero; + sender : _sender; recipient : to; amount : amount}; + msg_to_sender = {_tag : "TransferSuccessCallBack"; _recipient : _sender; _amount : zero; + sender : _sender; recipient : to; amount : amount}; + msgs = two_msgs msg_to_recipient msg_to_sender; + send msgs +end + +(* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param from: Address of the token_owner whose balance is decreased. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be transferred. *) +transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) + o_spender_allowed <- allowances[from][_sender]; + allowed = get_val o_spender_allowed; + can_do = uint128_le amount allowed; + match can_do with + | True => + AuthorizedMoveIfSufficientBalance from to amount; + handleBurn to amount; + e = {_eventname : "TransferFromSuccess"; initiator : _sender; sender : from; recipient : to; amount : amount}; + event e; + new_allowed = builtin sub allowed amount; + allowances[from][_sender] := new_allowed; + (* Prevent sending to a contract address that does not support transfers of token *) + msg_to_recipient = {_tag: "RecipientAcceptTransferFrom"; _recipient : to; _amount: zero; + initiator: _sender; sender : from; recipient: to; amount: amount}; + msg_to_sender = {_tag: "TransferFromSuccessCallBack"; _recipient: _sender; _amount: zero; + initiator: _sender; sender: from; recipient: to; amount: amount}; + msgs = two_msgs msg_to_recipient msg_to_sender; + send msgs + | False => + err = CodeInsufficientAllowance; + ThrowError err + end +end + +(* @dev: Burn existing tokens. Only contract self can burn. *) +(* @param burn_account: Address of the token_owner whose balance is to decrease. *) +(* @param amount: Number of tokens to be burned. *) +transition Burn(burn_account: ByStr20, amount: Uint128) + isSelf; + burn burn_account amount; + lp <- lock_proxy; + e = { _eventname : "Burnt"; burner : lp; burn_account : burn_account; amount : amount }; + event e; + (* Provide the sender the status of the burn. *) + msg_call_back = { _tag: "BurnSuccessCallBack"; _recipient : _sender; _amount: zero; + burner: lp; burn_account: burn_account; amount: amount }; + msgs = one_msg msg_call_back; + send msgs +end + +transition ChangeLockProxy(addr: ByStr20) + IsOwner; + lock_proxy := addr; + e = {_eventname : "ChangeLockProxy"; lockproxy : addr}; + event e +end + +transition BurnSuccessCallBack(burner: ByStr20, burn_account: ByStr20, amount: Uint128) +end \ No newline at end of file diff --git a/scilla-contracts/contracts/ZRC2ProxyForZRC2.sol b/scilla-contracts/contracts/ZRC2ProxyForZRC2.sol new file mode 100644 index 0000000..4332aeb --- /dev/null +++ b/scilla-contracts/contracts/ZRC2ProxyForZRC2.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {ScillaConnector} from "./ScillaConnector.sol"; + +contract ZRC2ProxyForZRC2 is IERC20 { + using ScillaConnector for address; + using SafeCast for uint256; + + address public zrc2_proxy; + + // Additional variables useful for wallets + uint8 public decimals; + string public symbol; + string public name; + + /** + * @notice Constructs a new ZRC2Proxy contract + * @param zrc2_address The address of the underlying ZRC2 contract + */ + constructor(address zrc2_address) { + zrc2_proxy = zrc2_address; + + symbol = zrc2_proxy.readString("symbol"); + decimals = uint256(zrc2_proxy.readUint32("decimals")).toUint8(); + name = zrc2_proxy.readString("name"); + } + + /** + * @notice Get the total supply of tokens + * @return The total supply of tokens + */ + function totalSupply() external view returns (uint256) { + return zrc2_proxy.readUint128("total_supply"); + } + + /** + * @notice Get the token balance for a specific account + * @param tokenOwner The address of the account + * @return The balance of the account + */ + function balanceOf(address tokenOwner) external view returns (uint256) { + return zrc2_proxy.readMapUint128("balances", tokenOwner); + } + + /** + * @notice Transfer tokens to a specified address + * @param to The address to transfer to + * @param tokens The amount of tokens to transfer + * @return true if transfer was successful + */ + function transfer(address to, uint256 tokens) external returns (bool) { + zrc2_proxy.call("Transfer", to, tokens.toUint128()); + return true; + } + + /** + * @notice Transfer tokens from one address to another + * @param from The address to transfer from + * @param to The address to transfer to + * @param tokens The amount of tokens to transfer + * @return true if transfer was successful + */ + function transferFrom( + address from, + address to, + uint256 tokens + ) external returns (bool) { + zrc2_proxy.call("TransferFrom", from, to, tokens.toUint128()); + return true; + } + + /** + * @notice Check the amount of tokens that an owner has allowed a spender to use + * @param tokenOwner The address of the token owner + * @param spender The address of the spender + * @return The amount of tokens remaining for the spender + */ + function allowance( + address tokenOwner, + address spender + ) external view returns (uint256) { + return + zrc2_proxy.readNestedMapUint128("allowances", tokenOwner, spender); + } + + /** + * @notice Approve a spender to spend a certain amount of tokens + * @param spender The address of the spender + * @param new_allowance The new allowance for the spender + * @return true if approval was successful + */ + function approve( + address spender, + uint256 new_allowance + ) external returns (bool) { + uint256 current_allowance = this.allowance(msg.sender, spender); + + if (current_allowance >= new_allowance) { + zrc2_proxy.call( + "DecreaseAllowance", + spender, + (current_allowance - new_allowance).toUint128() + ); + } else { + zrc2_proxy.call( + "IncreaseAllowance", + spender, + (new_allowance - current_allowance).toUint128() + ); + } + return true; + } +} diff --git a/scilla-contracts/hardhat.config.js b/scilla-contracts/hardhat.config.js new file mode 100644 index 0000000..5924682 --- /dev/null +++ b/scilla-contracts/hardhat.config.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +require("@nomicfoundation/hardhat-toolbox"); +require("hardhat-scilla-plugin"); +const config = { + solidity: "0.8.24", + networks: { + zq_testnet: { + url: "https://dev-api.zilliqa.com", + websocketUrl: "wss://dev-api.zilliqa.com", + accounts: [process.env.PRIVATE_KEY_ZILBRIDGE], + chainId: 33101, + zilliqaNetwork: true, + }, + zq_testnet_mitmweb: { + url: "http://localhost:6200", + websocketUrl: "ws://localhost:6200", + accounts: [process.env.PRIVATE_KEY_ZILBRIDGE], + chainId: 33101, + zilliqaNetwork: true, + }, + }, +}; +exports.default = config; diff --git a/scilla-contracts/hardhat.config.ts b/scilla-contracts/hardhat.config.ts new file mode 100644 index 0000000..db23c38 --- /dev/null +++ b/scilla-contracts/hardhat.config.ts @@ -0,0 +1,25 @@ +import { HardhatUserConfig } from "hardhat/config"; +import "@nomicfoundation/hardhat-toolbox"; +import "hardhat-scilla-plugin"; + +const config: HardhatUserConfig = { + solidity: "0.8.24", + networks: { + zq_testnet: { + url: "https://dev-api.zilliqa.com", + websocketUrl: "wss://dev-api.zilliqa.com", + accounts: [process.env.PRIVATE_KEY_ZILBRIDGE], + chainId: 33101, + zilliqaNetwork: true, + }, + zq_testnet_mitmweb: { + url: "http://localhost:6200", + websocketUrl: "ws://localhost:6200", + accounts: [process.env.PRIVATE_KEY_ZILBRIDGE], + chainId: 33101, + zilliqaNetwork: true, + }, + }, +}; + +export default config; diff --git a/scilla-contracts/ignition/modules/Lock.js b/scilla-contracts/ignition/modules/Lock.js new file mode 100644 index 0000000..0cfdbe0 --- /dev/null +++ b/scilla-contracts/ignition/modules/Lock.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const modules_1 = require("@nomicfoundation/hardhat-ignition/modules"); +const JAN_1ST_2030 = 1893456000; +const ONE_GWEI = 1000000000n; +const LockModule = (0, modules_1.buildModule)("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + return { lock }; +}); +exports.default = LockModule; diff --git a/scilla-contracts/ignition/modules/Lock.ts b/scilla-contracts/ignition/modules/Lock.ts new file mode 100644 index 0000000..eda0eba --- /dev/null +++ b/scilla-contracts/ignition/modules/Lock.ts @@ -0,0 +1,17 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +const JAN_1ST_2030 = 1893456000; +const ONE_GWEI: bigint = 1_000_000_000n; + +const LockModule = buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + +export default LockModule; diff --git a/scilla-contracts/package-lock.json b/scilla-contracts/package-lock.json new file mode 100644 index 0000000..ad22fa1 --- /dev/null +++ b/scilla-contracts/package-lock.json @@ -0,0 +1,8113 @@ +{ + "name": "scilla-contracts", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "scilla-contracts", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@openzeppelin/contracts": "^5.0.2", + "hardhat-scilla-plugin": "^3.8.0" + }, + "devDependencies": { + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "hardhat": "^2.22.6" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "dev": true, + "peer": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "peer": true + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "devOptional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomicfoundation/edr": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.4.2.tgz", + "integrity": "sha512-U7v0HuZHfrsl/5FpUzuB2FYA0+FUglHHwiO6NhvLtNYKMZcPzdS6iUriMp/7GWs0SVxW3bAht9GinZPxdhVwWg==", + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.4.2", + "@nomicfoundation/edr-darwin-x64": "0.4.2", + "@nomicfoundation/edr-linux-arm64-gnu": "0.4.2", + "@nomicfoundation/edr-linux-arm64-musl": "0.4.2", + "@nomicfoundation/edr-linux-x64-gnu": "0.4.2", + "@nomicfoundation/edr-linux-x64-musl": "0.4.2", + "@nomicfoundation/edr-win32-x64-msvc": "0.4.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.2.tgz", + "integrity": "sha512-S+hhepupfqpBvMa9M1PVS08sVjGXsLnjyAsjhrrsjsNuTHVLhKzhkguvBD5g4If5skrwgOaVqpag4wnQbd15kQ==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.2.tgz", + "integrity": "sha512-/zM94AUrXz6CmcsecRNHJ50jABDUFafmGc4iBmkfX/mTp4tVZj7XTyIogrQIt0FnTaeb4CgZoLap2+8tW/Uldg==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.2.tgz", + "integrity": "sha512-TV3Pr2tFvvmCfPCi9PaCGLtqn+oLaPKfL2NWpnoCeFFdzDQXi2L930yP1oUPY5RXd78NLdVHMkEkbhb2b6Wuvg==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.2.tgz", + "integrity": "sha512-PALwrLBk1M9rolXyhSX8xdhe5jL0qf/PgiCIF7W7lUyVKrI/I0oiU0EHDk/Xw7yi2UJg4WRyhhZoHYa0g4g8Qg==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.2.tgz", + "integrity": "sha512-5svkftypDjAZ1LxV1onojlaqPRxrTEjJLkrUwLL+Fao5ZMe7aTnk5QQ1Jv76gW6WYZnMXNgjPhRcnw3oSNrqFA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.2.tgz", + "integrity": "sha512-qiMlXQTggdH9zfOB4Eil4rQ95z8s7QdLJcOfz5Aym12qJNkCyF9hi4cc4dDCWA0CdI3x3oLbuf8qb81SF8R45w==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.2.tgz", + "integrity": "sha512-hDkAb0iaMmGYwBY/rA1oCX8VpsezfQcHPEPIEGXEcWC3WbnOgIZo0Qkpu/g0OMtFOJSQlWLXvKZuV7blhnrQag==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "dependencies": { + "@nomicfoundation/ethereumjs-util": "9.0.4" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.7.tgz", + "integrity": "sha512-RQfsiTwdf0SP+DtuNYvm4921X6VirCQq0Xyh+mnuGlTwEFSPZ/o27oQC+l+3Y/l48DDU7+ZcYBR+Fp+Rp94LfQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "chai": "^4.2.0", + "ethers": "^6.1.0", + "hardhat": "^2.9.4" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", + "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.1.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.5.tgz", + "integrity": "sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==", + "dev": true, + "peer": true, + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.5", + "@nomicfoundation/ignition-ui": "^0.15.5", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.1", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition-ethers": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.5.tgz", + "integrity": "sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==", + "dev": true, + "peer": true, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@nomicfoundation/hardhat-ignition": "^0.15.5", + "@nomicfoundation/ignition-core": "^0.15.5", + "ethers": "^6.7.0", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.11.tgz", + "integrity": "sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==", + "dev": true, + "peer": true, + "dependencies": { + "ethereumjs-util": "^7.1.4" + }, + "peerDependencies": { + "hardhat": "^2.9.5" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-toolbox": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", + "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", + "dev": true, + "peerDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", + "@types/chai": "^4.2.0", + "@types/mocha": ">=9.1.0", + "@types/node": ">=18.0.0", + "chai": "^4.2.0", + "ethers": "^6.4.0", + "hardhat": "^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "solidity-coverage": "^0.8.1", + "ts-node": ">=8.0.0", + "typechain": "^8.3.0", + "typescript": ">=4.5.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.8.tgz", + "integrity": "sha512-x/OYya7A2Kcz+3W/J78dyDHxr0ezU23DKTrRKfy5wDPCnePqnr79vm8EXqX3gYps6IjPBYyGPZ9K6E5BnrWx5Q==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "lodash.clonedeep": "^4.5.0", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.5.tgz", + "integrity": "sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.7.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.5.tgz", + "integrity": "sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", + "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", + "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", + "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", + "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", + "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", + "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", + "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", + "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==" + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@scure/base": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", + "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "dev": true, + "peer": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true, + "peer": true + }, + "node_modules/@typechain/ethers-v6": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", + "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "ethers": "6.x", + "typechain": "^8.3.2", + "typescript": ">=4.7.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", + "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", + "dev": true, + "peer": true, + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "@typechain/ethers-v6": "^0.5.1", + "ethers": "^6.1.0", + "hardhat": "^2.9.9", + "typechain": "^8.3.2" + } + }, + "node_modules/@typechain/hardhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "peer": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typechain/hardhat/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@typechain/hardhat/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==" + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/chai-subset": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", + "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "peer": true + }, + "node_modules/@types/mocha": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "dev": true, + "peer": true + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "peer": true + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true, + "peer": true + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@zilliqa-js/account": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/account/-/account-3.5.0.tgz", + "integrity": "sha512-ojy+YjofL6CnuqAYjcf7gkqOMJzDSWsqaR64UF6gQshcPl76RitFbC6Udw0cmkJqStycqiEQS/OzjFRoiqvE7w==", + "dependencies": { + "@zilliqa-js/core": "3.5.0", + "@zilliqa-js/crypto": "3.5.0", + "@zilliqa-js/proto": "3.5.0", + "@zilliqa-js/util": "3.5.0", + "bip39": "^2.5.0", + "buffer": "^6.0.3", + "hash.js": "^1.1.7", + "hdkey": "^1.1.0", + "tslib": "2.3.1" + } + }, + "node_modules/@zilliqa-js/account/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@zilliqa-js/blockchain": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/blockchain/-/blockchain-3.5.0.tgz", + "integrity": "sha512-YuWfmt5mAGTpWuSAgY0jHxQFxWkKplyC7+ebUo+wpkw45gzT4gc2X75cAckgt5nps5c9dO85OruWNZoKynoQ3g==", + "dependencies": { + "@zilliqa-js/account": "3.5.0", + "@zilliqa-js/core": "3.5.0", + "@zilliqa-js/crypto": "3.5.0", + "@zilliqa-js/util": "3.5.0", + "tslib": "2.3.1" + } + }, + "node_modules/@zilliqa-js/blockchain/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@zilliqa-js/contract": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/contract/-/contract-3.5.0.tgz", + "integrity": "sha512-eojquTPaMTGy74fDV0w5KMjyvb4uIopcND2u3dGAx2aYoZzafuvBzw8sevu1hqUQhKSxJUZEcHIeeEK53PffMw==", + "dependencies": { + "@zilliqa-js/account": "3.5.0", + "@zilliqa-js/blockchain": "3.5.0", + "@zilliqa-js/core": "3.5.0", + "@zilliqa-js/crypto": "3.5.0", + "@zilliqa-js/util": "3.5.0", + "bn.js": "^4.11.8", + "buffer-from": "^1.1.2", + "cross-fetch": "2.2.5", + "hash.js": "^1.1.5", + "node-fetch": "^3.2.10", + "tslib": "2.3.1", + "utility-types": "^2.1.0" + } + }, + "node_modules/@zilliqa-js/contract/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/@zilliqa-js/contract/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@zilliqa-js/core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/core/-/core-3.5.0.tgz", + "integrity": "sha512-sc3RaF7W4bwnLrOffuVhzmHGmXcfLGnCHxVkhJRNNkGzgjwjV9EhumtbNLinDTosvmaZY68mvSLlPkyyYEP1Yg==", + "dependencies": { + "buffer": "^6.0.3", + "cross-fetch": "2.2.6", + "mitt": "^1.1.3", + "tslib": "2.3.1" + } + }, + "node_modules/@zilliqa-js/core/node_modules/cross-fetch": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.6.tgz", + "integrity": "sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA==", + "dependencies": { + "node-fetch": "^2.6.7", + "whatwg-fetch": "^2.0.4" + } + }, + "node_modules/@zilliqa-js/core/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@zilliqa-js/core/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@zilliqa-js/crypto": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/crypto/-/crypto-3.5.0.tgz", + "integrity": "sha512-KMTY4hREh706k0oqCJ7KTFCEgPvgWuckv7z1SkOc9UDjJnnfOD8KxGWrleaKMZOw+EjKJRybxgewPUvSZ+o7Mw==", + "dependencies": { + "@zilliqa-js/util": "3.5.0", + "aes-js": "^3.1.1", + "buffer": "^6.0.3", + "crypto-js": "^4.2.0", + "elliptic": "^6.5.0", + "hash.js": "^1.1.5", + "hmac-drbg": "^1.0.1", + "pbkdf2": "^3.0.16", + "scrypt-js": "^3.0.1", + "scryptsy": "^2.1.0", + "tslib": "2.3.1", + "uuid": "8.3.2" + } + }, + "node_modules/@zilliqa-js/crypto/node_modules/aes-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" + }, + "node_modules/@zilliqa-js/crypto/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@zilliqa-js/proto": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/proto/-/proto-3.5.0.tgz", + "integrity": "sha512-Ids/iS+lYYseC0g1lzkLVRzrsVnB/6QQdDIxbqXzMQwGEjJVwX+UJqGV5eCREQ9w04bI9SS0lmeaNZ3KmN8CdA==", + "dependencies": { + "protobufjs": "^6.8.8" + } + }, + "node_modules/@zilliqa-js/subscriptions": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/subscriptions/-/subscriptions-3.5.0.tgz", + "integrity": "sha512-K7qN03xu71C8fMdweMThvsHWG1yj5aQCtbincVqiCYSrKeMTLViNFHRK6th/FOhoWF2AFgJzMap6/Pv2tFbQ4w==", + "peer": true, + "dependencies": { + "buffer": "^6.0.3", + "camelcase": "5.0.0", + "mitt": "^1.1.3", + "tslib": "2.3.1", + "websocket": "^1.0.28" + } + }, + "node_modules/@zilliqa-js/subscriptions/node_modules/camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@zilliqa-js/subscriptions/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "peer": true + }, + "node_modules/@zilliqa-js/util": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/util/-/util-3.5.0.tgz", + "integrity": "sha512-YT8OhYAv2nCIrRTMMwXLDEqyV/O0jbtfc5Uvlb0qkIx56a4OeneebIJtBlTwf9ld7MZlU5LvvDOEJyljQErz6w==", + "dependencies": { + "bn.js": "^4.11.8", + "camelcase": "^5.0.0", + "long": "^4.0.0", + "tslib": "2.3.1" + } + }, + "node_modules/@zilliqa-js/util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/@zilliqa-js/util/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@zilliqa-js/util/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@zilliqa-js/zilliqa": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@zilliqa-js/zilliqa/-/zilliqa-3.5.0.tgz", + "integrity": "sha512-CQ9HG16wtKOBFSPfSf8ZLOpyJy1+qXJOk7gvhE+fkBuR/pCdi3IKIxWH7bo/hCwBr+bEFo+Pi4fY22/8LsNN7Q==", + "peer": true, + "dependencies": { + "@zilliqa-js/account": "3.5.0", + "@zilliqa-js/blockchain": "3.5.0", + "@zilliqa-js/contract": "3.5.0", + "@zilliqa-js/core": "3.5.0", + "@zilliqa-js/crypto": "3.5.0", + "@zilliqa-js/proto": "3.5.0", + "@zilliqa-js/subscriptions": "3.5.0", + "@zilliqa-js/util": "3.5.0", + "buffer": "^6.0.3", + "tslib": "2.3.1" + } + }, + "node_modules/@zilliqa-js/zilliqa/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "peer": true + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true, + "peer": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "devOptional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "devOptional": true, + "peer": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "dev": true, + "peer": true + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "peer": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true, + "peer": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "peer": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "peer": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "peer": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dev": true, + "peer": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true, + "peer": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip39": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", + "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", + "dependencies": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "node_modules/bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "peer": true + }, + "node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "peer": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "dev": true, + "peer": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chai-subset": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz", + "integrity": "sha512-K3d+KmqdS5XKW5DWPd5sgNffL3uxdDe+6GdnJh3AYPhwnBGRY5urfvfcbRtWIvvpz+KxkL9FeBB6MZewLUNwug==", + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "peer": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "peer": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "peer": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "peer": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true, + "peer": true + }, + "node_modules/cross-fetch": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.5.tgz", + "integrity": "sha512-xqYAhQb4NhCJSRym03dwxpP1bYXpK3y7UN83Bo2WFi3x1Zmzn0SL/6xGoPr+gpt4WmNrgCCX3HPysvOwFOW36w==", + "dependencies": { + "node-fetch": "2.6.1", + "whatwg-fetch": "2.0.4" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", + "dev": true, + "peer": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "peer": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "dev": true, + "peer": true, + "dependencies": { + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "peer": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", + "dependencies": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "peer": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "peer": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", + "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.1.tgz", + "integrity": "sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", + "dev": true, + "peer": true + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true, + "peer": true + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "peer": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true, + "peer": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "peer": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "peer": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hardhat": { + "version": "2.22.6", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.6.tgz", + "integrity": "sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/edr": "^0.4.1", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.8.26", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "dev": true, + "peer": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat-scilla-plugin": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/hardhat-scilla-plugin/-/hardhat-scilla-plugin-3.8.0.tgz", + "integrity": "sha512-iYEg3uceDwTi/PVSiaLfgoeyoRS8iATL6U9WNamfToKICEHFP6IKArYZGTd7MsaZFNPMJad1E9mjqt5ATzSkpg==", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@types/chai-subset": "^1.3.5", + "@zilliqa-js/account": "^3.5.0", + "@zilliqa-js/contract": "^3.5.0", + "@zilliqa-js/core": "^3.5.0", + "@zilliqa-js/crypto": "^3.5.0", + "@zilliqa-js/util": "^3.5.0", + "chai-subset": "^1.6.0", + "cli-color": "^2.0.4", + "glob": "^10.3.10", + "s-expression": "^3.1.1" + }, + "peerDependencies": { + "@zilliqa-js/zilliqa": "^3.4.3", + "hardhat": "^2.18.0" + } + }, + "node_modules/hardhat-scilla-plugin/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/hardhat-scilla-plugin/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/hardhat-scilla-plugin/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hdkey": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.2.tgz", + "integrity": "sha512-PTQ4VKu0oRnCrYfLp04iQZ7T2Cxz0UsEXYauk2j8eh6PJXCpbXuCFhOmtIFtbET0i3PMWmHN9J11gU8LEgUljQ==", + "dependencies": { + "bs58check": "^2.1.2", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, + "node_modules/hdkey/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/hdkey/node_modules/secp256k1": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", + "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.5.2", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true, + "peer": true + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "peer": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true, + "peer": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "peer": true + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "peer": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "peer": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "peer": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "peer": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "peer": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "dev": true, + "peer": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "peer": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true, + "peer": true + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true, + "peer": true + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "peer": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mitt": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", + "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", + "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nan": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==" + }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "peer": true, + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "peer": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "peer": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true, + "peer": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true, + "peer": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "peer": true + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "peer": true + }, + "node_modules/qs": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", + "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "peer": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "peer": true, + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", + "dev": true, + "peer": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "dev": true, + "peer": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/s-expression": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/s-expression/-/s-expression-3.1.1.tgz", + "integrity": "sha512-VMsW7sIvixXfIDmDll7XCePMYYY52UlUtA7OlFQUovqj3XtQ2UkZkjjAvnSFW8o+SbswzUEeCBMmpAx9LS3qrg==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true, + "peer": true + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/scryptsy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", + "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "peer": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "dev": true, + "peer": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "peer": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/solc": { + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", + "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solidity-coverage": { + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", + "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.18.0", + "chalk": "^2.4.2", + "death": "^1.1.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.21", + "mocha": "^10.2.0", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true, + "peer": true + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "peer": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "dev": true, + "peer": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "peer": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "peer": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true, + "peer": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/timers-ext": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "dependencies": { + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-command-line-args": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", + "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" + }, + "bin": { + "write-markdown": "dist/write-markdown.js" + } + }, + "node_modules/ts-command-line-args/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-command-line-args/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-command-line-args/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ts-command-line-args/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/ts-command-line-args/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-command-line-args/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typechain": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/prettier": "^2.1.1", + "debug": "^4.3.1", + "fs-extra": "^7.0.0", + "glob": "7.1.7", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.3.0" + } + }, + "node_modules/typechain/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "peer": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "peer": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "devOptional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uglify-js": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utility-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-2.1.0.tgz", + "integrity": "sha512-/nP2gqavggo6l38rtQI/CdeV+2fmBGXVvHgj9kV2MAnms3TIi77Mz9BtapPFI0+GZQCqqom0vACQ+VlTTaCovw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true, + "peer": true + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/websocket": { + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.35.tgz", + "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==", + "peer": true, + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.63", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "node_modules/whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "peer": true + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "peer": true, + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "peer": true, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/scilla-contracts/package.json b/scilla-contracts/package.json new file mode 100644 index 0000000..2495922 --- /dev/null +++ b/scilla-contracts/package.json @@ -0,0 +1,19 @@ +{ + "name": "scilla-contracts", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "devDependencies": { + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "hardhat": "^2.22.6" + }, + "dependencies": { + "hardhat-scilla-plugin": "^3.8.0" + } +} diff --git a/scilla-contracts/pnpm-lock.yaml b/scilla-contracts/pnpm-lock.yaml new file mode 100644 index 0000000..78729ef --- /dev/null +++ b/scilla-contracts/pnpm-lock.yaml @@ -0,0 +1,4449 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@openzeppelin/contracts': + specifier: ^5.0.2 + version: 5.0.2 + hardhat-scilla-plugin: + specifier: /home/rrw/work/zilliqa/src/hardhat-scilla-plugin + version: link:../../hardhat-scilla-plugin + devDependencies: + '@nomicfoundation/hardhat-toolbox': + specifier: ^5.0.0 + version: 5.0.0(hf4zzcstdnacbsmrqafg7ueixe) + hardhat: + specifier: ^2.22.6 + version: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + +packages: + + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@ethersproject/abi@5.7.0': + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + + '@ethersproject/abstract-provider@5.7.0': + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + + '@ethersproject/abstract-signer@5.7.0': + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + + '@ethersproject/address@5.6.1': + resolution: {integrity: sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==} + + '@ethersproject/address@5.7.0': + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + + '@ethersproject/base64@5.7.0': + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + + '@ethersproject/basex@5.7.0': + resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} + + '@ethersproject/bignumber@5.7.0': + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + + '@ethersproject/bytes@5.7.0': + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + + '@ethersproject/constants@5.7.0': + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + + '@ethersproject/contracts@5.7.0': + resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} + + '@ethersproject/hash@5.7.0': + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + + '@ethersproject/hdnode@5.7.0': + resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} + + '@ethersproject/json-wallets@5.7.0': + resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} + + '@ethersproject/keccak256@5.7.0': + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + + '@ethersproject/logger@5.7.0': + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + + '@ethersproject/networks@5.7.1': + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + + '@ethersproject/pbkdf2@5.7.0': + resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} + + '@ethersproject/properties@5.7.0': + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + + '@ethersproject/providers@5.7.2': + resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==} + + '@ethersproject/random@5.7.0': + resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} + + '@ethersproject/rlp@5.7.0': + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + + '@ethersproject/sha2@5.7.0': + resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} + + '@ethersproject/signing-key@5.7.0': + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + + '@ethersproject/solidity@5.7.0': + resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} + + '@ethersproject/strings@5.7.0': + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + + '@ethersproject/transactions@5.7.0': + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + + '@ethersproject/units@5.7.0': + resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} + + '@ethersproject/wallet@5.7.0': + resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} + + '@ethersproject/web@5.7.1': + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + + '@ethersproject/wordlists@5.7.0': + resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@metamask/eth-sig-util@4.0.1': + resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==} + engines: {node: '>=12.0.0'} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/hashes@1.2.0': + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/secp256k1@1.7.1': + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nomicfoundation/edr-darwin-arm64@0.4.2': + resolution: {integrity: sha512-S+hhepupfqpBvMa9M1PVS08sVjGXsLnjyAsjhrrsjsNuTHVLhKzhkguvBD5g4If5skrwgOaVqpag4wnQbd15kQ==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-darwin-x64@0.4.2': + resolution: {integrity: sha512-/zM94AUrXz6CmcsecRNHJ50jABDUFafmGc4iBmkfX/mTp4tVZj7XTyIogrQIt0FnTaeb4CgZoLap2+8tW/Uldg==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-arm64-gnu@0.4.2': + resolution: {integrity: sha512-TV3Pr2tFvvmCfPCi9PaCGLtqn+oLaPKfL2NWpnoCeFFdzDQXi2L930yP1oUPY5RXd78NLdVHMkEkbhb2b6Wuvg==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-arm64-musl@0.4.2': + resolution: {integrity: sha512-PALwrLBk1M9rolXyhSX8xdhe5jL0qf/PgiCIF7W7lUyVKrI/I0oiU0EHDk/Xw7yi2UJg4WRyhhZoHYa0g4g8Qg==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-x64-gnu@0.4.2': + resolution: {integrity: sha512-5svkftypDjAZ1LxV1onojlaqPRxrTEjJLkrUwLL+Fao5ZMe7aTnk5QQ1Jv76gW6WYZnMXNgjPhRcnw3oSNrqFA==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-x64-musl@0.4.2': + resolution: {integrity: sha512-qiMlXQTggdH9zfOB4Eil4rQ95z8s7QdLJcOfz5Aym12qJNkCyF9hi4cc4dDCWA0CdI3x3oLbuf8qb81SF8R45w==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-win32-x64-msvc@0.4.2': + resolution: {integrity: sha512-hDkAb0iaMmGYwBY/rA1oCX8VpsezfQcHPEPIEGXEcWC3WbnOgIZo0Qkpu/g0OMtFOJSQlWLXvKZuV7blhnrQag==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr@0.4.2': + resolution: {integrity: sha512-U7v0HuZHfrsl/5FpUzuB2FYA0+FUglHHwiO6NhvLtNYKMZcPzdS6iUriMp/7GWs0SVxW3bAht9GinZPxdhVwWg==} + engines: {node: '>= 18'} + + '@nomicfoundation/ethereumjs-common@4.0.4': + resolution: {integrity: sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==} + + '@nomicfoundation/ethereumjs-rlp@5.0.4': + resolution: {integrity: sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==} + engines: {node: '>=18'} + hasBin: true + + '@nomicfoundation/ethereumjs-tx@5.0.4': + resolution: {integrity: sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/ethereumjs-util@9.0.4': + resolution: {integrity: sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/hardhat-chai-matchers@2.0.7': + resolution: {integrity: sha512-RQfsiTwdf0SP+DtuNYvm4921X6VirCQq0Xyh+mnuGlTwEFSPZ/o27oQC+l+3Y/l48DDU7+ZcYBR+Fp+Rp94LfQ==} + peerDependencies: + '@nomicfoundation/hardhat-ethers': ^3.0.0 + chai: ^4.2.0 + ethers: ^6.1.0 + hardhat: ^2.9.4 + + '@nomicfoundation/hardhat-ethers@3.0.6': + resolution: {integrity: sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==} + peerDependencies: + ethers: ^6.1.0 + hardhat: ^2.0.0 + + '@nomicfoundation/hardhat-ignition-ethers@0.15.5': + resolution: {integrity: sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==} + peerDependencies: + '@nomicfoundation/hardhat-ethers': ^3.0.4 + '@nomicfoundation/hardhat-ignition': ^0.15.5 + '@nomicfoundation/ignition-core': ^0.15.5 + ethers: ^6.7.0 + hardhat: ^2.18.0 + + '@nomicfoundation/hardhat-ignition@0.15.5': + resolution: {integrity: sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==} + peerDependencies: + '@nomicfoundation/hardhat-verify': ^2.0.1 + hardhat: ^2.18.0 + + '@nomicfoundation/hardhat-network-helpers@1.0.11': + resolution: {integrity: sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==} + peerDependencies: + hardhat: ^2.9.5 + + '@nomicfoundation/hardhat-toolbox@5.0.0': + resolution: {integrity: sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==} + peerDependencies: + '@nomicfoundation/hardhat-chai-matchers': ^2.0.0 + '@nomicfoundation/hardhat-ethers': ^3.0.0 + '@nomicfoundation/hardhat-ignition-ethers': ^0.15.0 + '@nomicfoundation/hardhat-network-helpers': ^1.0.0 + '@nomicfoundation/hardhat-verify': ^2.0.0 + '@typechain/ethers-v6': ^0.5.0 + '@typechain/hardhat': ^9.0.0 + '@types/chai': ^4.2.0 + '@types/mocha': '>=9.1.0' + '@types/node': '>=18.0.0' + chai: ^4.2.0 + ethers: ^6.4.0 + hardhat: ^2.11.0 + hardhat-gas-reporter: ^1.0.8 + solidity-coverage: ^0.8.1 + ts-node: '>=8.0.0' + typechain: ^8.3.0 + typescript: '>=4.5.0' + + '@nomicfoundation/hardhat-verify@2.0.8': + resolution: {integrity: sha512-x/OYya7A2Kcz+3W/J78dyDHxr0ezU23DKTrRKfy5wDPCnePqnr79vm8EXqX3gYps6IjPBYyGPZ9K6E5BnrWx5Q==} + peerDependencies: + hardhat: ^2.0.4 + + '@nomicfoundation/ignition-core@0.15.5': + resolution: {integrity: sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==} + + '@nomicfoundation/ignition-ui@0.15.5': + resolution: {integrity: sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==} + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': + resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': + resolution: {integrity: sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': + resolution: {integrity: sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': + resolution: {integrity: sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': + resolution: {integrity: sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': + resolution: {integrity: sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': + resolution: {integrity: sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer@0.1.2': + resolution: {integrity: sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==} + engines: {node: '>= 12'} + + '@openzeppelin/contracts@5.0.2': + resolution: {integrity: sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==} + + '@scure/base@1.1.7': + resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==} + + '@scure/bip32@1.1.5': + resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip39@1.1.1': + resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@sentry/core@5.30.0': + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} + engines: {node: '>=6'} + + '@sentry/hub@5.30.0': + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} + + '@sentry/minimal@5.30.0': + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} + + '@sentry/node@5.30.0': + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} + + '@sentry/tracing@5.30.0': + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} + + '@sentry/types@5.30.0': + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} + + '@sentry/utils@5.30.0': + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} + + '@solidity-parser/parser@0.14.5': + resolution: {integrity: sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==} + + '@solidity-parser/parser@0.18.0': + resolution: {integrity: sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@typechain/ethers-v6@0.5.1': + resolution: {integrity: sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==} + peerDependencies: + ethers: 6.x + typechain: ^8.3.2 + typescript: '>=4.7.0' + + '@typechain/hardhat@9.1.0': + resolution: {integrity: sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==} + peerDependencies: + '@typechain/ethers-v6': ^0.5.1 + ethers: ^6.1.0 + hardhat: ^2.9.9 + typechain: ^8.3.2 + + '@types/bn.js@4.11.6': + resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} + + '@types/bn.js@5.1.5': + resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} + + '@types/chai-as-promised@7.1.8': + resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} + + '@types/chai@4.3.16': + resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} + + '@types/concat-stream@1.6.1': + resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} + + '@types/form-data@0.0.33': + resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/lru-cache@5.1.1': + resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/mocha@10.0.7': + resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + '@types/node@18.15.13': + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + + '@types/node@20.14.10': + resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + + '@types/node@8.10.66': + resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} + + '@types/pbkdf2@3.1.2': + resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} + + '@types/prettier@2.7.3': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + + '@types/secp256k1@4.0.6': + resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} + + abbrev@1.0.9: + resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} + + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + adm-zip@0.4.16: + resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} + engines: {node: '>=0.3.0'} + + aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + amdefine@1.0.1: + resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} + engines: {node: '>=0.4.2'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + antlr4ts@0.5.0-alpha.4: + resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} + + array-back@4.0.2: + resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} + engines: {node: '>=8'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.10: + resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bn.js@4.11.6: + resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} + + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + cbor@8.1.0: + resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} + engines: {node: '>=12.19'} + + cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} + engines: {node: '>=16'} + + chai-as-promised@7.1.2: + resolution: {integrity: sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==} + peerDependencies: + chai: '>= 2.1.2 < 6' + + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-table3@0.5.1: + resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} + engines: {node: '>=6'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + + command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} + + command-line-usage@6.1.3: + resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} + engines: {node: '>=8.0.0'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + death@1.1.0: + resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + + difflib@0.2.4: + resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + + elliptic@6.5.5: + resolution: {integrity: sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escodegen@1.8.1: + resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} + engines: {node: '>=0.12.0'} + hasBin: true + + esprima@2.7.3: + resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} + engines: {node: '>=0.10.0'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estraverse@1.9.3: + resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} + engines: {node: '>=0.10.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eth-gas-reporter@0.2.27: + resolution: {integrity: sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==} + peerDependencies: + '@codechecks/client': ^0.1.0 + peerDependenciesMeta: + '@codechecks/client': + optional: true + + ethereum-bloom-filters@1.1.0: + resolution: {integrity: sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==} + deprecated: do not use this package use package versions above as this can miss some topics + + ethereum-cryptography@0.1.3: + resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} + + ethereum-cryptography@1.2.0: + resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + ethereumjs-abi@0.6.8: + resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} + + ethereumjs-util@6.2.1: + resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} + + ethereumjs-util@7.1.5: + resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} + engines: {node: '>=10.0.0'} + + ethers@5.7.2: + resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==} + + ethers@6.13.1: + resolution: {integrity: sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==} + engines: {node: '>=14.0.0'} + + ethjs-unit@0.1.6: + resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} + engines: {node: '>=6.5.0', npm: '>=3'} + + ethjs-util@0.1.6: + resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} + engines: {node: '>=6.5.0', npm: '>=3'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-uri@3.0.1: + resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fp-ts@1.19.3: + resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-port@3.2.0: + resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} + engines: {node: '>=4'} + + ghost-testrpc@0.0.2: + resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@5.0.15: + resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + globby@10.0.2: + resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} + engines: {node: '>=8'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + hardhat-gas-reporter@1.0.10: + resolution: {integrity: sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==} + peerDependencies: + hardhat: ^2.0.2 + + hardhat@2.22.6: + resolution: {integrity: sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==} + hasBin: true + peerDependencies: + ts-node: '*' + typescript: '*' + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + http-basic@8.1.3: + resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} + engines: {node: '>=6.0.0'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + immer@10.0.2: + resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==} + + immutable@4.3.6: + resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + io-ts@1.10.4: + resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.14.0: + resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hex-prefixed@1.0.0: + resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} + engines: {node: '>=6.5.0', npm: '>=3'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonschema@1.4.1: + resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==} + + keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} + engines: {node: '>=10.0.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + markdown-table@1.1.3: + resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mnemonist@0.38.5: + resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + + mocha@10.6.0: + resolution: {integrity: sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==} + engines: {node: '>= 14.0.0'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + ndjson@2.0.0: + resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==} + engines: {node: '>=10'} + hasBin: true + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + + node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + hasBin: true + + nofilter@3.1.0: + resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} + engines: {node: '>=12.19'} + + nopt@3.0.6: + resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + number-to-bn@1.7.0: + resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} + engines: {node: '>=6.5.0', npm: '>=3'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + ordinal@1.0.3: + resolution: {integrity: sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + qs@6.12.3: + resolution: {integrity: sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + recursive-readdir@2.2.3: + resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} + engines: {node: '>=6.0.0'} + + reduce-flatten@2.0.0: + resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + engines: {node: '>=6'} + + req-cwd@2.0.0: + resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} + engines: {node: '>=4'} + + req-from@2.0.0: + resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} + engines: {node: '>=4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + + resolve@1.1.7: + resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} + + resolve@1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + rlp@2.2.7: + resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sc-istanbul@0.4.6: + resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} + hasBin: true + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + secp256k1@4.0.3: + resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} + engines: {node: '>=10.0.0'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sha1@1.1.1: + resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + solc@0.8.26: + resolution: {integrity: sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==} + engines: {node: '>=10.0.0'} + hasBin: true + + solidity-coverage@0.8.12: + resolution: {integrity: sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==} + hasBin: true + peerDependencies: + hardhat: ^2.11.0 + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.2.0: + resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} + engines: {node: '>=0.8.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stacktrace-parser@0.1.10: + resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} + engines: {node: '>=6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string-format@2.0.0: + resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-hex-prefix@1.0.0: + resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} + engines: {node: '>=6.5.0', npm: '>=3'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + sync-request@6.1.0: + resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} + engines: {node: '>=8.0.0'} + + sync-rpc@1.3.6: + resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} + + table-layout@1.0.2: + resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} + engines: {node: '>=8.0.0'} + + table@6.8.2: + resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} + engines: {node: '>=10.0.0'} + + then-request@6.0.2: + resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} + engines: {node: '>=6.0.0'} + + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + ts-command-line-args@2.5.1: + resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} + hasBin: true + + ts-essentials@7.0.3: + resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} + peerDependencies: + typescript: '>=3.7.0' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + + tsort@0.0.1: + resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + + tweetnacl-util@0.15.1: + resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + typechain@8.3.2: + resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} + hasBin: true + peerDependencies: + typescript: '>=4.3.0' + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + + typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + + typical@5.2.0: + resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} + engines: {node: '>=8'} + + uglify-js@3.18.0: + resolution: {integrity: sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==} + engines: {node: '>=0.8.0'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + utf8@3.0.0: + resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + web3-utils@1.10.4: + resolution: {integrity: sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==} + engines: {node: '>=8.0.0'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wordwrapjs@4.0.1: + resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} + engines: {node: '>=8.0.0'} + + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.4.6: + resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@adraffy/ens-normalize@1.10.1': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@ethersproject/abi@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/abstract-provider@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + + '@ethersproject/abstract-signer@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/address@5.6.1': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/address@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/base64@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + + '@ethersproject/basex@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/bignumber@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/constants@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + + '@ethersproject/contracts@5.7.0': + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + + '@ethersproject/hash@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/hdnode@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + '@ethersproject/json-wallets@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + aes-js: 3.0.0 + scrypt-js: 3.0.1 + + '@ethersproject/keccak256@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.7.0': {} + + '@ethersproject/networks@5.7.1': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/pbkdf2@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/sha2': 5.7.0 + + '@ethersproject/properties@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/providers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + bech32: 1.1.4 + ws: 7.4.6(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethersproject/random@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/rlp@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/sha2@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + hash.js: 1.1.7 + + '@ethersproject/signing-key@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + + '@ethersproject/solidity@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/strings@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/transactions@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + + '@ethersproject/units@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/wallet@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + '@ethersproject/web@5.7.1': + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/wordlists@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@fastify/busboy@2.1.1': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@metamask/eth-sig-util@4.0.1': + dependencies: + ethereumjs-abi: 0.6.8 + ethereumjs-util: 6.2.1 + ethjs-util: 0.1.6 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/hashes@1.2.0': {} + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.4.0': {} + + '@noble/secp256k1@1.7.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nomicfoundation/edr-darwin-arm64@0.4.2': {} + + '@nomicfoundation/edr-darwin-x64@0.4.2': {} + + '@nomicfoundation/edr-linux-arm64-gnu@0.4.2': {} + + '@nomicfoundation/edr-linux-arm64-musl@0.4.2': {} + + '@nomicfoundation/edr-linux-x64-gnu@0.4.2': {} + + '@nomicfoundation/edr-linux-x64-musl@0.4.2': {} + + '@nomicfoundation/edr-win32-x64-msvc@0.4.2': {} + + '@nomicfoundation/edr@0.4.2': + dependencies: + '@nomicfoundation/edr-darwin-arm64': 0.4.2 + '@nomicfoundation/edr-darwin-x64': 0.4.2 + '@nomicfoundation/edr-linux-arm64-gnu': 0.4.2 + '@nomicfoundation/edr-linux-arm64-musl': 0.4.2 + '@nomicfoundation/edr-linux-x64-gnu': 0.4.2 + '@nomicfoundation/edr-linux-x64-musl': 0.4.2 + '@nomicfoundation/edr-win32-x64-msvc': 0.4.2 + + '@nomicfoundation/ethereumjs-common@4.0.4': + dependencies: + '@nomicfoundation/ethereumjs-util': 9.0.4 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-rlp@5.0.4': {} + + '@nomicfoundation/ethereumjs-tx@5.0.4': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/ethereumjs-util@9.0.4': + dependencies: + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/hardhat-chai-matchers@2.0.7(@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(chai@4.4.1)(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))': + dependencies: + '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@types/chai-as-promised': 7.1.8 + chai: 4.4.1 + chai-as-promised: 7.1.2(chai@4.4.1) + deep-eql: 4.1.4 + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + ordinal: 1.0.3 + + '@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))': + dependencies: + debug: 4.3.5(supports-color@8.1.1) + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + lodash.isequal: 4.5.0 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/hardhat-ignition-ethers@0.15.5(@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.5(@nomicfoundation/hardhat-verify@2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))': + dependencies: + '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition': 0.15.5(@nomicfoundation/hardhat-verify@2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/ignition-core': 0.15.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + + '@nomicfoundation/hardhat-ignition@0.15.5(@nomicfoundation/hardhat-verify@2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@nomicfoundation/hardhat-verify': 2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/ignition-core': 0.15.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@nomicfoundation/ignition-ui': 0.15.5 + chalk: 4.1.2 + debug: 4.3.5(supports-color@8.1.1) + fs-extra: 10.1.0 + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + prompts: 2.4.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@nomicfoundation/hardhat-network-helpers@1.0.11(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))': + dependencies: + ethereumjs-util: 7.1.5 + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + + '@nomicfoundation/hardhat-toolbox@5.0.0(hf4zzcstdnacbsmrqafg7ueixe)': + dependencies: + '@nomicfoundation/hardhat-chai-matchers': 2.0.7(@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(chai@4.4.1)(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition-ethers': 0.15.5(@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.5(@nomicfoundation/hardhat-verify@2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-network-helpers': 1.0.11(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': 2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + '@typechain/ethers-v6': 0.5.1(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3))(typescript@5.5.3) + '@typechain/hardhat': 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3))(typescript@5.5.3))(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3)) + '@types/chai': 4.3.16 + '@types/mocha': 10.0.7 + '@types/node': 20.14.10 + chai: 4.4.1 + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + hardhat-gas-reporter: 1.0.10(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + solidity-coverage: 0.8.12(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)) + ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3) + typechain: 8.3.2(typescript@5.5.3) + typescript: 5.5.3 + + '@nomicfoundation/hardhat-verify@2.0.8(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))': + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/address': 5.7.0 + cbor: 8.1.0 + chalk: 2.4.2 + debug: 4.3.5(supports-color@8.1.1) + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + lodash.clonedeep: 4.5.0 + semver: 6.3.1 + table: 6.8.2 + undici: 5.28.4 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/ignition-core@0.15.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/address': 5.6.1 + '@nomicfoundation/solidity-analyzer': 0.1.2 + cbor: 9.0.2 + debug: 4.3.5(supports-color@8.1.1) + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: 10.1.0 + immer: 10.0.2 + lodash: 4.17.21 + ndjson: 2.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@nomicfoundation/ignition-ui@0.15.5': {} + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer@0.1.2': + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.2 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.2 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.2 + + '@openzeppelin/contracts@5.0.2': {} + + '@scure/base@1.1.7': {} + + '@scure/bip32@1.1.5': + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/base': 1.1.7 + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + + '@scure/bip39@1.1.1': + dependencies: + '@noble/hashes': 1.2.0 + '@scure/base': 1.1.7 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + + '@sentry/core@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/hub@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/minimal@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sentry/node@5.30.0': + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + + '@sentry/tracing@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/types@5.30.0': {} + + '@sentry/utils@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@solidity-parser/parser@0.14.5': + dependencies: + antlr4ts: 0.5.0-alpha.4 + + '@solidity-parser/parser@0.18.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@typechain/ethers-v6@0.5.1(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3))(typescript@5.5.3)': + dependencies: + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + lodash: 4.17.21 + ts-essentials: 7.0.3(typescript@5.5.3) + typechain: 8.3.2(typescript@5.5.3) + typescript: 5.5.3 + + '@typechain/hardhat@9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3))(typescript@5.5.3))(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3))': + dependencies: + '@typechain/ethers-v6': 0.5.1(ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.3))(typescript@5.5.3) + ethers: 6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: 9.1.0 + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + typechain: 8.3.2(typescript@5.5.3) + + '@types/bn.js@4.11.6': + dependencies: + '@types/node': 20.14.10 + + '@types/bn.js@5.1.5': + dependencies: + '@types/node': 20.14.10 + + '@types/chai-as-promised@7.1.8': + dependencies: + '@types/chai': 4.3.16 + + '@types/chai@4.3.16': {} + + '@types/concat-stream@1.6.1': + dependencies: + '@types/node': 20.14.10 + + '@types/form-data@0.0.33': + dependencies: + '@types/node': 20.14.10 + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 20.14.10 + + '@types/lru-cache@5.1.1': {} + + '@types/minimatch@5.1.2': {} + + '@types/mocha@10.0.7': {} + + '@types/node@10.17.60': {} + + '@types/node@18.15.13': {} + + '@types/node@20.14.10': + dependencies: + undici-types: 5.26.5 + + '@types/node@8.10.66': {} + + '@types/pbkdf2@3.1.2': + dependencies: + '@types/node': 20.14.10 + + '@types/prettier@2.7.3': {} + + '@types/qs@6.9.15': {} + + '@types/secp256k1@4.0.6': + dependencies: + '@types/node': 20.14.10 + + abbrev@1.0.9: {} + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + adm-zip@0.4.16: {} + + aes-js@3.0.0: {} + + aes-js@4.0.0-beta.5: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.5(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.1 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + amdefine@1.0.1: + optional: true + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@3.0.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + antlr4ts@0.5.0-alpha.4: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-back@3.1.0: {} + + array-back@4.0.2: {} + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + asap@2.0.6: {} + + assertion-error@1.1.0: {} + + astral-regex@2.0.0: {} + + async@1.5.2: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + axios@1.7.2: + dependencies: + follow-redirects: 1.15.6(debug@4.3.5) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base-x@3.0.10: + dependencies: + safe-buffer: 5.2.1 + + bech32@1.1.4: {} + + binary-extensions@2.3.0: {} + + blakejs@1.2.1: {} + + bn.js@4.11.6: {} + + bn.js@4.12.0: {} + + bn.js@5.2.1: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-stdout@1.3.1: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + bs58@4.0.1: + dependencies: + base-x: 3.0.10 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.1 + optional: true + + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + camelcase@6.3.0: {} + + caseless@0.12.0: {} + + cbor@8.1.0: + dependencies: + nofilter: 3.1.0 + + cbor@9.0.2: + dependencies: + nofilter: 3.1.0 + + chai-as-promised@7.1.2(chai@4.4.1): + dependencies: + chai: 4.4.1 + check-error: 1.0.3 + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + charenc@0.0.2: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + ci-info@2.0.0: {} + + cipher-base@1.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + clean-stack@2.2.0: {} + + cli-boxes@2.2.1: {} + + cli-table3@0.5.1: + dependencies: + object-assign: 4.1.1 + string-width: 2.1.1 + optionalDependencies: + colors: 1.4.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colors@1.4.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + command-exists@1.2.9: {} + + command-line-args@5.2.1: + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + + command-line-usage@6.1.3: + dependencies: + array-back: 4.0.2 + chalk: 2.4.2 + table-layout: 1.0.2 + typical: 5.2.0 + + commander@8.3.0: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + cookie@0.4.2: {} + + core-util-is@1.0.3: {} + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + create-require@1.1.1: {} + + crypt@0.0.2: {} + + death@1.1.0: {} + + debug@4.3.5(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@4.0.0: {} + + deep-eql@4.1.4: + dependencies: + type-detect: 4.0.8 + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + diff@4.0.2: {} + + diff@5.2.0: {} + + difflib@0.2.4: + dependencies: + heap: 0.2.7 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + elliptic@6.5.4: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + elliptic@6.5.5: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@8.0.0: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + env-paths@2.2.1: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escodegen@1.8.1: + dependencies: + esprima: 2.7.3 + estraverse: 1.9.3 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.2.0 + + esprima@2.7.3: {} + + esprima@4.0.1: {} + + estraverse@1.9.3: {} + + esutils@2.0.3: {} + + eth-gas-reporter@0.2.27(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@solidity-parser/parser': 0.14.5 + axios: 1.7.2 + cli-table3: 0.5.1 + colors: 1.4.0 + ethereum-cryptography: 1.2.0 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-readdir-recursive: 1.1.0 + lodash: 4.17.21 + markdown-table: 1.1.3 + mocha: 10.6.0 + req-cwd: 2.0.0 + sha1: 1.1.1 + sync-request: 6.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + ethereum-bloom-filters@1.1.0: + dependencies: + '@noble/hashes': 1.4.0 + + ethereum-cryptography@0.1.3: + dependencies: + '@types/pbkdf2': 3.1.2 + '@types/secp256k1': 4.0.6 + blakejs: 1.2.1 + browserify-aes: 1.2.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + hash.js: 1.1.7 + keccak: 3.0.4 + pbkdf2: 3.1.2 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scrypt-js: 3.0.1 + secp256k1: 4.0.3 + setimmediate: 1.0.5 + + ethereum-cryptography@1.2.0: + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/bip32': 1.1.5 + '@scure/bip39': 1.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + ethereumjs-abi@0.6.8: + dependencies: + bn.js: 4.12.0 + ethereumjs-util: 6.2.1 + + ethereumjs-util@6.2.1: + dependencies: + '@types/bn.js': 4.11.6 + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.5.5 + ethereum-cryptography: 0.1.3 + ethjs-util: 0.1.6 + rlp: 2.2.7 + + ethereumjs-util@7.1.5: + dependencies: + '@types/bn.js': 5.1.5 + bn.js: 5.2.1 + create-hash: 1.2.0 + ethereum-cryptography: 0.1.3 + rlp: 2.2.7 + + ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/contracts': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/providers': 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/solidity': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/units': 5.7.0 + '@ethersproject/wallet': 5.7.0 + '@ethersproject/web': 5.7.1 + '@ethersproject/wordlists': 5.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ethers@6.13.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ethjs-unit@0.1.6: + dependencies: + bn.js: 4.11.6 + number-to-bn: 1.7.0 + + ethjs-util@0.1.6: + dependencies: + is-hex-prefixed: 1.0.0 + strip-hex-prefix: 1.0.0 + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-levenshtein@2.0.6: {} + + fast-uri@3.0.1: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-replace@3.0.0: + dependencies: + array-back: 3.1.0 + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat@5.0.2: {} + + follow-redirects@1.15.6(debug@4.3.5): + optionalDependencies: + debug: 4.3.5(supports-color@8.1.1) + + form-data@2.5.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fp-ts@1.19.3: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-readdir-recursive@1.1.0: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-port@3.2.0: {} + + ghost-testrpc@0.0.2: + dependencies: + chalk: 2.4.2 + node-emoji: 1.11.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@5.0.15: + dependencies: + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.1.7: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + globby@10.0.2: + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + glob: 7.2.3 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.18.0 + + hardhat-gas-reporter@1.0.10(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10): + dependencies: + array-uniq: 1.0.3 + eth-gas-reporter: 0.2.27(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + sha1: 1.1.1 + transitivePeerDependencies: + - '@codechecks/client' + - bufferutil + - debug + - utf-8-validate + + hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@metamask/eth-sig-util': 4.0.1 + '@nomicfoundation/edr': 0.4.2 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@nomicfoundation/solidity-analyzer': 0.1.2 + '@sentry/node': 5.30.0 + '@types/bn.js': 5.1.5 + '@types/lru-cache': 5.1.1 + adm-zip: 0.4.16 + aggregate-error: 3.1.0 + ansi-escapes: 4.3.2 + boxen: 5.1.2 + chalk: 2.4.2 + chokidar: 3.6.0 + ci-info: 2.0.0 + debug: 4.3.5(supports-color@8.1.1) + enquirer: 2.4.1 + env-paths: 2.2.1 + ethereum-cryptography: 1.2.0 + ethereumjs-abi: 0.6.8 + find-up: 2.1.0 + fp-ts: 1.19.3 + fs-extra: 7.0.1 + glob: 7.2.0 + immutable: 4.3.6 + io-ts: 1.10.4 + keccak: 3.0.4 + lodash: 4.17.21 + mnemonist: 0.38.5 + mocha: 10.6.0 + p-map: 4.0.0 + raw-body: 2.5.2 + resolve: 1.17.0 + semver: 6.3.1 + solc: 0.8.26(debug@4.3.5) + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + tsort: 0.0.1 + undici: 5.28.4 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3) + typescript: 5.5.3 + transitivePeerDependencies: + - bufferutil + - c-kzg + - supports-color + - utf-8-validate + + has-flag@1.0.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hash-base@3.1.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + heap@0.2.7: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + http-basic@8.1.3: + dependencies: + caseless: 0.12.0 + concat-stream: 1.6.2 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-response-object@3.0.2: + dependencies: + '@types/node': 10.17.60 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.1: {} + + immer@10.0.2: {} + + immutable@4.3.6: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + interpret@1.4.0: {} + + io-ts@1.10.4: + dependencies: + fp-ts: 1.19.3 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.14.0: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@2.0.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hex-prefixed@1.0.0: {} + + is-number@7.0.0: {} + + is-plain-obj@2.1.0: {} + + is-unicode-supported@0.1.0: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + js-sha3@0.8.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-schema-traverse@1.0.0: {} + + json-stringify-safe@5.0.1: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonschema@1.4.1: {} + + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.1 + readable-stream: 3.6.2 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.camelcase@4.3.0: {} + + lodash.clonedeep@4.5.0: {} + + lodash.isequal@4.5.0: {} + + lodash.truncate@4.4.2: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lru_map@0.3.3: {} + + make-error@1.3.6: {} + + markdown-table@1.1.3: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + memorystream@0.3.1: {} + + merge2@1.4.1: {} + + micro-ftch@0.3.1: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mnemonist@0.38.5: + dependencies: + obliterator: 2.0.4 + + mocha@10.6.0: + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.3.5(supports-color@8.1.1) + diff: 5.2.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.1.6 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + + ms@2.1.2: {} + + ms@2.1.3: {} + + ndjson@2.0.0: + dependencies: + json-stringify-safe: 5.0.1 + minimist: 1.2.8 + readable-stream: 3.6.2 + split2: 3.2.2 + through2: 4.0.2 + + neo-async@2.6.2: {} + + node-addon-api@2.0.2: {} + + node-emoji@1.11.0: + dependencies: + lodash: 4.17.21 + + node-gyp-build@4.8.1: {} + + nofilter@3.1.0: {} + + nopt@3.0.6: + dependencies: + abbrev: 1.0.9 + + normalize-path@3.0.0: {} + + number-to-bn@1.7.0: + dependencies: + bn.js: 4.11.6 + strip-hex-prefix: 1.0.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.2: {} + + obliterator@2.0.4: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + + ordinal@1.0.3: {} + + os-tmpdir@1.0.2: {} + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-try@1.0.0: {} + + parse-cache-control@1.0.1: {} + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + pathval@1.1.1: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + picomatch@2.3.1: {} + + pify@4.0.1: {} + + prelude-ls@1.1.2: {} + + prettier@2.8.8: {} + + process-nextick-args@2.0.1: {} + + promise@8.3.0: + dependencies: + asap: 2.0.6 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-from-env@1.1.0: {} + + qs@6.12.3: + dependencies: + side-channel: 1.0.6 + + queue-microtask@1.2.3: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + rechoir@0.6.2: + dependencies: + resolve: 1.22.8 + + recursive-readdir@2.2.3: + dependencies: + minimatch: 3.1.2 + + reduce-flatten@2.0.0: {} + + req-cwd@2.0.0: + dependencies: + req-from: 2.0.0 + + req-from@2.0.0: + dependencies: + resolve-from: 3.0.0 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resolve-from@3.0.0: {} + + resolve@1.1.7: {} + + resolve@1.17.0: + dependencies: + path-parse: 1.0.7 + + resolve@1.22.8: + dependencies: + is-core-module: 2.14.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + ripemd160@2.0.2: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + + rlp@2.2.7: + dependencies: + bn.js: 5.2.1 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + sc-istanbul@0.4.6: + dependencies: + abbrev: 1.0.9 + async: 1.5.2 + escodegen: 1.8.1 + esprima: 2.7.3 + glob: 5.0.15 + handlebars: 4.7.8 + js-yaml: 3.14.1 + mkdirp: 0.5.6 + nopt: 3.0.6 + once: 1.4.0 + resolve: 1.1.7 + supports-color: 3.2.3 + which: 1.3.1 + wordwrap: 1.0.0 + + scrypt-js@3.0.1: {} + + secp256k1@4.0.3: + dependencies: + elliptic: 6.5.5 + node-addon-api: 2.0.2 + node-gyp-build: 4.8.1 + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.6.2: {} + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sha1@1.1.1: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + solc@0.8.26(debug@4.3.5): + dependencies: + command-exists: 1.2.9 + commander: 8.3.0 + follow-redirects: 1.15.6(debug@4.3.5) + js-sha3: 0.8.0 + memorystream: 0.3.1 + semver: 5.7.2 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + + solidity-coverage@0.8.12(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10)): + dependencies: + '@ethersproject/abi': 5.7.0 + '@solidity-parser/parser': 0.18.0 + chalk: 2.4.2 + death: 1.1.0 + difflib: 0.2.4 + fs-extra: 8.1.0 + ghost-testrpc: 0.0.2 + global-modules: 2.0.0 + globby: 10.0.2 + hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3)(utf-8-validate@5.0.10) + jsonschema: 1.4.1 + lodash: 4.17.21 + mocha: 10.6.0 + node-emoji: 1.11.0 + pify: 4.0.1 + recursive-readdir: 2.2.3 + sc-istanbul: 0.4.6 + semver: 7.6.2 + shelljs: 0.8.5 + web3-utils: 1.10.4 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.2.0: + dependencies: + amdefine: 1.0.1 + optional: true + + source-map@0.6.1: {} + + split2@3.2.2: + dependencies: + readable-stream: 3.6.2 + + sprintf-js@1.0.3: {} + + stacktrace-parser@0.1.10: + dependencies: + type-fest: 0.7.1 + + statuses@2.0.1: {} + + string-format@2.0.0: {} + + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-hex-prefix@1.0.0: + dependencies: + is-hex-prefixed: 1.0.0 + + strip-json-comments@3.1.1: {} + + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + sync-request@6.1.0: + dependencies: + http-response-object: 3.0.2 + sync-rpc: 1.3.6 + then-request: 6.0.2 + + sync-rpc@1.3.6: + dependencies: + get-port: 3.2.0 + + table-layout@1.0.2: + dependencies: + array-back: 4.0.2 + deep-extend: 0.6.0 + typical: 5.2.0 + wordwrapjs: 4.0.1 + + table@6.8.2: + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + then-request@6.0.2: + dependencies: + '@types/concat-stream': 1.6.1 + '@types/form-data': 0.0.33 + '@types/node': 8.10.66 + '@types/qs': 6.9.15 + caseless: 0.12.0 + concat-stream: 1.6.2 + form-data: 2.5.1 + http-basic: 8.1.3 + http-response-object: 3.0.2 + promise: 8.3.0 + qs: 6.12.3 + + through2@4.0.2: + dependencies: + readable-stream: 3.6.2 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + ts-command-line-args@2.5.1: + dependencies: + chalk: 4.1.2 + command-line-args: 5.2.1 + command-line-usage: 6.1.3 + string-format: 2.0.0 + + ts-essentials@7.0.3(typescript@5.5.3): + dependencies: + typescript: 5.5.3 + + ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.10 + acorn: 8.12.1 + acorn-walk: 8.3.3 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tslib@1.14.1: {} + + tslib@2.4.0: {} + + tsort@0.0.1: {} + + tweetnacl-util@0.15.1: {} + + tweetnacl@1.0.3: {} + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + + type-detect@4.0.8: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + typechain@8.3.2(typescript@5.5.3): + dependencies: + '@types/prettier': 2.7.3 + debug: 4.3.5(supports-color@8.1.1) + fs-extra: 7.0.1 + glob: 7.1.7 + js-sha3: 0.8.0 + lodash: 4.17.21 + mkdirp: 1.0.4 + prettier: 2.8.8 + ts-command-line-args: 2.5.1 + ts-essentials: 7.0.3(typescript@5.5.3) + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + typedarray@0.0.6: {} + + typescript@5.5.3: {} + + typical@4.0.0: {} + + typical@5.2.0: {} + + uglify-js@3.18.0: + optional: true + + undici-types@5.26.5: {} + + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.1 + optional: true + + utf8@3.0.0: {} + + util-deprecate@1.0.2: {} + + uuid@8.3.2: {} + + v8-compile-cache-lib@3.0.1: {} + + web3-utils@1.10.4: + dependencies: + '@ethereumjs/util': 8.1.0 + bn.js: 5.2.1 + ethereum-bloom-filters: 1.1.0 + ethereum-cryptography: 2.2.1 + ethjs-unit: 0.1.6 + number-to-bn: 1.7.0 + randombytes: 2.1.0 + utf8: 3.0.0 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wordwrapjs@4.0.1: + dependencies: + reduce-flatten: 2.0.0 + typical: 5.2.0 + + workerpool@6.5.1: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@7.4.6(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + y18n@5.0.8: {} + + yargs-parser@20.2.9: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/scilla-contracts/scripts/debug.ts b/scilla-contracts/scripts/debug.ts new file mode 100644 index 0000000..f5c99ff --- /dev/null +++ b/scilla-contracts/scripts/debug.ts @@ -0,0 +1,32 @@ +import { ethers, config } from "hardhat"; +import { ScillaContract, initZilliqa } from "hardhat-scilla-plugin"; + +async function main() { + const network = config.networks[hre.network.name]; + const privateKeys = network.accounts[0]; + const networkUrl = network.url; + const chain_id = network.chainId & ~0x8000; + initZilliqa(networkUrl, chain_id, [privateKeys], 40); + let account = hre.zilliqa.getDefaultAccount(); + let targetAddress = process.env.TEST_ADDRESS; + let tokenContractAddress = process.env.SCILLA_TOKEN_ADDRESS; + let evmContractAddress = process.env.EVM_TOKEN_ADDRESS; + console.log(`Balance of ${targetAddress} in ${tokenContractAddress} .. `); + let tokenContract = + await hre.interactWithScillaContract(tokenContractAddress); + console.log(`${JSON.stringify(tokenContract)}`); + console.log(`${JSON.stringify(tokenContract.balances())}`); + let factory = await ethers.getContractFactory("ZRC2ProxyForZRC2"); + console.log(`factory is ${factory}`); + const contract = await factory.attach(evmContractAddress); + console.log("got contract"); + let result = await contract.balanceOf(targetAddress); + console.log(` .... ${result}`); +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scilla-contracts/scripts/deploy.ts b/scilla-contracts/scripts/deploy.ts new file mode 100644 index 0000000..ff7ee8d --- /dev/null +++ b/scilla-contracts/scripts/deploy.ts @@ -0,0 +1,68 @@ +import { ethers, config } from "hardhat"; +import { ScillaContract, initZilliqa } from "hardhat-scilla-plugin"; + +function addressToConstant(address: string) { + let val = address; + if (address.startsWith("0x")) { + val = address.substring(2); + } + return "0x00" + val; +} + +async function main() { + const network = config.networks[hre.network.name]; + const privateKeys = network.accounts[0]; + const networkUrl = network.url; + const chain_id = network.chainId & ~0x8000; + initZilliqa(networkUrl, chain_id, [privateKeys], 40); + let account = hre.zilliqa.getDefaultAccount(); + console.log(`Deploying from ${account.address}`); + const zqTestnetTokenManager = process.env.TOKEN_MANAGER_ADDRESS; + if (zqTestnetTokenManager === undefined) { + throw new Error("No TOKEN_MANAGER_ADDRESS"); + } + let tokenContract = await hre.deployScillaContract( + "SwitcheoTokenZRC2", + "Bridged-XTST", + "XTST", + account.address, + 3, + 0, + zqTestnetTokenManager, + ); + console.log( + ` address public constant zqBridgedERC20Address = address(${addressToConstant(tokenContract.address)})`, + ); + + let nativeBridgedContract = await hre.deployScillaContract( + "SwitcheoTokenZRC2", + "Bridged-BNB", + "eBNB", + account.address, + 18, + 0, + zqTestnetTokenManager, + ); + console.log( + ` address public constant zqBridgedBNBAddress = address(${addressToConstant(nativeBridgedContract.address)})`, + ); + + let local = await hre.deployScillaContract( + "FungibleToken", + account.address, + "zq_native Test", + "ZTST", + 3, + 1_000_000_000, + ); + console.log( + ` address public constant zqZRC2Address = address(${addressToConstant(local.address)})`, + ); +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scilla-contracts/scripts/transfer.ts b/scilla-contracts/scripts/transfer.ts new file mode 100644 index 0000000..86528b9 --- /dev/null +++ b/scilla-contracts/scripts/transfer.ts @@ -0,0 +1,28 @@ +import { ethers, config } from "hardhat"; +import { ScillaContract, initZilliqa } from "hardhat-scilla-plugin"; + +async function main() { + const network = config.networks[hre.network.name]; + const privateKeys = network.accounts[0]; + const networkUrl = network.url; + const chain_id = network.chainId & ~0x8000; + initZilliqa(networkUrl, chain_id, [privateKeys], 40); + let account = hre.zilliqa.getDefaultAccount(); + let targetAddress = process.env.ZILBRIDGE_TEST_ADDRESS; + let testAmount = process.env.ZILBRIDGE_TEST_AMOUNT; + let tokenContractAddress = process.env.ZILBRIDGE_SCILLA_TOKEN_ADDRESS; + console.log( + `transferring ${testAmount} of ${tokenContractAddress} from ${account.address} to ${targetAddress}`, + ); + let tokenContract = + await hre.interactWithScillaContract(tokenContractAddress); + let result = await tokenContract.Transfer(targetAddress, testAmount); + console.log(`result = ${JSON.stringify(result)}`); +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scilla-contracts/tsconfig.json b/scilla-contracts/tsconfig.json new file mode 100644 index 0000000..574e785 --- /dev/null +++ b/scilla-contracts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } +} diff --git a/smart-contracts/README.md b/smart-contracts/README.md index 4f65145..5c1c835 100644 --- a/smart-contracts/README.md +++ b/smart-contracts/README.md @@ -277,16 +277,21 @@ Deterministic deployer not available, simple CREATE was used ### Zilliqa Testnet +See `script/configTestnet.s.sol` for up to date information. + - `ChainId`: 33101 - `ChainGateway`: `0x7370e69565BB2313C4dA12F9062C282513919230` - `ValidatorManager`: `0x782F8afa1bA3137a214D49840688215a8A379fA8` - `LockAndReleaseTokenManager`: `0x1509988c41f02014aA59d455c6a0D67b5b50f129` - `TestTokenZRC2Proxy`: `0x8618d39a8276D931603c6Bc7306af6A53aD2F1F3` +- `LockAndReleaseOrNativeTokenManager`: `0xBe90AB2cd65E207F097bEF733F8D239A59698b8A` Deterministic deployer not available, simple CREATE was used ### BSC Testnet +See `script/configTestnet.s.sol` for up to date information. + - `ChainId`: 97 - `ChainGateway`: `0xa9A14C90e53EdCD89dFd201A3bF94D867f8098fE` - `ValidatorManager`: `0xCc1CB36d981ae2907cea385F615e879434D20B1C` diff --git a/smart-contracts/contracts/periphery/LockProxyTokenManagerStorage.sol b/smart-contracts/contracts/periphery/LockProxyTokenManagerStorage.sol new file mode 100644 index 0000000..80e59ab --- /dev/null +++ b/smart-contracts/contracts/periphery/LockProxyTokenManagerStorage.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + +interface ILockProxyTokenManagerStorage { + event LockProxyUpdated(address oldLockProxy, address newLockProxy); + function getLockProxy() external view returns (address); + function setLockProxy(address lockProxy) external; +} + +abstract contract LockProxyTokenManagerStorage is ILockProxyTokenManagerStorage { + /// @custom:storage-location erc7201:zilliqa.storage.LockProxyTokenManagerStorage + struct LockProxyTokenManagerStorageStruct { + address lockProxy; + } + + // keccack256(abi.encode(uint256(keccack256("zilliqa.storage.LockProxyTokenManagerStorage"))-1)) & ~bytes32(uint256(0xff)) + bytes32 private constant Lock_Proxy_Storage_Location = 0xb22af1dfa3d79e3af56bf3b03e8c9cb6d48fc6bbb7ec48dcbfc0dbccf342f800; + + function _getLockProxyTokenManagerStorageStruct() private pure returns (LockProxyTokenManagerStorageStruct storage $) + { + assembly { + $.slot := Lock_Proxy_Storage_Location + } + } + + function getLockProxy() public view returns (address) { + LockProxyTokenManagerStorageStruct storage $ = _getLockProxyTokenManagerStorageStruct(); + return $.lockProxy; + } + + function _setLockProxy(address lockProxy) internal { + LockProxyTokenManagerStorageStruct storage $ = _getLockProxyTokenManagerStorageStruct(); + emit LockProxyUpdated($.lockProxy, lockProxy); + $.lockProxy = lockProxy; + } +} diff --git a/smart-contracts/contracts/periphery/LockProxyTokenManagerUpgradeable.sol b/smart-contracts/contracts/periphery/LockProxyTokenManagerUpgradeable.sol new file mode 100644 index 0000000..cb145f8 --- /dev/null +++ b/smart-contracts/contracts/periphery/LockProxyTokenManagerUpgradeable.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {TokenManagerUpgradeable, ITokenManager} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import { ILockProxyTokenManagerStorage, LockProxyTokenManagerStorage } from "contracts/periphery/LockProxyTokenManagerStorage.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +interface ILockProxyTokenManager is ITokenManager { + // Args in this order to match other token managers. + event SentToLockProxy(address indexed token, address indexed sender, uint amount); + event WithdrawnFromLockProxy(address indexed token, address indexed receipient, uint amount); + function setLockProxy(address lockProxy) external; +} + +// This contract exists almost entirely to be used in tests to prove upgradeability. +contract LockProxyTokenManagerUpgradeable is + ILockProxyTokenManager, + TokenManagerUpgradeable, + LockProxyTokenManagerStorage +{ + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + + function setLockProxy(address lockProxy) external override(ILockProxyTokenManagerStorage, ILockProxyTokenManager) onlyOwner { + _setLockProxy(lockProxy); + } + + function initialize(address _gateway, address lockProxy) external initializer { + __TokenManager_init(_gateway); + // for some reason we can't call setLockProxy() here, so .. + _setLockProxy(lockProxy); + } + + // Outgoing + function _handleTransfer( + address /* token */, + address /* from */, + uint /* amount */ + ) pure internal override { + revert(); + } + + // Incoming + function _handleAccept( + address /* token */, + address /* recipient */, + uint /* amount */ + ) pure internal override { + revert(); + } +} diff --git a/smart-contracts/contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol b/smart-contracts/contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol new file mode 100644 index 0000000..a17ede0 --- /dev/null +++ b/smart-contracts/contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {TokenManagerUpgradeableV3, ITokenManager} from "contracts/periphery/TokenManagerV3/TokenManagerUpgradeableV3.sol"; +import {IERC20} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {IRelayer, CallMetadata} from "contracts/core/Relayer.sol"; + +interface ILockAndReleaseOrNativeTokenManager { + event Locked(address indexed token, address indexed from, uint amount); + event Released( + address indexed token, + address indexed recipient, + uint amount + ); +} + +contract LockAndReleaseOrNativeTokenManagerUpgradeableV3 is + ILockAndReleaseOrNativeTokenManager, + TokenManagerUpgradeableV3 +{ + address public constant NATIVE_ASSET_HASH = address(0); + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @dev Allow this contract to receive native tokens. + receive() external payable {} + + // Outgoing + function _handleTransfer( + address token, + address from, + uint amount + ) internal override { + if (token == NATIVE_ASSET_HASH) { + (bool success, ) = payable(this).call{ value: amount }(""); + require(success, "Native asset transfer failed"); + } else { + IERC20(token).transferFrom(from, address(this), amount); + } + emit Locked(token, from, amount); + } + + // Incoming + function _handleAccept( + address token, + address recipient, + uint amount + ) internal override { + if (token == NATIVE_ASSET_HASH) { + (bool success, ) = recipient.call{value: amount}(""); + require(success, "Native asset transfer failed"); + } else { + IERC20(token).transfer(recipient, amount); + } + emit Released(token, recipient, amount); + } + + function xtransfer( + address token, + uint remoteChainId, + address remoteRecipient, + uint amount + ) external payable virtual whenNotPaused checkFees { + RemoteToken memory remoteToken = getRemoteTokens(token, remoteChainId); + + // Works here. + _handleTransfer(token, _msgSender(), amount); + + // Works here. + IRelayer(getGateway()).relayWithMetadata( + remoteToken.chainId, + remoteToken.tokenManager, + this.accept.selector, + abi.encode(AcceptArgs(remoteToken.token, remoteRecipient, amount)), + 1_000_000 + ); + // Fails here. + } +} diff --git a/smart-contracts/contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol b/smart-contracts/contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol new file mode 100644 index 0000000..2e61fe0 --- /dev/null +++ b/smart-contracts/contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {TokenManagerUpgradeableV3, ITokenManager} from "contracts/periphery/TokenManagerV3/TokenManagerUpgradeableV3.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import {IERC20} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import { ILockProxyTokenManagerStorage, LockProxyTokenManagerStorage } from "contracts/periphery/LockProxyTokenManagerStorage.sol"; + +interface ILockProxyTokenManager is ILockProxyTokenManagerStorage { + // Args in this order to match other token managers. + event SentToLockProxy(address indexed token, address indexed sender, uint amount); + event WithdrawnFromLockProxy(address indexed token, address indexed receipient, uint amount); +} + +// Exists purely so that we can call the extensionTransfer() endpoint on the lock proxy without having +// to include its code here. +interface ILockProxyExtensionTransfer { + function extensionTransfer( + address _receivingAddress, + address _assetHash, + uint256 _amount + ) + external + returns (bool); +} + +// This is the lock proxy token manager that runs on EVM chains. It talks to an EVM LockProxy. +contract LockProxyTokenManagerUpgradeableV3 is TokenManagerUpgradeableV3, ILockProxyTokenManager, LockProxyTokenManagerStorage { + address public constant NATIVE_ASSET_HASH = address(0); + + constructor() { + _disableInitializers(); + } + + function reinitialize(uint fees) external reinitializer(2) { + _setFees(fees); + } + + // Incoming currency - transfer into the lock proxy + function _handleTransfer(address token, address from, uint amount) internal override { + address lockProxyAddress = getLockProxy(); + // Just transfer value to the lock proxy. + if (token == NATIVE_ASSET_HASH) { + (bool success, ) = lockProxyAddress.call{value: amount}(""); + emit SentToLockProxy(token, from, amount); + require(success, "Transfer failed"); + return; + } + + IERC20 erc20token = IERC20(token); + erc20token.transferFrom(from, address(lockProxyAddress), amount); + emit SentToLockProxy(token, from, amount); + } + + function _handleAccept(address token, address recipient, uint amount) internal override { + address lockProxyAddress = getLockProxy(); + ILockProxyExtensionTransfer lp = ILockProxyExtensionTransfer(payable(lockProxyAddress)); + // Sadly, extensionTransfer() takes the same arguments as the withdrawn event but in a + // different order. This will automagically transfer native token if token==0. + + // Native tokens are transferred by the call; for everyone else, it sets an allowance and we + // then do the transfer from here. + if (token == address(0)) { + lp.extensionTransfer(recipient, address(0), amount); + } else { + lp.extensionTransfer(address(this), token, amount); + IERC20 erc20token = IERC20(token); + erc20token.transferFrom(address(lp), recipient, amount); + } + emit WithdrawnFromLockProxy(token, recipient, amount); + } + + function setLockProxy(address lockProxy) external onlyOwner { + _setLockProxy(lockProxy); + } + +} diff --git a/smart-contracts/contracts/periphery/ZilBridge/ccmCrossChainManager.sol b/smart-contracts/contracts/periphery/ZilBridge/ccmCrossChainManager.sol new file mode 100644 index 0000000..cbbffd1 --- /dev/null +++ b/smart-contracts/contracts/periphery/ZilBridge/ccmCrossChainManager.sol @@ -0,0 +1,1618 @@ +/** + *Submitted for verification at Etherscan.io on 2021-10-19 +*/ + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.2; + +abstract contract Context { + // Empty internal constructor, to prevent people from mistakenly deploying + // an instance of this contract, which should be used via inheritance. + constructor () { } + // solhint-disable-previous-line no-empty-blocks + + function _msgSender() internal view returns (address payable) { + return payable(msg.sender); + } + + function _msgData() internal view returns (bytes memory) { + this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 + return msg.data; + } +} + +interface IOwnable { + function isOwner() external view returns (bool); +} + +abstract contract Ownable is Context, IOwnable { + address private _owner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor () { + address msgSender = _msgSender(); + _owner = msgSender; + emit OwnershipTransferred(address(0), msgSender); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(isOwner(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Returns true if the caller is the current owner. + */ + function isOwner() public view returns (bool) { + return _msgSender() == _owner; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public onlyOwner { + emit OwnershipTransferred(_owner, address(0)); + _owner = address(0); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public onlyOwner { + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + */ + function _transferOwnership(address newOwner) internal { + require(newOwner != address(0), "Ownable: new owner is the zero address"); + emit OwnershipTransferred(_owner, newOwner); + _owner = newOwner; + } +} + +interface IPausable { + function paused() external view returns (bool); +} + +abstract contract Pausable is Context, IPausable { + /** + * @dev Emitted when the pause is triggered by a pauser (`account`). + */ + event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by a pauser (`account`). + */ + event Unpaused(address account); + + bool private _paused; + + /** + * @dev Initializes the contract in unpaused state. + */ + constructor () { + _paused = false; + } + + /** + * @dev Returns true if the contract is paused, and false otherwise. + */ + function paused() public view returns (bool) { + return _paused; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + */ + modifier whenNotPaused() { + require(!_paused, "Pausable: paused"); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + */ + modifier whenPaused() { + require(_paused, "Pausable: not paused"); + _; + } + + /** + * @dev Called to pause, triggers stopped state. + */ + function _pause() internal whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Called to unpause, returns to normal state. + */ + function _unpause() internal whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} + +library ZeroCopySink { + /* @notice Convert boolean value into bytes + * @param b The boolean value + * @return Converted bytes array + */ + function WriteBool(bool b) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + switch iszero(b) + case 1 { + mstore(add(buff, 0x20), shl(248, 0x00)) + // mstore8(add(buff, 0x20), 0x00) + } + default { + mstore(add(buff, 0x20), shl(248, 0x01)) + // mstore8(add(buff, 0x20), 0x01) + } + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert byte value into bytes + * @param b The byte value + * @return Converted bytes array + */ + function WriteByte(bytes1 b) internal pure returns (bytes memory) { + return WriteUint8(uint8(b)); + } + + /* @notice Convert uint8 value into bytes + * @param v The uint8 value + * @return Converted bytes array + */ + function WriteUint8(uint8 v) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + mstore(add(buff, 0x20), shl(248, v)) + // mstore(add(buff, 0x20), byte(0x1f, v)) + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert uint16 value into bytes + * @param v The uint16 value + * @return Converted bytes array + */ + function WriteUint16(uint16 v) internal pure returns (bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x02 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x22)) + } + return buff; + } + + /* @notice Convert uint32 value into bytes + * @param v The uint32 value + * @return Converted bytes array + */ + function WriteUint32(uint32 v) internal pure returns(bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + let byteLen := 0x04 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x24)) + } + return buff; + } + + /* @notice Convert uint64 value into bytes + * @param v The uint64 value + * @return Converted bytes array + */ + function WriteUint64(uint64 v) internal pure returns(bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x08 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x28)) + } + return buff; + } + + /* @notice Convert limited uint256 value into bytes + * @param v The uint256 value + * @return Converted bytes array + */ + function WriteUint255(uint256 v) internal pure returns (bytes memory) { + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds uint255 range"); + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x20 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x40)) + } + return buff; + } + + /* @notice Encode bytes format data into bytes + * @param data The bytes array data + * @return Encoded bytes array + */ + function WriteVarBytes(bytes memory data) internal pure returns (bytes memory) { + uint64 l = uint64(data.length); + return abi.encodePacked(WriteVarUint(l), data); + } + + function WriteVarUint(uint64 v) internal pure returns (bytes memory) { + if (v < 0xFD){ + return WriteUint8(uint8(v)); + } else if (v <= 0xFFFF) { + return abi.encodePacked(WriteByte(0xFD), WriteUint16(uint16(v))); + } else if (v <= 0xFFFFFFFF) { + return abi.encodePacked(WriteByte(0xFE), WriteUint32(uint32(v))); + } else { + return abi.encodePacked(WriteByte(0xFF), WriteUint64(uint64(v))); + } + } +} + +library ZeroCopySource { + /* @notice Read next byte as boolean type starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the boolean value + * @return The the read boolean value and new offset + */ + function NextBool(bytes memory buff, uint256 offset) internal pure returns(bool, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "Offset exceeds limit"); + // byte === bytes1 + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + bool value; + if (v == 0x01) { + value = true; + } else if (v == 0x00) { + value = false; + } else { + revert("NextBool value error"); + } + return (value, offset + 1); + } + + /* @notice Read next byte starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read byte value and new offset + */ + function NextByte(bytes memory buff, uint256 offset) internal pure returns (bytes1, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextByte, Offset exceeds maximum"); + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + return (v, offset + 1); + } + + /* @notice Read next byte as uint8 starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read uint8 value and new offset + */ + function NextUint8(bytes memory buff, uint256 offset) internal pure returns (uint8, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextUint8, Offset exceeds maximum"); + uint8 v; + assembly{ + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x01)) + v := mload(sub(tmpbytes, 0x1f)) + } + return (v, offset + 1); + } + + /* @notice Read next two bytes as uint16 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint16 value + * @return The read uint16 value and updated offset + */ + function NextUint16(bytes memory buff, uint256 offset) internal pure returns (uint16, uint256) { + require(offset + 2 <= buff.length && offset < offset + 2, "NextUint16, offset exceeds maximum"); + + uint16 v; + assembly { + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0x01, bvalue)) + mstore8(add(tmpbytes, 0x01), byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x02)) + v := mload(sub(tmpbytes, 0x1e)) + } + return (v, offset + 2); + } + + + /* @notice Read next four bytes as uint32 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint32 value + * @return The read uint32 value and updated offset + */ + function NextUint32(bytes memory buff, uint256 offset) internal pure returns (uint32, uint256) { + require(offset + 4 <= buff.length && offset < offset + 4, "NextUint32, offset exceeds maximum"); + uint32 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x04 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 4); + } + + /* @notice Read next eight bytes as uint64 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint64 value + * @return The read uint64 value and updated offset + */ + function NextUint64(bytes memory buff, uint256 offset) internal pure returns (uint64, uint256) { + require(offset + 8 <= buff.length && offset < offset + 8, "NextUint64, offset exceeds maximum"); + uint64 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x08 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 8); + } + + /* @notice Read next 32 bytes as uint256 type starting from offset, + there are limits considering the numerical limits in multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the uint256 value + * @return The read uint256 value and updated offset + */ + function NextUint255(bytes memory buff, uint256 offset) internal pure returns (uint256, uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextUint255, offset exceeds maximum"); + uint256 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x20 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(tmpbytes) + } + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + return (v, offset + 32); + } + /* @notice Read next variable bytes starting from offset, + the decoding rule coming from multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read variable bytes array value and updated offset + */ + function NextVarBytes(bytes memory buff, uint256 offset) internal pure returns(bytes memory, uint256) { + uint len; + (len, offset) = NextVarUint(buff, offset); + require(offset + len <= buff.length && offset < offset + len, "NextVarBytes, offset exceeds maximum"); + bytes memory tempBytes; + assembly{ + switch iszero(len) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + let lengthmod := and(len, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, len) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(buff, lengthmod), mul(0x20, iszero(lengthmod))), offset) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, len) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return (tempBytes, offset + len); + } + /* @notice Read next 32 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes32 value and updated offset + */ + function NextHash(bytes memory buff, uint256 offset) internal pure returns (bytes32 , uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextHash, offset exceeds maximum"); + bytes32 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 32); + } + + /* @notice Read next 20 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes20 value and updated offset + */ + function NextBytes20(bytes memory buff, uint256 offset) internal pure returns (bytes20 , uint256) { + require(offset + 20 <= buff.length && offset < offset + 20, "NextBytes20, offset exceeds maximum"); + bytes20 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 20); + } + + function NextVarUint(bytes memory buff, uint256 offset) internal pure returns(uint, uint256) { + bytes1 v; + (v, offset) = NextByte(buff, offset); + + uint value; + if (v == 0xFD) { + // return NextUint16(buff, offset); + (value, offset) = NextUint16(buff, offset); + require(value >= 0xFD && value <= 0xFFFF, "NextUint16, value outside range"); + return (value, offset); + } else if (v == 0xFE) { + // return NextUint32(buff, offset); + (value, offset) = NextUint32(buff, offset); + require(value > 0xFFFF && value <= 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else if (v == 0xFF) { + // return NextUint64(buff, offset); + (value, offset) = NextUint64(buff, offset); + require(value > 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else{ + // return (uint8(v), offset); + value = uint8(v); + require(value < 0xFD, "NextVarUint, value outside range"); + return (value, offset); + } + } +} + +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + * + * _Available since v2.4.0._ + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + * + * _Available since v2.4.0._ + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b != 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + * + * _Available since v2.4.0._ + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} + + +library Utils { + + /* @notice Convert the bytes array to bytes32 type, the bytes array length must be 32 + * @param _bs Source bytes array + * @return bytes32 + */ + function bytesToBytes32(bytes memory _bs) internal pure returns (bytes32 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 0x20 since the first 0x20 bytes stores _bs length + value := mload(add(_bs, 0x20)) + } + } + + /* @notice Convert bytes to uint256 + * @param _b Source bytes should have length of 32 + * @return uint256 + */ + function bytesToUint256(bytes memory _bs) internal pure returns (uint256 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 32 + value := mload(add(_bs, 0x20)) + } + require(value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + } + + /* @notice Convert uint256 to bytes + * @param _b uint256 that needs to be converted + * @return bytes + */ + function uint256ToBytes(uint256 _value) internal pure returns (bytes memory bs) { + require(_value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 0x20 at the first word, the length of bytes for uint256 value + mstore(bs, 0x20) + //In the next word, put value in bytes format to the next 32 bytes + mstore(add(bs, 0x20), _value) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Convert bytes to address + * @param _bs Source bytes: bytes length must be 20 + * @return Converted address from source bytes + */ + function bytesToAddress(bytes memory _bs) internal pure returns (address addr) + { + require(_bs.length == 20, "bytes length does not match address"); + assembly { + // for _bs, first word store _bs.length, second word store _bs.value + // load 32 bytes from mem[_bs+20], convert it into Uint160, meaning we take last 20 bytes as addr (address). + addr := mload(add(_bs, 0x14)) + } + + } + + /* @notice Convert address to bytes + * @param _addr Address need to be converted + * @return Converted bytes from address + */ + function addressToBytes(address _addr) internal pure returns (bytes memory bs){ + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 20 (address byte length) at the first word, the length of bytes for uint256 value + mstore(bs, 0x14) + // logical shift left _a by 12 bytes, change _a from right-aligned to left-aligned + mstore(add(bs, 0x20), shl(96, _addr)) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Do hash leaf as the multi-chain does + * @param _data Data in bytes format + * @return Hashed value in bytes32 format + */ + function hashLeaf(bytes memory _data) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x0), _data)); + } + + /* @notice Do hash children as the multi-chain does + * @param _l Left node + * @param _r Right node + * @return Hashed value in bytes32 format + */ + function hashChildren(bytes32 _l, bytes32 _r) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x01), _l, _r)); + } + + /* @notice Compare if two bytes are equal, which are in storage and memory, seperately + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L368 + * @param _preBytes The bytes stored in storage + * @param _postBytes The bytes stored in memory + * @return Bool type indicating if they are equal + */ + function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { + bool success = true; + + assembly { + // we know _preBytes_offset is 0 + let fslot := sload(_preBytes.slot) + // Arrays of 31 bytes or less have an even value in their slot, + // while longer arrays have an odd value. The actual length is + // the slot divided by two for odd values, and the lowest order + // byte divided by two for even values. + // If the slot is even, bitwise and the slot with 255 and divide by + // two to get the length. If the slot is odd, bitwise and the slot + // with -1 and divide by two. + let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) + let mlength := mload(_postBytes) + + // if lengths don't match the arrays are not equal + switch eq(slength, mlength) + case 1 { + // fslot can contain both the length and contents of the array + // if slength < 32 bytes so let's prepare for that + // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage + // slength != 0 + if iszero(iszero(slength)) { + switch lt(slength, 32) + case 1 { + // blank the last byte which is the length + fslot := mul(div(fslot, 0x100), 0x100) + + if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { + // unsuccess: + success := 0 + } + } + default { + // cb is a circuit breaker in the for loop since there's + // no said feature for inline assembly loops + // cb = 1 - don't breaker + // cb = 0 - break + let cb := 1 + + // get the keccak hash to get the contents of the array + mstore(0x0, _preBytes.slot) + let sc := keccak256(0x0, 0x20) + + let mc := add(_postBytes, 0x20) + let end := add(mc, mlength) + + // the next line is the loop condition: + // while(uint(mc < end) + cb == 2) + for {} eq(add(lt(mc, end), cb), 2) { + sc := add(sc, 1) + mc := add(mc, 0x20) + } { + if iszero(eq(sload(sc), mload(mc))) { + // unsuccess: + success := 0 + cb := 0 + } + } + } + } + } + default { + // unsuccess: + success := 0 + } + } + + return success; + } + + /* @notice Slice the _bytes from _start index till the result has length of _length + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L246 + * @param _bytes The original bytes needs to be sliced + * @param _start The index of _bytes for the start of sliced bytes + * @param _length The index of _bytes for the end of sliced bytes + * @return The sliced bytes + */ + function slice( + bytes memory _bytes, + uint _start, + uint _length + ) + internal + pure + returns (bytes memory) + { + require(_bytes.length >= (_start + _length)); + + bytes memory tempBytes; + + assembly { + switch iszero(_length) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + // lengthmod <= _length % 32 + let lengthmod := and(_length, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, _length) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, _length) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return tempBytes; + } + /* @notice Check if the elements number of _signers within _keepers array is no less than _m + * @param _keepers The array consists of serveral address + * @param _signers Some specific addresses to be looked into + * @param _m The number requirement paramter + * @return True means containment, false meansdo do not contain. + */ + function containMAddresses(address[] memory _keepers, address[] memory _signers, uint _m) internal pure returns (bool){ + uint m = 0; + for(uint i = 0; i < _signers.length; i++){ + for (uint j = 0; j < _keepers.length; j++) { + if (_signers[i] == _keepers[j]) { + m++; + delete _keepers[j]; + } + } + } + return m >= _m; + } + + /* @notice TODO + * @param key + * @return + */ + function compressMCPubKey(bytes memory key) internal pure returns (bytes memory newkey) { + require(key.length >= 67, "key lenggh is too short"); + newkey = slice(key, 0, 35); + if (uint8(key[66]) % 2 == 0){ + newkey[2] = bytes1(0x02); + } else { + newkey[2] = bytes1(0x03); + } + return newkey; + } + + /** + * @dev Returns true if `account` is a contract. + * Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L18 + * + * This test is non-exhaustive, and there may be false-negatives: during the + * execution of a contract's constructor, its address will be reported as + * not containing a contract. + * + * IMPORTANT: It is unsafe to assume that an address for which this + * function returns false is an externally-owned account (EOA) and not a + * contract. + */ + function isContract(address account) internal view returns (bool) { + // This method relies in extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != 0x0 && codehash != accountHash); + } +} + +library ECCUtils { + using SafeMath for uint256; + + struct Header { + uint32 version; + uint64 chainId; + uint32 timestamp; + uint32 height; + uint64 consensusData; + bytes32 prevBlockHash; + bytes32 transactionsRoot; + bytes32 crossStatesRoot; + bytes32 blockRoot; + bytes consensusPayload; + bytes20 nextBookkeeper; + } + + struct ToMerkleValue { + bytes txHash; // cross chain txhash + uint64 fromChainID; + TxParam makeTxParam; + } + + struct TxParam { + bytes txHash; // source chain txhash + bytes crossChainId; + bytes fromContract; + uint64 toChainId; + bytes toContract; + bytes method; + bytes args; + } + + uint constant POLYCHAIN_PUBKEY_LEN = 67; + uint constant POLYCHAIN_SIGNATURE_LEN = 65; + + /* @notice Verify Poly chain transaction whether exist or not + * @param _auditPath Poly chain merkle proof + * @param _root Poly chain root + * @return The verified value included in _auditPath + */ + function merkleProve(bytes memory _auditPath, bytes32 _root) internal pure returns (bytes memory) { + uint256 off = 0; + bytes memory value; + (value, off) = ZeroCopySource.NextVarBytes(_auditPath, off); + + bytes32 hash = Utils.hashLeaf(value); + uint size = _auditPath.length.sub(off).div(33); + bytes32 nodeHash; + bytes1 pos; + for (uint i = 0; i < size; i++) { + (pos, off) = ZeroCopySource.NextByte(_auditPath, off); + (nodeHash, off) = ZeroCopySource.NextHash(_auditPath, off); + if (pos == 0x00) { + hash = Utils.hashChildren(nodeHash, hash); + } else if (pos == 0x01) { + hash = Utils.hashChildren(hash, nodeHash); + } else { + revert("merkleProve, NextByte for position info failed"); + } + } + require(hash == _root, "merkleProve, expect root is not equal actual root"); + return value; + } + + /* @notice calculate next book keeper according to public key list + * @param _keyLen consensus node number + * @param _m minimum signature number + * @param _pubKeyList consensus node public key list + * @return two element: next book keeper, consensus node signer addresses + */ + function _getBookKeeper(uint _keyLen, uint _m, bytes memory _pubKeyList) internal pure returns (bytes20, address[] memory){ + bytes memory buff; + buff = ZeroCopySink.WriteUint16(uint16(_keyLen)); + address[] memory keepers = new address[](_keyLen); + bytes32 hash; + bytes memory publicKey; + for(uint i = 0; i < _keyLen; i++){ + publicKey = Utils.slice(_pubKeyList, i*POLYCHAIN_PUBKEY_LEN, POLYCHAIN_PUBKEY_LEN); + buff = abi.encodePacked(buff, ZeroCopySink.WriteVarBytes(Utils.compressMCPubKey(publicKey))); + hash = keccak256(Utils.slice(publicKey, 3, 64)); + keepers[i] = address(uint160(uint256(hash))); + } + + buff = abi.encodePacked(buff, ZeroCopySink.WriteUint16(uint16(_m))); + bytes20 nextBookKeeper = ripemd160(abi.encodePacked(sha256(buff))); + return (nextBookKeeper, keepers); + } + + /* @notice Verify public key derived from Poly chain + * @param _pubKeyList serialized consensus node public key list + * @param _sigList consensus node signature list + * @return return two element: next book keeper, consensus node signer addresses + */ + function verifyPubkey(bytes memory _pubKeyList) internal pure returns (bytes20, address[] memory) { + require(_pubKeyList.length % POLYCHAIN_PUBKEY_LEN == 0, "_pubKeyList length illegal!"); + uint n = _pubKeyList.length / POLYCHAIN_PUBKEY_LEN; + require(n >= 1, "too short _pubKeyList!"); + return _getBookKeeper(n, n - (n - 1) / 3, _pubKeyList); + } + + /* @notice Verify Poly chain consensus node signature + * @param _rawHeader Poly chain block header raw bytes + * @param _sigList consensus node signature list + * @param _keepers addresses corresponding with Poly chain book keepers' public keys + * @param _m minimum signature number + * @return true or false + */ + function verifySig(bytes memory _rawHeader, bytes memory _sigList, address[] memory _keepers, uint _m) internal pure returns (bool){ + bytes32 hash = getHeaderHash(_rawHeader); + + uint sigCount = _sigList.length.div(POLYCHAIN_SIGNATURE_LEN); + address[] memory signers = new address[](sigCount); + bytes32 r; + bytes32 s; + uint8 v; + for(uint j = 0; j < sigCount; j++){ + r = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN, 32)); + s = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN + 32, 32)); + v = uint8(_sigList[j*POLYCHAIN_SIGNATURE_LEN + 64]) + 27; + signers[j] = ecrecover(sha256(abi.encodePacked(hash)), v, r, s); + if (signers[j] == address(0)) return false; + } + return Utils.containMAddresses(_keepers, signers, _m); + } + + + /* @notice Serialize Poly chain book keepers' info in Ethereum addresses format into raw bytes + * @param keepersBytes The serialized addresses + * @return serialized bytes result + */ + function serializeKeepers(address[] memory keepers) internal pure returns (bytes memory) { + uint256 keeperLen = keepers.length; + bytes memory keepersBytes = ZeroCopySink.WriteUint64(uint64(keeperLen)); + for(uint i = 0; i < keeperLen; i++) { + keepersBytes = abi.encodePacked(keepersBytes, ZeroCopySink.WriteVarBytes(Utils.addressToBytes(keepers[i]))); + } + return keepersBytes; + } + + /* @notice Deserialize bytes into Ethereum addresses + * @param keepersBytes The serialized addresses derived from Poly chain book keepers in bytes format + * @return addresses + */ + function deserializeKeepers(bytes memory keepersBytes) internal pure returns (address[] memory) { + uint256 off = 0; + uint64 keeperLen; + (keeperLen, off) = ZeroCopySource.NextUint64(keepersBytes, off); + address[] memory keepers = new address[](keeperLen); + bytes memory keeperBytes; + for(uint i = 0; i < keeperLen; i++) { + (keeperBytes, off) = ZeroCopySource.NextVarBytes(keepersBytes, off); + keepers[i] = Utils.bytesToAddress(keeperBytes); + } + return keepers; + } + + /* @notice Deserialize Poly chain transaction raw value + * @param _valueBs Poly chain transaction raw bytes + * @return ToMerkleValue struct + */ + function deserializeMerkleValue(bytes memory _valueBs) internal pure returns (ToMerkleValue memory) { + ToMerkleValue memory toMerkleValue; + uint256 off = 0; + + (toMerkleValue.txHash, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (toMerkleValue.fromChainID, off) = ZeroCopySource.NextUint64(_valueBs, off); + + TxParam memory txParam; + + (txParam.txHash, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.crossChainId, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.fromContract, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.toChainId, off) = ZeroCopySource.NextUint64(_valueBs, off); + + (txParam.toContract, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.method, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.args, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + toMerkleValue.makeTxParam = txParam; + + return toMerkleValue; + } + + /* @notice Deserialize Poly chain block header raw bytes + * @param _valueBs Poly chain block header raw bytes + * @return Header struct + */ + function deserializeHeader(bytes memory _headerBs) internal pure returns (Header memory) { + Header memory header; + uint256 off = 0; + (header.version, off) = ZeroCopySource.NextUint32(_headerBs, off); + + (header.chainId, off) = ZeroCopySource.NextUint64(_headerBs, off); + + (header.prevBlockHash, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.transactionsRoot, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.crossStatesRoot, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.blockRoot, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.timestamp, off) = ZeroCopySource.NextUint32(_headerBs, off); + + (header.height, off) = ZeroCopySource.NextUint32(_headerBs, off); + + (header.consensusData, off) = ZeroCopySource.NextUint64(_headerBs, off); + + (header.consensusPayload, off) = ZeroCopySource.NextVarBytes(_headerBs, off); + + (header.nextBookkeeper, off) = ZeroCopySource.NextBytes20(_headerBs, off); + + return header; + } + + /* @notice Deserialize Poly chain block header raw bytes + * @param rawHeader Poly chain block header raw bytes + * @return header hash same as Poly chain + */ + function getHeaderHash(bytes memory rawHeader) internal pure returns (bytes32) { + return sha256(abi.encodePacked(sha256(rawHeader))); + } +} + +interface IEthCrossChainData { + function putCurEpochStartHeight(uint32 curEpochStartHeight) external returns (bool); + function getCurEpochStartHeight() external view returns (uint32); + function putCurEpochConPubKeyBytes(bytes calldata curEpochPkBytes) external returns (bool); + function getCurEpochConPubKeyBytes() external view returns (bytes memory); + function markFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external returns (bool); + function checkIfFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external view returns (bool); + function getEthTxHashIndex() external view returns (uint256); + function putEthTxHash(bytes32 ethTxHash) external returns (bool); + function putExtraData(bytes32 key1, bytes32 key2, bytes calldata value) external returns (bool); + function getExtraData(bytes32 key1, bytes32 key2) external view returns (bytes memory); + function transferOwnership(address newOwner) external; + function pause() external returns (bool); + function unpause() external returns (bool); + function paused() external view returns (bool); + // Not used currently by ECCM + function getEthTxHash(uint256 ethTxHashIndex) external view returns (bytes32); +} + +interface IUpgradableECCM is IOwnable, IPausable { + function pause() external returns (bool); + function unpause() external returns (bool); + function upgradeToNew(address) external returns (bool); + function setChainId(uint64 _newChainId) external returns (bool); +} + + +interface IEthCrossChainManager { + function crossChain(uint64 _toChainId, bytes calldata _toContract, bytes calldata _method, bytes calldata _txData) external returns (bool); +} + +contract UpgradableECCM is IUpgradableECCM, Ownable, Pausable { + address public EthCrossChainDataAddress; + uint64 public chainId; + + constructor (address ethCrossChainDataAddr, uint64 _chainId) Pausable() Ownable() { + EthCrossChainDataAddress = ethCrossChainDataAddr; + chainId = _chainId; + } + function pause() onlyOwner public returns (bool) { + if (!paused()) { + _pause(); + } + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + if (!eccd.paused()) { + require(eccd.pause(), "pause EthCrossChainData contract failed"); + } + return true; + } + + function unpause() onlyOwner public returns (bool) { + if (paused()) { + _unpause(); + } + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + if (eccd.paused()) { + require(eccd.unpause(), "unpause EthCrossChainData contract failed"); + } + return true; + } + + // if we want to upgrade this contract, we need to invoke this method + function upgradeToNew(address newEthCrossChainManagerAddress) whenPaused onlyOwner public returns (bool) { + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + eccd.transferOwnership(newEthCrossChainManagerAddress); + return true; + } + + function setChainId(uint64 _newChainId) whenPaused onlyOwner public returns (bool) { + chainId = _newChainId; + return true; + } +} + +contract EthCrossChainManager is IEthCrossChainManager, UpgradableECCM { + using SafeMath for uint256; + + address public whiteLister; + mapping(address => bool) public whiteListFromContract; + mapping(address => mapping(bytes => bool)) public whiteListContractMethodMap; + + event InitGenesisBlockEvent(uint256 height, bytes rawHeader); + event ChangeBookKeeperEvent(uint256 height, bytes rawHeader); + event CrossChainEvent(address indexed sender, bytes txId, address proxyOrAssetContract, uint64 toChainId, bytes toContract, bytes rawdata); + event VerifyHeaderAndExecuteTxEvent(uint64 fromChainID, bytes toContract, bytes crossChainTxHash, bytes fromChainTxHash); + constructor( + address _eccd, + uint64 _chainId, + address[] memory fromContractWhiteList, + bytes[] memory contractMethodWhiteList + ) UpgradableECCM(_eccd,_chainId) { + whiteLister = msg.sender; + for (uint i=0;i curEpochStartHeight, "The height of header is lower than current epoch start height!"); + + // Ensure the rawHeader is the key header including info of switching consensus peers by containing non-empty nextBookKeeper field + require(header.nextBookkeeper != bytes20(0), "The nextBookKeeper of header is empty"); + + // Verify signature of rawHeader comes from pubKeyList + address[] memory polyChainBKs = ECCUtils.deserializeKeepers(eccd.getCurEpochConPubKeyBytes()); + uint n = polyChainBKs.length; + require(ECCUtils.verifySig(rawHeader, sigList, polyChainBKs, n - (n - 1) / 3), "Verify signature failed!"); + + // Convert pubKeyList into ethereum address format and make sure the compound address from the converted ethereum addresses + // equals passed in header.nextBooker + (bytes20 nextBookKeeper, address[] memory keepers) = ECCUtils.verifyPubkey(pubKeyList); + require(header.nextBookkeeper == nextBookKeeper, "NextBookers illegal"); + + // update current epoch start height of Poly chain and current epoch consensus peers book keepers addresses + require(eccd.putCurEpochStartHeight(header.height), "Save MC LatestHeight to Data contract failed!"); + require(eccd.putCurEpochConPubKeyBytes(ECCUtils.serializeKeepers(keepers)), "Save Poly chain book keepers bytes to Data contract failed!"); + + // Fire the change book keeper event + emit ChangeBookKeeperEvent(header.height, rawHeader); + return true; + } + + + /* @notice ERC20 token cross chain to other blockchain. + * this function push tx event to blockchain + * @param toChainId Target chain id + * @param toContract Target smart contract address in target block chain + * @param txData Transaction data for target chain, include to_address, amount + * @return true or false + */ + function crossChain(uint64 toChainId, bytes calldata toContract, bytes calldata method, bytes calldata txData) whenNotPaused external returns (bool) { + // Only allow whitelist contract to call + require(whiteListFromContract[msg.sender],"Invalid from contract"); + + // Load Ethereum cross chain data contract + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + + // To help differentiate two txs, the ethTxHashIndex is increasing automatically + uint256 txHashIndex = eccd.getEthTxHashIndex(); + + // Convert the uint256 into bytes + bytes memory paramTxHash = Utils.uint256ToBytes(txHashIndex); + + // Construct the makeTxParam, and put the hash info storage, to help provide proof of tx existence + bytes memory rawParam = abi.encodePacked(ZeroCopySink.WriteVarBytes(paramTxHash), + ZeroCopySink.WriteVarBytes(abi.encodePacked(sha256(abi.encodePacked(address(this), paramTxHash)))), + ZeroCopySink.WriteVarBytes(Utils.addressToBytes(msg.sender)), + ZeroCopySink.WriteUint64(toChainId), + ZeroCopySink.WriteVarBytes(toContract), + ZeroCopySink.WriteVarBytes(method), + ZeroCopySink.WriteVarBytes(txData) + ); + + // Must save it in the storage to be included in the proof to be verified. + require(eccd.putEthTxHash(keccak256(rawParam)), "Save ethTxHash by index to Data contract failed!"); + + // Fire the cross chain event denoting there is a cross chain request from Ethereum network to other public chains through Poly chain network + emit CrossChainEvent(tx.origin, paramTxHash, msg.sender, toChainId, toContract, rawParam); + return true; + } + /* @notice Verify Poly chain header and proof, execute the cross chain tx from Poly chain to Ethereum + * @param proof Poly chain tx merkle proof + * @param rawHeader The header containing crossStateRoot to verify the above tx merkle proof + * @param headerProof The header merkle proof used to verify rawHeader + * @param curRawHeader Any header in current epoch consensus of Poly chain + * @param headerSig The coverted signature veriable for solidity derived from Poly chain consensus nodes' signature + * used to verify the validity of curRawHeader + * @return true or false + */ + function verifyHeaderAndExecuteTx(bytes memory proof, bytes memory rawHeader, bytes memory headerProof, bytes memory curRawHeader,bytes memory headerSig) whenNotPaused public returns (bool){ + ECCUtils.Header memory header = ECCUtils.deserializeHeader(rawHeader); + // Load ehereum cross chain data contract + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + + // Get stored consensus public key bytes of current poly chain epoch and deserialize Poly chain consensus public key bytes to address[] + address[] memory polyChainBKs = ECCUtils.deserializeKeepers(eccd.getCurEpochConPubKeyBytes()); + + uint256 curEpochStartHeight = eccd.getCurEpochStartHeight(); + + uint n = polyChainBKs.length; + if (header.height >= curEpochStartHeight) { + // It's enough to verify rawHeader signature + require(ECCUtils.verifySig(rawHeader, headerSig, polyChainBKs, n - ( n - 1) / 3), "Verify poly chain header signature failed!"); + } else { + // We need to verify the signature of curHeader + require(ECCUtils.verifySig(curRawHeader, headerSig, polyChainBKs, n - ( n - 1) / 3), "Verify poly chain current epoch header signature failed!"); + + // Then use curHeader.StateRoot and headerProof to verify rawHeader.CrossStateRoot + ECCUtils.Header memory curHeader = ECCUtils.deserializeHeader(curRawHeader); + bytes memory proveValue = ECCUtils.merkleProve(headerProof, curHeader.blockRoot); + require(ECCUtils.getHeaderHash(rawHeader) == Utils.bytesToBytes32(proveValue), "verify header proof failed!"); + } + + // Through rawHeader.CrossStatesRoot, the toMerkleValue or cross chain msg can be verified and parsed from proof + bytes memory toMerkleValueBs = ECCUtils.merkleProve(proof, header.crossStatesRoot); + + // Parse the toMerkleValue struct and make sure the tx has not been processed, then mark this tx as processed + ECCUtils.ToMerkleValue memory toMerkleValue = ECCUtils.deserializeMerkleValue(toMerkleValueBs); + require(!eccd.checkIfFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "the transaction has been executed!"); + require(eccd.markFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "Save crosschain tx exist failed!"); + + // Ethereum ChainId is 2, we need to check the transaction is for Ethereum network + require(toMerkleValue.makeTxParam.toChainId == chainId, "This Tx is not aiming at this network!"); + + // Obtain the targeting contract, so that Ethereum cross chain manager contract can trigger the executation of cross chain tx on Ethereum side + address toContract = Utils.bytesToAddress(toMerkleValue.makeTxParam.toContract); + + // only invoke PreWhiteListed Contract and method For Now + require(whiteListContractMethodMap[toContract][toMerkleValue.makeTxParam.method],"Invalid to contract or method"); + + //TODO: check this part to make sure we commit the next line when doing local net UT test + require(_executeCrossChainTx(toContract, toMerkleValue.makeTxParam.method, toMerkleValue.makeTxParam.args, toMerkleValue.makeTxParam.fromContract, toMerkleValue.fromChainID), "Execute CrossChain Tx failed!"); + + // Fire the cross chain event denoting the executation of cross chain tx is successful, + // and this tx is coming from other public chains to current Ethereum network + emit VerifyHeaderAndExecuteTxEvent(toMerkleValue.fromChainID, toMerkleValue.makeTxParam.toContract, toMerkleValue.txHash, toMerkleValue.makeTxParam.txHash); + + return true; + } + + /* @notice Dynamically invoke the targeting contract, and trigger executation of cross chain tx on Ethereum side + * @param _toContract The targeting contract that will be invoked by the Ethereum Cross Chain Manager contract + * @param _method At which method will be invoked within the targeting contract + * @param _args The parameter that will be passed into the targeting contract + * @param _fromContractAddr From chain smart contract address + * @param _fromChainId Indicate from which chain current cross chain tx comes + * @return true or false + */ + function _executeCrossChainTx(address _toContract, bytes memory _method, bytes memory _args, bytes memory _fromContractAddr, uint64 _fromChainId) internal returns (bool){ + // Ensure the targeting contract gonna be invoked is indeed a contract rather than a normal account address + require(Utils.isContract(_toContract), "The passed in address is not a contract!"); + bytes memory returnData; + bool success; + + // The returnData will be bytes32, the last byte must be 01; + (success, returnData) = _toContract.call(abi.encodePacked(bytes4(keccak256(abi.encodePacked(_method, "(bytes,bytes,uint64)"))), abi.encode(_args, _fromContractAddr, _fromChainId))); + + // Ensure the executation is successful + require(success == true, "EthCrossChain call business contract failed"); + + // Ensure the returned value is true + require(returnData.length != 0, "No return value from business contract!"); + (bool res,) = ZeroCopySource.NextBool(returnData, 31); + require(res == true, "EthCrossChain call business contract return is not true"); + + return true; + } +} diff --git a/smart-contracts/contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol b/smart-contracts/contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol new file mode 100644 index 0000000..260384f --- /dev/null +++ b/smart-contracts/contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import { Utils, ZeroCopySink, IEthCrossChainManager, IUpgradableECCM, + UpgradableECCM, IEthCrossChainData, EthCrossChainManager } from "contracts/periphery/ZilBridge/ccmCrossChainManager.sol"; +import { Ownable } from "lib/openzeppelin-contracts/contracts/access/Ownable.sol"; + + + +interface ILockProxy { + function addExtension( + bytes calldata _argsBz, + bytes calldata /* _fromContractAddr */, + uint64 _fromChainId + ) external returns (bool); + + function removeExtension( + bytes calldata _argsBz, + bytes calldata /* _fromContractAddr */, + uint64 _fromChainId + ) external returns (bool); +} + +// This is a contract which can replace the CCM. It allows the owner to register lock proxy extensions, +// and forwards all other requests to the original cross chain manager. +// see docs/zilbridge.md for details. +// We can't implement IEthCrossChainManager, because we use the fallback for that. +contract EthExtendCrossChainManager is EthCrossChainManager { + address public _extensionManager; + event ExtensionManagerTransferred(address indexed previousExtender, address indexed newExtender); + + constructor(address _eccd, + uint64 _chainId, + address[] memory fromContractWhiteList, + bytes[] memory contractMethodWhiteList) EthCrossChainManager(_eccd, _chainId, fromContractWhiteList, contractMethodWhiteList) + { + _extensionManager = payable(msg.sender); + emit ExtensionManagerTransferred(address(0), _extensionManager); + } + + function extensionManager() public view returns (address) { return _extensionManager; } + + function isExtensionManager() public view returns (bool) { + return payable(msg.sender) == _extensionManager; + } + + modifier onlyExtensionManager() { + require(isExtensionManager(), "CCM: Caller is not the extension manager"); + _; + } + + function transferExtensionManagement(address newManager) public onlyExtensionManager { + _transferExtensionManagement(newManager); + } + + function renounceExtensionManagement() public onlyExtensionManager { + emit ExtensionManagerTransferred(_extensionManager, address(0)); + _extensionManager = address(0); + } + + function _transferExtensionManagement(address newManager) internal { + require(newManager != address(0), "ExtensionManager: new owner is 0 address"); + emit ExtensionManagerTransferred(_extensionManager, newManager); + _extensionManager = newManager; + } + + function forciblyAddExtension(address targetAddress, address addressToRegister, uint64 fromChainId) external onlyExtensionManager { + ILockProxy lockProxy = ILockProxy(targetAddress); + bytes memory payload = ZeroCopySink.WriteVarBytes(Utils.addressToBytes(addressToRegister)); + lockProxy.addExtension(payload, payload, fromChainId); + } +} diff --git a/smart-contracts/script/bsc-testnet/bridgeTokens.s.sol b/smart-contracts/script/bsc-testnet/bridgeTokens.s.sol index 245c5b5..e4ecc62 100644 --- a/smart-contracts/script/bsc-testnet/bridgeTokens.s.sol +++ b/smart-contracts/script/bsc-testnet/bridgeTokens.s.sol @@ -5,18 +5,19 @@ import {Script} from "forge-std/Script.sol"; import {MintAndBurnTokenManagerUpgradeable} from "contracts/periphery/MintAndBurnTokenManagerUpgradeable.sol"; import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Transfer is Script { +contract Transfer is Script,TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Owner is %s", owner); - address tokenManagerAddress = 0xd10077bCE4A9D19068965dE519CED8a2fC1B096C; - address tokenAddress = 0x6d78c86D66DfE5Be5F55FBAA8B1d3FD28edfF396; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; + address tokenAddress = bscTestTokenAddress; - uint remoteChainId = 33101; + uint remoteChainId = zqChainId; address remoteRecipient = owner; uint amount = 10; diff --git a/smart-contracts/script/bsc-testnet/deployBridge.s.sol b/smart-contracts/script/bsc-testnet/deployBridge.s.sol index 8a7fa63..4ac3755 100644 --- a/smart-contracts/script/bsc-testnet/deployBridge.s.sol +++ b/smart-contracts/script/bsc-testnet/deployBridge.s.sol @@ -8,6 +8,7 @@ import {MintAndBurnTokenManagerUpgradeable} from "contracts/periphery/MintAndBur import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {ChainGateway} from "contracts/core/ChainGateway.sol"; import "forge-std/console.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; contract Deployment is Script { function run() external { @@ -31,6 +32,8 @@ contract Deployment is Script { validatorManager.isValidator(validators[0]), validatorManager.validatorsSize() ); + console.log( + " address public constant bscValidatorManagerAddress = %s", address(validatorManager)); // Deploy Chain Gateway ChainGateway chainGateway = new ChainGateway{salt: "zilliqa"}( @@ -42,6 +45,8 @@ contract Deployment is Script { address(chainGateway), address(chainGateway.validatorManager()) ); + console.log( + " address public constant bscChainGatewayAddress = %s", address(chainGateway)); // Deploy MintAndBurnTokenManager address implementation = address( @@ -51,7 +56,6 @@ contract Deployment is Script { MintAndBurnTokenManagerUpgradeable.initialize, address(chainGateway) ); - address proxy = address( new ERC1967Proxy(implementation, initializeData) ); @@ -65,6 +69,9 @@ contract Deployment is Script { tokenManager.owner(), tokenManager.getGateway() ); + console.log( + " address public constant bscMintAndBurnTokenManagerAddress = %s", address(tokenManager)); + // Register TokenManager to ChainGateway chainGateway.register(proxy); diff --git a/smart-contracts/script/bsc-testnet/deployBridgeToken.s.sol b/smart-contracts/script/bsc-testnet/deployBridgeToken.s.sol index 0adde26..4b64a81 100644 --- a/smart-contracts/script/bsc-testnet/deployBridgeToken.s.sol +++ b/smart-contracts/script/bsc-testnet/deployBridgeToken.s.sol @@ -5,23 +5,24 @@ import {Script} from "forge-std/Script.sol"; import {MintAndBurnTokenManagerUpgradeable} from "contracts/periphery/MintAndBurnTokenManagerUpgradeable.sol"; import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Deployment is Script { +contract Deployment is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Owner is %s", owner); - address tokenManagerAddress = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; string memory tokenName = "test token"; string memory tokenSymbol = "TST"; uint8 tokenDecimals = 3; - address remoteToken = 0x8618d39a8276D931603c6Bc7306af6A53aD2F1F3; - address remoteTokenManager = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; - uint remoteChainId = 33101; + address remoteToken = zqLegacyTestTokenAddress; + address remoteTokenManager = zqLockAndReleaseTokenManagerAddress; + uint remoteChainId = zqChainId; MintAndBurnTokenManagerUpgradeable tokenManager = MintAndBurnTokenManagerUpgradeable( tokenManagerAddress diff --git a/smart-contracts/script/bsc-testnet/deployCoreUpgradeable.s.sol b/smart-contracts/script/bsc-testnet/deployCoreUpgradeable.s.sol index f8d5b14..e8541da 100644 --- a/smart-contracts/script/bsc-testnet/deployCoreUpgradeable.s.sol +++ b/smart-contracts/script/bsc-testnet/deployCoreUpgradeable.s.sol @@ -6,15 +6,16 @@ import {ValidatorManagerUpgradeable} from "contracts/core-upgradeable/ValidatorM import {ChainGatewayUpgradeable} from "contracts/core-upgradeable/ChainGatewayUpgradeable.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "forge-std/console.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; -contract Deployment is Script { +contract Deployment is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Owner is %s", owner); address[] memory validators = new address[](1); - address tokenManager = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address tokenManager = bscMintAndBurnTokenManagerAddress; validators[0] = owner; vm.startBroadcast(deployerPrivateKey); @@ -40,6 +41,8 @@ contract Deployment is Script { validatorManager.isValidator(validators[0]), validatorManager.validatorsSize() ); + console.log( + " address public constant bscValidatorManagerAddress = %s", address(validatorManager)); // Deploy Chain Gateway address cgImplementation = address( @@ -59,6 +62,8 @@ contract Deployment is Script { address(chainGateway), address(chainGateway.validatorManager()) ); + console.log( + " address public constant bscChainGatewayAddress = %s", address(chainGateway)); // Register TokenManager to ChainGateway chainGateway.register(tokenManager); diff --git a/smart-contracts/script/bsc-testnet/deployMockZilBridge.s.sol b/smart-contracts/script/bsc-testnet/deployMockZilBridge.s.sol new file mode 100644 index 0000000..69c7fcf --- /dev/null +++ b/smart-contracts/script/bsc-testnet/deployMockZilBridge.s.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {Tester} from "test/Tester.sol"; +import {TestToken} from "test/Helpers.sol"; +import { LockProxy } from "test/zilbridge/infrastructure/lockProxy.sol"; +import { EthCrossChainManagerProxy } from "test/zilbridge/infrastructure/ccmProxy.sol"; +import { EthCrossChainManager } from "test/zilbridge/infrastructure/ccmCrossChainManager.sol"; +import { EthCrossChainData } from "test/zilbridge/infrastructure/ethCrossChainData.sol"; +import { EthExtendCrossChainManager } from "contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol"; +import { LockProxyTokenManagerUpgradeableV3 } from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import { LockProxyTokenManagerDeployer } from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; + +/*** @notice does what ZilBridgeFixture::deployOriginalContracts() does */ +contract deployMockZilBridge is Script, TestnetConfig { + function run() external { + EthCrossChainManager ccm; + EthCrossChainManagerProxy ccmProxy; + EthCrossChainData eccd; + LockProxy lockProxy; + + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_ZILBRIDGE"); + address owner = vm.addr(deployerPrivateKey); + address[] memory a = new address[](0); + bytes[] memory b = new bytes[](0); + vm.startBroadcast(deployerPrivateKey); + console.log("Owner: %s", owner); + eccd = new EthCrossChainData(); + console.log( + " address public constant bscEthCrossChainDataAddress = %s", address(eccd)); + ccm = new EthCrossChainManager(address(eccd), zbBscChainId, a, b); + console.log( + " address public constant bscCCMAddress = %s", address(ccm)); + ccmProxy = new EthCrossChainManagerProxy(address(ccm)); + console.log( + " address public constant bscCCMProxyAddress = %s", address(ccmProxy)); + ccm.transferOwnership(address(ccmProxy)); + eccd.transferOwnership(address(ccm)); + lockProxy = new LockProxy(address(ccmProxy), zbZilliqaChainId); + console.log( + " address public constant bscLockProxyAddress = %s", address(lockProxy)); + } +} diff --git a/smart-contracts/script/bsc-testnet/deployXBridgeOverMockZilBridge.s.sol b/smart-contracts/script/bsc-testnet/deployXBridgeOverMockZilBridge.s.sol new file mode 100644 index 0000000..4821b97 --- /dev/null +++ b/smart-contracts/script/bsc-testnet/deployXBridgeOverMockZilBridge.s.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {Tester} from "test/Tester.sol"; +import {TestToken} from "test/Helpers.sol"; +import { LockProxy } from "test/zilbridge/infrastructure/lockProxy.sol"; +import { EthCrossChainManagerProxy } from "test/zilbridge/infrastructure/ccmProxy.sol"; +import { EthCrossChainManager } from "test/zilbridge/infrastructure/ccmCrossChainManager.sol"; +import { EthCrossChainData } from "test/zilbridge/infrastructure/ethCrossChainData.sol"; +import { EthExtendCrossChainManager } from "contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol"; +import { LockProxyTokenManagerUpgradeableV3 } from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import { LockProxyTokenManagerDeployer } from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; + +/*** @notice ZilBridgeFixture::installExtendCrossManager() */ +contract deployXBridgeOverMockZilBridge is Script, TestnetConfig { + // Plug in the data from deployMockZilBridge here. + EthCrossChainData public constant eccd = EthCrossChainData(bscEthCrossChainDataAddress); + EthCrossChainManager public constant ccm = EthCrossChainManager(bscCCMAddress); + EthCrossChainManagerProxy public constant ccmProxy = EthCrossChainManagerProxy(bscCCMProxyAddress); + LockProxy public constant lockProxy = LockProxy(payable(bscLockProxyAddress)); + EthExtendCrossChainManager extendCCM; + + function run() external { + address[] memory a = new address[](0); + bytes[] memory b = new bytes[](0); + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_ZILBRIDGE"); + vm.startBroadcast(deployerPrivateKey); + extendCCM = new EthExtendCrossChainManager(address(eccd), 2, a, b); + ccmProxy.pauseEthCrossChainManager(); + extendCCM.transferOwnership(address(ccmProxy)); + ccmProxy.upgradeEthCrossChainManager(address(extendCCM)); + ccmProxy.unpauseEthCrossChainManager(); + console.log( + " address public constant bscExtendCCMAddress = %s", address(extendCCM)); + } +} diff --git a/smart-contracts/script/bsc-testnet/deployZilBridgeTokenManagers.s.sol b/smart-contracts/script/bsc-testnet/deployZilBridgeTokenManagers.s.sol new file mode 100644 index 0000000..1d457b0 --- /dev/null +++ b/smart-contracts/script/bsc-testnet/deployZilBridgeTokenManagers.s.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import "forge-std/console.sol"; +import {Tester} from "test/Tester.sol"; +import {TestToken} from "test/Helpers.sol"; +import { LockProxy } from "test/zilbridge/infrastructure/lockProxy.sol"; +import { TestingLockProxy } from "test/zilbridge/TestingLockProxy.sol"; +import { EthCrossChainManagerProxy } from "test/zilbridge/infrastructure/ccmProxy.sol"; +import { EthCrossChainManager } from "test/zilbridge/infrastructure/ccmCrossChainManager.sol"; +import { EthCrossChainData } from "test/zilbridge/infrastructure/ethCrossChainData.sol"; +import { EthExtendCrossChainManager } from "contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol"; +import { ChainGateway } from "contracts/core/ChainGateway.sol"; +import { LockProxyTokenManagerUpgradeableV3 } from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import { LockProxyTokenManagerDeployer } from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerDeployer} from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import {MintAndBurnTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/MintAndBurnTokenManagerDeployer.sol"; +import {LockAndReleaseTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/LockAndReleaseTokenManagerDeployer.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; + +/*** @notice Deploy token managers over the extension manager + */ +contract deployZilBridgeTokenManagers is Script, LockProxyTokenManagerDeployer, TestnetConfig { + EthExtendCrossChainManager constant extendCCM = EthExtendCrossChainManager(bscExtendCCMAddress); + ChainGateway constant chainGateway = ChainGateway(bscChainGatewayAddress); + LockProxy constant lockProxy = LockProxy(payable(bscLockProxyAddress)); + // Different from 0.00025 so that we can tell the difference! + uint fees = 0.00007 ether; + + // This has to be 18, because that is what the original (ZilBridge) contracts were + // deployed with. The mainnet value is 5. + uint64 constant COUNTERPART_CHAIN_ID = zbZilliqaChainId; + + function run() external { + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + uint256 bridgePrivateKey = vm.envUint("PRIVATE_KEY_ZILBRIDGE"); + // token managers are apparently not pausable, so .. + vm.startBroadcast(validatorPrivateKey); + LockProxyTokenManagerUpgradeableV3 tokenManager = deployLatestLockProxyTokenManager(address(chainGateway), address(lockProxy), fees); + console.log( + " address public constant bscLockProxyTokenManagerAddress = %s", address(tokenManager)); + vm.stopBroadcast(); + vm.startBroadcast(bridgePrivateKey); + extendCCM.forciblyAddExtension(address(lockProxy), address(tokenManager), COUNTERPART_CHAIN_ID); + vm.stopBroadcast(); + vm.startBroadcast(validatorPrivateKey); + chainGateway.register(address(tokenManager)); + vm.stopBroadcast(); + } +} diff --git a/smart-contracts/script/bsc-testnet/deployZilBridgeTokens.s.sol b/smart-contracts/script/bsc-testnet/deployZilBridgeTokens.s.sol new file mode 100644 index 0000000..9fb2a78 --- /dev/null +++ b/smart-contracts/script/bsc-testnet/deployZilBridgeTokens.s.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {MintAndBurnTokenManagerUpgradeable} from "contracts/periphery/MintAndBurnTokenManagerUpgradeable.sol"; +import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import "forge-std/console.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; + +contract MyERC20 is ERC20 { +constructor(string memory name_, string memory symbol_, uint256 supply_) ERC20(name_, symbol_) { + _mint(address(msg.sender), supply_); + } + function decimals() public pure override returns (uint8) { + return 3; + } +} + + +contract Deployment is Script, TestnetConfig { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + address owner = vm.addr(deployerPrivateKey); + console.log("Owner is %s", owner); + + vm.startBroadcast(deployerPrivateKey); + // The other half of these tokens are deployed via the scilla-contracts/scripts/deploy.ts script. + + // Native on BSC + uint256 totalSupply = 1_000_000_000; + string memory tokenName = "XTST_token"; + string memory tokenSymbol = "XTST"; + MyERC20 theContract = new MyERC20(tokenName, tokenSymbol, totalSupply); + console.log( + " address public constant bscERC20Address = %s", address(theContract)); + + // Native on Zilliqa + SwitcheoToken bridgedFromZilliqa = new SwitcheoToken(bscLockProxyAddress, "Bridged ZTST", "eZTST", 3); + console.log( + " address public constant bscBridgedZRC2Address = %s", address(bridgedFromZilliqa)); + + // Bridged ZIL - this is EVM ZIL, so scale = 18 + SwitcheoToken bridgedZIL = new SwitcheoToken(bscLockProxyAddress, "eZIL", "Bridged ZIL", 18); + console.log( + " address public constant bscBridgedZILAddress = %s", address(bridgedZIL)); + } +} diff --git a/smart-contracts/script/bsc-testnet/pauseBridge.s.sol b/smart-contracts/script/bsc-testnet/pauseBridge.s.sol index f448c33..bed91d3 100644 --- a/smart-contracts/script/bsc-testnet/pauseBridge.s.sol +++ b/smart-contracts/script/bsc-testnet/pauseBridge.s.sol @@ -3,18 +3,22 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Pause is Script { + +contract Pause is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Deployer is %s", owner); - address tokenManagerAddress = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; vm.startBroadcast(deployerPrivateKey); - MintAndBurnTokenManagerUpgradeableV3 tokenManager = MintAndBurnTokenManagerUpgradeableV3( + { + MintAndBurnTokenManagerUpgradeableV3 tokenManager = MintAndBurnTokenManagerUpgradeableV3( tokenManagerAddress ); tokenManager.pause(); @@ -23,6 +27,18 @@ contract Pause is Script { tokenManagerAddress, tokenManager.paused() ); + } + { + LockProxyTokenManagerUpgradeableV3 tokenManager = LockProxyTokenManagerUpgradeableV3( + bscLockProxyTokenManagerAddress + ); + tokenManager.pause(); + console.log( + "TokenManager %s, paused: %s", + tokenManagerAddress, + tokenManager.paused() + ); + } vm.stopBroadcast(); } } diff --git a/smart-contracts/script/bsc-testnet/setChainGatewayOnTokenManager.s.sol b/smart-contracts/script/bsc-testnet/setChainGatewayOnTokenManager.s.sol index 2341657..3f446ab 100644 --- a/smart-contracts/script/bsc-testnet/setChainGatewayOnTokenManager.s.sol +++ b/smart-contracts/script/bsc-testnet/setChainGatewayOnTokenManager.s.sol @@ -3,16 +3,17 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Update is Script { +contract Update is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Deployer is %s", owner); - address newChainGateway = 0xa9A14C90e53EdCD89dFd201A3bF94D867f8098fE; // UPDATE; - address tokenManagerAddress = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address newChainGateway = bscChainGatewayAddress; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; vm.startBroadcast(deployerPrivateKey); MintAndBurnTokenManagerUpgradeableV3 tokenManager = MintAndBurnTokenManagerUpgradeableV3( diff --git a/smart-contracts/script/bsc-testnet/setZilBridgeRouting.s.sol b/smart-contracts/script/bsc-testnet/setZilBridgeRouting.s.sol new file mode 100644 index 0000000..e5d2d87 --- /dev/null +++ b/smart-contracts/script/bsc-testnet/setZilBridgeRouting.s.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {MintAndBurnTokenManagerUpgradeable} from "contracts/periphery/MintAndBurnTokenManagerUpgradeable.sol"; +import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import "forge-std/console.sol"; +import {LockProxyTokenManagerUpgradeable} from "contracts/periphery/LockProxyTokenManagerUpgradeable.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; + +/*** @title Route tokens from the BSC side. + */ +contract Deployment is Script, TestnetConfig { + function run() external { + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + address owner = vm.addr(validatorPrivateKey); + console.log("Owner is %s", owner); + + vm.startBroadcast(validatorPrivateKey); + LockAndReleaseTokenManagerUpgradeable zilliqaTokenManager = LockAndReleaseTokenManagerUpgradeable(zqLockAndReleaseOrNativeTokenManagerAddress); + LockProxyTokenManagerUpgradeable bscTokenManager = LockProxyTokenManagerUpgradeable(bscLockProxyTokenManagerAddress); + + // OK. Now set up the routing .. + + // When bscERC20 arrives at bscTokenManager, send it to zilliqaBridgedERC20 on zilliqaTokenManager + ITokenManagerStructs.RemoteToken memory sourceBscERC20GasStruct = ITokenManagerStructs.RemoteToken({ + token: address(zqBridgedERC20EVMAddress), + tokenManager: address(zilliqaTokenManager), + chainId: zqChainId}); + bscTokenManager.registerToken(address(bscERC20Address), sourceBscERC20GasStruct); + + // When bscBridgedZRC2FromZilliqa arrives at bscTokenManager, send it to zilliqaZRC2 on zilliqaTokenManager + ITokenManagerStructs.RemoteToken memory bridgedZRC2 = ITokenManagerStructs.RemoteToken({ + token: address(zqZRC2EVMAddress), + tokenManager: address(zilliqaTokenManager), + chainId: zqChainId}); + bscTokenManager.registerToken(address(bscBridgedZRC2Address), bridgedZRC2); + + // When bscBridgedZIL arrives at bscTokenManager, send it to 0 on zilliqaTokenManager + ITokenManagerStructs.RemoteToken memory bridgedZIL = ITokenManagerStructs.RemoteToken({ + token: address(0), + tokenManager: address(zilliqaTokenManager), + chainId: zqChainId}); + bscTokenManager.registerToken(address(bscBridgedZILAddress), bridgedZIL); + + // When BNB arrives at bscTokenManager, sent it to zilliqaBridgedBNB on zilliqaTokenManager + ITokenManagerStructs.RemoteToken memory bridgedBNB = ITokenManagerStructs.RemoteToken({ + token: address(zqBridgedBNBEVMAddress), + tokenManager: address(zilliqaTokenManager), + chainId: zqChainId}); + bscTokenManager.registerToken(address(0), bridgedBNB); + } +} + diff --git a/smart-contracts/script/bsc-testnet/unpauseBridge.s.sol b/smart-contracts/script/bsc-testnet/unpauseBridge.s.sol index 20d95a5..5403e35 100644 --- a/smart-contracts/script/bsc-testnet/unpauseBridge.s.sol +++ b/smart-contracts/script/bsc-testnet/unpauseBridge.s.sol @@ -3,26 +3,41 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Unpause is Script { +contract Unpause is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Deployer is %s", owner); - address tokenManagerAddress = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; vm.startBroadcast(deployerPrivateKey); - MintAndBurnTokenManagerUpgradeableV3 tokenManager = MintAndBurnTokenManagerUpgradeableV3( + { + MintAndBurnTokenManagerUpgradeableV3 tokenManager = MintAndBurnTokenManagerUpgradeableV3( tokenManagerAddress + ); + tokenManager.unpause(); + console.log( + "TokenManager %s, paused: %s", + tokenManagerAddress, + tokenManager.paused() + ); + } + { + LockProxyTokenManagerUpgradeableV3 tokenManager = LockProxyTokenManagerUpgradeableV3( + bscLockProxyTokenManagerAddress ); - tokenManager.unpause(); - console.log( - "TokenManager %s, paused: %s", - tokenManagerAddress, - tokenManager.paused() - ); + tokenManager.unpause(); + console.log( + "TokenManager %s, paused: %s", + tokenManagerAddress, + tokenManager.paused() + ); + } vm.stopBroadcast(); } } diff --git a/smart-contracts/script/bsc-testnet/upgradeTokenManagerV2.s.sol b/smart-contracts/script/bsc-testnet/upgradeTokenManagerV2.s.sol index d0f32f6..dc86626 100644 --- a/smart-contracts/script/bsc-testnet/upgradeTokenManagerV2.s.sol +++ b/smart-contracts/script/bsc-testnet/upgradeTokenManagerV2.s.sol @@ -4,16 +4,17 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {MintAndBurnTokenManagerUpgradeableV2} from "contracts/periphery/TokenManagerV2/MintAndBurnTokenManagerUpgradeableV2.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Upgrade is Script { +contract Upgrade is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Signer is %s", owner); // Constants - address tokenManagerAddress = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; uint fees = 0.00025 ether; // 0.00025 BNB TokenManagerUpgradeable tokenManager = TokenManagerUpgradeable( diff --git a/smart-contracts/script/bsc-testnet/upgradeTokenManagerV3.s.sol b/smart-contracts/script/bsc-testnet/upgradeTokenManagerV3.s.sol index af5a764..09a156c 100644 --- a/smart-contracts/script/bsc-testnet/upgradeTokenManagerV3.s.sol +++ b/smart-contracts/script/bsc-testnet/upgradeTokenManagerV3.s.sol @@ -4,16 +4,17 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Upgrade is Script { +contract Upgrade is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Signer is %s", owner); // Constants - address tokenManagerAddress = 0xA6D73210AF20a59832F264fbD991D2abf28401d0; + address tokenManagerAddress = bscMintAndBurnTokenManagerAddress; TokenManagerUpgradeable tokenManager = TokenManagerUpgradeable( tokenManagerAddress diff --git a/smart-contracts/script/bsc-testnet/zilBridgeTransferERC20.s.sol b/smart-contracts/script/bsc-testnet/zilBridgeTransferERC20.s.sol new file mode 100644 index 0000000..caae2cf --- /dev/null +++ b/smart-contracts/script/bsc-testnet/zilBridgeTransferERC20.s.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; +import "forge-std/console.sol"; + + +contract Deployment is Script, TestnetConfig { + function run() external { + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + address validator = vm.addr(validatorPrivateKey); + address recipient = vm.envAddress("ZILBRIDGE_TEST_ADDRESS"); + uint256 amount = vm.envUint("ZILBRIDGE_TEST_AMOUNT"); + console.log("Owner is %s", validator); + vm.startBroadcast(validatorPrivateKey); + ERC20 theContract = ERC20(bscERC20Address); + // rrw's address for testing. + theContract.transfer( recipient, amount ); + } + +} diff --git a/smart-contracts/script/config.ts b/smart-contracts/script/config.ts index 47e0337..93269ae 100644 --- a/smart-contracts/script/config.ts +++ b/smart-contracts/script/config.ts @@ -1,5 +1,7 @@ import { parseUnits } from "ethers"; +// These turn out to be testnet addresses. + export const config = { zq: { tokenManager: "0x6D61eFb60C17979816E4cE12CD5D29054E755948", @@ -7,6 +9,7 @@ export const config = { token: "0x241c677D9969419800402521ae87C411897A029f", remoteToken: "0x351dA1E7500aBA1d168b9435DCE73415718d212F", remoteTokenManager: "0xF391A1Ee7b3ccad9a9451D2B7460Ac646F899f23", + remoteZilBridgeTokenManager: "0x103617938D41f7bea62F0B5b4E8e50585083048F", remoteChainId: 56, remoteRecipient: "0xb34b88220Fa1EAeDba5d50b271AF8c3eE14A24Dd", amount: parseUnits("1000000", 12), @@ -18,6 +21,7 @@ export const config = { token: "0x351dA1E7500aBA1d168b9435DCE73415718d212F", remoteToken: "0x241c677D9969419800402521ae87C411897A029f", remoteTokenManager: "0x6D61eFb60C17979816E4cE12CD5D29054E755948", + remoteZilBridgeTokenManager: "", remoteChainId: 32769, remoteRecipient: "0xb34b88220Fa1EAeDba5d50b271AF8c3eE14A24Dd", amount: parseUnits("1000000", 12), diff --git a/smart-contracts/script/testnetConfig.s.sol b/smart-contracts/script/testnetConfig.s.sol new file mode 100644 index 0000000..dac53ac --- /dev/null +++ b/smart-contracts/script/testnetConfig.s.sol @@ -0,0 +1,52 @@ +pragma solidity ^0.8.20; + +/*** @dev Inherit from this contract to get constants that tells you where other testnet contracts are. + * I did consider structuring this a bit more closely, but there is sufficient diversity between + * chains that I haven't, yet. + */ +abstract contract TestnetConfig { + // bsc testnet + address public constant bscEthCrossChainDataAddress = 0xd77a160f954AbF8154f80EA53378ACa55bcAD548; + + uint public constant bscChainId = 97; + // Can't be verified. + address public constant bscCCMAddress = 0x0EDb0830a5a28E60Bc28BCce3f4e1EC23b5E5783; + address public constant bscCCMProxyAddress = 0xE19738378c75cf2b3D704472bE81d7e036F4Ee04; + address public constant bscLockProxyAddress = 0x5B51e17837fc8F01b3C3ef29E882981e9414C159; + // Can't be verified. + address public constant bscExtendCCMAddress = 0x32ffa2C4c670A0fd0e94CF6457ac2FA7Ef007d55; + address public constant bscLockProxyTokenManagerAddress = 0x36b8A9cd6Bf9bfA5984093005cf81CAfB1Bf06F7; + // BSC zilbridge tokens. + address public constant bscERC20Address = 0xa1a47FA4D26137329BB08aC2E5F9a6C32D180fE3; + address public constant bscBridgedZRC2Address = 0x201eDd0521cF4B577399F789e22E05405D500163; + address public constant bscBridgedZILAddress = 0xfA3cF3BBa7f0fA1E8FECeE532512434A7d275d41; + + /// Deployed by the original XBridge testnet deployment (prior to zilBridge) + address public constant bscChainGatewayAddress = 0xa9A14C90e53EdCD89dFd201A3bF94D867f8098fE; + address public constant bscMintAndBurnTokenManagerAddress = 0xd10077bCE4A9D19068965dE519CED8a2fC1B096C; + address public constant bscTestTokenAddress = 0x6d78c86D66DfE5Be5F55FBAA8B1d3FD28edfF396; + + /// Zilliqa testnet + + uint public constant zqChainId = 33101; + address public constant zqChainGatewayAddress = 0x7370e69565BB2313C4dA12F9062C282513919230; + address public constant zqLockAndReleaseTokenManagerAddress = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address public constant zqLockAndReleaseOrNativeTokenManagerAddress = 0x41823941D00f47Ea1a98D75586915BF828F4a038; + + // Scilla contracts. + address public constant zqBridgedERC20Address = address(0x009892a6E972B46Bca767ed552Fb06E25A35a49ebF); + address public constant zqBridgedBNBAddress = address(0x008fe819662a7Db7e03943877BA771E7A0902Ef96d); + address public constant zqZRC2Address = address(0x005dD38E64DA8F7d541d8af45fE00Bf37F6A2C6195); + + // ERC20 fascias for Scilla contracts + address public constant zqBridgedERC20EVMAddress = 0x9Be4DCfB335A263c65a8A763d55710718bbdb416; + address public constant zqBridgedBNBEVMAddress = 0x40647A0C0024755Ef48Bc7C26a979ED833Eb6a15; + address public constant zqZRC2EVMAddress = 0xd3750B930ED52C26584C18B4f5eeAb986D7f3b36; + + // Deployed back in the depths of time; recorded here so we can use them in scripts + address public constant zqLegacyTestTokenAddress = 0x63B6ebD476C84bFDd5DcaCB3f974794FC6C2e721; + + /// ZilBridge constants that we use whilst testing the zilbridge/xbridge integration + uint64 public constant zbZilliqaChainId = 18; + uint64 public constant zbBscChainId = 6; +} diff --git a/smart-contracts/script/zq-testnet/bridgeTokens.s.sol b/smart-contracts/script/zq-testnet/bridgeTokens.s.sol index 746b429..2051292 100644 --- a/smart-contracts/script/zq-testnet/bridgeTokens.s.sol +++ b/smart-contracts/script/zq-testnet/bridgeTokens.s.sol @@ -6,17 +6,18 @@ import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAnd import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "forge-std/console.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; -contract Transfer is Script { +contract Transfer is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Owner is %s", owner); - address tokenManagerAddress = 0xd10077bCE4A9D19068965dE519CED8a2fC1B096C; - address tokenAddress = 0x63B6ebD476C84bFDd5DcaCB3f974794FC6C2e721; + address tokenManagerAddress = zqLockAndReleaseTokenManagerAddress; + address tokenAddress = zqLegacyTestTokenAddress; - uint remoteChainId = 97; + uint remoteChainId = bscChainId; address remoteRecipient = owner; uint amount = 10; diff --git a/smart-contracts/script/zq-testnet/deployChainGateway.s.sol b/smart-contracts/script/zq-testnet/deployChainGateway.s.sol index a93ed4f..8b32d8d 100644 --- a/smart-contracts/script/zq-testnet/deployChainGateway.s.sol +++ b/smart-contracts/script/zq-testnet/deployChainGateway.s.sol @@ -6,8 +6,9 @@ import {Relayer} from "contracts/core/Relayer.sol"; import {ValidatorManager} from "contracts/core/ValidatorManager.sol"; import {ChainGateway} from "contracts/core/ChainGateway.sol"; import "forge-std/console.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; -contract Deployment is Script { +contract Deployment is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); @@ -40,6 +41,10 @@ contract Deployment is Script { address(chainGateway), address(chainGateway.validatorManager()) ); + console.log( + " address public constant zqChainGatewayAddress = %s", address(chainGateway)); + console.log( + " address public constant zqValidatorManagerAddress = %s", address(chainGateway.validatorManager())); vm.stopBroadcast(); } diff --git a/smart-contracts/script/zq-testnet/deployCoreUpgradeable.s.sol b/smart-contracts/script/zq-testnet/deployCoreUpgradeable.s.sol index ef641e7..260cb05 100644 --- a/smart-contracts/script/zq-testnet/deployCoreUpgradeable.s.sol +++ b/smart-contracts/script/zq-testnet/deployCoreUpgradeable.s.sol @@ -5,16 +5,17 @@ import {Script} from "forge-std/Script.sol"; import {ValidatorManagerUpgradeable} from "contracts/core-upgradeable/ValidatorManagerUpgradeable.sol"; import {ChainGatewayUpgradeable} from "contracts/core-upgradeable/ChainGatewayUpgradeable.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Deployment is Script { +contract Deployment is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Owner is %s", owner); address[] memory validators = new address[](1); - address tokenManager = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address tokenManager = zqLockAndReleaseTokenManagerAddress; validators[0] = owner; vm.startBroadcast(deployerPrivateKey); @@ -38,6 +39,8 @@ contract Deployment is Script { validatorManager.isValidator(validators[0]), validatorManager.validatorsSize() ); + console.log( + " address public constant zqValidatorManagerAddress = %s", address(validatorManager)); // Deploy Chain Gateway address cgImplementation = address(new ChainGatewayUpgradeable()); @@ -55,6 +58,8 @@ contract Deployment is Script { address(chainGateway), address(chainGateway.validatorManager()) ); + console.log( + " address public constant zqChainGatewayAddress = %s", address(chainGateway)); // Register TokenManager to ChainGateway chainGateway.register(tokenManager); @@ -64,6 +69,8 @@ contract Deployment is Script { address(chainGateway), chainGateway.registered(tokenManager) ); + console.log( + " address public constant zqLockAndReleaseTokenManagerAddress = %s", address(tokenManager)); vm.stopBroadcast(); } diff --git a/smart-contracts/script/zq-testnet/deployNativeTokenManagerV3.s.sol b/smart-contracts/script/zq-testnet/deployNativeTokenManagerV3.s.sol new file mode 100644 index 0000000..24c4577 --- /dev/null +++ b/smart-contracts/script/zq-testnet/deployNativeTokenManagerV3.s.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {LockAndReleaseOrNativeTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {ChainGateway} from "contracts/core/ChainGateway.sol"; +import {LockAndReleaseOrNativeTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/LockAndReleaseOrNativeTokenManagerDeployer.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; +import "forge-std/console.sol"; + +contract Deployment is Script, LockAndReleaseOrNativeTokenManagerDeployer,TestnetConfig { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + address chainGatewayAddress = zqChainGatewayAddress; + uint fees = 60 ether; // 60 ZIL + + vm.startBroadcast(deployerPrivateKey); + LockAndReleaseOrNativeTokenManagerUpgradeableV3 tokenManager = + deployLatestLockAndReleaseOrNativeTokenManager(chainGatewayAddress, fees); + console.log( + "LockAndReleaseOrNativeTokenManager Proxy deployed to %s, with owner %s and gateway %s", + address(tokenManager), + tokenManager.owner(), + tokenManager.getGateway() + ); + console.log( + " address public constant zqLockAndReleaseOrNativeTokenManagerAddress = %s", address(tokenManager)); + + ChainGateway chainGateway = ChainGateway(chainGatewayAddress); + chainGateway.register(address(tokenManager)); + + console.log( + "TokenManager %s registered to %s ChainGateway: %s", + address(tokenManager), + address(chainGateway), + chainGateway.registered(address(tokenManager)) + ); + + vm.stopBroadcast(); + } +} diff --git a/smart-contracts/script/zq-testnet/deployTokenManager.s.sol b/smart-contracts/script/zq-testnet/deployTokenManager.s.sol index 147b995..025b2c9 100644 --- a/smart-contracts/script/zq-testnet/deployTokenManager.s.sol +++ b/smart-contracts/script/zq-testnet/deployTokenManager.s.sol @@ -5,12 +5,14 @@ import {Script} from "forge-std/Script.sol"; import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {ChainGateway} from "contracts/core/ChainGateway.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Deployment is Script { + +contract Deployment is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); - address chainGatewayAddress = 0x10917A34FE60eE8364a401a6b1d3adaf80D84eb6; + address chainGatewayAddress = zqChainGatewayAddress; vm.startBroadcast(deployerPrivateKey); @@ -37,6 +39,8 @@ contract Deployment is Script { tokenManager.owner(), tokenManager.getGateway() ); + console.log( + " address public constant zqLockAndReleaseTokenManagerAddress = %s", address(tokenManager)); ChainGateway chainGateway = ChainGateway(chainGatewayAddress); chainGateway.register(proxy); diff --git a/smart-contracts/script/zq-testnet/deployZRC2ERC20.s.sol b/smart-contracts/script/zq-testnet/deployZRC2ERC20.s.sol new file mode 100644 index 0000000..350e61e --- /dev/null +++ b/smart-contracts/script/zq-testnet/deployZRC2ERC20.s.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ZRC2ProxyForZRC2 } from "test/zilbridge/tokens/zrc2erc20/ZRC2ProxyForZRC2.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; +import "forge-std/console.sol"; + +/*** @title Deploy an ERC20 proxy for our ZRC2, so we can set routing with it. + */ +contract Deployment is Script, TestnetConfig { + function run() external { + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + address validator = vm.addr(validatorPrivateKey); + console.log("Owner is %s", validator); + vm.startBroadcast(validatorPrivateKey); + { + ZRC2ProxyForZRC2 proxy = new ZRC2ProxyForZRC2(zqBridgedERC20Address); + console.log( + " address public constant zqBridgedERC20EVMAddress = %s", address(proxy)); + } + { + ZRC2ProxyForZRC2 proxy = new ZRC2ProxyForZRC2(zqBridgedBNBAddress); + console.log( + " address public constant zqBridgedBNBEVMAddress = %s", address(proxy)); + } + { + ZRC2ProxyForZRC2 proxy = new ZRC2ProxyForZRC2(zqZRC2Address); + console.log( + " address public constant zqZRC2EVMAddress = %s", address(proxy)); + } + } +} diff --git a/smart-contracts/script/zq-testnet/dispatchRelay.s.sol b/smart-contracts/script/zq-testnet/dispatchRelay.s.sol index 4a07585..7351acb 100644 --- a/smart-contracts/script/zq-testnet/dispatchRelay.s.sol +++ b/smart-contracts/script/zq-testnet/dispatchRelay.s.sol @@ -5,8 +5,12 @@ import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/Messa import {Script} from "forge-std/Script.sol"; import {ChainGateway} from "contracts/core/ChainGateway.sol"; import {ValidatorManager} from "contracts/core/ValidatorManager.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; -contract Dispatch is Script { +/*** @dev this script contains hardwired addresses - remember to hand-edit them to match the testnet config, + * or it won't work! + */ +contract Dispatch is Script, TestnetConfig { using MessageHashUtils for bytes; function run() external { diff --git a/smart-contracts/script/zq-testnet/pauseBridge.s.sol b/smart-contracts/script/zq-testnet/pauseBridge.s.sol index 626dcfa..40895a2 100644 --- a/smart-contracts/script/zq-testnet/pauseBridge.s.sol +++ b/smart-contracts/script/zq-testnet/pauseBridge.s.sol @@ -3,26 +3,41 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import {LockAndReleaseOrNativeTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Pause is Script { +contract Pause is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Deployer is %s", owner); - address tokenManagerAddress = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address tokenManagerAddress = zqLockAndReleaseTokenManagerAddress; vm.startBroadcast(deployerPrivateKey); - LockAndReleaseTokenManagerUpgradeableV3 tokenManager = LockAndReleaseTokenManagerUpgradeableV3( - tokenManagerAddress - ); - tokenManager.pause(); - console.log( - "TokenManager %s, paused: %s", - tokenManagerAddress, - tokenManager.paused() - ); + { + LockAndReleaseTokenManagerUpgradeableV3 tokenManager = LockAndReleaseTokenManagerUpgradeableV3( + tokenManagerAddress + ); + tokenManager.pause(); + console.log( + "TokenManager %s, paused: %s", + tokenManagerAddress, + tokenManager.paused() + ); + } + { + LockAndReleaseOrNativeTokenManagerUpgradeableV3 tokenManager = LockAndReleaseOrNativeTokenManagerUpgradeableV3( + payable(zqLockAndReleaseOrNativeTokenManagerAddress) + ); + tokenManager.pause(); + console.log( + "LockAndReleaseOrNativeTokenManager %s, paused: %s", + zqLockAndReleaseOrNativeTokenManagerAddress, + tokenManager.paused() + ); + } vm.stopBroadcast(); } } diff --git a/smart-contracts/script/zq-testnet/registerToken.s.sol b/smart-contracts/script/zq-testnet/registerToken.s.sol index 10dbd14..9daea46 100644 --- a/smart-contracts/script/zq-testnet/registerToken.s.sol +++ b/smart-contracts/script/zq-testnet/registerToken.s.sol @@ -5,9 +5,12 @@ import {Script} from "forge-std/Script.sol"; import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Deployment is Script { +/*** @dev uses hardwired addresses; I've left these alone .. + */ +contract Deployment is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); diff --git a/smart-contracts/script/zq-testnet/setChainGatewayOnTokenManager.s.sol b/smart-contracts/script/zq-testnet/setChainGatewayOnTokenManager.s.sol index bbe8cae..67b284a 100644 --- a/smart-contracts/script/zq-testnet/setChainGatewayOnTokenManager.s.sol +++ b/smart-contracts/script/zq-testnet/setChainGatewayOnTokenManager.s.sol @@ -3,16 +3,19 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import {LockAndReleaseOrNativeTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Update is Script { +contract Update is TestnetConfig,Script { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Deployer is %s", owner); - address newChainGateway = 0x7370e69565BB2313C4dA12F9062C282513919230; // UPDATE; - address tokenManagerAddress = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address newChainGateway = zqChainGatewayAddress; + address tokenManagerAddress = zqLockAndReleaseTokenManagerAddress; + address nativeTokenManagerAddress = zqLockAndReleaseOrNativeTokenManagerAddress; vm.startBroadcast(deployerPrivateKey); LockAndReleaseTokenManagerUpgradeableV3 tokenManager = LockAndReleaseTokenManagerUpgradeableV3( @@ -20,10 +23,20 @@ contract Update is Script { ); tokenManager.setGateway(newChainGateway); console.log( - "TokenManager %s, newChainGateway: %s", + "LockAndReleaseTokenManager %s, newChainGateway: %s", tokenManagerAddress, tokenManager.getGateway() ); + LockAndReleaseOrNativeTokenManagerUpgradeableV3 nativeTokenManager = LockAndReleaseOrNativeTokenManagerUpgradeableV3( + payable(nativeTokenManagerAddress) + ); + nativeTokenManager.setGateway(newChainGateway); + console.log( + "NativeLockAndReleaseTokenManager %s, newChainGateway: %s", + nativeTokenManagerAddress, + nativeTokenManager.getGateway() + ); + vm.stopBroadcast(); } } diff --git a/smart-contracts/script/zq-testnet/setZilBridgeRouting.s.sol b/smart-contracts/script/zq-testnet/setZilBridgeRouting.s.sol new file mode 100644 index 0000000..9afd027 --- /dev/null +++ b/smart-contracts/script/zq-testnet/setZilBridgeRouting.s.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {MintAndBurnTokenManagerUpgradeable} from "contracts/periphery/MintAndBurnTokenManagerUpgradeable.sol"; +import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import "forge-std/console.sol"; +import {LockProxyTokenManagerUpgradeable} from "contracts/periphery/LockProxyTokenManagerUpgradeable.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; + +/*** @title Route tokens from the BSC side. + */ +contract Deployment is Script, TestnetConfig { + function run() external { + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + address validator = vm.addr(validatorPrivateKey); + console.log("Owner is %s", validator); + + vm.startBroadcast(validatorPrivateKey); + LockAndReleaseTokenManagerUpgradeable zilliqaTokenManager = LockAndReleaseTokenManagerUpgradeable(address(zqLockAndReleaseOrNativeTokenManagerAddress)); + + // OK. Now set up the routing .. + + // When zilliqaBridgedERC20 arrives at zilliqaTokenManager, send it to bscERC20 on bscTokenManager + ITokenManagerStructs.RemoteToken memory sourceBscERC20GasStruct = ITokenManagerStructs.RemoteToken({ + token: address(bscERC20Address), + tokenManager: address(bscLockProxyTokenManagerAddress), + chainId: bscChainId}); + zilliqaTokenManager.registerToken(address(zqBridgedERC20EVMAddress), sourceBscERC20GasStruct); + + // When zilliqaZRC2 arrives at zilliqaTokenManager, send it to bscBridgedZRC2FromZilliqa on bscTokenManager + ITokenManagerStructs.RemoteToken memory bridgedZRC2 = ITokenManagerStructs.RemoteToken({ + token: address(bscBridgedZRC2Address), + tokenManager: address(bscLockProxyTokenManagerAddress), + chainId: bscChainId}); + zilliqaTokenManager.registerToken(address(zqZRC2EVMAddress), bridgedZRC2); + + // When ZIL arrives at zilliqaTokenManager, send it to bscBridgedZIL on bscTokenManager + ITokenManagerStructs.RemoteToken memory bridgedZIL = ITokenManagerStructs.RemoteToken({ + token: address(bscBridgedZILAddress), + tokenManager: address(bscLockProxyTokenManagerAddress), + chainId: bscChainId}); + zilliqaTokenManager.registerToken(address(0), bridgedZIL); + + // When zilliqaBridgedBNB arrives at zilliqaTokenManager, send it to 0 on bscTokenManager + ITokenManagerStructs.RemoteToken memory bridgedBNB = ITokenManagerStructs.RemoteToken({ + token: address(0), + tokenManager: address(bscLockProxyTokenManagerAddress), + chainId: bscChainId}); + zilliqaTokenManager.registerToken(address(zqBridgedBNBEVMAddress), bridgedBNB); + } +} + diff --git a/smart-contracts/script/zq-testnet/unpauseBridge.s.sol b/smart-contracts/script/zq-testnet/unpauseBridge.s.sol index 7f4c3e0..9ee21f2 100644 --- a/smart-contracts/script/zq-testnet/unpauseBridge.s.sol +++ b/smart-contracts/script/zq-testnet/unpauseBridge.s.sol @@ -3,26 +3,40 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Unpause is Script { +contract Unpause is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Deployer is %s", owner); - address tokenManagerAddress = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address tokenManagerAddress = zqLockAndReleaseTokenManagerAddress; vm.startBroadcast(deployerPrivateKey); - LockAndReleaseTokenManagerUpgradeableV3 tokenManager = LockAndReleaseTokenManagerUpgradeableV3( + { + LockAndReleaseTokenManagerUpgradeableV3 tokenManager = LockAndReleaseTokenManagerUpgradeableV3( tokenManagerAddress - ); - tokenManager.unpause(); - console.log( - "TokenManager %s, paused: %s", - tokenManagerAddress, - tokenManager.paused() - ); + ); + tokenManager.unpause(); + console.log( + "TokenManager %s, paused: %s", + tokenManagerAddress, + tokenManager.paused() + ); + } + { + LockAndReleaseTokenManagerUpgradeableV3 tokenManager = LockAndReleaseTokenManagerUpgradeableV3( + zqLockAndReleaseOrNativeTokenManagerAddress + ); + tokenManager.unpause(); + console.log( + "TokenManager %s, paused: %s", + address(tokenManager), + tokenManager.paused() + ); + } vm.stopBroadcast(); } } diff --git a/smart-contracts/script/zq-testnet/upgradeTokenManagerV2.s.sol b/smart-contracts/script/zq-testnet/upgradeTokenManagerV2.s.sol index 11756de..e80ac05 100644 --- a/smart-contracts/script/zq-testnet/upgradeTokenManagerV2.s.sol +++ b/smart-contracts/script/zq-testnet/upgradeTokenManagerV2.s.sol @@ -4,16 +4,17 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {LockAndReleaseTokenManagerUpgradeableV2} from "contracts/periphery/TokenManagerV2/LockAndReleaseTokenManagerUpgradeableV2.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Upgrade is Script { +contract Upgrade is Script, TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Signer is %s", owner); // Constants - address tokenManagerAddress = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address tokenManagerAddress = zqLockAndReleaseTokenManagerAddress; uint fees = 60 ether; // 60 ZIL TokenManagerUpgradeable tokenManager = TokenManagerUpgradeable( diff --git a/smart-contracts/script/zq-testnet/upgradeTokenManagerV3.s.sol b/smart-contracts/script/zq-testnet/upgradeTokenManagerV3.s.sol index 1a1bc76..6a96f8e 100644 --- a/smart-contracts/script/zq-testnet/upgradeTokenManagerV3.s.sol +++ b/smart-contracts/script/zq-testnet/upgradeTokenManagerV3.s.sol @@ -4,16 +4,17 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; import "forge-std/console.sol"; -contract Upgrade is Script { +contract Upgrade is Script,TestnetConfig { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); address owner = vm.addr(deployerPrivateKey); console.log("Signer is %s", owner); // Constants - address tokenManagerAddress = 0x1509988c41f02014aA59d455c6a0D67b5b50f129; + address tokenManagerAddress = zqLockAndReleaseTokenManagerAddress; TokenManagerUpgradeable tokenManager = TokenManagerUpgradeable( tokenManagerAddress diff --git a/smart-contracts/script/zq-testnet/zilBridgeDebug.s.sol b/smart-contracts/script/zq-testnet/zilBridgeDebug.s.sol new file mode 100644 index 0000000..aedde88 --- /dev/null +++ b/smart-contracts/script/zq-testnet/zilBridgeDebug.s.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {LockAndReleaseOrNativeTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol"; +import {ITokenManagerStructs, ITokenManager} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {ZRC2ProxyForZRC2} from "test/zilbridge/tokens/zrc2erc20/ZRC2ProxyForZRC2.sol"; +import "forge-std/console.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; +import {IERC20} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {IRelayer, Relayer, CallMetadata} from "contracts/core/Relayer.sol"; +import {Registry} from "contracts/core/Registry.sol"; +import {ChainGateway} from "contracts/core/ChainGateway.sol"; + +contract Deployment is Script, TestnetConfig { + function run() external { + // uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_ZILBRIDGE"); + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_TESTNET"); + + address validator = vm.addr(validatorPrivateKey); + vm.startBroadcast(validatorPrivateKey); + console.log("I am %s", validator); + console.log("Token manager at %s", zqLockAndReleaseOrNativeTokenManagerAddress); + console.log("ChainGateway %s", zqChainGatewayAddress); + ChainGateway chainGateway = ChainGateway(zqChainGatewayAddress); + chainGateway.register(address(zqLockAndReleaseOrNativeTokenManagerAddress)); + console.log( + "TokenManager %s registered to %s ChainGateway: %s", + address(zqLockAndReleaseOrNativeTokenManagerAddress), + address(chainGateway), + chainGateway.registered(address(zqLockAndReleaseOrNativeTokenManagerAddress)) + ); + + Relayer relayer = Relayer(zqChainGatewayAddress); + bool amRegistered = relayer.registered(zqLockAndReleaseOrNativeTokenManagerAddress); + console.log("isRegistered %d", amRegistered); + } +} diff --git a/smart-contracts/script/zq-testnet/zilBridgeTransferERC20.s.sol b/smart-contracts/script/zq-testnet/zilBridgeTransferERC20.s.sol new file mode 100644 index 0000000..af1c391 --- /dev/null +++ b/smart-contracts/script/zq-testnet/zilBridgeTransferERC20.s.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.8.20; + +import {Script} from "forge-std/Script.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {ITokenManagerStructs} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { TestnetConfig } from "script/testnetConfig.s.sol"; +import "forge-std/console.sol"; + +contract Deployment is Script, TestnetConfig { + function run() external { + uint256 validatorPrivateKey = vm.envUint("PRIVATE_KEY_ZILBRIDGE"); + address validator = vm.addr(validatorPrivateKey); + address recipient = vm.envAddress("ZILBRIDGE_TEST_ADDRESS"); + uint256 amount = vm.envUint("ZILBRIDGE_TEST_AMOUNT"); + console.log("Owner is %s", validator); + vm.startBroadcast(validatorPrivateKey); + ERC20 theContract = ERC20(zqZRC2EVMAddress); + theContract.transfer( recipient, amount ); + } + +} diff --git a/smart-contracts/test/periphery/TokenBridge.native.t.sol b/smart-contracts/test/periphery/TokenBridge.native.t.sol new file mode 100644 index 0000000..8f29ca7 --- /dev/null +++ b/smart-contracts/test/periphery/TokenBridge.native.t.sol @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import {Tester, Vm} from "test/Tester.sol"; +import {ITokenManagerStructs, TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {LockAndReleaseOrNativeTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol"; +import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import {CallMetadata, IRelayerEvents} from "contracts/core/Relayer.sol"; +import {ValidatorManager} from "contracts/core/ValidatorManager.sol"; +import {ChainGateway} from "contracts/core/ChainGateway.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import {TestToken} from "test/Helpers.sol"; +import {LockAndReleaseOrNativeTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/LockAndReleaseOrNativeTokenManagerDeployer.sol"; +import {MintAndBurnTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/MintAndBurnTokenManagerDeployer.sol"; + +// Integration Tests combining the TokenManagers and ChainGateway +contract TokenBridgeNativeTests is + Tester, + IRelayerEvents, + LockAndReleaseOrNativeTokenManagerDeployer, + MintAndBurnTokenManagerDeployer +{ + using MessageHashUtils for bytes; + + // Gateway shared between the two chains + Vm.Wallet validatorWallet = vm.createWallet(1); + address validator = validatorWallet.addr; + address[] validators = [validator]; + address sourceUser = vm.addr(2); + address remoteUser = vm.addr(3); + uint originalTokenSupply = 1000 ether; + uint fees = 0.1 ether; + + LockAndReleaseOrNativeTokenManagerUpgradeableV3 sourceTokenManager; + TestToken originalToken; + ChainGateway sourceChainGateway; + ValidatorManager sourceValidatorManager; + + MintAndBurnTokenManagerUpgradeableV3 remoteTokenManager; + BridgedToken bridgedToken; + ChainGateway remoteChainGateway; + ValidatorManager remoteValidatorManager; + + function setUp() external { + vm.startPrank(validator); + // Deploy Source Infra + sourceValidatorManager = new ValidatorManager(validator); + sourceValidatorManager.initialize(validators); + sourceChainGateway = new ChainGateway( + address(sourceValidatorManager), + validator + ); + + // Deploy Target Infra + remoteValidatorManager = new ValidatorManager(validator); + remoteValidatorManager.initialize(validators); + remoteChainGateway = new ChainGateway( + address(remoteValidatorManager), + validator + ); + + // Deploy LockAndReleaseTokenManagerUpgradeable + sourceTokenManager = deployLatestLockAndReleaseOrNativeTokenManager( + address(sourceChainGateway), + fees + ); + + // Deploy MintAndBurnTokenManagerUpgradeable + remoteTokenManager = deployLatestMintAndBurnTokenManager( + address(remoteChainGateway), + fees + ); + + // Register contracts to chaingateway + sourceChainGateway.register(address(sourceTokenManager)); + remoteChainGateway.register(address(remoteTokenManager)); + + // Deploy bridged ERC20 + bridgedToken = remoteTokenManager.deployToken( + "GASZ", + "Zilliqa GAS", + address(0), + address(sourceTokenManager), + block.chainid + ); + + ITokenManagerStructs.RemoteToken + memory remoteToken = ITokenManagerStructs.RemoteToken({ + token: address(bridgedToken), + tokenManager: address(remoteTokenManager), + chainId: block.chainid + }); + + // Register bridged token with original token + sourceTokenManager.registerToken(address(0), remoteToken); + + vm.stopPrank(); + } + + function test_happyPath() external { + /* Give the source user some gas to play with. Redundant, as it + * happens, since foundry will make them have all the gas in the + * world anyway, but I feel better including it. + */ + uint amount = originalTokenSupply; + vm.deal(sourceUser, amount); + startHoax(sourceUser); + uint sourceChainId = block.chainid; + uint remoteChainId = block.chainid; + uint sourceUserOriginalBalance = sourceUser.balance; + assertGe(sourceUser.balance, amount); + + bytes memory data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + CallMetadata(sourceChainId, address(sourceTokenManager)), // From + abi.encode( + ITokenManagerStructs.AcceptArgs( + address(bridgedToken), + remoteUser, + amount + ) + ) // To + ); + + // Transfer. + vm.expectEmit(address(sourceChainGateway)); + emit IRelayerEvents.Relayed( + remoteChainId, + address(remoteTokenManager), + data, + 1_000_000, + 0 + ); + sourceTokenManager.transfer{value: amount + fees}( + address(0), + remoteChainId, + remoteUser, + amount + ); + + // Make the bridge txn + vm.startPrank(validator); + bytes[] memory signatures = new bytes[](1); + signatures[0] = sign( + validatorWallet, + abi + .encode( + sourceChainId, + remoteChainId, + address(remoteTokenManager), + data, + 1_000_000, + 0 + ) + .toEthSignedMessageHash() + ); + remoteChainGateway.dispatch( + sourceChainId, + address(remoteTokenManager), + data, + 1_000_000, + 0, + signatures + ); + + // Check balances + assertEq(bridgedToken.balanceOf(remoteUser), amount); + assertEq(bridgedToken.totalSupply(), amount); + assertLe(sourceUser.balance, sourceUserOriginalBalance - amount); + uint sourceUserIntermediateBalance = sourceUser.balance; + + // Now sending it back + startHoax(remoteUser); + bridgedToken.approve(address(remoteTokenManager), amount); + remoteTokenManager.transfer{value: fees}( + address(bridgedToken), + sourceChainId, + sourceUser, + amount + ); + + //Mock Call + // Make the bridge txn + vm.startPrank(validator); + data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + CallMetadata(remoteChainId, address(remoteTokenManager)), // From + abi.encode( + ITokenManagerStructs.AcceptArgs( + address(originalToken), + sourceUser, + amount + ) + ) // To + ); + signatures[0] = sign( + validatorWallet, + abi + .encode( + remoteChainId, + sourceChainId, + address(sourceTokenManager), + data, + 1_000_000, + 0 + ) + .toEthSignedMessageHash() + ); + sourceChainGateway.dispatch( + remoteChainId, + address(sourceTokenManager), + data, + 1_000_000, + 0, + signatures + ); + + // Check balances back to normal + // Make an allowance for the gas fee. + uint est_gas_fee = 0.001 ether; + assertEq(bridgedToken.balanceOf(remoteUser), 0); + assertGe(sourceUser.balance, sourceUserIntermediateBalance + amount - est_gas_fee); + } +} diff --git a/smart-contracts/test/periphery/TokenManagerDeployers/LockAndReleaseOrNativeTokenManagerDeployer.sol b/smart-contracts/test/periphery/TokenManagerDeployers/LockAndReleaseOrNativeTokenManagerDeployer.sol new file mode 100644 index 0000000..2f7b48b --- /dev/null +++ b/smart-contracts/test/periphery/TokenManagerDeployers/LockAndReleaseOrNativeTokenManagerDeployer.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {LockAndReleaseTokenManagerUpgradeable} from "contracts/periphery/LockAndReleaseTokenManagerUpgradeable.sol"; +import {LockAndReleaseTokenManagerUpgradeableV2} from "contracts/periphery/TokenManagerV2/LockAndReleaseTokenManagerUpgradeableV2.sol"; +import {LockAndReleaseOrNativeTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseOrNativeTokenManagerUpgradeableV3.sol"; +import {LockAndReleaseTokenManagerDeployer} from "./LockAndReleaseTokenManagerDeployer.sol"; + +abstract contract LockAndReleaseOrNativeTokenManagerDeployer is + LockAndReleaseTokenManagerDeployer { + function deployLockAndReleaseOrNativeTokenManagerV3( + address chainGateway, + uint fees + ) public returns (LockAndReleaseOrNativeTokenManagerUpgradeableV3) { + LockAndReleaseTokenManagerUpgradeableV2 proxy = deployLockAndReleaseTokenManagerV2( + chainGateway, + fees + ); + + address newImplementation = address( + new LockAndReleaseOrNativeTokenManagerUpgradeableV3() + ); + + proxy.upgradeToAndCall(newImplementation, ""); + + return LockAndReleaseOrNativeTokenManagerUpgradeableV3(payable(address(proxy))); + } + + function deployLatestLockAndReleaseOrNativeTokenManager( + address chainGateway, + uint fees + ) public returns (LockAndReleaseOrNativeTokenManagerUpgradeableV3) { + return deployLockAndReleaseOrNativeTokenManagerV3(chainGateway, fees); + } +} diff --git a/smart-contracts/test/zilbridge/DeployZilBridge.t.sol b/smart-contracts/test/zilbridge/DeployZilBridge.t.sol new file mode 100644 index 0000000..f8c2910 --- /dev/null +++ b/smart-contracts/test/zilbridge/DeployZilBridge.t.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import "forge-std/console.sol"; +import {Tester} from "test/Tester.sol"; +import {TestToken} from "test/Helpers.sol"; +import { LockProxy } from "test/zilbridge/infrastructure/lockProxy.sol"; +import { TestingLockProxy } from "./TestingLockProxy.sol"; +import { EthCrossChainManagerProxy } from "test/zilbridge/infrastructure/ccmProxy.sol"; +import { EthCrossChainManager } from "test/zilbridge/infrastructure/ccmCrossChainManager.sol"; +import { EthCrossChainData } from "test/zilbridge/infrastructure/ethCrossChainData.sol"; +import { EthExtendCrossChainManager } from "contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol"; +import { LockProxyTokenManagerUpgradeableV3 } from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import { LockProxyTokenManagerDeployer } from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; + +abstract contract ZilBridgeFixture is Tester, LockProxyTokenManagerDeployer { + address owner = vm.createWallet("owner").addr; + address tokenDeployer = vm.createWallet("tokenDeployer").addr; + address other = vm.createWallet("other").addr; + address third = vm.createWallet("third").addr; + uint64 constant COUNTERPART_CHAIN_ID = 5; + uint64 constant CHAIN_ID = 2; + + EthCrossChainManager ccm; + EthCrossChainManagerProxy ccmProxy; + EthCrossChainData eccd; + TestingLockProxy lockProxy; + EthExtendCrossChainManager extendCCM; + + + function deployOriginalContracts() internal { + vm.startPrank(owner); + address[] memory a = new address[](0); + bytes[] memory b = new bytes[](0); + console.log("deploy_as = %s", owner); + eccd = new EthCrossChainData(); + ccm = new EthCrossChainManager(address(eccd), CHAIN_ID, a,b); + ccmProxy = new EthCrossChainManagerProxy(address(ccm)); + // Now give the ccm to the ccmProxy + ccm.transferOwnership(address(ccmProxy)); + // and give the data to the ccm. + eccd.transferOwnership(address(ccm)); + lockProxy = new TestingLockProxy(address(ccmProxy), COUNTERPART_CHAIN_ID); + vm.stopPrank(); + } + + function installExtendCrossChainManager(address act_as) internal { + vm.startPrank(act_as); + console.log("act_as = %s", act_as); + address[] memory a = new address[](0); + bytes[] memory b = new bytes[](0); + extendCCM = new EthExtendCrossChainManager(address(eccd), 2, a, b); + console.log("ccmProxy owner = %s", ccmProxy.owner()); + console.log("ccmProxy ccm = %s", ccmProxy.getEthCrossChainManager()); + console.log("eccm owner = %s", ccm.owner()); + console.log("eccd owner = %s", eccd.owner()); + console.log("ccm = %s", address(ccm)); + ccmProxy.pauseEthCrossChainManager(); + extendCCM.transferOwnership(address(ccmProxy)); + require(ccmProxy.upgradeEthCrossChainManager(address(extendCCM))); + ccmProxy.unpauseEthCrossChainManager(); + vm.stopPrank(); + } + + function setUpZilBridgeForTesting() internal { + deployOriginalContracts(); + installExtendCrossChainManager(owner); + } + + function installTokenManager(address lpTokenManager) internal { + // Make it an extension + vm.startPrank(owner); + extendCCM.forciblyAddExtension(address(lockProxy), address(lpTokenManager), COUNTERPART_CHAIN_ID); + vm.stopPrank(); + } + + function getLockProxy() public view returns (TestingLockProxy) { + return lockProxy; + } + +} + +contract DeployZilBridgeTest is ZilBridgeFixture { + function test_ZilBridgeDeploy() external { + deployOriginalContracts(); + // The owner of the proxy is us + require(ccmProxy.owner() == owner); + // The ccmProxy's ccm is the ccm we installed. + require(ccmProxy.getEthCrossChainManager() == address(ccm)); + // The owner of the ccm is the ccmProxy + require(ccm.owner() == address(ccmProxy)); + // the eccd is installed + require(ccm.EthCrossChainDataAddress() == address(eccd)); + // the eccd's owner is the ccm + require(eccd.owner() == address(ccm)); + } + + function test_ZilBridgeUpgrade() external { + deployOriginalContracts(); + installExtendCrossChainManager(owner); + + // The owner of the proxy is us + require(ccmProxy.owner() == owner); + // The ccmProxy's ccm is the new CCM + require(ccmProxy.getEthCrossChainManager() == address(extendCCM)); + // The ccm's owner is the ccm Proxy + require(extendCCM.owner() == address(ccmProxy)); + // The ccm's eccd is intact + require(extendCCM.EthCrossChainDataAddress() == address(eccd)); + // The eccd's owner is the ccm. + require(eccd.owner() == address(extendCCM)); + + // We're unpaused + require(!extendCCM.paused()); + require(!ccmProxy.paused()); + } + + + + function test_installTokenManager() external { + deployOriginalContracts(); + installExtendCrossChainManager(owner); + } +} diff --git a/smart-contracts/test/zilbridge/MockLockProxy.sol b/smart-contracts/test/zilbridge/MockLockProxy.sol new file mode 100644 index 0000000..a8777bb --- /dev/null +++ b/smart-contracts/test/zilbridge/MockLockProxy.sol @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +// This is a mock lock proxy - it looks like a LockProxy, but has the CCM stuff removed so that it can be +// deployed fairly easily. We use it to test the remote side of transfers, because otherwise we would have to +// generate a lot of complex spurious mechanism. + +interface ERC20 { + function approve(address spender, uint256 amount) external returns (bool); + function transfer(address recipient, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + function balanceOf(address account) external view returns (uint256); +} + + +/** + * @dev Wrappers over Solidity's arithmetic operations with added overflow + * checks. + * + * Arithmetic operations in Solidity wrap on overflow. This can easily result + * in bugs, because programmers usually assume that an overflow raises an + * error, which is the standard behavior in high level programming languages. + * `SafeMath` restores this intuition by reverting the transaction when an + * operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + */ +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} + + +// THIS CONTRACT IS WOEFULLY INSECURE AND ONLY TO BE USED FOR TESTING! +contract MockLockProxy { + using SafeMath for uint256; + address public constant ETH_ASSET_HASH = address(0); + + constructor() { } + + /// @dev Allow this contract to receive Ethereum + receive() external payable {} + + function extensionTransfer(address _receivingAddress, address _assetHash, uint256 _amount) external returns (bool) { + if (_assetHash == ETH_ASSET_HASH) { + // we use `call` here since the _receivingAddress could be a contract + // see https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + // for more info + (bool success, ) = _receivingAddress.call{value: _amount}(""); + require(success, "Transfer failed"); + return true; + } + + ERC20 token = ERC20(_assetHash); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + _receivingAddress, + _amount + ) + ); + + return true; + } + + + function mock_transferIn( + address _assetHash, + uint256 _amount, + uint256 _callAmount + ) + public payable + { + if (_assetHash == ETH_ASSET_HASH) { + require(msg.value == _amount, "ETH transferred does not match the expected amount"); + return; + } + + ERC20 token = ERC20(_assetHash); + uint256 before = token.balanceOf(address(this)); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transferFrom.selector, + msg.sender, + address(this), + _callAmount + ) + ); + uint256 transferred = token.balanceOf(address(this)).sub(before); + require(transferred == _amount, "Tokens transferred does not match the expected amount"); + } + + /// @dev transfers funds from this contract to the _toAddress + function mock_transferOut( + address _toAddress, + address _assetHash, + uint256 _amount + ) + public + { + if (_assetHash == ETH_ASSET_HASH) { + // we use `call` here since the _receivingAddress could be a contract + // see https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + // for more info + (bool success, ) = _toAddress.call{value: _amount}(""); + require(success, "Transfer failed"); + return; + } + + ERC20 token = ERC20(_assetHash); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transfer.selector, + _toAddress, + _amount + ) + ); + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(ERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. + + // A Solidity high level call has three parts: + // 1. The target address is checked to verify it contains contract code + // 2. The call itself is made, and success asserted + // 3. The return value is decoded, which in turn checks the size of the returned data. + // solhint-disable-next-line max-line-length + require(_isContract(address(token)), "SafeERC20: call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = address(token).call(data); + require(success, "SafeERC20: low-level call failed"); + + if (returndata.length > 0) { // Return data is optional + // solhint-disable-next-line max-line-length + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } + + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `_isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function _isContract(address account) private view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != accountHash && codehash != 0x0); + } + + +} diff --git a/smart-contracts/test/zilbridge/TestingLockProxy.sol b/smart-contracts/test/zilbridge/TestingLockProxy.sol new file mode 100644 index 0000000..6debfc9 --- /dev/null +++ b/smart-contracts/test/zilbridge/TestingLockProxy.sol @@ -0,0 +1,1896 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +// This is a real LockProxy extended with methods for testing which are +// WOEFULLY INSECURE - they allow you to synthetically lock and unlock funds +// so we can test the cases where we bridge tokens over XBridge that were +// previously bridged on ZilBridge. + +/** + *Submitted for verification at Etherscan.io on 2020-11-09 +*/ + +// File: contracts/libs/common/ZeroCopySource.sol + +/** + * @dev Wrappers over decoding and deserialization operation from bytes into bassic types in Solidity for PolyNetwork cross chain utility. + * + * Decode into basic types in Solidity from bytes easily. It's designed to be used + * for PolyNetwork cross chain application, and the decoding rules on Ethereum chain + * and the encoding rule on other chains should be consistent, and . Here we + * follow the underlying deserialization rule with implementation found here: + * https://github.com/polynetwork/poly/blob/master/common/zero_copy_source.go + * + * Using this library instead of the unchecked serialization method can help reduce + * the risk of serious bugs and handfule, so it's recommended to use it. + * + * Please note that risk can be minimized, yet not eliminated. + */ +library ZeroCopySource { + /* @notice Read next byte as boolean type starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the boolean value + * @return The the read boolean value and new offset + */ + function NextBool(bytes memory buff, uint256 offset) internal pure returns(bool, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "Offset exceeds limit"); + // byte === bytes1 + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + bool value; + if (v == 0x01) { + value = true; + } else if (v == 0x00) { + value = false; + } else { + revert("NextBool value error"); + } + return (value, offset + 1); + } + + /* @notice Read next byte starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read byte value and new offset + */ + function NextByte(bytes memory buff, uint256 offset) internal pure returns (bytes1, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextByte, Offset exceeds maximum"); + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + return (v, offset + 1); + } + + /* @notice Read next byte as uint8 starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read uint8 value and new offset + */ + function NextUint8(bytes memory buff, uint256 offset) internal pure returns (uint8, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextUint8, Offset exceeds maximum"); + uint8 v; + assembly{ + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x01)) + v := mload(sub(tmpbytes, 0x1f)) + } + return (v, offset + 1); + } + + /* @notice Read next two bytes as uint16 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint16 value + * @return The read uint16 value and updated offset + */ + function NextUint16(bytes memory buff, uint256 offset) internal pure returns (uint16, uint256) { + require(offset + 2 <= buff.length && offset < offset + 2, "NextUint16, offset exceeds maximum"); + + uint16 v; + assembly { + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0x01, bvalue)) + mstore8(add(tmpbytes, 0x01), byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x02)) + v := mload(sub(tmpbytes, 0x1e)) + } + return (v, offset + 2); + } + + + /* @notice Read next four bytes as uint32 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint32 value + * @return The read uint32 value and updated offset + */ + function NextUint32(bytes memory buff, uint256 offset) internal pure returns (uint32, uint256) { + require(offset + 4 <= buff.length && offset < offset + 4, "NextUint32, offset exceeds maximum"); + uint32 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x04 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 4); + } + + /* @notice Read next eight bytes as uint64 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint64 value + * @return The read uint64 value and updated offset + */ + function NextUint64(bytes memory buff, uint256 offset) internal pure returns (uint64, uint256) { + require(offset + 8 <= buff.length && offset < offset + 8, "NextUint64, offset exceeds maximum"); + uint64 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x08 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 8); + } + + /* @notice Read next 32 bytes as uint256 type starting from offset, + there are limits considering the numerical limits in multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the uint256 value + * @return The read uint256 value and updated offset + */ + function NextUint255(bytes memory buff, uint256 offset) internal pure returns (uint256, uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextUint255, offset exceeds maximum"); + uint256 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x20 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(tmpbytes) + } + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + return (v, offset + 32); + } + /* @notice Read next variable bytes starting from offset, + the decoding rule coming from multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read variable bytes array value and updated offset + */ + function NextVarBytes(bytes memory buff, uint256 offset) internal pure returns(bytes memory, uint256) { + uint len; + (len, offset) = NextVarUint(buff, offset); + require(offset + len <= buff.length && offset < offset + len, "NextVarBytes, offset exceeds maximum"); + bytes memory tempBytes; + assembly{ + switch iszero(len) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + let lengthmod := and(len, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, len) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(buff, lengthmod), mul(0x20, iszero(lengthmod))), offset) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, len) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return (tempBytes, offset + len); + } + /* @notice Read next 32 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes32 value and updated offset + */ + function NextHash(bytes memory buff, uint256 offset) internal pure returns (bytes32 , uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextHash, offset exceeds maximum"); + bytes32 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 32); + } + + /* @notice Read next 20 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes20 value and updated offset + */ + function NextBytes20(bytes memory buff, uint256 offset) internal pure returns (bytes20 , uint256) { + require(offset + 20 <= buff.length && offset < offset + 20, "NextBytes20, offset exceeds maximum"); + bytes20 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 20); + } + + function NextVarUint(bytes memory buff, uint256 offset) internal pure returns(uint, uint256) { + bytes1 v; + (v, offset) = NextByte(buff, offset); + + uint value; + if (v == 0xFD) { + // return NextUint16(buff, offset); + (value, offset) = NextUint16(buff, offset); + require(value >= 0xFD && value <= 0xFFFF, "NextUint16, value outside range"); + return (value, offset); + } else if (v == 0xFE) { + // return NextUint32(buff, offset); + (value, offset) = NextUint32(buff, offset); + require(value > 0xFFFF && value <= 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else if (v == 0xFF) { + // return NextUint64(buff, offset); + (value, offset) = NextUint64(buff, offset); + require(value > 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else{ + // return (uint8(v), offset); + value = uint8(v); + require(value < 0xFD, "NextVarUint, value outside range"); + return (value, offset); + } + } +} + +// File: contracts/libs/common/ZeroCopySink.sol + + +/** + * @dev Wrappers over encoding and serialization operation into bytes from bassic types in Solidity for PolyNetwork cross chain utility. + * + * Encode basic types in Solidity into bytes easily. It's designed to be used + * for PolyNetwork cross chain application, and the encoding rules on Ethereum chain + * and the decoding rules on other chains should be consistent. Here we + * follow the underlying serialization rule with implementation found here: + * https://github.com/polynetwork/poly/blob/master/common/zero_copy_sink.go + * + * Using this library instead of the unchecked serialization method can help reduce + * the risk of serious bugs and handfule, so it's recommended to use it. + * + * Please note that risk can be minimized, yet not eliminated. + */ +library ZeroCopySink { + /* @notice Convert boolean value into bytes + * @param b The boolean value + * @return Converted bytes array + */ + function WriteBool(bool b) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + switch iszero(b) + case 1 { + mstore(add(buff, 0x20), shl(248, 0x00)) + // mstore8(add(buff, 0x20), 0x00) + } + default { + mstore(add(buff, 0x20), shl(248, 0x01)) + // mstore8(add(buff, 0x20), 0x01) + } + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert byte value into bytes + * @param b The byte value + * @return Converted bytes array + */ + function WriteByte(bytes1 b) internal pure returns (bytes memory) { + return WriteUint8(uint8(b)); + } + + /* @notice Convert uint8 value into bytes + * @param v The uint8 value + * @return Converted bytes array + */ + function WriteUint8(uint8 v) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + mstore(add(buff, 0x20), shl(248, v)) + // mstore(add(buff, 0x20), byte(0x1f, v)) + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert uint16 value into bytes + * @param v The uint16 value + * @return Converted bytes array + */ + function WriteUint16(uint16 v) internal pure returns (bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x02 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x22)) + } + return buff; + } + + /* @notice Convert uint32 value into bytes + * @param v The uint32 value + * @return Converted bytes array + */ + function WriteUint32(uint32 v) internal pure returns(bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + let byteLen := 0x04 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x24)) + } + return buff; + } + + /* @notice Convert uint64 value into bytes + * @param v The uint64 value + * @return Converted bytes array + */ + function WriteUint64(uint64 v) internal pure returns(bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x08 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x28)) + } + return buff; + } + + /* @notice Convert limited uint256 value into bytes + * @param v The uint256 value + * @return Converted bytes array + */ + function WriteUint255(uint256 v) internal pure returns (bytes memory) { + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds uint255 range"); + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x20 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x40)) + } + return buff; + } + + /* @notice Encode bytes format data into bytes + * @param data The bytes array data + * @return Encoded bytes array + */ + function WriteVarBytes(bytes memory data) internal pure returns (bytes memory) { + uint64 l = uint64(data.length); + return abi.encodePacked(WriteVarUint(l), data); + } + + function WriteVarUint(uint64 v) internal pure returns (bytes memory) { + if (v < 0xFD){ + return WriteUint8(uint8(v)); + } else if (v <= 0xFFFF) { + return abi.encodePacked(WriteByte(0xFD), WriteUint16(uint16(v))); + } else if (v <= 0xFFFFFFFF) { + return abi.encodePacked(WriteByte(0xFE), WriteUint32(uint32(v))); + } else { + return abi.encodePacked(WriteByte(0xFF), WriteUint64(uint64(v))); + } + } +} + +// File: contracts/libs/utils/ReentrancyGuard.sol + + +/** + * @dev Contract module that helps prevent reentrant calls to a function. + * + * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier + * available, which can be applied to functions to make sure there are no nested + * (reentrant) calls to them. + * + * Note that because there is a single `nonReentrant` guard, functions marked as + * `nonReentrant` may not call one another. This can be worked around by making + * those functions `private`, and then adding `external` `nonReentrant` entry + * points to them. + * + * TIP: If you would like to learn more about reentrancy and alternative ways + * to protect against it, check out our blog post + * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. + */ +abstract contract ReentrancyGuard { + bool private _notEntered; + + constructor () { + // Storing an initial non-zero value makes deployment a bit more + // expensive, but in exchange the refund on every call to nonReentrant + // will be lower in amount. Since refunds are capped to a percetange of + // the total transaction's gas, it is best to keep them low in cases + // like this one, to increase the likelihood of the full refund coming + // into effect. + _notEntered = true; + } + + /** + * @dev Prevents a contract from calling itself, directly or indirectly. + * Calling a `nonReentrant` function from another `nonReentrant` + * function is not supported. It is possible to prevent this from happening + * by making the `nonReentrant` function external, and make it call a + * `private` function that does the actual work. + */ + modifier nonReentrant() { + // On the first call to nonReentrant, _notEntered will be true + require(_notEntered, "ReentrancyGuard: reentrant call"); + + // Any calls to nonReentrant after this point will fail + _notEntered = false; + + _; + + // By storing the original value once again, a refund is triggered (see + // https://eips.ethereum.org/EIPS/eip-2200) + _notEntered = true; + } +} + +// File: contracts/libs/utils/Utils.sol + + +library Utils { + + /* @notice Convert the bytes array to bytes32 type, the bytes array length must be 32 + * @param _bs Source bytes array + * @return bytes32 + */ + function bytesToBytes32(bytes memory _bs) internal pure returns (bytes32 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 0x20 since the first 0x20 bytes stores _bs length + value := mload(add(_bs, 0x20)) + } + } + + /* @notice Convert bytes to uint256 + * @param _b Source bytes should have length of 32 + * @return uint256 + */ + function bytesToUint256(bytes memory _bs) internal pure returns (uint256 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 32 + value := mload(add(_bs, 0x20)) + } + require(value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + } + + /* @notice Convert uint256 to bytes + * @param _b uint256 that needs to be converted + * @return bytes + */ + function uint256ToBytes(uint256 _value) internal pure returns (bytes memory bs) { + require(_value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 0x20 at the first word, the length of bytes for uint256 value + mstore(bs, 0x20) + //In the next word, put value in bytes format to the next 32 bytes + mstore(add(bs, 0x20), _value) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Convert bytes to address + * @param _bs Source bytes: bytes length must be 20 + * @return Converted address from source bytes + */ + function bytesToAddress(bytes memory _bs) internal pure returns (address addr) + { + require(_bs.length == 20, "bytes length does not match address"); + assembly { + // for _bs, first word store _bs.length, second word store _bs.value + // load 32 bytes from mem[_bs+20], convert it into Uint160, meaning we take last 20 bytes as addr (address). + addr := mload(add(_bs, 0x14)) + } + + } + + /* @notice Convert address to bytes + * @param _addr Address need to be converted + * @return Converted bytes from address + */ + function addressToBytes(address _addr) internal pure returns (bytes memory bs){ + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 20 (address byte length) at the first word, the length of bytes for uint256 value + mstore(bs, 0x14) + // logical shift left _a by 12 bytes, change _a from right-aligned to left-aligned + mstore(add(bs, 0x20), shl(96, _addr)) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Do hash leaf as the multi-chain does + * @param _data Data in bytes format + * @return Hashed value in bytes32 format + */ + function hashLeaf(bytes memory _data) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x0), _data)); + } + + /* @notice Do hash children as the multi-chain does + * @param _l Left node + * @param _r Right node + * @return Hashed value in bytes32 format + */ + function hashChildren(bytes32 _l, bytes32 _r) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x01), _l, _r)); + } + + /* @notice Compare if two bytes are equal, which are in storage and memory, seperately + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L368 + * @param _preBytes The bytes stored in storage + * @param _postBytes The bytes stored in memory + * @return Bool type indicating if they are equal + */ + function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { + bool success = true; + + assembly { + // we know _preBytes_offset is 0 + let fslot := sload(_preBytes.slot) + // Arrays of 31 bytes or less have an even value in their slot, + // while longer arrays have an odd value. The actual length is + // the slot divided by two for odd values, and the lowest order + // byte divided by two for even values. + // If the slot is even, bitwise and the slot with 255 and divide by + // two to get the length. If the slot is odd, bitwise and the slot + // with -1 and divide by two. + let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) + let mlength := mload(_postBytes) + + // if lengths don't match the arrays are not equal + switch eq(slength, mlength) + case 1 { + // fslot can contain both the length and contents of the array + // if slength < 32 bytes so let's prepare for that + // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage + // slength != 0 + if iszero(iszero(slength)) { + switch lt(slength, 32) + case 1 { + // blank the last byte which is the length + fslot := mul(div(fslot, 0x100), 0x100) + + if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { + // unsuccess: + success := 0 + } + } + default { + // cb is a circuit breaker in the for loop since there's + // no said feature for inline assembly loops + // cb = 1 - don't breaker + // cb = 0 - break + let cb := 1 + + // get the keccak hash to get the contents of the array + mstore(0x0, _preBytes.slot) + let sc := keccak256(0x0, 0x20) + + let mc := add(_postBytes, 0x20) + let end := add(mc, mlength) + + // the next line is the loop condition: + // while(uint(mc < end) + cb == 2) + for {} eq(add(lt(mc, end), cb), 2) { + sc := add(sc, 1) + mc := add(mc, 0x20) + } { + if iszero(eq(sload(sc), mload(mc))) { + // unsuccess: + success := 0 + cb := 0 + } + } + } + } + } + default { + // unsuccess: + success := 0 + } + } + + return success; + } + + /* @notice Slice the _bytes from _start index till the result has length of _length + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L246 + * @param _bytes The original bytes needs to be sliced + * @param _start The index of _bytes for the start of sliced bytes + * @param _length The index of _bytes for the end of sliced bytes + * @return The sliced bytes + */ + function slice( + bytes memory _bytes, + uint _start, + uint _length + ) + internal + pure + returns (bytes memory) + { + require(_bytes.length >= (_start + _length)); + + bytes memory tempBytes; + + assembly { + switch iszero(_length) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + // lengthmod <= _length % 32 + let lengthmod := and(_length, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, _length) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, _length) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return tempBytes; + } + /* @notice Check if the elements number of _signers within _keepers array is no less than _m + * @param _keepers The array consists of serveral address + * @param _signers Some specific addresses to be looked into + * @param _m The number requirement paramter + * @return True means containment, false meansdo do not contain. + */ + function containMAddresses(address[] memory _keepers, address[] memory _signers, uint _m) internal pure returns (bool){ + uint m = 0; + for(uint i = 0; i < _signers.length; i++){ + for (uint j = 0; j < _keepers.length; j++) { + if (_signers[i] == _keepers[j]) { + m++; + delete _keepers[j]; + } + } + } + return m >= _m; + } + + /* @notice TODO + * @param key + * @return + */ + function compressMCPubKey(bytes memory key) internal pure returns (bytes memory newkey) { + require(key.length >= 67, "key lenggh is too short"); + newkey = slice(key, 0, 35); + if (uint8(key[66]) % 2 == 0){ + newkey[2] = bytes1(0x02); + } else { + newkey[2] = bytes1(0x03); + } + return newkey; + } + + /** + * @dev Returns true if `account` is a contract. + * Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L18 + * + * This test is non-exhaustive, and there may be false-negatives: during the + * execution of a contract's constructor, its address will be reported as + * not containing a contract. + * + * IMPORTANT: It is unsafe to assume that an address for which this + * function returns false is an externally-owned account (EOA) and not a + * contract. + */ + function isContract(address account) internal view returns (bool) { + // This method relies in extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != 0x0 && codehash != accountHash); + } +} + +// File: contracts/libs/math/SafeMath.sol + + + +/** + * @dev Wrappers over Solidity's arithmetic operations with added overflow + * checks. + * + * Arithmetic operations in Solidity wrap on overflow. This can easily result + * in bugs, because programmers usually assume that an overflow raises an + * error, which is the standard behavior in high level programming languages. + * `SafeMath` restores this intuition by reverting the transaction when an + * operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + */ +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} + +// File: contracts/Wallet.sol + + + +interface ERC20 { + function approve(address spender, uint256 amount) external returns (bool); + function transfer(address recipient, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + function balanceOf(address account) external view returns (uint256); +} + +/// @title The Wallet contract for Switcheo TradeHub +/// @author Switcheo Network +/// @notice This contract faciliates deposits for Switcheo TradeHub. +/// @dev This contract is used together with the LockProxy contract to allow users +/// to deposit funds without requiring them to have ETH +contract Wallet { + bool public isInitialized; + address public creator; + address public owner; + bytes public swthAddress; + + function initialize(address _owner, bytes calldata _swthAddress) external { + require(isInitialized == false, "Contract already initialized"); + isInitialized = true; + creator = msg.sender; + owner = _owner; + swthAddress = _swthAddress; + } + + /// @dev Allow this contract to receive Ethereum + receive() external payable {} + + /// @dev Allow this contract to receive ERC223 tokens + // An empty implementation is required so that the ERC223 token will not + // throw an error on transfer + function tokenFallback(address, uint, bytes calldata) external {} + + /// @dev send ETH from this contract to its creator + function sendETHToCreator(uint256 _amount) external { + require(msg.sender == creator, "Sender must be creator"); + // we use `call` here following the recommendation from + // https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + (bool success, ) = creator.call{value: _amount}(""); + require(success, "Transfer failed"); + } + + /// @dev send tokens from this contract to its creator + function sendERC20ToCreator(address _assetId, uint256 _amount) external { + require(msg.sender == creator, "Sender must be creator"); + + ERC20 token = ERC20(_assetId); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transfer.selector, + creator, + _amount + ) + ); + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(ERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. + + // A Solidity high level call has three parts: + // 1. The target address is checked to verify it contains contract code + // 2. The call itself is made, and success asserted + // 3. The return value is decoded, which in turn checks the size of the returned data. + // solhint-disable-next-line max-line-length + require(_isContract(address(token)), "SafeERC20: call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = address(token).call(data); + require(success, "SafeERC20: low-level call failed"); + + if (returndata.length > 0) { // Return data is optional + // solhint-disable-next-line max-line-length + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } + + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `_isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function _isContract(address account) private view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != accountHash && codehash != 0x0); + } +} + +// File: contracts/LockProxy.sol + + +interface CCM { + function crossChain(uint64 _toChainId, bytes calldata _toContract, bytes calldata _method, bytes calldata _txData) external returns (bool); +} + +interface CCMProxy { + function getEthCrossChainManager() external view returns (address); +} + +/// @title The LockProxy contract for Switcheo TradeHub +/// @author Switcheo Network +/// @notice This contract faciliates deposits and withdrawals to Switcheo TradeHub. +/// @dev The contract also allows for additional features in the future through "extension" contracts. +contract TestingLockProxy is ReentrancyGuard { + using SafeMath for uint256; + + // used for cross-chain addExtension and removeExtension methods + struct ExtensionTxArgs { + bytes extensionAddress; + } + + // used for cross-chain registerAsset method + struct RegisterAssetTxArgs { + bytes assetHash; + bytes nativeAssetHash; + } + + // used for cross-chain lock and unlock methods + struct TransferTxArgs { + bytes fromAssetHash; + bytes toAssetHash; + bytes toAddress; + uint256 amount; + uint256 feeAmount; + bytes feeAddress; + bytes fromAddress; + uint256 nonce; + } + + // used to create a unique salt for wallet creation + bytes public constant SALT_PREFIX = "switcheo-eth-wallet-factory-v1"; + address public constant ETH_ASSET_HASH = address(0); + + CCMProxy public ccmProxy; + uint64 public counterpartChainId; + uint256 public currentNonce = 0; + + // a mapping of assetHashes to the hash of + // (associated proxy address on Switcheo TradeHub, associated asset hash on Switcheo TradeHub) + mapping(address => bytes32) public registry; + + // a record of signed messages to prevent replay attacks + mapping(bytes32 => bool) public seenMessages; + + // a mapping of extension contracts + mapping(address => bool) public extensions; + + // a record of created wallets + mapping(address => bool) public wallets; + + event LockEvent( + address fromAssetHash, + address fromAddress, + uint64 toChainId, + bytes toAssetHash, + bytes toAddress, + bytes txArgs + ); + + event UnlockEvent( + address toAssetHash, + address toAddress, + uint256 amount, + bytes txArgs + ); + + constructor(address _ccmProxyAddress, uint64 _counterpartChainId) { + require(_counterpartChainId > 0, "counterpartChainId cannot be zero"); + require(_ccmProxyAddress != address(0), "ccmProxyAddress cannot be empty"); + counterpartChainId = _counterpartChainId; + ccmProxy = CCMProxy(_ccmProxyAddress); + } + + modifier onlyManagerContract() { + require( + msg.sender == ccmProxy.getEthCrossChainManager(), + "msg.sender is not CCM" + ); + _; + } + + /// @dev Allow this contract to receive Ethereum + receive() external payable {} + + /// @dev Allow this contract to receive ERC223 tokens + /// An empty implementation is required so that the ERC223 token will not + /// throw an error on transfer, this is specific to ERC223 tokens which + /// require this implementation, e.g. DGTX + function tokenFallback(address, uint, bytes calldata) external {} + + /// @dev Calculate the wallet address for the given owner and Switcheo TradeHub address + /// @param _ownerAddress the Ethereum address which the user has control over, i.e. can sign msgs with + /// @param _swthAddress the hex value of the user's Switcheo TradeHub address + /// @param _bytecodeHash the hash of the wallet contract's bytecode + /// @return the wallet address + function getWalletAddress( + address _ownerAddress, + bytes calldata _swthAddress, + bytes32 _bytecodeHash + ) + external + view + returns (address) + { + bytes32 salt = _getSalt( + _ownerAddress, + _swthAddress + ); + + bytes32 data = keccak256( + abi.encodePacked(bytes1(0xff), address(this), salt, _bytecodeHash) + ); + + return address(bytes20(data << 96)); + } + + /// @dev Create the wallet for the given owner and Switcheo TradeHub address + /// @param _ownerAddress the Ethereum address which the user has control over, i.e. can sign msgs with + /// @param _swthAddress the hex value of the user's Switcheo TradeHub address + /// @return true if success + function createWallet( + address _ownerAddress, + bytes calldata _swthAddress + ) + external + nonReentrant + returns (bool) + { + require(_ownerAddress != address(0), "Empty ownerAddress"); + require(_swthAddress.length != 0, "Empty swthAddress"); + + bytes32 salt = _getSalt( + _ownerAddress, + _swthAddress + ); + + Wallet wallet = new Wallet{salt: salt}(); + wallet.initialize(_ownerAddress, _swthAddress); + wallets[address(wallet)] = true; + + return true; + } + + /// @dev Add a contract as an extension + /// @param _argsBz the serialized ExtensionTxArgs + /// @param _fromChainId the originating chainId + /// @return true if success + function addExtension( + bytes calldata _argsBz, + bytes calldata /* _fromContractAddr */, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + ExtensionTxArgs memory args = _deserializeExtensionTxArgs(_argsBz); + address extensionAddress = Utils.bytesToAddress(args.extensionAddress); + extensions[extensionAddress] = true; + + return true; + } + + /// @dev Remove a contract from the extensions mapping + /// @param _argsBz the serialized ExtensionTxArgs + /// @param _fromChainId the originating chainId + /// @return true if success + function removeExtension( + bytes calldata _argsBz, + bytes calldata /* _fromContractAddr */, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + ExtensionTxArgs memory args = _deserializeExtensionTxArgs(_argsBz); + address extensionAddress = Utils.bytesToAddress(args.extensionAddress); + extensions[extensionAddress] = false; + + return true; + } + + /// @dev Marks an asset as registered by mapping the asset's address to + /// the specified _fromContractAddr and assetHash on Switcheo TradeHub + /// @param _argsBz the serialized RegisterAssetTxArgs + /// @param _fromContractAddr the associated contract address on Switcheo TradeHub + /// @param _fromChainId the originating chainId + /// @return true if success + function registerAsset( + bytes calldata _argsBz, + bytes calldata _fromContractAddr, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + RegisterAssetTxArgs memory args = _deserializeRegisterAssetTxArgs(_argsBz); + _markAssetAsRegistered( + Utils.bytesToAddress(args.nativeAssetHash), + _fromContractAddr, + args.assetHash + ); + + return true; + } + + /// @dev Performs a deposit from a Wallet contract + /// @param _walletAddress address of the wallet contract, the wallet contract + /// does not receive ETH in this call, but _walletAddress still needs to be payable + /// since the wallet contract can receive ETH, there would be compile errors otherwise + /// @param _assetHash the asset to deposit + /// @param _targetProxyHash the associated proxy hash on Switcheo TradeHub + /// @param _toAssetHash the associated asset hash on Switcheo TradeHub + /// @param _feeAddress the hex version of the Switcheo TradeHub address to send the fee to + /// @param _values[0]: amount, the number of tokens to deposit + /// @param _values[1]: feeAmount, the number of tokens to be used as fees + /// @param _values[2]: nonce, to prevent replay attacks + /// @param _values[3]: callAmount, some tokens may burn an amount before transfer + /// so we allow a callAmount to support these tokens + /// @param _v: the v value of the wallet owner's signature + /// @param _rs: the r, s values of the wallet owner's signature + function lockFromWallet( + address payable _walletAddress, + address _assetHash, + bytes calldata _targetProxyHash, + bytes calldata _toAssetHash, + bytes calldata _feeAddress, + uint256[] calldata _values, + uint8 _v, + bytes32[] calldata _rs + ) + external + nonReentrant + returns (bool) + { + require(wallets[_walletAddress], "Invalid wallet address"); + + Wallet wallet = Wallet(_walletAddress); + _validateLockFromWallet( + wallet.owner(), + _assetHash, + _targetProxyHash, + _toAssetHash, + _feeAddress, + _values, + _v, + _rs + ); + + // it is very important that this function validates the success of a transfer correctly + // since, once this line is passed, the deposit is assumed to be successful + // which will eventually result in the specified amount of tokens being minted for the + // wallet.swthAddress on Switcheo TradeHub + _transferInFromWallet(_walletAddress, _assetHash, _values[0], _values[3]); + + _lock( + _assetHash, + _targetProxyHash, + _toAssetHash, + wallet.swthAddress(), + _values[0], + _values[1], + _feeAddress + ); + + return true; + } + + /// @dev Performs a deposit + /// @param _assetHash the asset to deposit + /// @param _targetProxyHash the associated proxy hash on Switcheo TradeHub + /// @param _toAddress the hex version of the Switcheo TradeHub address to deposit to + /// @param _toAssetHash the associated asset hash on Switcheo TradeHub + /// @param _feeAddress the hex version of the Switcheo TradeHub address to send the fee to + /// @param _values[0]: amount, the number of tokens to deposit + /// @param _values[1]: feeAmount, the number of tokens to be used as fees + /// @param _values[2]: callAmount, some tokens may burn an amount before transfer + /// so we allow a callAmount to support these tokens + function lock( + address _assetHash, + bytes calldata _targetProxyHash, + bytes calldata _toAddress, + bytes calldata _toAssetHash, + bytes calldata _feeAddress, + uint256[] calldata _values + ) + external + payable + nonReentrant + returns (bool) + { + + // it is very important that this function validates the success of a transfer correctly + // since, once this line is passed, the deposit is assumed to be successful + // which will eventually result in the specified amount of tokens being minted for the + // _toAddress on Switcheo TradeHub + _transferIn(_assetHash, _values[0], _values[2]); + + _lock( + _assetHash, + _targetProxyHash, + _toAssetHash, + _toAddress, + _values[0], + _values[1], + _feeAddress + ); + + return true; + } + + /// @dev Performs a withdrawal that was initiated on Switcheo TradeHub + /// @param _argsBz the serialized TransferTxArgs + /// @param _fromContractAddr the associated contract address on Switcheo TradeHub + /// @param _fromChainId the originating chainId + /// @return true if success + function unlock( + bytes calldata _argsBz, + bytes calldata _fromContractAddr, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + TransferTxArgs memory args = _deserializeTransferTxArgs(_argsBz); + require(args.fromAssetHash.length > 0, "Invalid fromAssetHash"); + require(args.toAssetHash.length == 20, "Invalid toAssetHash"); + + address toAssetHash = Utils.bytesToAddress(args.toAssetHash); + address toAddress = Utils.bytesToAddress(args.toAddress); + + _validateAssetRegistration(toAssetHash, _fromContractAddr, args.fromAssetHash); + _transferOut(toAddress, toAssetHash, args.amount); + + emit UnlockEvent(toAssetHash, toAddress, args.amount, _argsBz); + return true; + } + + /// @dev Performs a transfer of funds, this is only callable by approved extension contracts + /// the `nonReentrant` guard is intentionally not added to this function, to allow for more flexibility. + /// The calling contract should be secure and have its own `nonReentrant` guard as needed. + /// @param _receivingAddress the address to transfer to + /// @param _assetHash the asset to transfer + /// @param _amount the amount to transfer + /// @return true if success + function extensionTransfer( + address _receivingAddress, + address _assetHash, + uint256 _amount + ) + external + returns (bool) + { + require( + extensions[msg.sender] == true, + "Invalid extension" + ); + + if (_assetHash == ETH_ASSET_HASH) { + // we use `call` here since the _receivingAddress could be a contract + // see https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + // for more info + (bool success, ) = _receivingAddress.call{value: _amount}(""); + require(success, "Transfer failed"); + return true; + } + + ERC20 token = ERC20(_assetHash); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + _receivingAddress, + _amount + ) + ); + + return true; + } + + /// @dev Marks an asset as registered by associating it to a specified Switcheo TradeHub proxy and asset hash + /// @param _assetHash the address of the asset to mark + /// @param _proxyAddress the associated proxy address on Switcheo TradeHub + /// @param _toAssetHash the associated asset hash on Switcheo TradeHub + function _markAssetAsRegistered( + address _assetHash, + bytes memory _proxyAddress, + bytes memory _toAssetHash + ) + private + { + require(_proxyAddress.length == 20, "Invalid proxyAddress"); + require( + registry[_assetHash] == bytes32(0), + "Asset already registered" + ); + + bytes32 value = keccak256(abi.encodePacked( + _proxyAddress, + _toAssetHash + )); + + registry[_assetHash] = value; + } + + /// @dev Validates that an asset's registration matches the given params + /// @param _assetHash the address of the asset to check + /// @param _proxyAddress the expected proxy address on Switcheo TradeHub + /// @param _toAssetHash the expected asset hash on Switcheo TradeHub + function _validateAssetRegistration( + address _assetHash, + bytes memory _proxyAddress, + bytes memory _toAssetHash + ) + private + view + { + require(_proxyAddress.length == 20, "Invalid proxyAddress"); + bytes32 value = keccak256(abi.encodePacked( + _proxyAddress, + _toAssetHash + )); + require(registry[_assetHash] == value, "Asset not registered"); + } + + /// @dev validates the asset registration and calls the CCM contract + function _lock( + address _fromAssetHash, + bytes memory _targetProxyHash, + bytes memory _toAssetHash, + bytes memory _toAddress, + uint256 _amount, + uint256 _feeAmount, + bytes memory _feeAddress + ) + private + { + require(_targetProxyHash.length == 20, "Invalid targetProxyHash"); + require(_toAssetHash.length > 0, "Empty toAssetHash"); + require(_toAddress.length > 0, "Empty toAddress"); + require(_amount > 0, "Amount must be more than zero"); + require(_feeAmount < _amount, "Fee amount cannot be greater than amount"); + + _validateAssetRegistration(_fromAssetHash, _targetProxyHash, _toAssetHash); + + TransferTxArgs memory txArgs = TransferTxArgs({ + fromAssetHash: Utils.addressToBytes(_fromAssetHash), + toAssetHash: _toAssetHash, + toAddress: _toAddress, + amount: _amount, + feeAmount: _feeAmount, + feeAddress: _feeAddress, + fromAddress: abi.encodePacked(msg.sender), + nonce: _getNextNonce() + }); + + bytes memory txData = _serializeTransferTxArgs(txArgs); + CCM ccm = _getCcm(); + require( + ccm.crossChain(counterpartChainId, _targetProxyHash, "unlock", txData), + "EthCrossChainManager crossChain executed error!" + ); + + emit LockEvent(_fromAssetHash, msg.sender, counterpartChainId, _toAssetHash, _toAddress, txData); + } + + /// @dev validate the signature for lockFromWallet + function _validateLockFromWallet( + address _walletOwner, + address _assetHash, + bytes memory _targetProxyHash, + bytes memory _toAssetHash, + bytes memory _feeAddress, + uint256[] memory _values, + uint8 _v, + bytes32[] memory _rs + ) + private + { + bytes32 message = keccak256(abi.encodePacked( + "sendTokens", + _assetHash, + _targetProxyHash, + _toAssetHash, + _feeAddress, + _values[0], + _values[1], + _values[2] + )); + + require(seenMessages[message] == false, "Message already seen"); + seenMessages[message] = true; + _validateSignature(message, _walletOwner, _v, _rs[0], _rs[1]); + } + + /// @dev transfers funds from a Wallet contract into this contract + /// the difference between this contract's before and after balance must equal _amount + /// this is assumed to be sufficient in ensuring that the expected amount + /// of funds were transferred in + function _transferInFromWallet( + address payable _walletAddress, + address _assetHash, + uint256 _amount, + uint256 _callAmount + ) + private + { + Wallet wallet = Wallet(_walletAddress); + if (_assetHash == ETH_ASSET_HASH) { + uint256 before = address(this).balance; + + wallet.sendETHToCreator(_callAmount); + + uint256 transferred = address(this).balance.sub(before); + require(transferred == _amount, "ETH transferred does not match the expected amount"); + return; + } + + ERC20 token = ERC20(_assetHash); + { + uint256 before = token.balanceOf(address(this)); + + wallet.sendERC20ToCreator(_assetHash, _callAmount); + + uint256 transferred = token.balanceOf(address(this)).sub(before); + require(transferred == _amount, "Tokens transferred does not match the expected amount"); + } + } + + /// @dev transfers funds from an address into this contract + /// for ETH transfers, we only check that msg.value == _amount, and _callAmount is ignored + /// for token transfers, the difference between this contract's before and after balance must equal _amount + /// these checks are assumed to be sufficient in ensuring that the expected amount + /// of funds were transferred in + function _transferIn( + address _assetHash, + uint256 _amount, + uint256 _callAmount + ) + private + { + if (_assetHash == ETH_ASSET_HASH) { + require(msg.value == _amount, "ETH transferred does not match the expected amount"); + return; + } + + ERC20 token = ERC20(_assetHash); + uint256 before = token.balanceOf(address(this)); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transferFrom.selector, + msg.sender, + address(this), + _callAmount + ) + ); + uint256 transferred = token.balanceOf(address(this)).sub(before); + require(transferred == _amount, "Tokens transferred does not match the expected amount"); + } + + /// @dev transfers funds from this contract to the _toAddress + function _transferOut( + address _toAddress, + address _assetHash, + uint256 _amount + ) + private + { + if (_assetHash == ETH_ASSET_HASH) { + // we use `call` here since the _receivingAddress could be a contract + // see https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + // for more info + (bool success, ) = _toAddress.call{value: _amount}(""); + require(success, "Transfer failed"); + return; + } + + ERC20 token = ERC20(_assetHash); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transfer.selector, + _toAddress, + _amount + ) + ); + } + + /// @dev validates a signature against the specified user address + function _validateSignature( + bytes32 _message, + address _user, + uint8 _v, + bytes32 _r, + bytes32 _s + ) + private + pure + { + bytes32 prefixedMessage = keccak256(abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + _message + )); + + require( + _user == ecrecover(prefixedMessage, _v, _r, _s), + "Invalid signature" + ); + } + + function _serializeTransferTxArgs(TransferTxArgs memory args) private pure returns (bytes memory) { + bytes memory buff; + buff = abi.encodePacked( + ZeroCopySink.WriteVarBytes(args.fromAssetHash), + ZeroCopySink.WriteVarBytes(args.toAssetHash), + ZeroCopySink.WriteVarBytes(args.toAddress), + ZeroCopySink.WriteUint255(args.amount), + ZeroCopySink.WriteUint255(args.feeAmount), + ZeroCopySink.WriteVarBytes(args.feeAddress), + ZeroCopySink.WriteVarBytes(args.fromAddress), + ZeroCopySink.WriteUint255(args.nonce) + ); + return buff; + } + + function _deserializeTransferTxArgs(bytes memory valueBz) private pure returns (TransferTxArgs memory) { + TransferTxArgs memory args; + uint256 off = 0; + (args.fromAssetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.toAssetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.toAddress, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.amount, off) = ZeroCopySource.NextUint255(valueBz, off); + return args; + } + + function _deserializeRegisterAssetTxArgs(bytes memory valueBz) private pure returns (RegisterAssetTxArgs memory) { + RegisterAssetTxArgs memory args; + uint256 off = 0; + (args.assetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.nativeAssetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + return args; + } + + function _deserializeExtensionTxArgs(bytes memory valueBz) private pure returns (ExtensionTxArgs memory) { + ExtensionTxArgs memory args; + uint256 off = 0; + (args.extensionAddress, off) = ZeroCopySource.NextVarBytes(valueBz, off); + return args; + } + + function _getCcm() private view returns (CCM) { + CCM ccm = CCM(ccmProxy.getEthCrossChainManager()); + return ccm; + } + + function _getNextNonce() private returns (uint256) { + currentNonce = currentNonce.add(1); + return currentNonce; + } + + function _getSalt( + address _ownerAddress, + bytes memory _swthAddress + ) + private + pure + returns (bytes32) + { + return keccak256(abi.encodePacked( + SALT_PREFIX, + _ownerAddress, + _swthAddress + )); + } + + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(ERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. + + // A Solidity high level call has three parts: + // 1. The target address is checked to verify it contains contract code + // 2. The call itself is made, and success asserted + // 3. The return value is decoded, which in turn checks the size of the returned data. + // solhint-disable-next-line max-line-length + require(_isContract(address(token)), "SafeERC20: call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = address(token).call(data); + require(success, "SafeERC20: low-level call failed"); + + if (returndata.length > 0) { // Return data is optional + // solhint-disable-next-line max-line-length + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } + + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `_isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function _isContract(address account) private view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != accountHash && codehash != 0x0); + } + + function mock_transferIn(address assetHash, uint256 amount, uint callAmount) public payable { + _transferIn(assetHash, amount, callAmount); + } + + function mock_transferOut(address toAddress, address assetHash, uint amount) public { + _transferOut(toAddress, assetHash, amount); + } +} diff --git a/smart-contracts/test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol b/smart-contracts/test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol new file mode 100644 index 0000000..ac3c784 --- /dev/null +++ b/smart-contracts/test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerUpgradeable} from "contracts/periphery/LockProxyTokenManagerUpgradeable.sol"; + +abstract contract LockProxyTokenManagerDeployer { + + // This is rather spurious, but serves to prove (albeit lightly!) that we could upgrade if we wanted to. + function deployLockProxyTokenManagerUpgradeable(address chainGateway, address lockProxyAddress) public returns (LockProxyTokenManagerUpgradeable) { + address implementation = address(new LockProxyTokenManagerUpgradeable()); + // Deploy proxy and attach our initial implementation. + address proxy = address( + new ERC1967Proxy(implementation, abi.encodeCall(LockProxyTokenManagerUpgradeable.initialize, (chainGateway, lockProxyAddress)))); + return LockProxyTokenManagerUpgradeable(proxy); + } + + function deployLockProxyTokenManagerV3( + address chainGateway, + address lockProxyAddress, + uint fees) public returns (LockProxyTokenManagerUpgradeableV3) { + LockProxyTokenManagerUpgradeable proxy = deployLockProxyTokenManagerUpgradeable(chainGateway, lockProxyAddress); + address newImplementation = address(new LockProxyTokenManagerUpgradeableV3()); + bytes memory encodedInitializerCall = abi.encodeCall( + LockProxyTokenManagerUpgradeableV3.reinitialize, fees); + proxy.upgradeToAndCall(newImplementation, encodedInitializerCall); + return LockProxyTokenManagerUpgradeableV3(address(proxy)); + } + + function deployLatestLockProxyTokenManager(address chainGateway, address lockProxy, uint fees) public returns (LockProxyTokenManagerUpgradeableV3) { + return deployLockProxyTokenManagerV3(chainGateway, lockProxy, fees); + } +} diff --git a/smart-contracts/test/zilbridge/ZilBridgeTokenBridge.compat.t.sol b/smart-contracts/test/zilbridge/ZilBridgeTokenBridge.compat.t.sol new file mode 100644 index 0000000..8657cfb --- /dev/null +++ b/smart-contracts/test/zilbridge/ZilBridgeTokenBridge.compat.t.sol @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import "forge-std/console.sol"; +import {Tester, Vm} from "test/Tester.sol"; +import {ITokenManagerStructs, TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import {CallMetadata, IRelayerEvents} from "contracts/core/Relayer.sol"; +import {ValidatorManager} from "contracts/core/ValidatorManager.sol"; +import {ChainGateway} from "contracts/core/ChainGateway.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import {TestToken} from "test/Helpers.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerDeployer} from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import {MintAndBurnTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/MintAndBurnTokenManagerDeployer.sol"; +import {LockAndReleaseTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/LockAndReleaseTokenManagerDeployer.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import { ZilBridgeFixture } from "test/zilbridge/DeployZilBridge.t.sol"; +import { MockLockProxy } from "./MockLockProxy.sol"; +import { ZilBridgeTokenBridgeIntegrationFixture } from "./ZilBridgeTokenIntegrationFixture.t.sol"; +import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol"; + +/*** @notice provides utility routines for the compatibility tests. These are very similar to the + * orutines in the integration tests. + */ +contract ZilBridgeTokenBridgeCompatibilityFixture is ZilBridgeTokenBridgeIntegrationFixture { + using MessageHashUtils for bytes; + + /// @notice send amount wrapped tokens to the remote user. + function transferToRemoteUser(address sourceToken_, address remoteToken_, + address sourceUser_, address remoteUser_, uint256 amount_) public { + startHoax(sourceUser_); + uint sourceChainId_ = block.chainid; + uint remoteChainId_ = block.chainid; + uint valueToSend = fees; + uint sourceBalance; + if (sourceToken_ == address(0)) { + // Check for native + assertGe(sourceUser_.balance, amount_); + sourceBalance = sourceUser_.balance; + valueToSend += amount_; + } else { + // Check that the source user has the funds. + sourceBalance = IERC20(sourceToken_).balanceOf(sourceUser_); + assertGe(sourceBalance, amount_); + // Set up an allowance + IERC20(sourceToken_).approve(address(sourceTokenManager), amount_); + } + uint remoteBalance; + if (remoteToken_ == address(0)) { + remoteBalance = remoteUser_.balance; + } else { + remoteBalance = IERC20(remoteToken_).balanceOf(remoteUser_); + } + + bytes memory data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(sourceChainId_, address(sourceTokenManager)), + // To + abi.encode(ITokenManagerStructs.AcceptArgs(address(remoteToken_), remoteUser_, amount_))); + + vm.expectEmit(address(sourceChainGateway)); + emit IRelayerEvents.Relayed(remoteChainId_, + address(remoteTokenManager), data, 1_000_000, 0); + sourceTokenManager.transfer{value: valueToSend} ( + address(sourceToken_), remoteChainId_, remoteUser_, amount_); + vm.startPrank(validator); + bytes[] memory signatures = new bytes[](1); + signatures[0] = sign(validatorWallet, abi.encode(sourceChainId_, remoteChainId_, + address(remoteTokenManager), data, + 1_000_000, 0) + .toEthSignedMessageHash()); + remoteChainGateway.dispatch(sourceChainId_, + address(remoteTokenManager), + data, 1_000_000, 0, signatures); + if (remoteToken_ == address(0)) { + assertGe(remoteUser_.balance, remoteBalance + amount_); + } else { + assertEq(IERC20(remoteToken_).balanceOf(remoteUser_), remoteBalance + amount_); + } + if (sourceToken_ == address(0)) { + assertLe(sourceUser_.balance, sourceBalance - amount_); + } else { + assertEq(IERC20(sourceToken_).balanceOf(sourceUser_), sourceBalance - amount_); + } + } + + /// @notice send amount wrapped tokens to a source user. + function transferFromRemoteUser(address sourceToken_, address remoteToken_, + address sourceUser_, address remoteUser_, uint256 amount_) public { + startHoax(remoteUser_); + uint sourceChainId_ = block.chainid; + uint remoteChainId_ = block.chainid; + uint valueToSend = fees; + uint remoteBalance; + if (remoteToken_ == address(0)) { + // Check for native + assertGe(remoteUser_.balance, amount_); + remoteBalance = remoteUser_.balance; + valueToSend += amount_; + } else { + // Check that the source user has the funds. + remoteBalance = IERC20(remoteToken_).balanceOf(remoteUser_); + assertGe(remoteBalance, amount_); + // Set up an allowance + IERC20(remoteToken_).approve(address(remoteTokenManager), amount_); + } + uint sourceBalance; + if (sourceToken_ == address(0)) { + sourceBalance = sourceUser_.balance; + } else { + sourceBalance = IERC20(sourceToken_).balanceOf(sourceUser_); + } + + bytes memory data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(remoteChainId_, address(remoteTokenManager)), + // To + abi.encode(ITokenManagerStructs.AcceptArgs(address(sourceToken_), sourceUser_, amount_))); + + vm.expectEmit(address(remoteChainGateway)); + emit IRelayerEvents.Relayed(sourceChainId_, + address(sourceTokenManager), data, 1_000_000, 0); + remoteTokenManager.transfer{value: valueToSend} ( + address(remoteToken_), sourceChainId_, sourceUser_, amount_); + vm.startPrank(validator); + bytes[] memory signatures = new bytes[](1); + signatures[0] = sign(validatorWallet, abi.encode(remoteChainId_, sourceChainId_, + address(sourceTokenManager), data, + 1_000_000, 0) + .toEthSignedMessageHash()); + sourceChainGateway.dispatch(remoteChainId_, + address(sourceTokenManager), + data, 1_000_000, 0, signatures); + if (sourceToken_ == address(0)) { + assertGe(sourceUser_.balance, sourceBalance + amount_); + } else { + assertEq(IERC20(sourceToken_).balanceOf(sourceUser_), sourceBalance + amount_); + } + if (remoteToken_ == address(0)) { + assertLe(remoteUser_.balance, remoteBalance - amount_); + } else { + assertEq(IERC20(remoteToken_).balanceOf(remoteUser_), remoteBalance - amount_); + } + } + +} + +/// @title Test that assets bridged via ZilBridge can be recovered via XBridge +/// @author rrw +/*** @notice This test is a replica of ZilBridgeTokenBridgeIntegrationTest which bridges assets that we fake up + * ( via MockLockProxy ) to have been locked by the original zilBridge, to prove that we can recover + * them via XBridge. + */ +contract ZilBridgeTokenBridgeCompatibilityTest is ZilBridgeTokenBridgeCompatibilityFixture { + using MessageHashUtils for bytes; + + function setUp() external { + installContracts(); + } + + function test_wrappedCompatibilityForward() external { + // Get an amount + uint256 amount = originalTokenSupply; + // Transfer it synthetically to the lock proxy at the source end. + startHoax(sourceUser); + nativelyOnSource.approve(address(lockProxy), amount); + lockProxy.mock_transferIn(address(nativelyOnSource), amount, amount); + + // Use the mock lock proxy to simulate transferring that to the remote user. + mockRemoteLockProxy.mock_transferOut(remoteUser, address(remoteNativelyOnSource), amount); + + assertEq(remoteNativelyOnSource.balanceOf(remoteUser), amount); + assertEq(nativelyOnSource.balanceOf(sourceUser), 0); + assertEq(nativelyOnSource.balanceOf(address(lockProxy)), amount); + + // OK. Now transfer it back again. + transferFromRemoteUser(address(nativelyOnSource), address(remoteNativelyOnSource), + sourceUser, remoteUser, amount); + } + + function test_wrappedCompatibilityNative() external { + // Get am amount + uint256 amount = originalTokenSupply; + startHoax(sourceUser); + uint256 gas = 1 ether; + vm.deal(sourceUser, amount + gas); + + uint256 sourceBalance = sourceUser.balance; + uint256 lockBalance = address(lockProxy).balance; + lockProxy.mock_transferIn{value: originalTokenSupply}(address(0), amount, amount); + mockRemoteLockProxy.mock_transferOut(remoteUser, address(remoteBridgedGasToken), amount); + + assertEq(remoteBridgedGasToken.balanceOf(remoteUser), amount); + assertLe(sourceUser.balance, sourceBalance - amount); + assertEq(address(lockProxy).balance, lockBalance + amount); + + // OK. Now transfer it back again. + transferFromRemoteUser(address(0), address(remoteBridgedGasToken), + sourceUser, remoteUser, amount); + } + + function test_wrappedCompatibilityBackward() external { + // Get an amount + uint256 amount = originalTokenSupply; + // Transfer it synthetically to the lock proxy at the remote + startHoax(remoteUser); + nativelyOnRemote.approve(address(mockRemoteLockProxy), amount); + mockRemoteLockProxy.mock_transferIn(address(nativelyOnRemote), amount, amount); + lockProxy.mock_transferOut(sourceUser, address(sourceNativelyOnRemote), amount); + + assertEq(sourceNativelyOnRemote.balanceOf(sourceUser), amount); + assertEq(nativelyOnRemote.balanceOf(remoteUser), 0); + assertEq(nativelyOnRemote.balanceOf(address(mockRemoteLockProxy)), amount); + + // Now transfer it back again + transferToRemoteUser(address(sourceNativelyOnRemote), address(nativelyOnRemote), + sourceUser, remoteUser, originalTokenSupply); + } +} diff --git a/smart-contracts/test/zilbridge/ZilBridgeTokenBridge.integration.t.sol b/smart-contracts/test/zilbridge/ZilBridgeTokenBridge.integration.t.sol new file mode 100644 index 0000000..2c821da --- /dev/null +++ b/smart-contracts/test/zilbridge/ZilBridgeTokenBridge.integration.t.sol @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import "forge-std/console.sol"; +import {Tester, Vm} from "test/Tester.sol"; +import {ITokenManagerStructs, TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import {CallMetadata, IRelayerEvents} from "contracts/core/Relayer.sol"; +import {ValidatorManager} from "contracts/core/ValidatorManager.sol"; +import {ChainGateway} from "contracts/core/ChainGateway.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import {TestToken} from "test/Helpers.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerDeployer} from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import {MintAndBurnTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/MintAndBurnTokenManagerDeployer.sol"; +import {LockAndReleaseTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/LockAndReleaseTokenManagerDeployer.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import { ZilBridgeFixture } from "test/zilbridge/DeployZilBridge.t.sol"; +import { MockLockProxy } from "./MockLockProxy.sol"; +import { ZilBridgeTokenBridgeIntegrationFixture } from "./ZilBridgeTokenIntegrationFixture.t.sol"; + +/// @title A general integration test for ZilBridge. +/// @author rrw +/*** @notice Tests some of the basic transfer routes: TestToken -> SwitcheoToken and back, + * and native token -> SwitcheoToken and back. Testing SwitcheoToken -> nativetoken is + * skipped, partly because it is symmetric and partly because it's not possible in zq1 + * anyway. + */ +contract ZilBridgeTokenBridgeIntegrationTest is ZilBridgeTokenBridgeIntegrationFixture { + using MessageHashUtils for bytes; + + + function setUp() external { + installContracts(); + } + + /// @notice test the happy path for a wrapped token to wrapped token exchange from TestToken to SwitcheoToken and back. + function test_happyPathWrappedToRemote() external { + startHoax(sourceUser); + uint amount = originalTokenSupply; + uint sourceChainId = block.chainid; + uint remoteChainId = block.chainid; + assertEq(nativelyOnSource.balanceOf(sourceUser), amount); + + bytes memory data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(sourceChainId, address(sourceTokenManager)), + // To + abi.encode(ITokenManagerStructs.AcceptArgs(address(remoteNativelyOnSource), remoteUser, amount))); + + // approval goes to the token manager, which will transfer value to/from the lock proxy for you. + nativelyOnSource.approve(address(sourceTokenManager), amount); + + // Ask the source token manager to take the source tokens and emit a relayed event + // (this should transfer the tokens to the lock proxy) + // TBD: Check this. + vm.expectEmit(address(sourceChainGateway)); + emit IRelayerEvents.Relayed(remoteChainId, + address(remoteTokenManager), data, 1_000_000, 0); + sourceTokenManager.transfer{value: fees}( + address(nativelyOnSource), remoteChainId, remoteUser, amount); + + // Now bridge .. + vm.startPrank(validator); + bytes[] memory signatures = new bytes[](1); + signatures[0] = sign(validatorWallet, abi.encode(sourceChainId, remoteChainId, + address(remoteTokenManager), + data, + 1_000_000, 0) + .toEthSignedMessageHash() + ); + remoteChainGateway.dispatch(sourceChainId, + address(remoteTokenManager), + data, + 1_000_000, + 0, + signatures); + + // OK. Now .. + assertEq(remoteNativelyOnSource.balanceOf(remoteUser), amount); + assertEq(remoteNativelyOnSource.totalSupply(), amount); + assertEq(nativelyOnSource.totalSupply(), amount); + assertEq(nativelyOnSource.balanceOf(sourceUser), 0); + + // Send it back again. + startHoax(remoteUser); + remoteNativelyOnSource.approve(address(remoteTokenManager), amount); + remoteTokenManager.transfer{value: fees}( + address(remoteNativelyOnSource), sourceChainId, sourceUser, amount); + + vm.startPrank(validator); + data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(remoteChainId, address(remoteTokenManager)), + // To + abi.encode( + ITokenManagerStructs.AcceptArgs(address(nativelyOnSource), sourceUser, amount) + )); + signatures[0] = sign( + validatorWallet, + abi.encode(remoteChainId, sourceChainId, + address(sourceTokenManager), + data, + 1_000_000, + 0).toEthSignedMessageHash()); + sourceChainGateway.dispatch(remoteChainId, + address(sourceTokenManager), + data, + 1_000_000, + 0, + signatures); + // Check balances are back .. + assertEq(remoteNativelyOnSource.balanceOf(remoteUser), 0); + assertEq(nativelyOnSource.balanceOf(sourceUser), amount); + } + + + /// @notice Test native token to SwitcheoToken and back. + function test_happyPathNativeToken() external { + startHoax(sourceUser); + uint256 amount = originalTokenSupply; + + // add some to account for gas. + uint accountForGas = 1 ether; + vm.deal(sourceUser, amount + accountForGas); + vm.deal(remoteUser, accountForGas); + uint256 initialSourceBalance = sourceUser.balance; + uint sourceChainId = block.chainid; + uint remoteChainId = block.chainid; + assertGt(sourceUser.balance, originalTokenSupply); + + bytes memory data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(sourceChainId, address(sourceTokenManager)), + // To + abi.encode(ITokenManagerStructs.AcceptArgs(address(remoteBridgedGasToken), remoteUser, amount))); + vm.expectEmit(address(sourceChainGateway)); + emit IRelayerEvents.Relayed(remoteChainId, + address(remoteTokenManager), data, 1_000_000, 0); + sourceTokenManager.transfer{ value: fees + originalTokenSupply }( + address(0), remoteChainId, remoteUser, amount); + + // Bridge! + vm.startPrank(validator); + bytes[] memory signatures = new bytes[](1); + signatures[0] = sign(validatorWallet, abi.encode(sourceChainId, remoteChainId, + address(remoteTokenManager), + data, + 1_000_000, 0) + .toEthSignedMessageHash()); + + remoteChainGateway.dispatch(sourceChainId, address(remoteTokenManager), data, 1_000_000, 0, signatures); + + // The source user should now have less balance then accountForGas + assertLe(sourceUser.balance, initialSourceBalance - amount); + uint256 sourceUserBalanceAfterTransfer = sourceUser.balance; + // The lock proxy should have the balance. + assertEq(address(lockProxy).balance, amount); + // The remote user should have the right number of wrapped tokens + assertEq(remoteBridgedGasToken.balanceOf(sourceUser), 0); + assertEq(remoteBridgedGasToken.balanceOf(remoteUser), amount); + assertEq(remoteBridgedGasToken.totalSupply(), amount); + + // ..aaand send them all back again + vm.startPrank(remoteUser); + remoteBridgedGasToken.approve(address(remoteTokenManager), amount); + remoteTokenManager.transfer{value: fees}( + address(remoteBridgedGasToken), sourceChainId, sourceUser, amount); + vm.startPrank(validator); + data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(remoteChainId, address(remoteTokenManager)), + // To + abi.encode( + ITokenManagerStructs.AcceptArgs(address(0), sourceUser, amount))); + signatures[0] = sign( + validatorWallet, + abi.encode(remoteChainId, sourceChainId, + address(sourceTokenManager), + data, + 1_000_000, 0).toEthSignedMessageHash()); + sourceChainGateway.dispatch(remoteChainId, + address(sourceTokenManager), + data, + 1_000_000, + 0, + signatures); + // Balances should now be back + assertEq(sourceUser.balance, sourceUserBalanceAfterTransfer + amount); + assertEq(remoteBridgedGasToken.balanceOf(remoteUser), 0); + // Weirdly, the supply is nondecreasing - this seems to be intentional in SwitcheoToken... + assertEq(remoteBridgedGasToken.totalSupply(), amount); + } + + /// @notice test the happy path for a remote wrapped token back to the source. + function test_happyPathFromRemote() external { + startHoax(remoteUser); + uint amount = originalTokenSupply; + uint sourceChainId = block.chainid; + uint remoteChainId = block.chainid; + assertEq(nativelyOnRemote.balanceOf(remoteUser), amount); + + bytes memory data = abi.encodeWithSelector( + TokenManagerUpgradeable.accept.selector, + // From + CallMetadata(remoteChainId, address(remoteTokenManager)), + // To + abi.encode(ITokenManagerStructs.AcceptArgs(address(sourceNativelyOnRemote), sourceUser, amount))); + + nativelyOnRemote.approve(address(remoteTokenManager), amount); + + vm.expectEmit(address(remoteChainGateway)); + emit IRelayerEvents.Relayed(sourceChainId, + address(sourceTokenManager), data, 1_000_000, 0); + remoteTokenManager.transfer{value: fees} ( + address(nativelyOnRemote), sourceChainId, sourceUser, amount); + + vm.startPrank(validator); + bytes[] memory signatures = new bytes[](1); + signatures[0] = sign(validatorWallet, abi.encode(remoteChainId, sourceChainId, + address(sourceTokenManager), + data, + 1_000_000, 0).toEthSignedMessageHash()); + sourceChainGateway.dispatch(remoteChainId, + address(sourceTokenManager), + data, + 1_000_000, 0, signatures); + // OK. Now ... + assertEq(sourceNativelyOnRemote.balanceOf(sourceUser), amount); + assertEq(sourceNativelyOnRemote.totalSupply(), amount); + assertEq(nativelyOnRemote.totalSupply(), amount); + assertEq(nativelyOnRemote.balanceOf(remoteUser), 0); + } +} diff --git a/smart-contracts/test/zilbridge/ZilBridgeTokenIntegrationFixture.t.sol b/smart-contracts/test/zilbridge/ZilBridgeTokenIntegrationFixture.t.sol new file mode 100644 index 0000000..4efb78c --- /dev/null +++ b/smart-contracts/test/zilbridge/ZilBridgeTokenIntegrationFixture.t.sol @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import "forge-std/console.sol"; +import {Tester, Vm} from "test/Tester.sol"; +import {ITokenManagerStructs, TokenManagerUpgradeable} from "contracts/periphery/TokenManagerUpgradeable.sol"; +import {LockAndReleaseTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockAndReleaseTokenManagerUpgradeableV3.sol"; +import {MintAndBurnTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/MintAndBurnTokenManagerUpgradeableV3.sol"; +import {BridgedToken} from "contracts/periphery/BridgedToken.sol"; +import {CallMetadata, IRelayerEvents} from "contracts/core/Relayer.sol"; +import {ValidatorManager} from "contracts/core/ValidatorManager.sol"; +import {ChainGateway} from "contracts/core/ChainGateway.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import {TestToken} from "test/Helpers.sol"; +import {LockProxyTokenManagerUpgradeableV3} from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; +import {LockProxyTokenManagerDeployer} from "test/zilbridge/TokenManagerDeployers/LockProxyTokenManagerDeployer.sol"; +import {MintAndBurnTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/MintAndBurnTokenManagerDeployer.sol"; +import {LockAndReleaseTokenManagerDeployer} from "test/periphery/TokenManagerDeployers/LockAndReleaseTokenManagerDeployer.sol"; +import { SwitcheoToken } from "test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol"; +import { ZilBridgeFixture } from "test/zilbridge/DeployZilBridge.t.sol"; +import { MockLockProxy } from "./MockLockProxy.sol"; + + +/*** @notice This deploys a bridge that is ZilBridge token manager on one side and lock-and-release on the other. + * We do this so we can test ZilBridge integration end to end, though in fact the "other side" of the bridge will be provided + * by the code in the Scilla half of this repo. + * + * Since the word "native" is quite heavily overloaded, we use "gas" to describe the gas token - ETH on ethereum, for example. + */ +contract ZilBridgeTokenBridgeIntegrationFixture is +Tester, IRelayerEvents, LockAndReleaseTokenManagerDeployer, LockProxyTokenManagerDeployer, ZilBridgeFixture { + using MessageHashUtils for bytes; + + // Gateway shared between the two chains + Vm.Wallet validatorWallet = vm.createWallet(1); + address validator = validatorWallet.addr; + address[] validators = [ validator ]; + address sourceUser = vm.addr(2); + address remoteUser = vm.addr(3); + uint originalTokenSupply = 1000 ether; + uint fees = 0.1 ether; + + LockProxyTokenManagerUpgradeableV3 sourceTokenManager; + // There are "actually" three of these - native (which is lock/release), a mint/burn token and a conventional token. + // This means we need a remote lock manager and a remote mint burn manager. + TestToken nativelyOnSource; + SwitcheoToken sourceNativelyOnRemote; + ChainGateway sourceChainGateway; + ValidatorManager sourceValidatorManager; + + // see doc/zilbridge.md + MockLockProxy mockRemoteLockProxy; + LockProxyTokenManagerUpgradeableV3 remoteTokenManager; + SwitcheoToken remoteNativelyOnSource; + SwitcheoToken remoteBridgedGasToken; + TestToken nativelyOnRemote; + + ChainGateway remoteChainGateway; + ValidatorManager remoteValidatorManager; + + function installContracts() public { + setUpZilBridgeForTesting(); + + vm.startPrank(validator); + // Deploy source infra + sourceValidatorManager = new ValidatorManager(validator); + sourceValidatorManager.initialize(validators); + sourceChainGateway = new ChainGateway(address(sourceValidatorManager), validator); + + // Deploy target infra + remoteValidatorManager = new ValidatorManager(validator); + remoteValidatorManager.initialize(validators); + remoteChainGateway = new ChainGateway(address(remoteValidatorManager), validator); + + // Deploy the token managers + sourceTokenManager = deployLatestLockProxyTokenManager(address(sourceChainGateway), address(lockProxy), fees); + mockRemoteLockProxy = new MockLockProxy(); + remoteTokenManager = deployLatestLockProxyTokenManager(address(remoteChainGateway), address(mockRemoteLockProxy), fees); + + vm.stopPrank(); + // Make the token manager an extension. + installTokenManager(address(sourceTokenManager)); + + // That involved a prank, so we need to reset our caller to the validator. + vm.startPrank(validator); + + // Register contracts to chaingateway + sourceChainGateway.register(address(sourceTokenManager)); + remoteChainGateway.register(address(remoteTokenManager)); + + // Deploy the test tokens. + nativelyOnSource = new TestToken(originalTokenSupply); + nativelyOnSource.transfer(sourceUser, originalTokenSupply); + + remoteNativelyOnSource = new SwitcheoToken(address(mockRemoteLockProxy), "Bridged testToken", "eTST", 18); + // When coins arrive at the remote token manager for remoteNativelyOnSource, send them to nativelyOnSource's + // manager at sourceTokenManager. + ITokenManagerStructs.RemoteToken memory sourceNOSStruct = ITokenManagerStructs.RemoteToken({ + token: address(nativelyOnSource), + tokenManager: address(sourceTokenManager), + chainId: block.chainid }); + remoteTokenManager.registerToken(address(remoteNativelyOnSource), sourceNOSStruct); + + // When coins arrive at nativelyOnSource, send them to remoteNativelyOnSource's manager at remoteTokenManager + ITokenManagerStructs.RemoteToken memory remoteNOSStruct = ITokenManagerStructs.RemoteToken({ + token: address(remoteNativelyOnSource), + tokenManager: address(remoteTokenManager), + chainId: block.chainid }); + sourceTokenManager.registerToken(address(nativelyOnSource), remoteNOSStruct); + + // Now, we'll do the gas token. This has to be a switcheo token, because + // the other side can hardly be mint & burn. + remoteBridgedGasToken = new SwitcheoToken(address(mockRemoteLockProxy), "Bridged gas", "eGAS", 18); + console.log("remoteBridgedGasToken = %s", address(remoteBridgedGasToken)); + console.log("mockLockProxy = %s", address(mockRemoteLockProxy)); + // When coins arrive at the remote token manager, send them to 0 on the source token manager. + ITokenManagerStructs.RemoteToken memory sourceGasStruct = ITokenManagerStructs.RemoteToken({ + token: address(0), + tokenManager: address(sourceTokenManager), + chainId: block.chainid }); + remoteTokenManager.registerToken(address(remoteBridgedGasToken), sourceGasStruct); + + // When coins arrive at 0 on the source token manager, send them to remoteridgedGasToken on the remote + ITokenManagerStructs.RemoteToken memory remoteGasStruct = ITokenManagerStructs.RemoteToken({ + token: address(remoteBridgedGasToken), + tokenManager: address(remoteTokenManager), + chainId: block.chainid }); + sourceTokenManager.registerToken(address(0), remoteGasStruct); + + nativelyOnRemote = new TestToken(originalTokenSupply); + sourceNativelyOnRemote = new SwitcheoToken(address(lockProxy), "Back-ported test token", "bTST", 18); + nativelyOnRemote.transfer(remoteUser, originalTokenSupply); + + // When tokens arrive at the remote token manager, send them to the source + ITokenManagerStructs.RemoteToken memory sourceBackStruct = ITokenManagerStructs.RemoteToken({ + token: address(sourceNativelyOnRemote), + tokenManager: address(sourceTokenManager), + chainId: block.chainid }); + remoteTokenManager.registerToken(address(nativelyOnRemote), sourceBackStruct); + + // When tokens arrive at the source token manager, send them to the remote + ITokenManagerStructs.RemoteToken memory remoteBackStruct = ITokenManagerStructs.RemoteToken({ + token: address(nativelyOnRemote), + tokenManager: address(remoteTokenManager), + chainId: block.chainid }); + sourceTokenManager.registerToken(address(sourceNativelyOnRemote), remoteBackStruct); + + vm.stopPrank(); + } + +} + diff --git a/smart-contracts/test/zilbridge/ZilBridgeTransfer.t.sol b/smart-contracts/test/zilbridge/ZilBridgeTransfer.t.sol new file mode 100644 index 0000000..bcc99a3 --- /dev/null +++ b/smart-contracts/test/zilbridge/ZilBridgeTransfer.t.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import "forge-std/console.sol"; +import {Tester} from "test/Tester.sol"; +import {TestToken} from "test/Helpers.sol"; +import { LockProxy } from "test/zilbridge/infrastructure/lockProxy.sol"; +import { EthCrossChainManagerProxy } from "test/zilbridge/infrastructure/ccmProxy.sol"; +import { EthCrossChainManager } from "test/zilbridge/infrastructure//ccmCrossChainManager.sol"; +import { EthCrossChainData } from "test/zilbridge/infrastructure/ethCrossChainData.sol"; +import { EthExtendCrossChainManager } from "contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol"; +import { ZilBridgeFixture } from "./DeployZilBridge.t.sol"; + +contract ZilBridgeTransferTest is ZilBridgeFixture { + function test_installNativeTokenBridge() external { + //setUpZilBridgeForTesting(); + //installTokenManager(); + } +} diff --git a/smart-contracts/test/zilbridge/ccmExtendCrossChainManager.t.sol b/smart-contracts/test/zilbridge/ccmExtendCrossChainManager.t.sol new file mode 100644 index 0000000..14ac4b4 --- /dev/null +++ b/smart-contracts/test/zilbridge/ccmExtendCrossChainManager.t.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.20; + +import "forge-std/console.sol"; +import {Tester} from "test/Tester.sol"; +import {TestToken} from "test/Helpers.sol"; +import { EthExtendCrossChainManager } from "contracts/periphery/ZilBridge/ccmExtendCrossChainManager.sol"; +import { Utils, ZeroCopySink, ZeroCopySource } from "test/zilbridge/infrastructure/ccmCrossChainManager.sol"; +import { EthCrossChainData } from "test/zilbridge/infrastructure/ethCrossChainData.sol"; +import { ZilBridgeFixture } from "./DeployZilBridge.t.sol"; +import { LockProxyTokenManagerUpgradeableV3 } from "contracts/periphery/TokenManagerV3/LockProxyTokenManagerUpgradeableV3.sol"; + +contract ccmExtendCrossChainManager is ZilBridgeFixture { + + function test_extensionManagerValue() external { + setUpZilBridgeForTesting(); + require(extendCCM._extensionManager() == owner); + require(extendCCM.extensionManager() == owner); + } + + function testFail_invalidRenounce() external { + setUpZilBridgeForTesting(); + vm.startPrank(other); + extendCCM.renounceExtensionManagement(); + vm.stopPrank(); + } + + function testFail_invalidTransfer() external { + setUpZilBridgeForTesting(); + vm.startPrank(other); + extendCCM.transferExtensionManagement(third); + vm.stopPrank(); + } + + function test_transferExtensionManager() external { + setUpZilBridgeForTesting(); + vm.startPrank(owner); + extendCCM.transferExtensionManagement(other); + vm.stopPrank(); + vm.startPrank(other); + extendCCM.transferExtensionManagement(third); + vm.stopPrank(); + } + + // TODO: remainder of the authorisation tests for transferExtensionManager. + + function test_addExtension() external { + setUpZilBridgeForTesting(); + uint fees = 0.1 ether; + // Create a lock proxy token manager - fake out the source chain gateway + LockProxyTokenManagerUpgradeableV3 lpTokenManager = deployLatestLockProxyTokenManager(address(0), address(lockProxy), fees); + installTokenManager(address(lpTokenManager)); + require(lockProxy.extensions(address(lpTokenManager))==true); + } + + function test_Pickle() view external { + console.log("owner = %s", owner); + bytes memory payload = ZeroCopySink.WriteVarBytes(Utils.addressToBytes(owner)); + console.logBytes(payload); + uint256 off = 0; + bytes memory result; + { + bytes1 v; + uint256 offset = 0; + (v,offset) = ZeroCopySource.NextByte(payload, offset); + console.log("F"); + console.logBytes1(v); + } + { + uint len; + uint256 offset = 0; + (len,offset) = ZeroCopySource.NextVarUint(payload, offset); + console.log("len = %d offset = %d payload = %d", len, offset, payload.length); + } + (result, off) = ZeroCopySource.NextVarBytes(payload, off); + console.logBytes(result); + } +} + diff --git a/smart-contracts/test/zilbridge/infrastructure/ccmCrossChainManager.sol b/smart-contracts/test/zilbridge/infrastructure/ccmCrossChainManager.sol new file mode 100644 index 0000000..cbbffd1 --- /dev/null +++ b/smart-contracts/test/zilbridge/infrastructure/ccmCrossChainManager.sol @@ -0,0 +1,1618 @@ +/** + *Submitted for verification at Etherscan.io on 2021-10-19 +*/ + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.2; + +abstract contract Context { + // Empty internal constructor, to prevent people from mistakenly deploying + // an instance of this contract, which should be used via inheritance. + constructor () { } + // solhint-disable-previous-line no-empty-blocks + + function _msgSender() internal view returns (address payable) { + return payable(msg.sender); + } + + function _msgData() internal view returns (bytes memory) { + this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 + return msg.data; + } +} + +interface IOwnable { + function isOwner() external view returns (bool); +} + +abstract contract Ownable is Context, IOwnable { + address private _owner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor () { + address msgSender = _msgSender(); + _owner = msgSender; + emit OwnershipTransferred(address(0), msgSender); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(isOwner(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Returns true if the caller is the current owner. + */ + function isOwner() public view returns (bool) { + return _msgSender() == _owner; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public onlyOwner { + emit OwnershipTransferred(_owner, address(0)); + _owner = address(0); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public onlyOwner { + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + */ + function _transferOwnership(address newOwner) internal { + require(newOwner != address(0), "Ownable: new owner is the zero address"); + emit OwnershipTransferred(_owner, newOwner); + _owner = newOwner; + } +} + +interface IPausable { + function paused() external view returns (bool); +} + +abstract contract Pausable is Context, IPausable { + /** + * @dev Emitted when the pause is triggered by a pauser (`account`). + */ + event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by a pauser (`account`). + */ + event Unpaused(address account); + + bool private _paused; + + /** + * @dev Initializes the contract in unpaused state. + */ + constructor () { + _paused = false; + } + + /** + * @dev Returns true if the contract is paused, and false otherwise. + */ + function paused() public view returns (bool) { + return _paused; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + */ + modifier whenNotPaused() { + require(!_paused, "Pausable: paused"); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + */ + modifier whenPaused() { + require(_paused, "Pausable: not paused"); + _; + } + + /** + * @dev Called to pause, triggers stopped state. + */ + function _pause() internal whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Called to unpause, returns to normal state. + */ + function _unpause() internal whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} + +library ZeroCopySink { + /* @notice Convert boolean value into bytes + * @param b The boolean value + * @return Converted bytes array + */ + function WriteBool(bool b) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + switch iszero(b) + case 1 { + mstore(add(buff, 0x20), shl(248, 0x00)) + // mstore8(add(buff, 0x20), 0x00) + } + default { + mstore(add(buff, 0x20), shl(248, 0x01)) + // mstore8(add(buff, 0x20), 0x01) + } + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert byte value into bytes + * @param b The byte value + * @return Converted bytes array + */ + function WriteByte(bytes1 b) internal pure returns (bytes memory) { + return WriteUint8(uint8(b)); + } + + /* @notice Convert uint8 value into bytes + * @param v The uint8 value + * @return Converted bytes array + */ + function WriteUint8(uint8 v) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + mstore(add(buff, 0x20), shl(248, v)) + // mstore(add(buff, 0x20), byte(0x1f, v)) + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert uint16 value into bytes + * @param v The uint16 value + * @return Converted bytes array + */ + function WriteUint16(uint16 v) internal pure returns (bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x02 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x22)) + } + return buff; + } + + /* @notice Convert uint32 value into bytes + * @param v The uint32 value + * @return Converted bytes array + */ + function WriteUint32(uint32 v) internal pure returns(bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + let byteLen := 0x04 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x24)) + } + return buff; + } + + /* @notice Convert uint64 value into bytes + * @param v The uint64 value + * @return Converted bytes array + */ + function WriteUint64(uint64 v) internal pure returns(bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x08 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x28)) + } + return buff; + } + + /* @notice Convert limited uint256 value into bytes + * @param v The uint256 value + * @return Converted bytes array + */ + function WriteUint255(uint256 v) internal pure returns (bytes memory) { + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds uint255 range"); + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x20 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x40)) + } + return buff; + } + + /* @notice Encode bytes format data into bytes + * @param data The bytes array data + * @return Encoded bytes array + */ + function WriteVarBytes(bytes memory data) internal pure returns (bytes memory) { + uint64 l = uint64(data.length); + return abi.encodePacked(WriteVarUint(l), data); + } + + function WriteVarUint(uint64 v) internal pure returns (bytes memory) { + if (v < 0xFD){ + return WriteUint8(uint8(v)); + } else if (v <= 0xFFFF) { + return abi.encodePacked(WriteByte(0xFD), WriteUint16(uint16(v))); + } else if (v <= 0xFFFFFFFF) { + return abi.encodePacked(WriteByte(0xFE), WriteUint32(uint32(v))); + } else { + return abi.encodePacked(WriteByte(0xFF), WriteUint64(uint64(v))); + } + } +} + +library ZeroCopySource { + /* @notice Read next byte as boolean type starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the boolean value + * @return The the read boolean value and new offset + */ + function NextBool(bytes memory buff, uint256 offset) internal pure returns(bool, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "Offset exceeds limit"); + // byte === bytes1 + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + bool value; + if (v == 0x01) { + value = true; + } else if (v == 0x00) { + value = false; + } else { + revert("NextBool value error"); + } + return (value, offset + 1); + } + + /* @notice Read next byte starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read byte value and new offset + */ + function NextByte(bytes memory buff, uint256 offset) internal pure returns (bytes1, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextByte, Offset exceeds maximum"); + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + return (v, offset + 1); + } + + /* @notice Read next byte as uint8 starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read uint8 value and new offset + */ + function NextUint8(bytes memory buff, uint256 offset) internal pure returns (uint8, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextUint8, Offset exceeds maximum"); + uint8 v; + assembly{ + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x01)) + v := mload(sub(tmpbytes, 0x1f)) + } + return (v, offset + 1); + } + + /* @notice Read next two bytes as uint16 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint16 value + * @return The read uint16 value and updated offset + */ + function NextUint16(bytes memory buff, uint256 offset) internal pure returns (uint16, uint256) { + require(offset + 2 <= buff.length && offset < offset + 2, "NextUint16, offset exceeds maximum"); + + uint16 v; + assembly { + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0x01, bvalue)) + mstore8(add(tmpbytes, 0x01), byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x02)) + v := mload(sub(tmpbytes, 0x1e)) + } + return (v, offset + 2); + } + + + /* @notice Read next four bytes as uint32 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint32 value + * @return The read uint32 value and updated offset + */ + function NextUint32(bytes memory buff, uint256 offset) internal pure returns (uint32, uint256) { + require(offset + 4 <= buff.length && offset < offset + 4, "NextUint32, offset exceeds maximum"); + uint32 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x04 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 4); + } + + /* @notice Read next eight bytes as uint64 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint64 value + * @return The read uint64 value and updated offset + */ + function NextUint64(bytes memory buff, uint256 offset) internal pure returns (uint64, uint256) { + require(offset + 8 <= buff.length && offset < offset + 8, "NextUint64, offset exceeds maximum"); + uint64 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x08 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 8); + } + + /* @notice Read next 32 bytes as uint256 type starting from offset, + there are limits considering the numerical limits in multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the uint256 value + * @return The read uint256 value and updated offset + */ + function NextUint255(bytes memory buff, uint256 offset) internal pure returns (uint256, uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextUint255, offset exceeds maximum"); + uint256 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x20 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(tmpbytes) + } + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + return (v, offset + 32); + } + /* @notice Read next variable bytes starting from offset, + the decoding rule coming from multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read variable bytes array value and updated offset + */ + function NextVarBytes(bytes memory buff, uint256 offset) internal pure returns(bytes memory, uint256) { + uint len; + (len, offset) = NextVarUint(buff, offset); + require(offset + len <= buff.length && offset < offset + len, "NextVarBytes, offset exceeds maximum"); + bytes memory tempBytes; + assembly{ + switch iszero(len) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + let lengthmod := and(len, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, len) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(buff, lengthmod), mul(0x20, iszero(lengthmod))), offset) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, len) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return (tempBytes, offset + len); + } + /* @notice Read next 32 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes32 value and updated offset + */ + function NextHash(bytes memory buff, uint256 offset) internal pure returns (bytes32 , uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextHash, offset exceeds maximum"); + bytes32 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 32); + } + + /* @notice Read next 20 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes20 value and updated offset + */ + function NextBytes20(bytes memory buff, uint256 offset) internal pure returns (bytes20 , uint256) { + require(offset + 20 <= buff.length && offset < offset + 20, "NextBytes20, offset exceeds maximum"); + bytes20 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 20); + } + + function NextVarUint(bytes memory buff, uint256 offset) internal pure returns(uint, uint256) { + bytes1 v; + (v, offset) = NextByte(buff, offset); + + uint value; + if (v == 0xFD) { + // return NextUint16(buff, offset); + (value, offset) = NextUint16(buff, offset); + require(value >= 0xFD && value <= 0xFFFF, "NextUint16, value outside range"); + return (value, offset); + } else if (v == 0xFE) { + // return NextUint32(buff, offset); + (value, offset) = NextUint32(buff, offset); + require(value > 0xFFFF && value <= 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else if (v == 0xFF) { + // return NextUint64(buff, offset); + (value, offset) = NextUint64(buff, offset); + require(value > 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else{ + // return (uint8(v), offset); + value = uint8(v); + require(value < 0xFD, "NextVarUint, value outside range"); + return (value, offset); + } + } +} + +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + * + * _Available since v2.4.0._ + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + * + * _Available since v2.4.0._ + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b != 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + * + * _Available since v2.4.0._ + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} + + +library Utils { + + /* @notice Convert the bytes array to bytes32 type, the bytes array length must be 32 + * @param _bs Source bytes array + * @return bytes32 + */ + function bytesToBytes32(bytes memory _bs) internal pure returns (bytes32 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 0x20 since the first 0x20 bytes stores _bs length + value := mload(add(_bs, 0x20)) + } + } + + /* @notice Convert bytes to uint256 + * @param _b Source bytes should have length of 32 + * @return uint256 + */ + function bytesToUint256(bytes memory _bs) internal pure returns (uint256 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 32 + value := mload(add(_bs, 0x20)) + } + require(value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + } + + /* @notice Convert uint256 to bytes + * @param _b uint256 that needs to be converted + * @return bytes + */ + function uint256ToBytes(uint256 _value) internal pure returns (bytes memory bs) { + require(_value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 0x20 at the first word, the length of bytes for uint256 value + mstore(bs, 0x20) + //In the next word, put value in bytes format to the next 32 bytes + mstore(add(bs, 0x20), _value) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Convert bytes to address + * @param _bs Source bytes: bytes length must be 20 + * @return Converted address from source bytes + */ + function bytesToAddress(bytes memory _bs) internal pure returns (address addr) + { + require(_bs.length == 20, "bytes length does not match address"); + assembly { + // for _bs, first word store _bs.length, second word store _bs.value + // load 32 bytes from mem[_bs+20], convert it into Uint160, meaning we take last 20 bytes as addr (address). + addr := mload(add(_bs, 0x14)) + } + + } + + /* @notice Convert address to bytes + * @param _addr Address need to be converted + * @return Converted bytes from address + */ + function addressToBytes(address _addr) internal pure returns (bytes memory bs){ + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 20 (address byte length) at the first word, the length of bytes for uint256 value + mstore(bs, 0x14) + // logical shift left _a by 12 bytes, change _a from right-aligned to left-aligned + mstore(add(bs, 0x20), shl(96, _addr)) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Do hash leaf as the multi-chain does + * @param _data Data in bytes format + * @return Hashed value in bytes32 format + */ + function hashLeaf(bytes memory _data) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x0), _data)); + } + + /* @notice Do hash children as the multi-chain does + * @param _l Left node + * @param _r Right node + * @return Hashed value in bytes32 format + */ + function hashChildren(bytes32 _l, bytes32 _r) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x01), _l, _r)); + } + + /* @notice Compare if two bytes are equal, which are in storage and memory, seperately + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L368 + * @param _preBytes The bytes stored in storage + * @param _postBytes The bytes stored in memory + * @return Bool type indicating if they are equal + */ + function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { + bool success = true; + + assembly { + // we know _preBytes_offset is 0 + let fslot := sload(_preBytes.slot) + // Arrays of 31 bytes or less have an even value in their slot, + // while longer arrays have an odd value. The actual length is + // the slot divided by two for odd values, and the lowest order + // byte divided by two for even values. + // If the slot is even, bitwise and the slot with 255 and divide by + // two to get the length. If the slot is odd, bitwise and the slot + // with -1 and divide by two. + let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) + let mlength := mload(_postBytes) + + // if lengths don't match the arrays are not equal + switch eq(slength, mlength) + case 1 { + // fslot can contain both the length and contents of the array + // if slength < 32 bytes so let's prepare for that + // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage + // slength != 0 + if iszero(iszero(slength)) { + switch lt(slength, 32) + case 1 { + // blank the last byte which is the length + fslot := mul(div(fslot, 0x100), 0x100) + + if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { + // unsuccess: + success := 0 + } + } + default { + // cb is a circuit breaker in the for loop since there's + // no said feature for inline assembly loops + // cb = 1 - don't breaker + // cb = 0 - break + let cb := 1 + + // get the keccak hash to get the contents of the array + mstore(0x0, _preBytes.slot) + let sc := keccak256(0x0, 0x20) + + let mc := add(_postBytes, 0x20) + let end := add(mc, mlength) + + // the next line is the loop condition: + // while(uint(mc < end) + cb == 2) + for {} eq(add(lt(mc, end), cb), 2) { + sc := add(sc, 1) + mc := add(mc, 0x20) + } { + if iszero(eq(sload(sc), mload(mc))) { + // unsuccess: + success := 0 + cb := 0 + } + } + } + } + } + default { + // unsuccess: + success := 0 + } + } + + return success; + } + + /* @notice Slice the _bytes from _start index till the result has length of _length + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L246 + * @param _bytes The original bytes needs to be sliced + * @param _start The index of _bytes for the start of sliced bytes + * @param _length The index of _bytes for the end of sliced bytes + * @return The sliced bytes + */ + function slice( + bytes memory _bytes, + uint _start, + uint _length + ) + internal + pure + returns (bytes memory) + { + require(_bytes.length >= (_start + _length)); + + bytes memory tempBytes; + + assembly { + switch iszero(_length) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + // lengthmod <= _length % 32 + let lengthmod := and(_length, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, _length) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, _length) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return tempBytes; + } + /* @notice Check if the elements number of _signers within _keepers array is no less than _m + * @param _keepers The array consists of serveral address + * @param _signers Some specific addresses to be looked into + * @param _m The number requirement paramter + * @return True means containment, false meansdo do not contain. + */ + function containMAddresses(address[] memory _keepers, address[] memory _signers, uint _m) internal pure returns (bool){ + uint m = 0; + for(uint i = 0; i < _signers.length; i++){ + for (uint j = 0; j < _keepers.length; j++) { + if (_signers[i] == _keepers[j]) { + m++; + delete _keepers[j]; + } + } + } + return m >= _m; + } + + /* @notice TODO + * @param key + * @return + */ + function compressMCPubKey(bytes memory key) internal pure returns (bytes memory newkey) { + require(key.length >= 67, "key lenggh is too short"); + newkey = slice(key, 0, 35); + if (uint8(key[66]) % 2 == 0){ + newkey[2] = bytes1(0x02); + } else { + newkey[2] = bytes1(0x03); + } + return newkey; + } + + /** + * @dev Returns true if `account` is a contract. + * Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L18 + * + * This test is non-exhaustive, and there may be false-negatives: during the + * execution of a contract's constructor, its address will be reported as + * not containing a contract. + * + * IMPORTANT: It is unsafe to assume that an address for which this + * function returns false is an externally-owned account (EOA) and not a + * contract. + */ + function isContract(address account) internal view returns (bool) { + // This method relies in extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != 0x0 && codehash != accountHash); + } +} + +library ECCUtils { + using SafeMath for uint256; + + struct Header { + uint32 version; + uint64 chainId; + uint32 timestamp; + uint32 height; + uint64 consensusData; + bytes32 prevBlockHash; + bytes32 transactionsRoot; + bytes32 crossStatesRoot; + bytes32 blockRoot; + bytes consensusPayload; + bytes20 nextBookkeeper; + } + + struct ToMerkleValue { + bytes txHash; // cross chain txhash + uint64 fromChainID; + TxParam makeTxParam; + } + + struct TxParam { + bytes txHash; // source chain txhash + bytes crossChainId; + bytes fromContract; + uint64 toChainId; + bytes toContract; + bytes method; + bytes args; + } + + uint constant POLYCHAIN_PUBKEY_LEN = 67; + uint constant POLYCHAIN_SIGNATURE_LEN = 65; + + /* @notice Verify Poly chain transaction whether exist or not + * @param _auditPath Poly chain merkle proof + * @param _root Poly chain root + * @return The verified value included in _auditPath + */ + function merkleProve(bytes memory _auditPath, bytes32 _root) internal pure returns (bytes memory) { + uint256 off = 0; + bytes memory value; + (value, off) = ZeroCopySource.NextVarBytes(_auditPath, off); + + bytes32 hash = Utils.hashLeaf(value); + uint size = _auditPath.length.sub(off).div(33); + bytes32 nodeHash; + bytes1 pos; + for (uint i = 0; i < size; i++) { + (pos, off) = ZeroCopySource.NextByte(_auditPath, off); + (nodeHash, off) = ZeroCopySource.NextHash(_auditPath, off); + if (pos == 0x00) { + hash = Utils.hashChildren(nodeHash, hash); + } else if (pos == 0x01) { + hash = Utils.hashChildren(hash, nodeHash); + } else { + revert("merkleProve, NextByte for position info failed"); + } + } + require(hash == _root, "merkleProve, expect root is not equal actual root"); + return value; + } + + /* @notice calculate next book keeper according to public key list + * @param _keyLen consensus node number + * @param _m minimum signature number + * @param _pubKeyList consensus node public key list + * @return two element: next book keeper, consensus node signer addresses + */ + function _getBookKeeper(uint _keyLen, uint _m, bytes memory _pubKeyList) internal pure returns (bytes20, address[] memory){ + bytes memory buff; + buff = ZeroCopySink.WriteUint16(uint16(_keyLen)); + address[] memory keepers = new address[](_keyLen); + bytes32 hash; + bytes memory publicKey; + for(uint i = 0; i < _keyLen; i++){ + publicKey = Utils.slice(_pubKeyList, i*POLYCHAIN_PUBKEY_LEN, POLYCHAIN_PUBKEY_LEN); + buff = abi.encodePacked(buff, ZeroCopySink.WriteVarBytes(Utils.compressMCPubKey(publicKey))); + hash = keccak256(Utils.slice(publicKey, 3, 64)); + keepers[i] = address(uint160(uint256(hash))); + } + + buff = abi.encodePacked(buff, ZeroCopySink.WriteUint16(uint16(_m))); + bytes20 nextBookKeeper = ripemd160(abi.encodePacked(sha256(buff))); + return (nextBookKeeper, keepers); + } + + /* @notice Verify public key derived from Poly chain + * @param _pubKeyList serialized consensus node public key list + * @param _sigList consensus node signature list + * @return return two element: next book keeper, consensus node signer addresses + */ + function verifyPubkey(bytes memory _pubKeyList) internal pure returns (bytes20, address[] memory) { + require(_pubKeyList.length % POLYCHAIN_PUBKEY_LEN == 0, "_pubKeyList length illegal!"); + uint n = _pubKeyList.length / POLYCHAIN_PUBKEY_LEN; + require(n >= 1, "too short _pubKeyList!"); + return _getBookKeeper(n, n - (n - 1) / 3, _pubKeyList); + } + + /* @notice Verify Poly chain consensus node signature + * @param _rawHeader Poly chain block header raw bytes + * @param _sigList consensus node signature list + * @param _keepers addresses corresponding with Poly chain book keepers' public keys + * @param _m minimum signature number + * @return true or false + */ + function verifySig(bytes memory _rawHeader, bytes memory _sigList, address[] memory _keepers, uint _m) internal pure returns (bool){ + bytes32 hash = getHeaderHash(_rawHeader); + + uint sigCount = _sigList.length.div(POLYCHAIN_SIGNATURE_LEN); + address[] memory signers = new address[](sigCount); + bytes32 r; + bytes32 s; + uint8 v; + for(uint j = 0; j < sigCount; j++){ + r = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN, 32)); + s = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN + 32, 32)); + v = uint8(_sigList[j*POLYCHAIN_SIGNATURE_LEN + 64]) + 27; + signers[j] = ecrecover(sha256(abi.encodePacked(hash)), v, r, s); + if (signers[j] == address(0)) return false; + } + return Utils.containMAddresses(_keepers, signers, _m); + } + + + /* @notice Serialize Poly chain book keepers' info in Ethereum addresses format into raw bytes + * @param keepersBytes The serialized addresses + * @return serialized bytes result + */ + function serializeKeepers(address[] memory keepers) internal pure returns (bytes memory) { + uint256 keeperLen = keepers.length; + bytes memory keepersBytes = ZeroCopySink.WriteUint64(uint64(keeperLen)); + for(uint i = 0; i < keeperLen; i++) { + keepersBytes = abi.encodePacked(keepersBytes, ZeroCopySink.WriteVarBytes(Utils.addressToBytes(keepers[i]))); + } + return keepersBytes; + } + + /* @notice Deserialize bytes into Ethereum addresses + * @param keepersBytes The serialized addresses derived from Poly chain book keepers in bytes format + * @return addresses + */ + function deserializeKeepers(bytes memory keepersBytes) internal pure returns (address[] memory) { + uint256 off = 0; + uint64 keeperLen; + (keeperLen, off) = ZeroCopySource.NextUint64(keepersBytes, off); + address[] memory keepers = new address[](keeperLen); + bytes memory keeperBytes; + for(uint i = 0; i < keeperLen; i++) { + (keeperBytes, off) = ZeroCopySource.NextVarBytes(keepersBytes, off); + keepers[i] = Utils.bytesToAddress(keeperBytes); + } + return keepers; + } + + /* @notice Deserialize Poly chain transaction raw value + * @param _valueBs Poly chain transaction raw bytes + * @return ToMerkleValue struct + */ + function deserializeMerkleValue(bytes memory _valueBs) internal pure returns (ToMerkleValue memory) { + ToMerkleValue memory toMerkleValue; + uint256 off = 0; + + (toMerkleValue.txHash, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (toMerkleValue.fromChainID, off) = ZeroCopySource.NextUint64(_valueBs, off); + + TxParam memory txParam; + + (txParam.txHash, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.crossChainId, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.fromContract, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.toChainId, off) = ZeroCopySource.NextUint64(_valueBs, off); + + (txParam.toContract, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.method, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + + (txParam.args, off) = ZeroCopySource.NextVarBytes(_valueBs, off); + toMerkleValue.makeTxParam = txParam; + + return toMerkleValue; + } + + /* @notice Deserialize Poly chain block header raw bytes + * @param _valueBs Poly chain block header raw bytes + * @return Header struct + */ + function deserializeHeader(bytes memory _headerBs) internal pure returns (Header memory) { + Header memory header; + uint256 off = 0; + (header.version, off) = ZeroCopySource.NextUint32(_headerBs, off); + + (header.chainId, off) = ZeroCopySource.NextUint64(_headerBs, off); + + (header.prevBlockHash, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.transactionsRoot, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.crossStatesRoot, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.blockRoot, off) = ZeroCopySource.NextHash(_headerBs, off); + + (header.timestamp, off) = ZeroCopySource.NextUint32(_headerBs, off); + + (header.height, off) = ZeroCopySource.NextUint32(_headerBs, off); + + (header.consensusData, off) = ZeroCopySource.NextUint64(_headerBs, off); + + (header.consensusPayload, off) = ZeroCopySource.NextVarBytes(_headerBs, off); + + (header.nextBookkeeper, off) = ZeroCopySource.NextBytes20(_headerBs, off); + + return header; + } + + /* @notice Deserialize Poly chain block header raw bytes + * @param rawHeader Poly chain block header raw bytes + * @return header hash same as Poly chain + */ + function getHeaderHash(bytes memory rawHeader) internal pure returns (bytes32) { + return sha256(abi.encodePacked(sha256(rawHeader))); + } +} + +interface IEthCrossChainData { + function putCurEpochStartHeight(uint32 curEpochStartHeight) external returns (bool); + function getCurEpochStartHeight() external view returns (uint32); + function putCurEpochConPubKeyBytes(bytes calldata curEpochPkBytes) external returns (bool); + function getCurEpochConPubKeyBytes() external view returns (bytes memory); + function markFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external returns (bool); + function checkIfFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external view returns (bool); + function getEthTxHashIndex() external view returns (uint256); + function putEthTxHash(bytes32 ethTxHash) external returns (bool); + function putExtraData(bytes32 key1, bytes32 key2, bytes calldata value) external returns (bool); + function getExtraData(bytes32 key1, bytes32 key2) external view returns (bytes memory); + function transferOwnership(address newOwner) external; + function pause() external returns (bool); + function unpause() external returns (bool); + function paused() external view returns (bool); + // Not used currently by ECCM + function getEthTxHash(uint256 ethTxHashIndex) external view returns (bytes32); +} + +interface IUpgradableECCM is IOwnable, IPausable { + function pause() external returns (bool); + function unpause() external returns (bool); + function upgradeToNew(address) external returns (bool); + function setChainId(uint64 _newChainId) external returns (bool); +} + + +interface IEthCrossChainManager { + function crossChain(uint64 _toChainId, bytes calldata _toContract, bytes calldata _method, bytes calldata _txData) external returns (bool); +} + +contract UpgradableECCM is IUpgradableECCM, Ownable, Pausable { + address public EthCrossChainDataAddress; + uint64 public chainId; + + constructor (address ethCrossChainDataAddr, uint64 _chainId) Pausable() Ownable() { + EthCrossChainDataAddress = ethCrossChainDataAddr; + chainId = _chainId; + } + function pause() onlyOwner public returns (bool) { + if (!paused()) { + _pause(); + } + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + if (!eccd.paused()) { + require(eccd.pause(), "pause EthCrossChainData contract failed"); + } + return true; + } + + function unpause() onlyOwner public returns (bool) { + if (paused()) { + _unpause(); + } + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + if (eccd.paused()) { + require(eccd.unpause(), "unpause EthCrossChainData contract failed"); + } + return true; + } + + // if we want to upgrade this contract, we need to invoke this method + function upgradeToNew(address newEthCrossChainManagerAddress) whenPaused onlyOwner public returns (bool) { + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + eccd.transferOwnership(newEthCrossChainManagerAddress); + return true; + } + + function setChainId(uint64 _newChainId) whenPaused onlyOwner public returns (bool) { + chainId = _newChainId; + return true; + } +} + +contract EthCrossChainManager is IEthCrossChainManager, UpgradableECCM { + using SafeMath for uint256; + + address public whiteLister; + mapping(address => bool) public whiteListFromContract; + mapping(address => mapping(bytes => bool)) public whiteListContractMethodMap; + + event InitGenesisBlockEvent(uint256 height, bytes rawHeader); + event ChangeBookKeeperEvent(uint256 height, bytes rawHeader); + event CrossChainEvent(address indexed sender, bytes txId, address proxyOrAssetContract, uint64 toChainId, bytes toContract, bytes rawdata); + event VerifyHeaderAndExecuteTxEvent(uint64 fromChainID, bytes toContract, bytes crossChainTxHash, bytes fromChainTxHash); + constructor( + address _eccd, + uint64 _chainId, + address[] memory fromContractWhiteList, + bytes[] memory contractMethodWhiteList + ) UpgradableECCM(_eccd,_chainId) { + whiteLister = msg.sender; + for (uint i=0;i curEpochStartHeight, "The height of header is lower than current epoch start height!"); + + // Ensure the rawHeader is the key header including info of switching consensus peers by containing non-empty nextBookKeeper field + require(header.nextBookkeeper != bytes20(0), "The nextBookKeeper of header is empty"); + + // Verify signature of rawHeader comes from pubKeyList + address[] memory polyChainBKs = ECCUtils.deserializeKeepers(eccd.getCurEpochConPubKeyBytes()); + uint n = polyChainBKs.length; + require(ECCUtils.verifySig(rawHeader, sigList, polyChainBKs, n - (n - 1) / 3), "Verify signature failed!"); + + // Convert pubKeyList into ethereum address format and make sure the compound address from the converted ethereum addresses + // equals passed in header.nextBooker + (bytes20 nextBookKeeper, address[] memory keepers) = ECCUtils.verifyPubkey(pubKeyList); + require(header.nextBookkeeper == nextBookKeeper, "NextBookers illegal"); + + // update current epoch start height of Poly chain and current epoch consensus peers book keepers addresses + require(eccd.putCurEpochStartHeight(header.height), "Save MC LatestHeight to Data contract failed!"); + require(eccd.putCurEpochConPubKeyBytes(ECCUtils.serializeKeepers(keepers)), "Save Poly chain book keepers bytes to Data contract failed!"); + + // Fire the change book keeper event + emit ChangeBookKeeperEvent(header.height, rawHeader); + return true; + } + + + /* @notice ERC20 token cross chain to other blockchain. + * this function push tx event to blockchain + * @param toChainId Target chain id + * @param toContract Target smart contract address in target block chain + * @param txData Transaction data for target chain, include to_address, amount + * @return true or false + */ + function crossChain(uint64 toChainId, bytes calldata toContract, bytes calldata method, bytes calldata txData) whenNotPaused external returns (bool) { + // Only allow whitelist contract to call + require(whiteListFromContract[msg.sender],"Invalid from contract"); + + // Load Ethereum cross chain data contract + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + + // To help differentiate two txs, the ethTxHashIndex is increasing automatically + uint256 txHashIndex = eccd.getEthTxHashIndex(); + + // Convert the uint256 into bytes + bytes memory paramTxHash = Utils.uint256ToBytes(txHashIndex); + + // Construct the makeTxParam, and put the hash info storage, to help provide proof of tx existence + bytes memory rawParam = abi.encodePacked(ZeroCopySink.WriteVarBytes(paramTxHash), + ZeroCopySink.WriteVarBytes(abi.encodePacked(sha256(abi.encodePacked(address(this), paramTxHash)))), + ZeroCopySink.WriteVarBytes(Utils.addressToBytes(msg.sender)), + ZeroCopySink.WriteUint64(toChainId), + ZeroCopySink.WriteVarBytes(toContract), + ZeroCopySink.WriteVarBytes(method), + ZeroCopySink.WriteVarBytes(txData) + ); + + // Must save it in the storage to be included in the proof to be verified. + require(eccd.putEthTxHash(keccak256(rawParam)), "Save ethTxHash by index to Data contract failed!"); + + // Fire the cross chain event denoting there is a cross chain request from Ethereum network to other public chains through Poly chain network + emit CrossChainEvent(tx.origin, paramTxHash, msg.sender, toChainId, toContract, rawParam); + return true; + } + /* @notice Verify Poly chain header and proof, execute the cross chain tx from Poly chain to Ethereum + * @param proof Poly chain tx merkle proof + * @param rawHeader The header containing crossStateRoot to verify the above tx merkle proof + * @param headerProof The header merkle proof used to verify rawHeader + * @param curRawHeader Any header in current epoch consensus of Poly chain + * @param headerSig The coverted signature veriable for solidity derived from Poly chain consensus nodes' signature + * used to verify the validity of curRawHeader + * @return true or false + */ + function verifyHeaderAndExecuteTx(bytes memory proof, bytes memory rawHeader, bytes memory headerProof, bytes memory curRawHeader,bytes memory headerSig) whenNotPaused public returns (bool){ + ECCUtils.Header memory header = ECCUtils.deserializeHeader(rawHeader); + // Load ehereum cross chain data contract + IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress); + + // Get stored consensus public key bytes of current poly chain epoch and deserialize Poly chain consensus public key bytes to address[] + address[] memory polyChainBKs = ECCUtils.deserializeKeepers(eccd.getCurEpochConPubKeyBytes()); + + uint256 curEpochStartHeight = eccd.getCurEpochStartHeight(); + + uint n = polyChainBKs.length; + if (header.height >= curEpochStartHeight) { + // It's enough to verify rawHeader signature + require(ECCUtils.verifySig(rawHeader, headerSig, polyChainBKs, n - ( n - 1) / 3), "Verify poly chain header signature failed!"); + } else { + // We need to verify the signature of curHeader + require(ECCUtils.verifySig(curRawHeader, headerSig, polyChainBKs, n - ( n - 1) / 3), "Verify poly chain current epoch header signature failed!"); + + // Then use curHeader.StateRoot and headerProof to verify rawHeader.CrossStateRoot + ECCUtils.Header memory curHeader = ECCUtils.deserializeHeader(curRawHeader); + bytes memory proveValue = ECCUtils.merkleProve(headerProof, curHeader.blockRoot); + require(ECCUtils.getHeaderHash(rawHeader) == Utils.bytesToBytes32(proveValue), "verify header proof failed!"); + } + + // Through rawHeader.CrossStatesRoot, the toMerkleValue or cross chain msg can be verified and parsed from proof + bytes memory toMerkleValueBs = ECCUtils.merkleProve(proof, header.crossStatesRoot); + + // Parse the toMerkleValue struct and make sure the tx has not been processed, then mark this tx as processed + ECCUtils.ToMerkleValue memory toMerkleValue = ECCUtils.deserializeMerkleValue(toMerkleValueBs); + require(!eccd.checkIfFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "the transaction has been executed!"); + require(eccd.markFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "Save crosschain tx exist failed!"); + + // Ethereum ChainId is 2, we need to check the transaction is for Ethereum network + require(toMerkleValue.makeTxParam.toChainId == chainId, "This Tx is not aiming at this network!"); + + // Obtain the targeting contract, so that Ethereum cross chain manager contract can trigger the executation of cross chain tx on Ethereum side + address toContract = Utils.bytesToAddress(toMerkleValue.makeTxParam.toContract); + + // only invoke PreWhiteListed Contract and method For Now + require(whiteListContractMethodMap[toContract][toMerkleValue.makeTxParam.method],"Invalid to contract or method"); + + //TODO: check this part to make sure we commit the next line when doing local net UT test + require(_executeCrossChainTx(toContract, toMerkleValue.makeTxParam.method, toMerkleValue.makeTxParam.args, toMerkleValue.makeTxParam.fromContract, toMerkleValue.fromChainID), "Execute CrossChain Tx failed!"); + + // Fire the cross chain event denoting the executation of cross chain tx is successful, + // and this tx is coming from other public chains to current Ethereum network + emit VerifyHeaderAndExecuteTxEvent(toMerkleValue.fromChainID, toMerkleValue.makeTxParam.toContract, toMerkleValue.txHash, toMerkleValue.makeTxParam.txHash); + + return true; + } + + /* @notice Dynamically invoke the targeting contract, and trigger executation of cross chain tx on Ethereum side + * @param _toContract The targeting contract that will be invoked by the Ethereum Cross Chain Manager contract + * @param _method At which method will be invoked within the targeting contract + * @param _args The parameter that will be passed into the targeting contract + * @param _fromContractAddr From chain smart contract address + * @param _fromChainId Indicate from which chain current cross chain tx comes + * @return true or false + */ + function _executeCrossChainTx(address _toContract, bytes memory _method, bytes memory _args, bytes memory _fromContractAddr, uint64 _fromChainId) internal returns (bool){ + // Ensure the targeting contract gonna be invoked is indeed a contract rather than a normal account address + require(Utils.isContract(_toContract), "The passed in address is not a contract!"); + bytes memory returnData; + bool success; + + // The returnData will be bytes32, the last byte must be 01; + (success, returnData) = _toContract.call(abi.encodePacked(bytes4(keccak256(abi.encodePacked(_method, "(bytes,bytes,uint64)"))), abi.encode(_args, _fromContractAddr, _fromChainId))); + + // Ensure the executation is successful + require(success == true, "EthCrossChain call business contract failed"); + + // Ensure the returned value is true + require(returnData.length != 0, "No return value from business contract!"); + (bool res,) = ZeroCopySource.NextBool(returnData, 31); + require(res == true, "EthCrossChain call business contract return is not true"); + + return true; + } +} diff --git a/smart-contracts/test/zilbridge/infrastructure/ccmProxy.sol b/smart-contracts/test/zilbridge/infrastructure/ccmProxy.sol new file mode 100644 index 0000000..08a27f6 --- /dev/null +++ b/smart-contracts/test/zilbridge/infrastructure/ccmProxy.sol @@ -0,0 +1,265 @@ +/** + *Submitted for verification at Etherscan.io on 2023-02-06 +*/ + +// File: eth-contracts/contracts/core/cross_chain_manager/interface/IEthCrossChainManagerProxy.sol + +//pragma solidity ^0.5.0; +pragma solidity ^0.8.20; + +/** + * @dev Interface of the EthCrossChainManagerProxy for business contract like LockProxy to obtain the reliable EthCrossChainManager contract hash. + */ +interface IEthCrossChainManagerProxy { + function getEthCrossChainManager() external view returns (address); +} + +// File: eth-contracts/contracts/core/cross_chain_manager/interface/IUpgradableECCM.sol + +/** + * @dev Interface of upgradableECCM to make ECCM be upgradable, the implementation is in UpgradableECCM.sol + */ +interface IUpgradableECCM { + function pause() external returns (bool); + function unpause() external returns (bool); + function paused() external view returns (bool); + function upgradeToNew(address) external returns (bool); + function isOwner() external view returns (bool); + function setChainId(uint64 _newChainId) external returns (bool); +} + +// File: eth-contracts/contracts/libs/GSN/Context.sol + + +/* + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with GSN meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + * Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/GSN/Context.sol + */ +abstract contract Context { + // Empty internal constructor, to prevent people from mistakenly deploying + // an instance of this contract, which should be used via inheritance. + constructor () { } + // solhint-disable-previous-line no-empty-blocks + + function _msgSender() internal view returns (address payable) { + return payable(msg.sender); + } + + function _msgData() internal view returns (bytes memory) { + this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 + return msg.data; + } +} + +// File: eth-contracts/contracts/libs/lifecycle/Pausable.sol + + +/** + * @dev Contract module which allows children to implement an emergency stop + * mechanism that can be triggered by an authorized account. + * + * This module is used through inheritance. It will make available the + * modifiers `whenNotPaused` and `whenPaused`, which can be applied to + * the functions of your contract. Note that they will not be pausable by + * simply including this module, only once the modifiers are put in place. + */ +abstract contract Pausable is Context { + /** + * @dev Emitted when the pause is triggered by a pauser (`account`). + */ + event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by a pauser (`account`). + */ + event Unpaused(address account); + + bool private _paused; + + /** + * @dev Initializes the contract in unpaused state. + */ + constructor () { + _paused = false; + } + + /** + * @dev Returns true if the contract is paused, and false otherwise. + */ + function paused() public view returns (bool) { + return _paused; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + */ + modifier whenNotPaused() { + require(!_paused, "Pausable: paused"); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + */ + modifier whenPaused() { + require(_paused, "Pausable: not paused"); + _; + } + + /** + * @dev Called to pause, triggers stopped state. + */ + function _pause() internal whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Called to unpause, returns to normal state. + */ + function _unpause() internal whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} + +// File: eth-contracts/contracts/libs/ownership/Ownable.sol + + +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +abstract contract Ownable is Context { + address private _owner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor () { + address msgSender = _msgSender(); + _owner = msgSender; + emit OwnershipTransferred(address(0), msgSender); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(isOwner(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Returns true if the caller is the current owner. + */ + function isOwner() public view returns (bool) { + return _msgSender() == _owner; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public onlyOwner { + emit OwnershipTransferred(_owner, address(0)); + _owner = address(0); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public onlyOwner { + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + */ + function _transferOwnership(address newOwner) internal { + require(newOwner != address(0), "Ownable: new owner is the zero address"); + emit OwnershipTransferred(_owner, newOwner); + _owner = newOwner; + } +} + +// File: eth-contracts/contracts/core/cross_chain_manager/upgrade/EthCrossChainManagerProxy.sol + + + + + + +contract EthCrossChainManagerProxy is IEthCrossChainManagerProxy, Ownable, Pausable { + address private EthCrossChainManagerAddr_; + + constructor(address _ethCrossChainManagerAddr) { + EthCrossChainManagerAddr_ = _ethCrossChainManagerAddr; + } + + function pause() onlyOwner public returns (bool) { + if (paused()) { + return true; + } + _pause(); + return true; + } + function unpause() onlyOwner public returns (bool) { + if (!paused()) { + return true; + } + _unpause(); + return true; + } + function pauseEthCrossChainManager() onlyOwner whenNotPaused public returns (bool) { + IUpgradableECCM eccm = IUpgradableECCM(EthCrossChainManagerAddr_); + require(pause(), "pause EthCrossChainManagerProxy contract failed!"); + require(eccm.pause(), "pause EthCrossChainManager contract failed!"); + return true; + } + function upgradeEthCrossChainManager(address _newEthCrossChainManagerAddr) onlyOwner whenPaused public returns (bool) { + IUpgradableECCM eccm = IUpgradableECCM(EthCrossChainManagerAddr_); + if (!eccm.paused()) { + require(eccm.pause(), "Pause old EthCrossChainManager contract failed!"); + } + require(eccm.upgradeToNew(_newEthCrossChainManagerAddr), "EthCrossChainManager upgradeToNew failed!"); + IUpgradableECCM neweccm = IUpgradableECCM(_newEthCrossChainManagerAddr); + require(neweccm.isOwner(), "EthCrossChainManagerProxy is not owner of new EthCrossChainManager contract"); + EthCrossChainManagerAddr_ = _newEthCrossChainManagerAddr; + return true; + } + function unpauseEthCrossChainManager() onlyOwner whenPaused public returns (bool) { + IUpgradableECCM eccm = IUpgradableECCM(EthCrossChainManagerAddr_); + require(eccm.unpause(), "unpause EthCrossChainManager contract failed!"); + require(unpause(), "unpause EthCrossChainManagerProxy contract failed!"); + return true; + } + function getEthCrossChainManager() whenNotPaused public view returns (address) { + return EthCrossChainManagerAddr_; + } +} diff --git a/smart-contracts/test/zilbridge/infrastructure/ethCrossChainData.sol b/smart-contracts/test/zilbridge/infrastructure/ethCrossChainData.sol new file mode 100644 index 0000000..0c71567 --- /dev/null +++ b/smart-contracts/test/zilbridge/infrastructure/ethCrossChainData.sol @@ -0,0 +1,316 @@ +/** + *Submitted for verification at Etherscan.io on 2023-02-06 +*/ + +// File: eth-contracts/contracts/core/cross_chain_manager/interface/IEthCrossChainData.sol + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.2; + + +interface IPausable { + function paused() external view returns (bool); + function pause() external returns (bool); + function unpause() external returns (bool); +} + +interface IOwnable { + function isOwner() external view returns (bool); + function transferOwnership(address newOwner) external; +} + + +/** + * @dev Interface of the EthCrossChainData contract, the implementation is in EthCrossChainData.sol + */ +interface IEthCrossChainData is IPausable { + function putCurEpochStartHeight(uint32 curEpochStartHeight) external returns (bool); + function getCurEpochStartHeight() external view returns (uint32); + function putCurEpochConPubKeyBytes(bytes calldata curEpochPkBytes) external returns (bool); + function getCurEpochConPubKeyBytes() external view returns (bytes memory); + function markFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external returns (bool); + function checkIfFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external view returns (bool); + function getEthTxHashIndex() external view returns (uint256); + function putEthTxHash(bytes32 ethTxHash) external returns (bool); + function putExtraData(bytes32 key1, bytes32 key2, bytes calldata value) external returns (bool); + function getExtraData(bytes32 key1, bytes32 key2) external view returns (bytes memory); + // function transferOwnership(address newOwner) external; + // Not used currently by ECCM + function getEthTxHash(uint256 ethTxHashIndex) external view returns (bytes32); +} +// File: eth-contracts/contracts/libs/GSN/Context.sol + +/* + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with GSN meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + * Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/GSN/Context.sol + */ +abstract contract Context { + // solhint-disable-previous-line no-empty-blocks + + function _msgSender() internal view returns (address payable) { + return payable(msg.sender); + } + + function _msgData() internal view returns (bytes memory) { + this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 + return msg.data; + } +} + +// File: eth-contracts/contracts/libs/lifecycle/Pausable.sol + +/** + * @dev Contract module which allows children to implement an emergency stop + * mechanism that can be triggered by an authorized account. + * + * This module is used through inheritance. It will make available the + * modifiers `whenNotPaused` and `whenPaused`, which can be applied to + * the functions of your contract. Note that they will not be pausable by + * simply including this module, only once the modifiers are put in place. + */ +abstract contract Pausable is Context, IPausable { + /** + * @dev Emitted when the pause is triggered by a pauser (`account`). + */ + event Paused(address account); + + function paused() public view returns (bool) { + return _paused; + } + /** + * @dev Emitted when the pause is lifted by a pauser (`account`). + */ + event Unpaused(address account); + + bool private _paused; + + /** + * @dev Initializes the contract in unpaused state. + */ + constructor () { + _paused = false; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + */ + modifier whenNotPaused() { + require(!_paused, "Pausable: paused"); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + */ + modifier whenPaused() { + require(_paused, "Pausable: not paused"); + _; + } + + /** + * @dev Called to pause, triggers stopped state. + */ + function _pause() internal whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Called to unpause, returns to normal state. + */ + function _unpause() internal whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} + +// File: eth-contracts/contracts/libs/ownership/Ownable.sol + + + +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +abstract contract Ownable is Context, IOwnable { + address private _owner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor () { + address msgSender = _msgSender(); + _owner = msgSender; + emit OwnershipTransferred(address(0), msgSender); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(isOwner(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Returns true if the caller is the current owner. + */ + function isOwner() public view returns (bool) { + return _msgSender() == _owner; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public onlyOwner { + emit OwnershipTransferred(_owner, address(0)); + _owner = address(0); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public onlyOwner { + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + */ + function _transferOwnership(address newOwner) internal { + require(newOwner != address(0), "Ownable: new owner is the zero address"); + emit OwnershipTransferred(_owner, newOwner); + _owner = newOwner; + } +} + +// File: eth-contracts/contracts/core/cross_chain_manager/data/EthCrossChainData.sol + + + + + +contract EthCrossChainData is IEthCrossChainData, Ownable, Pausable { + /* + Ethereum cross chain tx hash indexed by the automatically increased index. + This map exists for the reason that Poly chain can verify the existence of + cross chain request tx coming from Ethereum + */ + mapping(uint256 => bytes32) public EthToPolyTxHashMap; + // This index records the current Map length + uint256 public EthToPolyTxHashIndex; + + /* + When Poly chain switches the consensus epoch book keepers, the consensus peers public keys of Poly chain should be + changed into no-compressed version so that solidity smart contract can convert it to address type and + verify the signature derived from Poly chain account signature. + ConKeepersPkBytes means Consensus book Keepers Public Key Bytes + */ + bytes public ConKeepersPkBytes; + + // CurEpochStartHeight means Current Epoch Start Height of Poly chain block + uint32 public CurEpochStartHeight; + + // Record the from chain txs that have been processed + mapping(uint64 => mapping(bytes32 => bool)) FromChainTxExist; + + // Extra map for the usage of future potentially + mapping(bytes32 => mapping(bytes32 => bytes)) public ExtraData; + + // Store Current Epoch Start Height of Poly chain block + function putCurEpochStartHeight(uint32 curEpochStartHeight) public whenNotPaused onlyOwner returns (bool) { + CurEpochStartHeight = curEpochStartHeight; + return true; + } + + // Get Current Epoch Start Height of Poly chain block + function getCurEpochStartHeight() public view returns (uint32) { + return CurEpochStartHeight; + } + + // Store Consensus book Keepers Public Key Bytes + function putCurEpochConPubKeyBytes(bytes memory curEpochPkBytes) public whenNotPaused onlyOwner returns (bool) { + ConKeepersPkBytes = curEpochPkBytes; + return true; + } + + // Get Consensus book Keepers Public Key Bytes + function getCurEpochConPubKeyBytes() public view returns (bytes memory) { + return ConKeepersPkBytes; + } + + // Mark from chain tx fromChainTx as exist or processed + function markFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) public whenNotPaused onlyOwner returns (bool) { + FromChainTxExist[fromChainId][fromChainTx] = true; + return true; + } + + // Check if from chain tx fromChainTx has been processed before + function checkIfFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) public view returns (bool) { + return FromChainTxExist[fromChainId][fromChainTx]; + } + + // Get current recorded index of cross chain txs requesting from Ethereum to other public chains + // in order to help cross chain manager contract differenciate two cross chain tx requests + function getEthTxHashIndex() public view returns (uint256) { + return EthToPolyTxHashIndex; + } + + // Store Ethereum cross chain tx hash, increase the index record by 1 + function putEthTxHash(bytes32 ethTxHash) public whenNotPaused onlyOwner returns (bool) { + EthToPolyTxHashMap[EthToPolyTxHashIndex] = ethTxHash; + EthToPolyTxHashIndex = EthToPolyTxHashIndex + 1; + return true; + } + + // Get Ethereum cross chain tx hash indexed by ethTxHashIndex + function getEthTxHash(uint256 ethTxHashIndex) public view returns (bytes32) { + return EthToPolyTxHashMap[ethTxHashIndex]; + } + + // Store extra data, which may be used in the future + function putExtraData(bytes32 key1, bytes32 key2, bytes memory value) public whenNotPaused onlyOwner returns (bool) { + ExtraData[key1][key2] = value; + return true; + } + // Get extra data, which may be used in the future + function getExtraData(bytes32 key1, bytes32 key2) public view returns (bytes memory) { + return ExtraData[key1][key2]; + } + + function pause() onlyOwner whenNotPaused public returns (bool) { + _pause(); + return true; + } + + function unpause() onlyOwner whenPaused public returns (bool) { + _unpause(); + return true; + } +} diff --git a/smart-contracts/test/zilbridge/infrastructure/lockProxy.sol b/smart-contracts/test/zilbridge/infrastructure/lockProxy.sol new file mode 100644 index 0000000..27609c0 --- /dev/null +++ b/smart-contracts/test/zilbridge/infrastructure/lockProxy.sol @@ -0,0 +1,1884 @@ +/** + *Submitted for verification at Etherscan.io on 2020-11-09 +*/ + +// File: contracts/libs/common/ZeroCopySource.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @dev Wrappers over decoding and deserialization operation from bytes into bassic types in Solidity for PolyNetwork cross chain utility. + * + * Decode into basic types in Solidity from bytes easily. It's designed to be used + * for PolyNetwork cross chain application, and the decoding rules on Ethereum chain + * and the encoding rule on other chains should be consistent, and . Here we + * follow the underlying deserialization rule with implementation found here: + * https://github.com/polynetwork/poly/blob/master/common/zero_copy_source.go + * + * Using this library instead of the unchecked serialization method can help reduce + * the risk of serious bugs and handfule, so it's recommended to use it. + * + * Please note that risk can be minimized, yet not eliminated. + */ +library ZeroCopySource { + /* @notice Read next byte as boolean type starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the boolean value + * @return The the read boolean value and new offset + */ + function NextBool(bytes memory buff, uint256 offset) internal pure returns(bool, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "Offset exceeds limit"); + // byte === bytes1 + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + bool value; + if (v == 0x01) { + value = true; + } else if (v == 0x00) { + value = false; + } else { + revert("NextBool value error"); + } + return (value, offset + 1); + } + + /* @notice Read next byte starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read byte value and new offset + */ + function NextByte(bytes memory buff, uint256 offset) internal pure returns (bytes1, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextByte, Offset exceeds maximum"); + bytes1 v; + assembly{ + v := mload(add(add(buff, 0x20), offset)) + } + return (v, offset + 1); + } + + /* @notice Read next byte as uint8 starting at offset from buff + * @param buff Source bytes array + * @param offset The position from where we read the byte value + * @return The read uint8 value and new offset + */ + function NextUint8(bytes memory buff, uint256 offset) internal pure returns (uint8, uint256) { + require(offset + 1 <= buff.length && offset < offset + 1, "NextUint8, Offset exceeds maximum"); + uint8 v; + assembly{ + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x01)) + v := mload(sub(tmpbytes, 0x1f)) + } + return (v, offset + 1); + } + + /* @notice Read next two bytes as uint16 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint16 value + * @return The read uint16 value and updated offset + */ + function NextUint16(bytes memory buff, uint256 offset) internal pure returns (uint16, uint256) { + require(offset + 2 <= buff.length && offset < offset + 2, "NextUint16, offset exceeds maximum"); + + uint16 v; + assembly { + let tmpbytes := mload(0x40) + let bvalue := mload(add(add(buff, 0x20), offset)) + mstore8(tmpbytes, byte(0x01, bvalue)) + mstore8(add(tmpbytes, 0x01), byte(0, bvalue)) + mstore(0x40, add(tmpbytes, 0x02)) + v := mload(sub(tmpbytes, 0x1e)) + } + return (v, offset + 2); + } + + + /* @notice Read next four bytes as uint32 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint32 value + * @return The read uint32 value and updated offset + */ + function NextUint32(bytes memory buff, uint256 offset) internal pure returns (uint32, uint256) { + require(offset + 4 <= buff.length && offset < offset + 4, "NextUint32, offset exceeds maximum"); + uint32 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x04 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 4); + } + + /* @notice Read next eight bytes as uint64 type starting from offset + * @param buff Source bytes array + * @param offset The position from where we read the uint64 value + * @return The read uint64 value and updated offset + */ + function NextUint64(bytes memory buff, uint256 offset) internal pure returns (uint64, uint256) { + require(offset + 8 <= buff.length && offset < offset + 8, "NextUint64, offset exceeds maximum"); + uint64 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x08 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(sub(tmpbytes, sub(0x20, byteLen))) + } + return (v, offset + 8); + } + + /* @notice Read next 32 bytes as uint256 type starting from offset, + there are limits considering the numerical limits in multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the uint256 value + * @return The read uint256 value and updated offset + */ + function NextUint255(bytes memory buff, uint256 offset) internal pure returns (uint256, uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextUint255, offset exceeds maximum"); + uint256 v; + assembly { + let tmpbytes := mload(0x40) + let byteLen := 0x20 + for { + let tindex := 0x00 + let bindex := sub(byteLen, 0x01) + let bvalue := mload(add(add(buff, 0x20), offset)) + } lt(tindex, byteLen) { + tindex := add(tindex, 0x01) + bindex := sub(bindex, 0x01) + }{ + mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) + } + mstore(0x40, add(tmpbytes, byteLen)) + v := mload(tmpbytes) + } + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + return (v, offset + 32); + } + /* @notice Read next variable bytes starting from offset, + the decoding rule coming from multi-chain + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read variable bytes array value and updated offset + */ + function NextVarBytes(bytes memory buff, uint256 offset) internal pure returns(bytes memory, uint256) { + uint len; + (len, offset) = NextVarUint(buff, offset); + require(offset + len <= buff.length && offset < offset + len, "NextVarBytes, offset exceeds maximum"); + bytes memory tempBytes; + assembly{ + switch iszero(len) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + let lengthmod := and(len, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, len) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(buff, lengthmod), mul(0x20, iszero(lengthmod))), offset) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, len) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return (tempBytes, offset + len); + } + /* @notice Read next 32 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes32 value and updated offset + */ + function NextHash(bytes memory buff, uint256 offset) internal pure returns (bytes32 , uint256) { + require(offset + 32 <= buff.length && offset < offset + 32, "NextHash, offset exceeds maximum"); + bytes32 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 32); + } + + /* @notice Read next 20 bytes starting from offset, + * @param buff Source bytes array + * @param offset The position from where we read the bytes value + * @return The read bytes20 value and updated offset + */ + function NextBytes20(bytes memory buff, uint256 offset) internal pure returns (bytes20 , uint256) { + require(offset + 20 <= buff.length && offset < offset + 20, "NextBytes20, offset exceeds maximum"); + bytes20 v; + assembly { + v := mload(add(buff, add(offset, 0x20))) + } + return (v, offset + 20); + } + + function NextVarUint(bytes memory buff, uint256 offset) internal pure returns(uint, uint256) { + bytes1 v; + (v, offset) = NextByte(buff, offset); + + uint value; + if (v == 0xFD) { + // return NextUint16(buff, offset); + (value, offset) = NextUint16(buff, offset); + require(value >= 0xFD && value <= 0xFFFF, "NextUint16, value outside range"); + return (value, offset); + } else if (v == 0xFE) { + // return NextUint32(buff, offset); + (value, offset) = NextUint32(buff, offset); + require(value > 0xFFFF && value <= 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else if (v == 0xFF) { + // return NextUint64(buff, offset); + (value, offset) = NextUint64(buff, offset); + require(value > 0xFFFFFFFF, "NextVarUint, value outside range"); + return (value, offset); + } else{ + // return (uint8(v), offset); + value = uint8(v); + require(value < 0xFD, "NextVarUint, value outside range"); + return (value, offset); + } + } +} + +// File: contracts/libs/common/ZeroCopySink.sol + + +/** + * @dev Wrappers over encoding and serialization operation into bytes from bassic types in Solidity for PolyNetwork cross chain utility. + * + * Encode basic types in Solidity into bytes easily. It's designed to be used + * for PolyNetwork cross chain application, and the encoding rules on Ethereum chain + * and the decoding rules on other chains should be consistent. Here we + * follow the underlying serialization rule with implementation found here: + * https://github.com/polynetwork/poly/blob/master/common/zero_copy_sink.go + * + * Using this library instead of the unchecked serialization method can help reduce + * the risk of serious bugs and handfule, so it's recommended to use it. + * + * Please note that risk can be minimized, yet not eliminated. + */ +library ZeroCopySink { + /* @notice Convert boolean value into bytes + * @param b The boolean value + * @return Converted bytes array + */ + function WriteBool(bool b) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + switch iszero(b) + case 1 { + mstore(add(buff, 0x20), shl(248, 0x00)) + // mstore8(add(buff, 0x20), 0x00) + } + default { + mstore(add(buff, 0x20), shl(248, 0x01)) + // mstore8(add(buff, 0x20), 0x01) + } + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert byte value into bytes + * @param b The byte value + * @return Converted bytes array + */ + function WriteByte(bytes1 b) internal pure returns (bytes memory) { + return WriteUint8(uint8(b)); + } + + /* @notice Convert uint8 value into bytes + * @param v The uint8 value + * @return Converted bytes array + */ + function WriteUint8(uint8 v) internal pure returns (bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + mstore(buff, 1) + mstore(add(buff, 0x20), shl(248, v)) + // mstore(add(buff, 0x20), byte(0x1f, v)) + mstore(0x40, add(buff, 0x21)) + } + return buff; + } + + /* @notice Convert uint16 value into bytes + * @param v The uint16 value + * @return Converted bytes array + */ + function WriteUint16(uint16 v) internal pure returns (bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x02 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x22)) + } + return buff; + } + + /* @notice Convert uint32 value into bytes + * @param v The uint32 value + * @return Converted bytes array + */ + function WriteUint32(uint32 v) internal pure returns(bytes memory) { + bytes memory buff; + assembly{ + buff := mload(0x40) + let byteLen := 0x04 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x24)) + } + return buff; + } + + /* @notice Convert uint64 value into bytes + * @param v The uint64 value + * @return Converted bytes array + */ + function WriteUint64(uint64 v) internal pure returns(bytes memory) { + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x08 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x28)) + } + return buff; + } + + /* @notice Convert limited uint256 value into bytes + * @param v The uint256 value + * @return Converted bytes array + */ + function WriteUint255(uint256 v) internal pure returns (bytes memory) { + require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds uint255 range"); + bytes memory buff; + + assembly{ + buff := mload(0x40) + let byteLen := 0x20 + mstore(buff, byteLen) + for { + let mindex := 0x00 + let vindex := 0x1f + } lt(mindex, byteLen) { + mindex := add(mindex, 0x01) + vindex := sub(vindex, 0x01) + }{ + mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) + } + mstore(0x40, add(buff, 0x40)) + } + return buff; + } + + /* @notice Encode bytes format data into bytes + * @param data The bytes array data + * @return Encoded bytes array + */ + function WriteVarBytes(bytes memory data) internal pure returns (bytes memory) { + uint64 l = uint64(data.length); + return abi.encodePacked(WriteVarUint(l), data); + } + + function WriteVarUint(uint64 v) internal pure returns (bytes memory) { + if (v < 0xFD){ + return WriteUint8(uint8(v)); + } else if (v <= 0xFFFF) { + return abi.encodePacked(WriteByte(0xFD), WriteUint16(uint16(v))); + } else if (v <= 0xFFFFFFFF) { + return abi.encodePacked(WriteByte(0xFE), WriteUint32(uint32(v))); + } else { + return abi.encodePacked(WriteByte(0xFF), WriteUint64(uint64(v))); + } + } +} + +// File: contracts/libs/utils/ReentrancyGuard.sol + + +/** + * @dev Contract module that helps prevent reentrant calls to a function. + * + * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier + * available, which can be applied to functions to make sure there are no nested + * (reentrant) calls to them. + * + * Note that because there is a single `nonReentrant` guard, functions marked as + * `nonReentrant` may not call one another. This can be worked around by making + * those functions `private`, and then adding `external` `nonReentrant` entry + * points to them. + * + * TIP: If you would like to learn more about reentrancy and alternative ways + * to protect against it, check out our blog post + * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. + */ +abstract contract ReentrancyGuard { + bool private _notEntered; + + constructor () { + // Storing an initial non-zero value makes deployment a bit more + // expensive, but in exchange the refund on every call to nonReentrant + // will be lower in amount. Since refunds are capped to a percetange of + // the total transaction's gas, it is best to keep them low in cases + // like this one, to increase the likelihood of the full refund coming + // into effect. + _notEntered = true; + } + + /** + * @dev Prevents a contract from calling itself, directly or indirectly. + * Calling a `nonReentrant` function from another `nonReentrant` + * function is not supported. It is possible to prevent this from happening + * by making the `nonReentrant` function external, and make it call a + * `private` function that does the actual work. + */ + modifier nonReentrant() { + // On the first call to nonReentrant, _notEntered will be true + require(_notEntered, "ReentrancyGuard: reentrant call"); + + // Any calls to nonReentrant after this point will fail + _notEntered = false; + + _; + + // By storing the original value once again, a refund is triggered (see + // https://eips.ethereum.org/EIPS/eip-2200) + _notEntered = true; + } +} + +// File: contracts/libs/utils/Utils.sol + + +library Utils { + + /* @notice Convert the bytes array to bytes32 type, the bytes array length must be 32 + * @param _bs Source bytes array + * @return bytes32 + */ + function bytesToBytes32(bytes memory _bs) internal pure returns (bytes32 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 0x20 since the first 0x20 bytes stores _bs length + value := mload(add(_bs, 0x20)) + } + } + + /* @notice Convert bytes to uint256 + * @param _b Source bytes should have length of 32 + * @return uint256 + */ + function bytesToUint256(bytes memory _bs) internal pure returns (uint256 value) { + require(_bs.length == 32, "bytes length is not 32."); + assembly { + // load 32 bytes from memory starting from position _bs + 32 + value := mload(add(_bs, 0x20)) + } + require(value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + } + + /* @notice Convert uint256 to bytes + * @param _b uint256 that needs to be converted + * @return bytes + */ + function uint256ToBytes(uint256 _value) internal pure returns (bytes memory bs) { + require(_value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range"); + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 0x20 at the first word, the length of bytes for uint256 value + mstore(bs, 0x20) + //In the next word, put value in bytes format to the next 32 bytes + mstore(add(bs, 0x20), _value) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Convert bytes to address + * @param _bs Source bytes: bytes length must be 20 + * @return Converted address from source bytes + */ + function bytesToAddress(bytes memory _bs) internal pure returns (address addr) + { + require(_bs.length == 20, "bytes length does not match address"); + assembly { + // for _bs, first word store _bs.length, second word store _bs.value + // load 32 bytes from mem[_bs+20], convert it into Uint160, meaning we take last 20 bytes as addr (address). + addr := mload(add(_bs, 0x14)) + } + + } + + /* @notice Convert address to bytes + * @param _addr Address need to be converted + * @return Converted bytes from address + */ + function addressToBytes(address _addr) internal pure returns (bytes memory bs){ + assembly { + // Get a location of some free memory and store it in result as + // Solidity does for memory variables. + bs := mload(0x40) + // Put 20 (address byte length) at the first word, the length of bytes for uint256 value + mstore(bs, 0x14) + // logical shift left _a by 12 bytes, change _a from right-aligned to left-aligned + mstore(add(bs, 0x20), shl(96, _addr)) + // Update the free-memory pointer by padding our last write location to 32 bytes + mstore(0x40, add(bs, 0x40)) + } + } + + /* @notice Do hash leaf as the multi-chain does + * @param _data Data in bytes format + * @return Hashed value in bytes32 format + */ + function hashLeaf(bytes memory _data) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x0), _data)); + } + + /* @notice Do hash children as the multi-chain does + * @param _l Left node + * @param _r Right node + * @return Hashed value in bytes32 format + */ + function hashChildren(bytes32 _l, bytes32 _r) internal pure returns (bytes32 result) { + result = sha256(abi.encodePacked(bytes1(0x01), _l, _r)); + } + + /* @notice Compare if two bytes are equal, which are in storage and memory, seperately + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L368 + * @param _preBytes The bytes stored in storage + * @param _postBytes The bytes stored in memory + * @return Bool type indicating if they are equal + */ + function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { + bool success = true; + + assembly { + // we know _preBytes_offset is 0 + let fslot := sload(_preBytes.slot) + // Arrays of 31 bytes or less have an even value in their slot, + // while longer arrays have an odd value. The actual length is + // the slot divided by two for odd values, and the lowest order + // byte divided by two for even values. + // If the slot is even, bitwise and the slot with 255 and divide by + // two to get the length. If the slot is odd, bitwise and the slot + // with -1 and divide by two. + let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) + let mlength := mload(_postBytes) + + // if lengths don't match the arrays are not equal + switch eq(slength, mlength) + case 1 { + // fslot can contain both the length and contents of the array + // if slength < 32 bytes so let's prepare for that + // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage + // slength != 0 + if iszero(iszero(slength)) { + switch lt(slength, 32) + case 1 { + // blank the last byte which is the length + fslot := mul(div(fslot, 0x100), 0x100) + + if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { + // unsuccess: + success := 0 + } + } + default { + // cb is a circuit breaker in the for loop since there's + // no said feature for inline assembly loops + // cb = 1 - don't breaker + // cb = 0 - break + let cb := 1 + + // get the keccak hash to get the contents of the array + mstore(0x0, _preBytes.slot) + let sc := keccak256(0x0, 0x20) + + let mc := add(_postBytes, 0x20) + let end := add(mc, mlength) + + // the next line is the loop condition: + // while(uint(mc < end) + cb == 2) + for {} eq(add(lt(mc, end), cb), 2) { + sc := add(sc, 1) + mc := add(mc, 0x20) + } { + if iszero(eq(sload(sc), mload(mc))) { + // unsuccess: + success := 0 + cb := 0 + } + } + } + } + } + default { + // unsuccess: + success := 0 + } + } + + return success; + } + + /* @notice Slice the _bytes from _start index till the result has length of _length + Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L246 + * @param _bytes The original bytes needs to be sliced + * @param _start The index of _bytes for the start of sliced bytes + * @param _length The index of _bytes for the end of sliced bytes + * @return The sliced bytes + */ + function slice( + bytes memory _bytes, + uint _start, + uint _length + ) + internal + pure + returns (bytes memory) + { + require(_bytes.length >= (_start + _length)); + + bytes memory tempBytes; + + assembly { + switch iszero(_length) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + // lengthmod <= _length % 32 + let lengthmod := and(_length, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, _length) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, _length) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return tempBytes; + } + /* @notice Check if the elements number of _signers within _keepers array is no less than _m + * @param _keepers The array consists of serveral address + * @param _signers Some specific addresses to be looked into + * @param _m The number requirement paramter + * @return True means containment, false meansdo do not contain. + */ + function containMAddresses(address[] memory _keepers, address[] memory _signers, uint _m) internal pure returns (bool){ + uint m = 0; + for(uint i = 0; i < _signers.length; i++){ + for (uint j = 0; j < _keepers.length; j++) { + if (_signers[i] == _keepers[j]) { + m++; + delete _keepers[j]; + } + } + } + return m >= _m; + } + + /* @notice TODO + * @param key + * @return + */ + function compressMCPubKey(bytes memory key) internal pure returns (bytes memory newkey) { + require(key.length >= 67, "key lenggh is too short"); + newkey = slice(key, 0, 35); + if (uint8(key[66]) % 2 == 0){ + newkey[2] = bytes1(0x02); + } else { + newkey[2] = bytes1(0x03); + } + return newkey; + } + + /** + * @dev Returns true if `account` is a contract. + * Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L18 + * + * This test is non-exhaustive, and there may be false-negatives: during the + * execution of a contract's constructor, its address will be reported as + * not containing a contract. + * + * IMPORTANT: It is unsafe to assume that an address for which this + * function returns false is an externally-owned account (EOA) and not a + * contract. + */ + function isContract(address account) internal view returns (bool) { + // This method relies in extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != 0x0 && codehash != accountHash); + } +} + +// File: contracts/libs/math/SafeMath.sol + + + +/** + * @dev Wrappers over Solidity's arithmetic operations with added overflow + * checks. + * + * Arithmetic operations in Solidity wrap on overflow. This can easily result + * in bugs, because programmers usually assume that an overflow raises an + * error, which is the standard behavior in high level programming languages. + * `SafeMath` restores this intuition by reverting the transaction when an + * operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + */ +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} + +// File: contracts/Wallet.sol + + + +interface ERC20 { + function approve(address spender, uint256 amount) external returns (bool); + function transfer(address recipient, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + function balanceOf(address account) external view returns (uint256); +} + +/// @title The Wallet contract for Switcheo TradeHub +/// @author Switcheo Network +/// @notice This contract faciliates deposits for Switcheo TradeHub. +/// @dev This contract is used together with the LockProxy contract to allow users +/// to deposit funds without requiring them to have ETH +contract Wallet { + bool public isInitialized; + address public creator; + address public owner; + bytes public swthAddress; + + function initialize(address _owner, bytes calldata _swthAddress) external { + require(isInitialized == false, "Contract already initialized"); + isInitialized = true; + creator = msg.sender; + owner = _owner; + swthAddress = _swthAddress; + } + + /// @dev Allow this contract to receive Ethereum + receive() external payable {} + + /// @dev Allow this contract to receive ERC223 tokens + // An empty implementation is required so that the ERC223 token will not + // throw an error on transfer + function tokenFallback(address, uint, bytes calldata) external {} + + /// @dev send ETH from this contract to its creator + function sendETHToCreator(uint256 _amount) external { + require(msg.sender == creator, "Sender must be creator"); + // we use `call` here following the recommendation from + // https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + (bool success, ) = creator.call{value: _amount}(""); + require(success, "Transfer failed"); + } + + /// @dev send tokens from this contract to its creator + function sendERC20ToCreator(address _assetId, uint256 _amount) external { + require(msg.sender == creator, "Sender must be creator"); + + ERC20 token = ERC20(_assetId); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transfer.selector, + creator, + _amount + ) + ); + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(ERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. + + // A Solidity high level call has three parts: + // 1. The target address is checked to verify it contains contract code + // 2. The call itself is made, and success asserted + // 3. The return value is decoded, which in turn checks the size of the returned data. + // solhint-disable-next-line max-line-length + require(_isContract(address(token)), "SafeERC20: call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = address(token).call(data); + require(success, "SafeERC20: low-level call failed"); + + if (returndata.length > 0) { // Return data is optional + // solhint-disable-next-line max-line-length + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } + + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `_isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function _isContract(address account) private view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != accountHash && codehash != 0x0); + } +} + +// File: contracts/LockProxy.sol + + +interface CCM { + function crossChain(uint64 _toChainId, bytes calldata _toContract, bytes calldata _method, bytes calldata _txData) external returns (bool); +} + +interface CCMProxy { + function getEthCrossChainManager() external view returns (address); +} + +/// @title The LockProxy contract for Switcheo TradeHub +/// @author Switcheo Network +/// @notice This contract faciliates deposits and withdrawals to Switcheo TradeHub. +/// @dev The contract also allows for additional features in the future through "extension" contracts. +contract LockProxy is ReentrancyGuard { + using SafeMath for uint256; + + // used for cross-chain addExtension and removeExtension methods + struct ExtensionTxArgs { + bytes extensionAddress; + } + + // used for cross-chain registerAsset method + struct RegisterAssetTxArgs { + bytes assetHash; + bytes nativeAssetHash; + } + + // used for cross-chain lock and unlock methods + struct TransferTxArgs { + bytes fromAssetHash; + bytes toAssetHash; + bytes toAddress; + uint256 amount; + uint256 feeAmount; + bytes feeAddress; + bytes fromAddress; + uint256 nonce; + } + + // used to create a unique salt for wallet creation + bytes public constant SALT_PREFIX = "switcheo-eth-wallet-factory-v1"; + address public constant ETH_ASSET_HASH = address(0); + + CCMProxy public ccmProxy; + uint64 public counterpartChainId; + uint256 public currentNonce = 0; + + // a mapping of assetHashes to the hash of + // (associated proxy address on Switcheo TradeHub, associated asset hash on Switcheo TradeHub) + mapping(address => bytes32) public registry; + + // a record of signed messages to prevent replay attacks + mapping(bytes32 => bool) public seenMessages; + + // a mapping of extension contracts + mapping(address => bool) public extensions; + + // a record of created wallets + mapping(address => bool) public wallets; + + event LockEvent( + address fromAssetHash, + address fromAddress, + uint64 toChainId, + bytes toAssetHash, + bytes toAddress, + bytes txArgs + ); + + event UnlockEvent( + address toAssetHash, + address toAddress, + uint256 amount, + bytes txArgs + ); + + constructor(address _ccmProxyAddress, uint64 _counterpartChainId) { + require(_counterpartChainId > 0, "counterpartChainId cannot be zero"); + require(_ccmProxyAddress != address(0), "ccmProxyAddress cannot be empty"); + counterpartChainId = _counterpartChainId; + ccmProxy = CCMProxy(_ccmProxyAddress); + } + + modifier onlyManagerContract() { + require( + msg.sender == ccmProxy.getEthCrossChainManager(), + "msg.sender is not CCM" + ); + _; + } + + /// @dev Allow this contract to receive Ethereum + receive() external payable {} + + /// @dev Allow this contract to receive ERC223 tokens + /// An empty implementation is required so that the ERC223 token will not + /// throw an error on transfer, this is specific to ERC223 tokens which + /// require this implementation, e.g. DGTX + function tokenFallback(address, uint, bytes calldata) external {} + + /// @dev Calculate the wallet address for the given owner and Switcheo TradeHub address + /// @param _ownerAddress the Ethereum address which the user has control over, i.e. can sign msgs with + /// @param _swthAddress the hex value of the user's Switcheo TradeHub address + /// @param _bytecodeHash the hash of the wallet contract's bytecode + /// @return the wallet address + function getWalletAddress( + address _ownerAddress, + bytes calldata _swthAddress, + bytes32 _bytecodeHash + ) + external + view + returns (address) + { + bytes32 salt = _getSalt( + _ownerAddress, + _swthAddress + ); + + bytes32 data = keccak256( + abi.encodePacked(bytes1(0xff), address(this), salt, _bytecodeHash) + ); + + return address(bytes20(data << 96)); + } + + /// @dev Create the wallet for the given owner and Switcheo TradeHub address + /// @param _ownerAddress the Ethereum address which the user has control over, i.e. can sign msgs with + /// @param _swthAddress the hex value of the user's Switcheo TradeHub address + /// @return true if success + function createWallet( + address _ownerAddress, + bytes calldata _swthAddress + ) + external + nonReentrant + returns (bool) + { + require(_ownerAddress != address(0), "Empty ownerAddress"); + require(_swthAddress.length != 0, "Empty swthAddress"); + + bytes32 salt = _getSalt( + _ownerAddress, + _swthAddress + ); + + Wallet wallet = new Wallet{salt: salt}(); + wallet.initialize(_ownerAddress, _swthAddress); + wallets[address(wallet)] = true; + + return true; + } + + /// @dev Add a contract as an extension + /// @param _argsBz the serialized ExtensionTxArgs + /// @param _fromChainId the originating chainId + /// @return true if success + function addExtension( + bytes calldata _argsBz, + bytes calldata /* _fromContractAddr */, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + ExtensionTxArgs memory args = _deserializeExtensionTxArgs(_argsBz); + address extensionAddress = Utils.bytesToAddress(args.extensionAddress); + extensions[extensionAddress] = true; + + return true; + } + + /// @dev Remove a contract from the extensions mapping + /// @param _argsBz the serialized ExtensionTxArgs + /// @param _fromChainId the originating chainId + /// @return true if success + function removeExtension( + bytes calldata _argsBz, + bytes calldata /* _fromContractAddr */, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + ExtensionTxArgs memory args = _deserializeExtensionTxArgs(_argsBz); + address extensionAddress = Utils.bytesToAddress(args.extensionAddress); + extensions[extensionAddress] = false; + + return true; + } + + /// @dev Marks an asset as registered by mapping the asset's address to + /// the specified _fromContractAddr and assetHash on Switcheo TradeHub + /// @param _argsBz the serialized RegisterAssetTxArgs + /// @param _fromContractAddr the associated contract address on Switcheo TradeHub + /// @param _fromChainId the originating chainId + /// @return true if success + function registerAsset( + bytes calldata _argsBz, + bytes calldata _fromContractAddr, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + RegisterAssetTxArgs memory args = _deserializeRegisterAssetTxArgs(_argsBz); + _markAssetAsRegistered( + Utils.bytesToAddress(args.nativeAssetHash), + _fromContractAddr, + args.assetHash + ); + + return true; + } + + /// @dev Performs a deposit from a Wallet contract + /// @param _walletAddress address of the wallet contract, the wallet contract + /// does not receive ETH in this call, but _walletAddress still needs to be payable + /// since the wallet contract can receive ETH, there would be compile errors otherwise + /// @param _assetHash the asset to deposit + /// @param _targetProxyHash the associated proxy hash on Switcheo TradeHub + /// @param _toAssetHash the associated asset hash on Switcheo TradeHub + /// @param _feeAddress the hex version of the Switcheo TradeHub address to send the fee to + /// @param _values[0]: amount, the number of tokens to deposit + /// @param _values[1]: feeAmount, the number of tokens to be used as fees + /// @param _values[2]: nonce, to prevent replay attacks + /// @param _values[3]: callAmount, some tokens may burn an amount before transfer + /// so we allow a callAmount to support these tokens + /// @param _v: the v value of the wallet owner's signature + /// @param _rs: the r, s values of the wallet owner's signature + function lockFromWallet( + address payable _walletAddress, + address _assetHash, + bytes calldata _targetProxyHash, + bytes calldata _toAssetHash, + bytes calldata _feeAddress, + uint256[] calldata _values, + uint8 _v, + bytes32[] calldata _rs + ) + external + nonReentrant + returns (bool) + { + require(wallets[_walletAddress], "Invalid wallet address"); + + Wallet wallet = Wallet(_walletAddress); + _validateLockFromWallet( + wallet.owner(), + _assetHash, + _targetProxyHash, + _toAssetHash, + _feeAddress, + _values, + _v, + _rs + ); + + // it is very important that this function validates the success of a transfer correctly + // since, once this line is passed, the deposit is assumed to be successful + // which will eventually result in the specified amount of tokens being minted for the + // wallet.swthAddress on Switcheo TradeHub + _transferInFromWallet(_walletAddress, _assetHash, _values[0], _values[3]); + + _lock( + _assetHash, + _targetProxyHash, + _toAssetHash, + wallet.swthAddress(), + _values[0], + _values[1], + _feeAddress + ); + + return true; + } + + /// @dev Performs a deposit + /// @param _assetHash the asset to deposit + /// @param _targetProxyHash the associated proxy hash on Switcheo TradeHub + /// @param _toAddress the hex version of the Switcheo TradeHub address to deposit to + /// @param _toAssetHash the associated asset hash on Switcheo TradeHub + /// @param _feeAddress the hex version of the Switcheo TradeHub address to send the fee to + /// @param _values[0]: amount, the number of tokens to deposit + /// @param _values[1]: feeAmount, the number of tokens to be used as fees + /// @param _values[2]: callAmount, some tokens may burn an amount before transfer + /// so we allow a callAmount to support these tokens + function lock( + address _assetHash, + bytes calldata _targetProxyHash, + bytes calldata _toAddress, + bytes calldata _toAssetHash, + bytes calldata _feeAddress, + uint256[] calldata _values + ) + external + payable + nonReentrant + returns (bool) + { + + // it is very important that this function validates the success of a transfer correctly + // since, once this line is passed, the deposit is assumed to be successful + // which will eventually result in the specified amount of tokens being minted for the + // _toAddress on Switcheo TradeHub + _transferIn(_assetHash, _values[0], _values[2]); + + _lock( + _assetHash, + _targetProxyHash, + _toAssetHash, + _toAddress, + _values[0], + _values[1], + _feeAddress + ); + + return true; + } + + /// @dev Performs a withdrawal that was initiated on Switcheo TradeHub + /// @param _argsBz the serialized TransferTxArgs + /// @param _fromContractAddr the associated contract address on Switcheo TradeHub + /// @param _fromChainId the originating chainId + /// @return true if success + function unlock( + bytes calldata _argsBz, + bytes calldata _fromContractAddr, + uint64 _fromChainId + ) + external + onlyManagerContract + nonReentrant + returns (bool) + { + require(_fromChainId == counterpartChainId, "Invalid chain ID"); + + TransferTxArgs memory args = _deserializeTransferTxArgs(_argsBz); + require(args.fromAssetHash.length > 0, "Invalid fromAssetHash"); + require(args.toAssetHash.length == 20, "Invalid toAssetHash"); + + address toAssetHash = Utils.bytesToAddress(args.toAssetHash); + address toAddress = Utils.bytesToAddress(args.toAddress); + + _validateAssetRegistration(toAssetHash, _fromContractAddr, args.fromAssetHash); + _transferOut(toAddress, toAssetHash, args.amount); + + emit UnlockEvent(toAssetHash, toAddress, args.amount, _argsBz); + return true; + } + + /// @dev Performs a transfer of funds, this is only callable by approved extension contracts + /// the `nonReentrant` guard is intentionally not added to this function, to allow for more flexibility. + /// The calling contract should be secure and have its own `nonReentrant` guard as needed. + /// @param _receivingAddress the address to transfer to + /// @param _assetHash the asset to transfer + /// @param _amount the amount to transfer + /// @return true if success + function extensionTransfer( + address _receivingAddress, + address _assetHash, + uint256 _amount + ) + external + returns (bool) + { + require( + extensions[msg.sender] == true, + "Invalid extension" + ); + + if (_assetHash == ETH_ASSET_HASH) { + // we use `call` here since the _receivingAddress could be a contract + // see https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + // for more info + (bool success, ) = _receivingAddress.call{value: _amount}(""); + require(success, "Transfer failed"); + return true; + } + + ERC20 token = ERC20(_assetHash); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + _receivingAddress, + _amount + ) + ); + + return true; + } + + /// @dev Marks an asset as registered by associating it to a specified Switcheo TradeHub proxy and asset hash + /// @param _assetHash the address of the asset to mark + /// @param _proxyAddress the associated proxy address on Switcheo TradeHub + /// @param _toAssetHash the associated asset hash on Switcheo TradeHub + function _markAssetAsRegistered( + address _assetHash, + bytes memory _proxyAddress, + bytes memory _toAssetHash + ) + private + { + require(_proxyAddress.length == 20, "Invalid proxyAddress"); + require( + registry[_assetHash] == bytes32(0), + "Asset already registered" + ); + + bytes32 value = keccak256(abi.encodePacked( + _proxyAddress, + _toAssetHash + )); + + registry[_assetHash] = value; + } + + /// @dev Validates that an asset's registration matches the given params + /// @param _assetHash the address of the asset to check + /// @param _proxyAddress the expected proxy address on Switcheo TradeHub + /// @param _toAssetHash the expected asset hash on Switcheo TradeHub + function _validateAssetRegistration( + address _assetHash, + bytes memory _proxyAddress, + bytes memory _toAssetHash + ) + private + view + { + require(_proxyAddress.length == 20, "Invalid proxyAddress"); + bytes32 value = keccak256(abi.encodePacked( + _proxyAddress, + _toAssetHash + )); + require(registry[_assetHash] == value, "Asset not registered"); + } + + /// @dev validates the asset registration and calls the CCM contract + function _lock( + address _fromAssetHash, + bytes memory _targetProxyHash, + bytes memory _toAssetHash, + bytes memory _toAddress, + uint256 _amount, + uint256 _feeAmount, + bytes memory _feeAddress + ) + private + { + require(_targetProxyHash.length == 20, "Invalid targetProxyHash"); + require(_toAssetHash.length > 0, "Empty toAssetHash"); + require(_toAddress.length > 0, "Empty toAddress"); + require(_amount > 0, "Amount must be more than zero"); + require(_feeAmount < _amount, "Fee amount cannot be greater than amount"); + + _validateAssetRegistration(_fromAssetHash, _targetProxyHash, _toAssetHash); + + TransferTxArgs memory txArgs = TransferTxArgs({ + fromAssetHash: Utils.addressToBytes(_fromAssetHash), + toAssetHash: _toAssetHash, + toAddress: _toAddress, + amount: _amount, + feeAmount: _feeAmount, + feeAddress: _feeAddress, + fromAddress: abi.encodePacked(msg.sender), + nonce: _getNextNonce() + }); + + bytes memory txData = _serializeTransferTxArgs(txArgs); + CCM ccm = _getCcm(); + require( + ccm.crossChain(counterpartChainId, _targetProxyHash, "unlock", txData), + "EthCrossChainManager crossChain executed error!" + ); + + emit LockEvent(_fromAssetHash, msg.sender, counterpartChainId, _toAssetHash, _toAddress, txData); + } + + /// @dev validate the signature for lockFromWallet + function _validateLockFromWallet( + address _walletOwner, + address _assetHash, + bytes memory _targetProxyHash, + bytes memory _toAssetHash, + bytes memory _feeAddress, + uint256[] memory _values, + uint8 _v, + bytes32[] memory _rs + ) + private + { + bytes32 message = keccak256(abi.encodePacked( + "sendTokens", + _assetHash, + _targetProxyHash, + _toAssetHash, + _feeAddress, + _values[0], + _values[1], + _values[2] + )); + + require(seenMessages[message] == false, "Message already seen"); + seenMessages[message] = true; + _validateSignature(message, _walletOwner, _v, _rs[0], _rs[1]); + } + + /// @dev transfers funds from a Wallet contract into this contract + /// the difference between this contract's before and after balance must equal _amount + /// this is assumed to be sufficient in ensuring that the expected amount + /// of funds were transferred in + function _transferInFromWallet( + address payable _walletAddress, + address _assetHash, + uint256 _amount, + uint256 _callAmount + ) + private + { + Wallet wallet = Wallet(_walletAddress); + if (_assetHash == ETH_ASSET_HASH) { + uint256 before = address(this).balance; + + wallet.sendETHToCreator(_callAmount); + + uint256 transferred = address(this).balance.sub(before); + require(transferred == _amount, "ETH transferred does not match the expected amount"); + return; + } + + ERC20 token = ERC20(_assetHash); + { + uint256 before = token.balanceOf(address(this)); + + wallet.sendERC20ToCreator(_assetHash, _callAmount); + + uint256 transferred = token.balanceOf(address(this)).sub(before); + require(transferred == _amount, "Tokens transferred does not match the expected amount"); + } + } + + /// @dev transfers funds from an address into this contract + /// for ETH transfers, we only check that msg.value == _amount, and _callAmount is ignored + /// for token transfers, the difference between this contract's before and after balance must equal _amount + /// these checks are assumed to be sufficient in ensuring that the expected amount + /// of funds were transferred in + function _transferIn( + address _assetHash, + uint256 _amount, + uint256 _callAmount + ) + private + { + if (_assetHash == ETH_ASSET_HASH) { + require(msg.value == _amount, "ETH transferred does not match the expected amount"); + return; + } + + ERC20 token = ERC20(_assetHash); + uint256 before = token.balanceOf(address(this)); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transferFrom.selector, + msg.sender, + address(this), + _callAmount + ) + ); + uint256 transferred = token.balanceOf(address(this)).sub(before); + require(transferred == _amount, "Tokens transferred does not match the expected amount"); + } + + /// @dev transfers funds from this contract to the _toAddress + function _transferOut( + address _toAddress, + address _assetHash, + uint256 _amount + ) + private + { + if (_assetHash == ETH_ASSET_HASH) { + // we use `call` here since the _receivingAddress could be a contract + // see https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/ + // for more info + (bool success, ) = _toAddress.call{value: _amount}(""); + require(success, "Transfer failed"); + return; + } + + ERC20 token = ERC20(_assetHash); + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.transfer.selector, + _toAddress, + _amount + ) + ); + } + + /// @dev validates a signature against the specified user address + function _validateSignature( + bytes32 _message, + address _user, + uint8 _v, + bytes32 _r, + bytes32 _s + ) + private + pure + { + bytes32 prefixedMessage = keccak256(abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + _message + )); + + require( + _user == ecrecover(prefixedMessage, _v, _r, _s), + "Invalid signature" + ); + } + + function _serializeTransferTxArgs(TransferTxArgs memory args) private pure returns (bytes memory) { + bytes memory buff; + buff = abi.encodePacked( + ZeroCopySink.WriteVarBytes(args.fromAssetHash), + ZeroCopySink.WriteVarBytes(args.toAssetHash), + ZeroCopySink.WriteVarBytes(args.toAddress), + ZeroCopySink.WriteUint255(args.amount), + ZeroCopySink.WriteUint255(args.feeAmount), + ZeroCopySink.WriteVarBytes(args.feeAddress), + ZeroCopySink.WriteVarBytes(args.fromAddress), + ZeroCopySink.WriteUint255(args.nonce) + ); + return buff; + } + + function _deserializeTransferTxArgs(bytes memory valueBz) private pure returns (TransferTxArgs memory) { + TransferTxArgs memory args; + uint256 off = 0; + (args.fromAssetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.toAssetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.toAddress, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.amount, off) = ZeroCopySource.NextUint255(valueBz, off); + return args; + } + + function _deserializeRegisterAssetTxArgs(bytes memory valueBz) private pure returns (RegisterAssetTxArgs memory) { + RegisterAssetTxArgs memory args; + uint256 off = 0; + (args.assetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + (args.nativeAssetHash, off) = ZeroCopySource.NextVarBytes(valueBz, off); + return args; + } + + function _deserializeExtensionTxArgs(bytes memory valueBz) private pure returns (ExtensionTxArgs memory) { + ExtensionTxArgs memory args; + uint256 off = 0; + (args.extensionAddress, off) = ZeroCopySource.NextVarBytes(valueBz, off); + return args; + } + + function _getCcm() private view returns (CCM) { + CCM ccm = CCM(ccmProxy.getEthCrossChainManager()); + return ccm; + } + + function _getNextNonce() private returns (uint256) { + currentNonce = currentNonce.add(1); + return currentNonce; + } + + function _getSalt( + address _ownerAddress, + bytes memory _swthAddress + ) + private + pure + returns (bytes32) + { + return keccak256(abi.encodePacked( + SALT_PREFIX, + _ownerAddress, + _swthAddress + )); + } + + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(ERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. + + // A Solidity high level call has three parts: + // 1. The target address is checked to verify it contains contract code + // 2. The call itself is made, and success asserted + // 3. The return value is decoded, which in turn checks the size of the returned data. + // solhint-disable-next-line max-line-length + require(_isContract(address(token)), "SafeERC20: call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = address(token).call(data); + require(success, "SafeERC20: low-level call failed"); + + if (returndata.length > 0) { // Return data is optional + // solhint-disable-next-line max-line-length + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } + + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `_isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function _isContract(address account) private view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != accountHash && codehash != 0x0); + } +} diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/libs/LICENSE b/smart-contracts/test/zilbridge/tokens/switcheo/libs/LICENSE new file mode 100644 index 0000000..98dd89c --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/libs/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Smart Contract Solutions, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/libs/README.md b/smart-contracts/test/zilbridge/tokens/switcheo/libs/README.md new file mode 100644 index 0000000..8827bd1 --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/libs/README.md @@ -0,0 +1,3 @@ +# Lib Contracts + +The contracts in this folder were copied from the OpenZeppelin repository at https://github.com/OpenZeppelin/openzeppelin-contracts for ease of reference. diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/libs/math/SafeMath.sol b/smart-contracts/test/zilbridge/tokens/switcheo/libs/math/SafeMath.sol new file mode 100644 index 0000000..92592c1 --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/libs/math/SafeMath.sol @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @dev Wrappers over Solidity's arithmetic operations with added overflow + * checks. + * + * Arithmetic operations in Solidity wrap on overflow. This can easily result + * in bugs, because programmers usually assume that an overflow raises an + * error, which is the standard behavior in high level programming languages. + * `SafeMath` restores this intuition by reverting the transaction when an + * operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + */ +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on + * overflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot overflow. + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. Reverts with custom message on + * division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } +} diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20.sol b/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20.sol new file mode 100644 index 0000000..7b41cd0 --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20.sol @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./IERC20.sol"; +import "../../math/SafeMath.sol"; + +/** + * @dev Implementation of the `IERC20` interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using `_mint`. + * For a generic mechanism see `ERC20Mintable`. + * + * *For a detailed writeup see our guide [How to implement supply + * mechanisms](https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226).* + * + * We have followed general OpenZeppelin guidelines: functions revert instead + * of returning `false` on failure. This behavior is nonetheless conventional + * and does not conflict with the expectations of ERC20 applications. + * + * Additionally, an `Approval` event is emitted on calls to `transferFrom`. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + * + * Finally, the non-standard `decreaseAllowance` and `increaseAllowance` + * functions have been added to mitigate the well-known issues around setting + * allowances. See `IERC20.approve`. + */ +contract ERC20 is IERC20 { + using SafeMath for uint256; + + mapping (address => uint256) private _balances; + + mapping (address => mapping (address => uint256)) private _allowances; + + uint256 private _totalSupply; + + /** + * @dev See `IERC20.totalSupply`. + */ + function totalSupply() public view override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See `IERC20.balanceOf`. + */ + function balanceOf(address account) public view override returns (uint256) { + return _balances[account]; + } + + /** + * @dev See `IERC20.transfer`. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(msg.sender, recipient, amount); + return true; + } + + /** + * @dev See `IERC20.allowance`. + */ + function allowance(address owner, address spender) public virtual override view returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See `IERC20.approve`. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 value) public virtual override returns (bool) { + _approve(msg.sender, spender, value); + return true; + } + + /** + * @dev See `IERC20.transferFrom`. + * + * Emits an `Approval` event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of `ERC20`; + * + * Requirements: + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `value`. + * - the caller must have allowance for `sender`'s tokens of at least + * `amount`. + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(sender, recipient, amount); + _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount)); + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to `approve` that can be used as a mitigation for + * problems described in `IERC20.approve`. + * + * Emits an `Approval` event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to `approve` that can be used as a mitigation for + * problems described in `IERC20.approve`. + * + * Emits an `Approval` event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue)); + return true; + } + + /** + * @dev Moves tokens `amount` from `sender` to `recipient`. + * + * This is internal function is equivalent to `transfer`, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a `Transfer` event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + */ + function _transfer(address sender, address recipient, uint256 amount) internal virtual { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); + + _balances[sender] = _balances[sender].sub(amount); + _balances[recipient] = _balances[recipient].add(amount); + emit Transfer(sender, recipient, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a `Transfer` event with `from` set to the zero address. + * + * Requirements + * + * - `to` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _totalSupply = _totalSupply.add(amount); + _balances[account] = _balances[account].add(amount); + emit Transfer(address(0), account, amount); + } + + /** + * @dev Destoys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a `Transfer` event with `to` set to the zero address. + * + * Requirements + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 value) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _totalSupply = _totalSupply.sub(value); + _balances[account] = _balances[account].sub(value); + emit Transfer(account, address(0), value); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. + * + * This is internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an `Approval` event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 value) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = value; + emit Approval(owner, spender, value); + } + + /** + * @dev Destoys `amount` tokens from `account`.`amount` is then deducted + * from the caller's allowance. + * + * See `_burn` and `_approve`. + */ + function _burnFrom(address account, uint256 amount) internal { + _burn(account, amount); + _approve(account, msg.sender, _allowances[account][msg.sender].sub(amount)); + } +} diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20Detailed.sol b/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20Detailed.sol new file mode 100644 index 0000000..9a356fb --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/ERC20Detailed.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @dev Optional functions from the ERC20 standard. + */ +contract ERC20Detailed { + string private _name; + string private _symbol; + uint8 private _decimals; + + /** + * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of + * these values are immutable: they can only be set once during + * construction. + */ + constructor (string memory name_, string memory symbol_, uint8 decimals_) { + _name = name_; + _symbol = symbol_; + _decimals = decimals_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5,05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. + * + * > Note that this information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * `IERC20.balanceOf` and `IERC20.transfer`. + */ + function decimals() public view returns (uint8) { + return _decimals; + } +} diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/IERC20.sol b/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/IERC20.sol new file mode 100644 index 0000000..a9a1319 --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/libs/token/ERC20/IERC20.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/smart-contracts/test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol b/smart-contracts/test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol new file mode 100644 index 0000000..960f454 --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/switcheo/tokens/SwitcheoTokenETH.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "../libs/token/ERC20/ERC20.sol"; +import "../libs/token/ERC20/ERC20Detailed.sol"; +import "../libs/math/SafeMath.sol"; + +/** +* @title SwitcheoToken - Switcheo Token for Ethereum. +* +* @dev Standard ERC20 that mints from the PoS lock +* contract. Does not burn after transferring to the lock contract +* as the lock contract checks for balance after deposits. +* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md +*/ +contract SwitcheoToken is ERC20, ERC20Detailed { + using SafeMath for uint256; + + address public lockProxyAddress; + + /// Added by rrw to make testing easier. + constructor(address _lockProxyAddress, string memory tokenName, string memory tokenSymbol, uint8 decimals) + ERC20Detailed(tokenName, tokenSymbol, decimals) { + lockProxyAddress = _lockProxyAddress; + } + + //constructor(address _lockProxyAddress) ERC20Detailed("ZilBridge_Test_ETH_Bridged", "ZTEB", 8) { + //lockProxyAddress = _lockProxyAddress; + // } + + function _transfer(address sender, address recipient, uint256 amount) internal override { + if (sender == lockProxyAddress) { + require(recipient != lockProxyAddress, "SwitcheoToken: lockProxy should not call transfer to self"); + // lockProxy is the primary minter - so mint whenever required. + uint256 balance = balanceOf(lockProxyAddress); + if (balance < amount) { + _mint(lockProxyAddress, amount.sub(balance)); + } + } + + super._transfer(sender, recipient, amount); + } + + function circulatingSupply() external view returns (uint256 amount) { + return totalSupply().sub(balanceOf(lockProxyAddress)); + } +} diff --git a/smart-contracts/test/zilbridge/tokens/zrc2erc20/ScillaConnector.sol b/smart-contracts/test/zilbridge/tokens/zrc2erc20/ScillaConnector.sol new file mode 100644 index 0000000..63f86ca --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/zrc2erc20/ScillaConnector.sol @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +library ScillaConnector { + uint private constant CALL_SCILLA_WITH_THE_SAME_SENDER = 1; + uint private constant SCILLA_CALL_PRECOMPILE_ADDRESS = 0x5a494c53; + uint private constant SCILLA_STATE_READ_PRECOMPILE_ADDRESS = 0x5a494c92; + + /** + * @dev Calls a ZRC2 contract function with two arguments + * @param target The address of the ZRC2 contract + * @param tran_name The name of the function to call + * @param arg1 The first argument to the function + * @param arg2 The second argument to the function + */ + function call( + address target, + string memory tran_name, + address arg1, + uint128 arg2 + ) internal { + bytes memory encodedArgs = abi.encode( + target, + tran_name, + CALL_SCILLA_WITH_THE_SAME_SENDER, + arg1, + arg2 + ); + uint256 argsLength = encodedArgs.length; + + assembly { + let alwaysSuccessForThisPrecompile := call( + 21000, + SCILLA_CALL_PRECOMPILE_ADDRESS, + 0, + add(encodedArgs, 0x20), + argsLength, + 0x20, + 0 + ) + } + } + + /** + * @dev Calls a ZRC2 contract function with three arguments + * @param target The address of the ZRC2 contract + * @param tran_name The name of the function to call on the ZRC2 contract + * @param arg1 The first argument to the function + * @param arg2 The second argument to the function + * @param arg3 The third argument to the function + */ + function call( + address target, + string memory tran_name, + address arg1, + address arg2, + uint128 arg3 + ) internal { + bytes memory encodedArgs = abi.encode( + target, + tran_name, + CALL_SCILLA_WITH_THE_SAME_SENDER, + arg1, + arg2, + arg3 + ); + uint256 argsLength = encodedArgs.length; + + assembly { + let alwaysSuccessForThisPrecompile := call( + 21000, + SCILLA_CALL_PRECOMPILE_ADDRESS, + 0, + add(encodedArgs, 0x20), + argsLength, + 0x20, + 0 + ) + } + } + + /** + * @dev Reads a 128 bit integer from a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the variable to read from the ZRC2 contract + * @return The value of the variable + */ + function readUint128( + address target, + string memory variable_name + ) internal view returns (uint128) { + bytes memory encodedArgs = abi.encode(target, variable_name); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint128)); + } + + /** + * @dev Reads a 32 bit integer from a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the variable to read from the ZRC2 contract + * @return The value of the variable + */ + function readUint32( + address target, + string memory variable_name + ) internal view returns (uint32) { + bytes memory encodedArgs = abi.encode(target, variable_name); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint32)); + } + + /** + * @dev Reads a string from a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the variable to read from the ZRC2 contract + * @return retVal The value of the variable + */ + function readString( + address target, + string memory variable_name + ) internal view returns (string memory retVal) { + bytes memory encodedArgs = abi.encode(target, variable_name); + uint256 argsLength = encodedArgs.length; + bool success; + bytes memory output = new bytes(128); + uint256 output_len = output.length - 4; + assembly { + success := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + output_len + ) + } + require(success); + + (retVal) = abi.decode(output, (string)); + return retVal; + } + + /** + * @dev Reads a 128 bit integer from a map in a ZRC2 contract + * @param variable_name The name of the map in the ZRC2 contract + * @param addressMapKey The key to the map + * @return The value associated with the key in the map + */ + function readMapUint128( + address target, + string memory variable_name, + address addressMapKey + ) internal view returns (uint128) { + bytes memory encodedArgs = abi.encode( + target, + variable_name, + addressMapKey + ); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint128)); + } + + /** + * @dev Reads a 128 bit integer from a nested map in a ZRC2 contract + * @param target The address of the ZRC2 contract + * @param variable_name The name of the map in the ZRC2 contract + * @param firstMapKey The first key to the map + * @param secondMapKey The second key to the map + * @return The value associated with the keys in the map + */ + function readNestedMapUint128( + address target, + string memory variable_name, + address firstMapKey, + address secondMapKey + ) internal view returns (uint128) { + bytes memory encodedArgs = abi.encode( + target, + variable_name, + firstMapKey, + secondMapKey + ); + uint256 argsLength = encodedArgs.length; + bytes memory output = new bytes(36); + + assembly { + let alwaysSuccessForThisPrecompile := staticcall( + 21000, + SCILLA_STATE_READ_PRECOMPILE_ADDRESS, + add(encodedArgs, 0x20), + argsLength, + add(output, 0x20), + 32 + ) + } + + return abi.decode(output, (uint128)); + } +} diff --git a/smart-contracts/test/zilbridge/tokens/zrc2erc20/ZRC2ProxyForZRC2.sol b/smart-contracts/test/zilbridge/tokens/zrc2erc20/ZRC2ProxyForZRC2.sol new file mode 100644 index 0000000..4332aeb --- /dev/null +++ b/smart-contracts/test/zilbridge/tokens/zrc2erc20/ZRC2ProxyForZRC2.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {ScillaConnector} from "./ScillaConnector.sol"; + +contract ZRC2ProxyForZRC2 is IERC20 { + using ScillaConnector for address; + using SafeCast for uint256; + + address public zrc2_proxy; + + // Additional variables useful for wallets + uint8 public decimals; + string public symbol; + string public name; + + /** + * @notice Constructs a new ZRC2Proxy contract + * @param zrc2_address The address of the underlying ZRC2 contract + */ + constructor(address zrc2_address) { + zrc2_proxy = zrc2_address; + + symbol = zrc2_proxy.readString("symbol"); + decimals = uint256(zrc2_proxy.readUint32("decimals")).toUint8(); + name = zrc2_proxy.readString("name"); + } + + /** + * @notice Get the total supply of tokens + * @return The total supply of tokens + */ + function totalSupply() external view returns (uint256) { + return zrc2_proxy.readUint128("total_supply"); + } + + /** + * @notice Get the token balance for a specific account + * @param tokenOwner The address of the account + * @return The balance of the account + */ + function balanceOf(address tokenOwner) external view returns (uint256) { + return zrc2_proxy.readMapUint128("balances", tokenOwner); + } + + /** + * @notice Transfer tokens to a specified address + * @param to The address to transfer to + * @param tokens The amount of tokens to transfer + * @return true if transfer was successful + */ + function transfer(address to, uint256 tokens) external returns (bool) { + zrc2_proxy.call("Transfer", to, tokens.toUint128()); + return true; + } + + /** + * @notice Transfer tokens from one address to another + * @param from The address to transfer from + * @param to The address to transfer to + * @param tokens The amount of tokens to transfer + * @return true if transfer was successful + */ + function transferFrom( + address from, + address to, + uint256 tokens + ) external returns (bool) { + zrc2_proxy.call("TransferFrom", from, to, tokens.toUint128()); + return true; + } + + /** + * @notice Check the amount of tokens that an owner has allowed a spender to use + * @param tokenOwner The address of the token owner + * @param spender The address of the spender + * @return The amount of tokens remaining for the spender + */ + function allowance( + address tokenOwner, + address spender + ) external view returns (uint256) { + return + zrc2_proxy.readNestedMapUint128("allowances", tokenOwner, spender); + } + + /** + * @notice Approve a spender to spend a certain amount of tokens + * @param spender The address of the spender + * @param new_allowance The new allowance for the spender + * @return true if approval was successful + */ + function approve( + address spender, + uint256 new_allowance + ) external returns (bool) { + uint256 current_allowance = this.allowance(msg.sender, spender); + + if (current_allowance >= new_allowance) { + zrc2_proxy.call( + "DecreaseAllowance", + spender, + (current_allowance - new_allowance).toUint128() + ); + } else { + zrc2_proxy.call( + "IncreaseAllowance", + spender, + (new_allowance - current_allowance).toUint128() + ); + } + return true; + } +} From d9dae63c0181490724986ea4f652cf87fa618571 Mon Sep 17 00:00:00 2001 From: Richard Watts Date: Fri, 30 Aug 2024 18:31:00 +0100 Subject: [PATCH 3/4] (feat) Update trunk in an attempt to get it to obey the configuration file. --- .trunk/trunk.yaml | 51 ++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index d510944..b63321c 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,36 +1,39 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml version: 0.1 cli: - version: 1.22.3 + version: 1.22.4 +# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) plugins: sources: - id: trunk ref: v1.6.2 uri: https://github.com/trunk-io/plugins - +# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) +runtimes: + enabled: + - node@18.12.1 + - python@3.10.8 +# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) lint: enabled: - - clippy@1.79.0 - - gofmt@1.20.4 - - golangci-lint@1.60.2 - - oxipng@9.1.2 - - shellcheck@0.10.0 - - taplo@0.9.3 - actionlint@1.7.1 - - hadolint@2.12.0 - - eslint@9.9.0 - - buildifier@7.1.2 + - checkov@3.2.239 + - clippy@1.79.0 - git-diff-check + - hadolint@2.12.0 - markdownlint@0.41.0 + - osv-scanner@1.8.4 + - oxipng@9.1.2 - prettier@3.3.3 - - shfmt@3.6.0 - - svgo@3.3.2 - - gitleaks@8.18.4 - - flake8@7.1.1 - - isort@5.13.2 - - black@24.8.0 - - rustfmt@1.79.0 - # - shellcheck@0.9.0 - removed for being over-prissy and wanting tab indents - rrw 2023-04-25 + - rustfmt@1.65.0 + - taplo@0.9.3 + - trufflehog@3.81.10 + - yamllint@1.35.1 ignore: + - linters: [osv-scanner] + paths: + - scilla-contracts/** - linters: [gitleaks] paths: - smart-contracts/script/config.ts @@ -39,6 +42,7 @@ lint: - linters: [eslint] paths: - bridge-web + - scilla-contracts - linters: [ALL] paths: - .devcontainer/* @@ -57,15 +61,12 @@ lint: - "**/templates/*" - "templates/**" - "**/templates/**" + - smart-contracts/test/zilbridge/tokens/switcheo/** -runtimes: - enabled: - - go@1.21.0 - - node@18.12.1 - - python@3.10.8 actions: - enabled: + disabled: - trunk-announce - trunk-check-pre-push - trunk-fmt-pre-commit + enabled: - trunk-upgrade-available From 4485678acb576db04984c813e21bcd58dc765686 Mon Sep 17 00:00:00 2001 From: Richard Watts Date: Fri, 30 Aug 2024 18:39:34 +0100 Subject: [PATCH 4/4] (fix) Trunk now complains about its own auto-generated default config file. --- .trunk/trunk.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index b63321c..4cf4be8 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,20 +1,24 @@ # This file controls the behavior of Trunk: https://docs.trunk.io/cli -# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml +# To learn more about the format of this file, +# see https://docs.trunk.io/reference/trunk-yaml version: 0.1 cli: version: 1.22.4 -# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) +# Trunk provides extensibility via plugins. +# (https://docs.trunk.io/plugins) plugins: sources: - id: trunk ref: v1.6.2 uri: https://github.com/trunk-io/plugins -# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) +# Many linters and tools depend on runtimes - +# configure them here. (https://docs.trunk.io/runtimes) runtimes: enabled: - node@18.12.1 - python@3.10.8 -# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) +# This is the section where you manage your linters. +# (https://docs.trunk.io/check/configuration) lint: enabled: - actionlint@1.7.1