diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 6babba45a..8f464c954 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -25,6 +25,10 @@ jobs:
run: cargo make build-contracts
- name: Test contracts
run: cargo make test-contracts
+ - name: Build Aurora Eth Connector contract
+ run: cargo make build-aurora-eth-connector
+ - name: List Aurora Eth Connector contract
+ run: ls -la engine-tests-connector/etc/aurora-eth-connector/bin/aurora-eth-connector-test.wasm
- name: Build mainnet test WASM
run: cargo make --profile mainnet build-test
- name: List mainnet WASM directory and root directory
diff --git a/Cargo.lock b/Cargo.lock
index 9a04f3a1e..7ff1b477d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -288,7 +288,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -299,13 +299,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae"
[[package]]
name = "async-trait"
-version = "0.1.71"
+version = "0.1.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
+checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -327,7 +327,7 @@ dependencies = [
[[package]]
name = "aurora-engine"
-version = "2.10.0"
+version = "2.10.1"
dependencies = [
"aurora-engine-modexp",
"aurora-engine-precompiles",
@@ -388,6 +388,18 @@ dependencies = [
"sha3",
]
+[[package]]
+name = "aurora-engine-standalone-nep141-legacy"
+version = "0.1.0"
+dependencies = [
+ "aurora-engine",
+ "aurora-engine-modexp",
+ "aurora-engine-sdk",
+ "aurora-engine-types",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "aurora-engine-test-doubles"
version = "1.0.0"
@@ -408,6 +420,7 @@ dependencies = [
"aurora-engine-modexp",
"aurora-engine-precompiles",
"aurora-engine-sdk",
+ "aurora-engine-standalone-nep141-legacy",
"aurora-engine-test-doubles",
"aurora-engine-transactions",
"aurora-engine-types",
@@ -428,6 +441,7 @@ dependencies = [
"near-crypto 0.17.0",
"near-primitives 0.17.0",
"near-primitives-core 0.17.0",
+ "near-sdk",
"near-vm-errors 0.17.0",
"near-vm-logic 0.17.0",
"near-vm-runner",
@@ -441,6 +455,24 @@ dependencies = [
"walrus",
]
+[[package]]
+name = "aurora-engine-tests-connector"
+version = "1.0.0"
+dependencies = [
+ "anyhow",
+ "aurora-engine",
+ "aurora-engine-types",
+ "byte-slice-cast",
+ "ethabi",
+ "hex 0.4.3",
+ "near-sdk",
+ "near-units",
+ "rlp",
+ "serde",
+ "tokio",
+ "workspaces",
+]
+
[[package]]
name = "aurora-engine-transactions"
version = "1.0.0"
@@ -669,7 +701,7 @@ dependencies = [
"async-lock",
"async-task",
"atomic-waker",
- "fastrand",
+ "fastrand 1.9.0",
"futures-lite",
"log",
]
@@ -787,7 +819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
dependencies = [
"memchr",
- "regex-automata 0.3.3",
+ "regex-automata 0.3.4",
"serde",
]
@@ -978,9 +1010,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.3.12"
+version = "4.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73"
+checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
dependencies = [
"clap_builder",
"clap_derive",
@@ -989,9 +1021,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.3.12"
+version = "4.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd"
+checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
dependencies = [
"anstream",
"anstyle",
@@ -1008,7 +1040,7 @@ dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -1322,9 +1354,9 @@ dependencies = [
[[package]]
name = "curl-sys"
-version = "0.4.63+curl-8.1.2"
+version = "0.4.65+curl-8.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc"
+checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986"
dependencies = [
"cc",
"libc",
@@ -1369,7 +1401,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -1380,7 +1412,16 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
+]
+
+[[package]]
+name = "deranged"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8810e7e2cf385b1e9b50d68264908ec367ba642c96d02edfe61c39e88e2a3c01"
+dependencies = [
+ "serde",
]
[[package]]
@@ -1391,7 +1432,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -1527,9 +1568,9 @@ dependencies = [
[[package]]
name = "either"
-version = "1.8.1"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "encoding_rs"
@@ -1548,6 +1589,7 @@ dependencies = [
"aurora-engine-modexp",
"aurora-engine-precompiles",
"aurora-engine-sdk",
+ "aurora-engine-standalone-nep141-legacy",
"aurora-engine-transactions",
"aurora-engine-types",
"evm-core",
@@ -1588,7 +1630,7 @@ checksum = "8560b409800a72d2d7860f8e5f4e0b0bd22bea6a352ea2a9ce30ccdef7f16d2f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -1609,7 +1651,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -1626,9 +1668,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
dependencies = [
"errno-dragonfly",
"libc",
@@ -1687,7 +1729,7 @@ dependencies = [
"ethereum-types",
"hash-db",
"hash256-std-hasher",
- "parity-scale-codec 3.6.3",
+ "parity-scale-codec 3.6.4",
"rlp",
"scale-info",
"serde",
@@ -1729,7 +1771,7 @@ dependencies = [
"evm-gasometer",
"evm-runtime",
"log",
- "parity-scale-codec 3.6.3",
+ "parity-scale-codec 3.6.4",
"primitive-types 0.12.1",
"rlp",
"scale-info",
@@ -1742,7 +1784,7 @@ name = "evm-core"
version = "0.39.0"
source = "git+https://github.com/aurora-is-near/sputnikvm.git?tag=v0.38.0-aurora#c5cdf0c9bf8da9f6baeb1e5b4a52a2a3405e123f"
dependencies = [
- "parity-scale-codec 3.6.3",
+ "parity-scale-codec 3.6.4",
"primitive-types 0.12.1",
"scale-info",
"serde",
@@ -1808,6 +1850,12 @@ dependencies = [
"instant",
]
+[[package]]
+name = "fastrand"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
+
[[package]]
name = "filetime"
version = "0.2.21"
@@ -1981,7 +2029,7 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [
- "fastrand",
+ "fastrand 1.9.0",
"futures-core",
"futures-io",
"memchr",
@@ -1998,7 +2046,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -2421,7 +2469,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f"
dependencies = [
- "parity-scale-codec 3.6.3",
+ "parity-scale-codec 3.6.4",
]
[[package]]
@@ -2698,9 +2746,9 @@ dependencies = [
[[package]]
name = "libz-sys"
-version = "1.1.9"
+version = "1.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
+checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
dependencies = [
"cc",
"libc",
@@ -3230,7 +3278,7 @@ dependencies = [
"smart-default",
"strum",
"thiserror",
- "time 0.3.23",
+ "time 0.3.24",
"tracing",
]
@@ -3321,7 +3369,7 @@ checksum = "84c1eda300e2e78f4f945ae58117d49e806899f4a51ee2faa09eda5ebc2e6571"
dependencies = [
"quote",
"serde",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -3355,7 +3403,7 @@ dependencies = [
"fs2",
"near-rpc-error-core 0.17.0",
"serde",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -3698,9 +3746,9 @@ dependencies = [
[[package]]
name = "num-traits"
-version = "0.2.15"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
dependencies = [
"autocfg",
]
@@ -3777,7 +3825,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -3868,15 +3916,15 @@ dependencies = [
[[package]]
name = "parity-scale-codec"
-version = "3.6.3"
+version = "3.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5"
+checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64"
dependencies = [
"arrayvec 0.7.4",
"bitvec 1.0.1",
"byte-slice-cast",
"impl-trait-for-tuples",
- "parity-scale-codec-derive 3.6.3",
+ "parity-scale-codec-derive 3.6.4",
"serde",
]
@@ -3894,9 +3942,9 @@ dependencies = [
[[package]]
name = "parity-scale-codec-derive"
-version = "3.6.3"
+version = "3.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476"
+checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e"
dependencies = [
"proc-macro-crate 1.3.1",
"proc-macro2",
@@ -4020,7 +4068,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -4342,9 +4390,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.31"
+version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0"
+checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [
"proc-macro2",
]
@@ -4529,7 +4577,7 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
dependencies = [
"aho-corasick",
"memchr",
- "regex-automata 0.3.3",
+ "regex-automata 0.3.4",
"regex-syntax 0.7.4",
]
@@ -4544,9 +4592,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.3.3"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
+checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294"
dependencies = [
"aho-corasick",
"memchr",
@@ -4802,7 +4850,7 @@ dependencies = [
"bitvec 1.0.1",
"cfg-if 1.0.0",
"derive_more",
- "parity-scale-codec 3.6.3",
+ "parity-scale-codec 3.6.4",
"scale-info-derive",
]
@@ -4853,9 +4901,9 @@ dependencies = [
[[package]]
name = "scopeguard"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "seahash"
@@ -4903,9 +4951,9 @@ dependencies = [
[[package]]
name = "security-framework"
-version = "2.9.1"
+version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8"
+checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
@@ -4916,9 +4964,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.9.0"
+version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7"
+checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
dependencies = [
"core-foundation-sys",
"libc",
@@ -4932,22 +4980,22 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
-version = "1.0.171"
+version = "1.0.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
+checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.171"
+version = "1.0.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
+checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -4963,9 +5011,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.103"
+version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b"
+checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
dependencies = [
"itoa",
"ryu",
@@ -4974,13 +5022,13 @@ dependencies = [
[[package]]
name = "serde_repr"
-version = "0.1.14"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731"
+checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -4997,9 +5045,9 @@ dependencies = [
[[package]]
name = "serde_with"
-version = "3.0.0"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513"
+checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3"
dependencies = [
"base64 0.21.2",
"chrono",
@@ -5008,26 +5056,26 @@ dependencies = [
"serde",
"serde_json",
"serde_with_macros",
- "time 0.3.23",
+ "time 0.3.24",
]
[[package]]
name = "serde_with_macros"
-version = "3.0.0"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070"
+checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65"
dependencies = [
"darling",
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
name = "serde_yaml"
-version = "0.9.23"
+version = "0.9.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da6075b41c7e3b079e5f246eb6094a44850d3a4c25a67c581c80796c80134012"
+checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
dependencies = [
"indexmap 2.0.0",
"itoa",
@@ -5087,9 +5135,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "signal-hook"
-version = "0.3.16"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b824b6e687aff278cdbf3b36f07aa52d4bd4099699324d5da86a2ebce3aa00b3"
+checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
dependencies = [
"libc",
"signal-hook-registry",
@@ -5255,9 +5303,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.26"
+version = "2.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970"
+checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
dependencies = [
"proc-macro2",
"quote",
@@ -5295,21 +5343,20 @@ dependencies = [
[[package]]
name = "target-lexicon"
-version = "0.12.9"
+version = "0.12.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df8e77cb757a61f51b947ec4a7e3646efd825b73561db1c232a8ccb639e611a0"
+checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e"
[[package]]
name = "tempfile"
-version = "3.6.0"
+version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
+checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
dependencies = [
- "autocfg",
"cfg-if 1.0.0",
- "fastrand",
+ "fastrand 2.0.0",
"redox_syscall 0.3.5",
- "rustix 0.37.23",
+ "rustix 0.38.4",
"windows-sys 0.48.0",
]
@@ -5350,22 +5397,22 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.43"
+version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
+checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.43"
+version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
+checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -5391,10 +5438,11 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.23"
+version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446"
+checksum = "b79eabcd964882a646b3584543ccabeae7869e9ac32a46f6f22b7a5bd405308b"
dependencies = [
+ "deranged",
"itoa",
"serde",
"time-core",
@@ -5409,9 +5457,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "time-macros"
-version = "0.2.10"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4"
+checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd"
dependencies = [
"time-core",
]
@@ -5487,7 +5535,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -5695,7 +5743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
dependencies = [
"crossbeam-channel",
- "time 0.3.23",
+ "time 0.3.24",
"tracing-subscriber",
]
@@ -5707,7 +5755,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
@@ -5983,7 +6031,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
"wasm-bindgen-shared",
]
@@ -6017,7 +6065,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -6568,9 +6616,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "winnow"
-version = "0.5.0"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
+checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7"
dependencies = [
"memchr",
]
@@ -6658,7 +6706,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.26",
+ "syn 2.0.28",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index fea7dc915..b31bb6c4e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ aurora-engine-sdk = { path = "engine-sdk", default-features = false }
aurora-engine-transactions = { path = "engine-transactions", default-features = false }
aurora-engine-types = { path = "engine-types", default-features = false }
aurora-engine-modexp = { path = "engine-modexp", default-features = false }
+aurora-engine-standalone-nep141-legacy = { path = "engine-standalone-nep141-legacy", default-features = false }
aurora-engine-test-doubles = { path = "engine-test-doubles" }
aurora-engine-workspace = { path = "engine-workspace" }
engine-standalone-storage = { path = "engine-standalone-storage" }
@@ -74,9 +75,11 @@ members = [
"engine-modexp",
"engine-precompiles",
"engine-sdk",
+ "engine-standalone-nep141-legacy",
"engine-standalone-storage",
"engine-standalone-tracing",
"engine-tests",
+ "engine-tests-connector",
"engine-transactions",
"engine-types",
"engine-workspace",
diff --git a/Makefile.toml b/Makefile.toml
index b6b17c875..8a36af309 100644
--- a/Makefile.toml
+++ b/Makefile.toml
@@ -347,9 +347,31 @@ args = [
"--ignored",
]
+[tasks.build-aurora-eth-connector]
+category = "Build"
+script = '''
+AURORA_ETH_CONNECTOR_DIR="engine-tests-connector/etc/aurora-eth-connector/"
+AURORA_ETH_CONNECTOR_ETC="engine-tests-connector/etc/"
+AURORA_ETH_CONNECTOR_REPO_NAME="aurora-eth-connector"
+AURORA_ETH_CONNECTOR_REPO="https://github.com/aurora-is-near/"$AURORA_ETH_CONNECTOR_REPO_NAME
+if [ -d $AURORA_ETH_CONNECTOR_DIR ]; then
+ cd $AURORA_ETH_CONNECTOR_DIR
+ echo "Pull Aurora Eth-Connector repo"
+ git pull origin master
+else
+ mkdir $AURORA_ETH_CONNECTOR_ETC || true
+ cd $AURORA_ETH_CONNECTOR_ETC
+ echo "Clone Aurora Eth-Connector repo: "$AURORA_ETH_CONNECTOR_REPO
+ git clone --depth 1 $AURORA_ETH_CONNECTOR_REPO
+ cd $AURORA_ETH_CONNECTOR_REPO_NAME
+fi
+cargo make --profile mainnet build-test
+'''
+
[tasks.test-flow]
category = "Test"
dependencies = [
+ "build-aurora-eth-connector",
"build-test",
"test-contracts",
"test-workspace",
diff --git a/doc/eth-connector.md b/doc/eth-connector.md
index c519c647f..8e0897a69 100644
--- a/doc/eth-connector.md
+++ b/doc/eth-connector.md
@@ -29,7 +29,6 @@ For more details see: [NEP-141](https://nomicon.io/Standards/Tokens/FungibleToke
* ft_total_supply (view)
* ft_total_eth_supply_on_near (view)
-* ft_total_eth_supply_on_aurora (view)
* ft_balance_of (view)
* ft_balance_of_eth (view)
* ft_transfer (mutable, payable)
diff --git a/engine-precompiles/src/lib.rs b/engine-precompiles/src/lib.rs
index 49f475a8a..2045b9e81 100644
--- a/engine-precompiles/src/lib.rs
+++ b/engine-precompiles/src/lib.rs
@@ -358,7 +358,10 @@ impl<'a, I: IO + Copy, E: Env, H: ReadOnlyPromiseHandler> Precompiles<'a, I, E,
mut generic_precompiles: BTreeMap
>,
ctx: PrecompileConstructorContext<'a, I, E, H, M>,
) -> Self {
+ #[cfg(feature = "error_refund")]
let near_exit = ExitToNear::new(ctx.current_account_id.clone(), ctx.io);
+ #[cfg(not(feature = "error_refund"))]
+ let near_exit = ExitToNear::new(ctx.io);
let ethereum_exit = ExitToEthereum::new(ctx.current_account_id.clone(), ctx.io);
let cross_contract_call = CrossContractCall::new(ctx.current_account_id, ctx.io);
let predecessor_account_id = PredecessorAccount::new(ctx.env);
diff --git a/engine-precompiles/src/native.rs b/engine-precompiles/src/native.rs
index 272a76cc3..f1fa694ea 100644
--- a/engine-precompiles/src/native.rs
+++ b/engine-precompiles/src/native.rs
@@ -1,4 +1,5 @@
use super::{EvmPrecompileResult, Precompile};
+use crate::prelude::types::EthGas;
use crate::prelude::{
format,
parameters::{PromiseArgs, PromiseCreateArgs, WithdrawCallArgs},
@@ -12,9 +13,8 @@ use crate::prelude::{
parameters::{PromiseWithCallbackArgs, RefundCallArgs},
types,
};
-
-use crate::prelude::types::EthGas;
use crate::PrecompileOutput;
+use aurora_engine_types::storage::EthConnectorStorageId;
use aurora_engine_types::{account_id::AccountId, types::NEP141Wei};
use evm::backend::Log;
use evm::{Context, ExitError};
@@ -196,6 +196,7 @@ pub mod events {
//TransferEthToNear
pub struct ExitToNear {
+ #[cfg(feature = "error_refund")]
current_account_id: AccountId,
io: I,
}
@@ -211,6 +212,12 @@ pub mod exit_to_near {
}
impl ExitToNear {
+ #[cfg(not(feature = "error_refund"))]
+ pub const fn new(io: I) -> Self {
+ Self { io }
+ }
+
+ #[cfg(feature = "error_refund")]
pub const fn new(current_account_id: AccountId, io: I) -> Self {
Self {
current_account_id,
@@ -235,6 +242,21 @@ fn get_nep141_from_erc20(erc20_token: &[u8], io: &I) -> Result(io: &I) -> Result {
+ io.read_storage(&construct_contract_key(
+ EthConnectorStorageId::EthConnectorAccount,
+ ))
+ .ok_or(ExitError::Other(Cow::Borrowed("ERR_KEY_NOT_FOUND")))
+ .and_then(|x| {
+ x.to_value()
+ .map_err(|_| ExitError::Other(Cow::Borrowed("ERR_DESERIALIZE")))
+ })
+}
+
+fn construct_contract_key(suffix: EthConnectorStorageId) -> Vec {
+ bytes_to_key(KeyPrefix::EthConnector, &[u8::from(suffix)])
+}
+
fn validate_amount(amount: U256) -> Result<(), ExitError> {
if amount > U256::from(u128::MAX) {
return Err(ExitError::Other(Cow::from("ERR_INVALID_AMOUNT")));
@@ -299,9 +321,8 @@ impl Precompile for ExitToNear {
let (refund_address, mut input) = parse_input(input)?;
#[cfg(not(feature = "error_refund"))]
let mut input = parse_input(input)?;
- let current_account_id = self.current_account_id.clone();
#[cfg(feature = "error_refund")]
- let refund_on_error_target = current_account_id.clone();
+ let refund_on_error_target = self.current_account_id.clone();
let (nep141_address, args, exit_event) = match flag {
0x0 => {
@@ -310,13 +331,15 @@ impl Precompile for ExitToNear {
// Input slice format:
// recipient_account_id (bytes) - the NEAR recipient account which will receive NEP-141 ETH tokens
+ let eth_connector_contract_account = get_eth_connector_contract_account(&self.io)?;
+
if let Ok(dest_account) = AccountId::try_from(input) {
(
- current_account_id,
+ eth_connector_contract_account,
// There is no way to inject json, given the encoding of both arguments
// as decimal and valid account id respectively.
format!(
- r#"{{"receiver_id": "{}", "amount": "{}", "memo": null}}"#,
+ r#"{{"receiver_id": "{}", "amount": "{}", "memo": null}}"#,
dest_account,
context.apparent_value.as_u128()
),
@@ -379,7 +402,9 @@ impl Precompile for ExitToNear {
)));
}
}
- _ => return Err(ExitError::Other(Cow::from("ERR_INVALID_FLAG"))),
+ _ => {
+ return Err(ExitError::Other(Cow::from("ERR_INVALID_FLAG")));
+ }
};
#[cfg(feature = "error_refund")]
diff --git a/engine-standalone-nep141-legacy/Cargo.toml b/engine-standalone-nep141-legacy/Cargo.toml
new file mode 100644
index 000000000..1e83b2001
--- /dev/null
+++ b/engine-standalone-nep141-legacy/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+name = "aurora-engine-standalone-nep141-legacy"
+version = "0.1.0"
+authors.workspace = true
+edition.workspace = true
+description = "Aurora engine standalone NEP-141 legacy library. Provides the legacy NEP-141 code used by the standalone engine."
+homepage.workspace = true
+repository.workspace = true
+license.workspace = true
+publish.workspace = true
+autobenches = false
+
+[lib]
+crate-type = ["lib"]
+
+[dependencies]
+aurora-engine = { workspace = true, features = ["std"] }
+aurora-engine-modexp = { workspace = true, features = ["std"] }
+aurora-engine-types = { workspace = true, features = ["std"] }
+aurora-engine-sdk = { workspace = true, features = ["std"] }
+serde.workspace = true
+serde_json.workspace = true
+
+[features]
diff --git a/engine-standalone-nep141-legacy/src/admin_controlled.rs b/engine-standalone-nep141-legacy/src/admin_controlled.rs
new file mode 100644
index 000000000..1197bd778
--- /dev/null
+++ b/engine-standalone-nep141-legacy/src/admin_controlled.rs
@@ -0,0 +1,137 @@
+use aurora_engine_types::borsh::{self, BorshDeserialize, BorshSerialize};
+
+pub type PausedMask = u8;
+
+pub const ERR_PAUSED: &str = "ERR_PAUSED";
+
+#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
+pub struct PauseEthConnectorCallArgs {
+ pub paused_mask: PausedMask,
+}
+
+pub trait AdminControlled {
+ /// Return the current mask representing all paused events.
+ fn get_paused(&self) -> PausedMask;
+
+ /// Update mask with all paused events.
+ /// Implementor is responsible for guaranteeing that this function can only be
+ /// called by owner of the contract.
+ fn set_paused(&mut self, paused: PausedMask);
+
+ /// Return if the contract is paused for the current flag and user
+ fn is_paused(&self, flag: PausedMask, is_owner: bool) -> bool {
+ (self.get_paused() & flag) != 0 && !is_owner
+ }
+
+ /// Asserts the passed paused flag is not set. Returns `PausedError` if paused.
+ fn assert_not_paused(&self, flag: PausedMask, is_owner: bool) -> Result<(), PausedError> {
+ if self.is_paused(flag, is_owner) {
+ Err(PausedError)
+ } else {
+ Ok(())
+ }
+ }
+}
+
+pub struct PausedError;
+
+impl AsRef<[u8]> for PausedError {
+ fn as_ref(&self) -> &[u8] {
+ ERR_PAUSED.as_bytes()
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ struct MockAdminControlled {
+ mask: PausedMask,
+ }
+
+ impl MockAdminControlled {
+ pub fn new() -> Self {
+ Self { mask: 0 }
+ }
+ }
+
+ impl AdminControlled for MockAdminControlled {
+ fn get_paused(&self) -> PausedMask {
+ self.mask
+ }
+
+ fn set_paused(&mut self, paused: PausedMask) {
+ self.mask = paused
+ }
+ }
+
+ #[test]
+ fn test_setting_paused_mask_with_1_bit_marks_it_as_paused() {
+ let is_owner = false;
+ let mask = 1u8;
+ let mut admin_controlled = MockAdminControlled::new();
+
+ assert!(!admin_controlled.is_paused(mask, is_owner));
+ admin_controlled.set_paused(mask);
+ assert!(admin_controlled.is_paused(mask, is_owner));
+ }
+
+ #[test]
+ fn test_setting_paused_mask_with_0_bit_marks_it_as_not_paused() {
+ let is_owner = false;
+ let mask = 1u8;
+ let mut admin_controlled = MockAdminControlled::new();
+ admin_controlled.set_paused(mask);
+
+ assert!(admin_controlled.is_paused(mask, is_owner));
+ admin_controlled.set_paused(0u8);
+ assert!(!admin_controlled.is_paused(mask, is_owner));
+ }
+
+ #[test]
+ fn test_setting_paused_mask_with_1_bit_fails_to_assert_not_paused() {
+ let is_owner = false;
+ let mask = 1u8;
+ let admin_controlled = MockAdminControlled::new();
+
+ let result = admin_controlled.assert_not_paused(mask, is_owner);
+ assert!(result.is_ok(), "asserting as paused failed");
+ }
+
+ #[test]
+ fn test_setting_paused_mask_with_0_bit_asserts_not_paused() {
+ let is_owner = false;
+ let mask = 1u8;
+ let mut admin_controlled = MockAdminControlled::new();
+
+ admin_controlled.set_paused(mask);
+ let error = admin_controlled
+ .assert_not_paused(mask, is_owner)
+ .expect_err("asserting as not paused failed");
+
+ let expected_error_message = b"ERR_PAUSED";
+ let actual_error_message = error.as_ref();
+ assert_eq!(expected_error_message, actual_error_message);
+ }
+
+ #[test]
+ fn test_paused_mask_has_no_effect_on_owner() {
+ let is_owner = true;
+ let mask = 1u8;
+ let mut admin_controlled = MockAdminControlled::new();
+
+ admin_controlled.set_paused(mask);
+ assert!(!admin_controlled.is_paused(mask, is_owner));
+ }
+
+ #[test]
+ fn test_asserting_paused_mask_has_no_effect_on_owner() {
+ let is_owner = true;
+ let mask = 1u8;
+ let mut admin_controlled = MockAdminControlled::new();
+
+ admin_controlled.set_paused(mask);
+ let result = admin_controlled.assert_not_paused(mask, is_owner);
+ assert!(result.is_ok(), "asserting as not paused failed");
+ }
+}
diff --git a/engine/src/fungible_token.rs b/engine-standalone-nep141-legacy/src/fungible_token.rs
similarity index 93%
rename from engine/src/fungible_token.rs
rename to engine-standalone-nep141-legacy/src/fungible_token.rs
index 7570e1318..faacb032c 100644
--- a/engine/src/fungible_token.rs
+++ b/engine-standalone-nep141-legacy/src/fungible_token.rs
@@ -1,17 +1,22 @@
-use crate::connector::ZERO_ATTACHED_BALANCE;
-use crate::engine;
-use crate::parameters::{NEP141FtOnTransferArgs, ResolveTransferCallArgs, StorageBalance};
-use crate::prelude::account_id::AccountId;
-use crate::prelude::Wei;
-use crate::prelude::{
- sdk, storage, vec, Address, Balance, BorshDeserialize, BorshSerialize, NearGas, PromiseAction,
- PromiseBatchAction, PromiseCreateArgs, PromiseResult, PromiseWithCallbackArgs,
- StorageBalanceBounds, StorageUsage, String, ToString, Vec,
+use crate::legacy_connector::ZERO_ATTACHED_BALANCE;
+use aurora_engine::{
+ engine,
+ parameters::{NEP141FtOnTransferArgs, ResolveTransferCallArgs, StorageBalance},
};
+use aurora_engine_sdk as sdk;
use aurora_engine_sdk::io::{StorageIntermediate, IO};
-use aurora_engine_types::borsh;
-pub use aurora_engine_types::parameters::connector::FungibleTokenMetadata;
-use aurora_engine_types::types::{NEP141Wei, Yocto, ZERO_NEP141_WEI, ZERO_YOCTO};
+use aurora_engine_types::borsh::{self, BorshDeserialize, BorshSerialize};
+use aurora_engine_types::{
+ account_id::AccountId,
+ parameters::{PromiseAction, PromiseBatchAction, PromiseCreateArgs, PromiseWithCallbackArgs},
+ storage,
+ types::{
+ Address, Balance, NEP141Wei, NearGas, PromiseResult, StorageBalanceBounds, StorageUsage,
+ Wei, Yocto, ZERO_NEP141_WEI, ZERO_YOCTO,
+ },
+ vec, String, ToString, Vec,
+};
+use serde::{Deserialize, Serialize};
/// Gas for `resolve_transfer`: 5 `TGas`
const GAS_FOR_RESOLVE_TRANSFER: NearGas = NearGas::new(5_000_000_000_000);
@@ -56,6 +61,25 @@ pub struct FungibleTokenOps {
io: I,
}
+/// Fungible token Reference hash type.
+/// Used for `FungibleTokenMetadata`
+#[derive(Debug, BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone, PartialEq, Eq)]
+pub struct FungibleReferenceHash([u8; 32]);
+
+impl FungibleReferenceHash {
+ /// Encode to base64-encoded string
+ #[must_use]
+ pub fn encode(&self) -> String {
+ aurora_engine_sdk::base64::encode(self)
+ }
+}
+
+impl AsRef<[u8]> for FungibleReferenceHash {
+ fn as_ref(&self) -> &[u8] {
+ &self.0
+ }
+}
+
impl FungibleTokenOps {
pub fn new(io: I) -> Self {
FungibleToken::default().ops(io)
@@ -488,7 +512,7 @@ impl FungibleTokenOps {
storage::bytes_to_key(
storage::KeyPrefix::EthConnector,
&[u8::from(
- crate::prelude::EthConnectorStorageId::StatisticsAuroraAccountsCounter,
+ aurora_engine_types::storage:: EthConnectorStorageId::StatisticsAuroraAccountsCounter,
)],
)
}
@@ -500,14 +524,14 @@ impl FungibleTokenOps {
.read_u64(&key)
.unwrap_or(0)
.checked_add(1)
- .expect(crate::errors::ERR_ACCOUNTS_COUNTER_OVERFLOW);
+ .expect(aurora_engine::errors::ERR_ACCOUNTS_COUNTER_OVERFLOW);
self.io.write_storage(&key, &accounts_counter.to_le_bytes());
}
}
pub mod error {
- use crate::errors;
- use crate::prelude::types::balance::error::BalanceOverflowError;
+ use aurora_engine::errors;
+ use aurora_engine_types::types::balance::error::BalanceOverflowError;
const TOTAL_SUPPLY_OVERFLOW: &[u8; 25] = errors::ERR_TOTAL_SUPPLY_OVERFLOW;
const BALANCE_OVERFLOW: &[u8; 20] = errors::ERR_BALANCE_OVERFLOW;
diff --git a/engine-standalone-nep141-legacy/src/legacy_connector.rs b/engine-standalone-nep141-legacy/src/legacy_connector.rs
new file mode 100644
index 000000000..1af46af41
--- /dev/null
+++ b/engine-standalone-nep141-legacy/src/legacy_connector.rs
@@ -0,0 +1,900 @@
+use crate::admin_controlled::{AdminControlled, PauseEthConnectorCallArgs, PausedMask};
+use crate::fungible_token::{self, FungibleToken, FungibleTokenOps};
+use aurora_engine::connector::proof_key;
+use aurora_engine::{
+ deposit_event::{DepositedEvent, FtTransferMessageData, TokenMessageData},
+ engine::Engine,
+ parameters::{
+ BalanceOfCallArgs, BalanceOfEthCallArgs, FinishDepositCallArgs, InitCallArgs,
+ NEP141FtOnTransferArgs, ResolveTransferCallArgs, SetContractDataCallArgs,
+ StorageBalanceOfCallArgs, StorageDepositCallArgs, StorageWithdrawCallArgs,
+ TransferCallArgs, TransferCallCallArgs, WithdrawResult,
+ },
+ proof::Proof,
+};
+use aurora_engine_modexp::ModExpAlgorithm;
+use aurora_engine_sdk as sdk;
+use aurora_engine_sdk::{
+ env::Env,
+ io::{StorageIntermediate, IO},
+};
+use aurora_engine_types::borsh::{self, BorshDeserialize, BorshSerialize};
+use aurora_engine_types::parameters::connector::FungibleTokenMetadata;
+use aurora_engine_types::{
+ account_id::AccountId,
+ format,
+ parameters::{
+ PromiseBatchAction, PromiseCreateArgs, PromiseWithCallbackArgs, WithdrawCallArgs,
+ },
+ storage::{EthConnectorStorageId, KeyPrefix},
+ str,
+ types::{
+ address::error::AddressError, Address, NEP141Wei, NearGas, PromiseResult, Wei, Yocto,
+ ERR_FAILED_PARSE, ZERO_NEP141_WEI, ZERO_WEI,
+ },
+ ToString, Vec, U256,
+};
+
+pub const ERR_NOT_ENOUGH_BALANCE_FOR_FEE: &str = "ERR_NOT_ENOUGH_BALANCE_FOR_FEE";
+/// Indicate zero attached balance for promise call
+pub const ZERO_ATTACHED_BALANCE: Yocto = Yocto::new(0);
+/// NEAR Gas for calling `fininsh_deposit` promise. Used in the `deposit` logic.
+pub const GAS_FOR_FINISH_DEPOSIT: NearGas = NearGas::new(50_000_000_000_000);
+/// NEAR Gas for calling `verify_log_entry` promise. Used in the `deposit` logic.
+// Note: Is 40Tgas always enough?
+const GAS_FOR_VERIFY_LOG_ENTRY: NearGas = NearGas::new(40_000_000_000_000);
+
+/// Admin control flow flag indicates that all control flow unpause (unblocked).
+pub const UNPAUSE_ALL: PausedMask = 0;
+/// Admin control flow flag indicates that the deposit is paused.
+pub const PAUSE_DEPOSIT: PausedMask = 1 << 0;
+/// Admin control flow flag indicates that withdrawal is paused.
+pub const PAUSE_WITHDRAW: PausedMask = 1 << 1;
+
+/// Eth-connector contract data. It's stored in the storage.
+/// Contains:
+/// * connector specific data
+/// * Fungible token data
+/// * paused_mask - admin control flow data
+/// * io - I/O trait handler
+pub struct EthConnectorContract {
+ contract: EthConnector,
+ ft: FungibleTokenOps,
+ paused_mask: PausedMask,
+ io: I,
+}
+
+/// Connector specific data. It always should contain `prover account` -
+#[derive(BorshSerialize, BorshDeserialize)]
+pub struct EthConnector {
+ /// It used in the Deposit flow, to verify log entry form incoming proof.
+ pub prover_account: AccountId,
+ /// It is Eth address, used in the Deposit and Withdraw logic.
+ pub eth_custodian_address: Address,
+}
+
+impl EthConnectorContract {
+ /// Init Eth-connector contract instance.
+ /// Load contract data from storage and init I/O handler.
+ /// Used as single point of contract access for various contract actions
+ pub fn init_instance(io: I) -> Result {
+ Ok(Self {
+ contract: get_contract_data(&io, &EthConnectorStorageId::Contract)?,
+ ft: get_contract_data::(&io, &EthConnectorStorageId::FungibleToken)?
+ .ops(io),
+ paused_mask: get_contract_data(&io, &EthConnectorStorageId::PausedMask)
+ .unwrap_or(UNPAUSE_ALL),
+ io,
+ })
+ }
+
+ /// Create contract data - init eth-connector contract specific data.
+ /// Used only once for first time initialization.
+ /// Initialized contract data stored in the storage.
+ pub fn create_contract(
+ mut io: I,
+ owner_id: AccountId,
+ args: InitCallArgs,
+ ) -> Result<(), error::InitContractError> {
+ // Check is it already initialized
+ let contract_key_exists =
+ io.storage_has_key(&construct_contract_key(&EthConnectorStorageId::Contract));
+ if contract_key_exists {
+ return Err(error::InitContractError::AlreadyInitialized);
+ }
+
+ sdk::log!("[init contract]");
+
+ let contract_data = set_contract_data(
+ &mut io,
+ SetContractDataCallArgs {
+ prover_account: args.prover_account,
+ eth_custodian_address: args.eth_custodian_address,
+ metadata: args.metadata,
+ },
+ )
+ .map_err(error::InitContractError::InvalidCustodianAddress)?;
+
+ let mut ft = FungibleTokenOps::new(io);
+ // Register FT account for current contract
+ ft.internal_register_account(&owner_id);
+
+ let paused_mask = UNPAUSE_ALL;
+ io.write_borsh(
+ &construct_contract_key(&EthConnectorStorageId::PausedMask),
+ &paused_mask,
+ );
+
+ Self {
+ contract: contract_data,
+ ft,
+ paused_mask,
+ io,
+ }
+ .save_ft_contract();
+
+ Ok(())
+ }
+
+ /// Deposit all types of tokens
+ pub fn deposit(
+ &self,
+ raw_proof: Vec,
+ current_account_id: AccountId,
+ predecessor_account_id: AccountId,
+ ) -> Result {
+ // Check is current account owner
+ let is_owner = current_account_id == predecessor_account_id;
+ // Check is current flow paused. If it's owner account just skip it.
+ self.assert_not_paused(PAUSE_DEPOSIT, is_owner)
+ .map_err(|_| error::DepositError::Paused)?;
+
+ sdk::log!("[Deposit tokens]");
+
+ // Get incoming deposit arguments
+ let proof: Proof =
+ Proof::try_from_slice(&raw_proof).map_err(|_| error::DepositError::ProofParseFailed)?;
+ // Fetch event data from Proof
+ let event = DepositedEvent::from_log_entry_data(&proof.log_entry_data)
+ .map_err(error::DepositError::EventParseFailed)?;
+
+ sdk::log!(
+ "Deposit started: from {} to recipient {:?} with amount: {:?} and fee {:?}",
+ event.sender.encode(),
+ event.token_message_data.recipient(),
+ event.amount,
+ event.fee
+ );
+
+ sdk::log!(
+ "Event's address {}, custodian address {}",
+ event.eth_custodian_address.encode(),
+ self.contract.eth_custodian_address.encode(),
+ );
+
+ if event.eth_custodian_address != self.contract.eth_custodian_address {
+ return Err(error::DepositError::CustodianAddressMismatch);
+ }
+
+ if NEP141Wei::new(event.fee.as_u128()) >= event.amount {
+ return Err(error::DepositError::InsufficientAmountForFee);
+ }
+
+ // Verify proof data with cross-contract call to prover account
+ sdk::log!(
+ "Deposit verify_log_entry for prover: {}",
+ self.contract.prover_account,
+ );
+
+ // Do not skip bridge call. This is only used for development and diagnostics.
+ let skip_bridge_call = false.try_to_vec().unwrap();
+ let mut proof_to_verify = raw_proof;
+ proof_to_verify.extend(skip_bridge_call);
+
+ let verify_call = PromiseCreateArgs {
+ target_account_id: self.contract.prover_account.clone(),
+ method: "verify_log_entry".to_string(),
+ args: proof_to_verify,
+ attached_balance: ZERO_ATTACHED_BALANCE,
+ attached_gas: GAS_FOR_VERIFY_LOG_ENTRY,
+ };
+
+ // Finalize deposit
+ let data = match event.token_message_data {
+ // Deposit to NEAR accounts
+ TokenMessageData::Near(account_id) => FinishDepositCallArgs {
+ new_owner_id: account_id,
+ amount: event.amount,
+ proof_key: proof_key(&proof),
+ relayer_id: predecessor_account_id,
+ fee: event.fee,
+ msg: None,
+ }
+ .try_to_vec()
+ .unwrap(),
+ // Deposit to Eth accounts
+ // fee is being minted in the `ft_on_transfer` callback method
+ TokenMessageData::Eth {
+ receiver_id,
+ message,
+ } => {
+ // Transfer to self and then transfer ETH in `ft_on_transfer`
+ // address - is NEAR account
+ let transfer_data = TransferCallCallArgs {
+ receiver_id,
+ amount: event.amount,
+ memo: None,
+ msg: message.encode(),
+ }
+ .try_to_vec()
+ .unwrap();
+
+ // Send to self - current account id
+ FinishDepositCallArgs {
+ new_owner_id: current_account_id.clone(),
+ amount: event.amount,
+ proof_key: proof_key(&proof),
+ relayer_id: predecessor_account_id,
+ fee: event.fee,
+ msg: Some(transfer_data),
+ }
+ .try_to_vec()
+ .unwrap()
+ }
+ };
+
+ let finish_call = PromiseCreateArgs {
+ target_account_id: current_account_id,
+ method: "finish_deposit".to_string(),
+ args: data,
+ attached_balance: ZERO_ATTACHED_BALANCE,
+ attached_gas: GAS_FOR_FINISH_DEPOSIT,
+ };
+ Ok(PromiseWithCallbackArgs {
+ base: verify_call,
+ callback: finish_call,
+ })
+ }
+
+ /// Finish deposit (private method)
+ /// NOTE: we should `record_proof` only after `mint` operation. The reason
+ /// is that in this case we only calculate the amount to be credited but
+ /// do not save it, however, if an error occurs during the calculation,
+ /// this will happen before `record_proof`. After that contract will save.
+ pub fn finish_deposit(
+ &mut self,
+ predecessor_account_id: AccountId,
+ current_account_id: AccountId,
+ data: FinishDepositCallArgs,
+ prepaid_gas: NearGas,
+ ) -> Result