From d45d5097c8c4e5a2cb9de615befcf61e49f4c0f3 Mon Sep 17 00:00:00 2001 From: kalepail Date: Mon, 4 Aug 2025 09:15:06 -0400 Subject: [PATCH 1/4] updates for p22 --- contracts/factory-interface/Cargo.lock | 438 +++++++++++------ contracts/factory-interface/Cargo.toml | 6 +- contracts/factory/Cargo.lock | 440 +++++++++++------ contracts/factory/Cargo.toml | 12 +- contracts/factory/Makefile | 6 +- contracts/factory/src/pair.rs | 4 +- contracts/factory/src/test.rs | 6 +- contracts/factory/src/test/deterministic.rs | 6 +- contracts/library/Cargo.lock | 45 +- contracts/library/Cargo.toml | 6 +- contracts/library/Makefile | 8 +- contracts/library/README.md | 2 +- contracts/library/src/soroswap_pair.wasm | Bin 32421 -> 26808 bytes contracts/library/src/test.rs | 8 +- contracts/pair/Cargo.lock | 455 ++++++++++++------ contracts/pair/Cargo.toml | 15 +- contracts/pair/Makefile | 6 +- contracts/pair/src/lib.rs | 2 +- contracts/pair/src/test.rs | 8 +- contracts/router/Cargo.lock | 455 ++++++++++++------ contracts/router/Cargo.toml | 15 +- contracts/router/Makefile | 6 +- contracts/router/src/factory.rs | 2 +- contracts/router/src/lib.rs | 2 +- contracts/router/src/pair.rs | 2 +- contracts/router/src/test.rs | 8 +- contracts/token/Cargo.lock | 443 +++++++++++------ contracts/token/Cargo.toml | 8 +- contracts/token/Makefile | 6 +- scripts/initialize_scripts/initialize.sh | 4 +- .../initialize_scripts/initialize_factory.sh | 6 +- scripts/initialize_scripts/initialize_pair.sh | 6 +- .../initialize_scripts/interact_futurenet.sh | 4 +- scripts/old_bash/add_liquidity.sh | 2 +- scripts/old_bash/check_how_many_pairs.sh | 2 +- scripts/old_bash/create_pair.sh | 2 +- scripts/old_bash/create_token.sh | 4 +- scripts/old_bash/deploy_initialize_factory.sh | 4 +- scripts/old_bash/deploy_initialize_router.sh | 2 +- scripts/old_bash/deploy_random_tokens.sh | 2 +- utils/contract.ts | 8 +- 41 files changed, 1596 insertions(+), 870 deletions(-) diff --git a/contracts/factory-interface/Cargo.lock b/contracts/factory-interface/Cargo.lock index 3fd96a07..267316c1 100644 --- a/contracts/factory-interface/Cargo.lock +++ b/contracts/factory-interface/Cargo.lock @@ -1,22 +1,19 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.21.0" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "gimli", + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -42,37 +39,134 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "ark-bls12-381" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] [[package]] -name = "backtrace" -version = "0.3.69" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", ] [[package]] -name = "base16ct" -version = "0.2.0" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "base32" +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -116,7 +210,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -203,26 +297,25 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn", + "syn 2.0.104", ] [[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", @@ -236,7 +329,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -260,7 +353,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.104", ] [[package]] @@ -271,9 +364,15 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.104", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "der" version = "0.7.8" @@ -294,6 +393,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -302,7 +412,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -334,7 +444,6 @@ dependencies = [ "elliptic-curve", "rfc6979", "signature", - "spki", ] [[package]] @@ -349,15 +458,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -379,7 +489,6 @@ dependencies = [ "ff", "generic-array", "group", - "pkcs8", "rand_core", "sec1", "subtle", @@ -450,12 +559,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "group" version = "0.13.0" @@ -473,6 +576,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -562,9 +674,9 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "itertools" -version = "0.11.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -586,16 +698,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "once_cell", "sha2", - "signature", ] [[package]] @@ -625,21 +735,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "num-bigint" version = "0.4.4" @@ -659,7 +754,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -681,21 +776,24 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "paste" version = "1.0.14" @@ -712,12 +810,6 @@ dependencies = [ "spki", ] -[[package]] -name = "platforms" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" - [[package]] name = "powerfmt" version = "0.2.0" @@ -737,23 +829,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.104", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -798,17 +899,11 @@ dependencies = [ "subtle", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -828,7 +923,6 @@ dependencies = [ "base16ct", "der", "generic-array", - "pkcs8", "subtle", "zeroize", ] @@ -856,7 +950,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -896,7 +990,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -938,21 +1032,21 @@ checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "soroban-builtin-sdk-macros" -version = "20.0.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42487d6b0268748f753feeb579c6f7908dbb002faf20b703e6a7185b12f0527" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-env-common" -version = "20.0.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb493483fa3e3ebfb4c081472495d14b0abcfbe04ba142a56ff63056cc62700" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" dependencies = [ "arbitrary", "crate-git-revision", @@ -964,13 +1058,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-xdr", + "wasmparser", ] [[package]] name = "soroban-env-guest" -version = "20.0.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f31a738ef5faf4084c4b1824a8e3f93dfff0261a3909e86060f818e728479a3" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" dependencies = [ "soroban-env-common", "static_assertions", @@ -978,13 +1073,19 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "20.0.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd1172a76c0bc2ce67ec7f28ca37dddbe9fefabe583f80434f5f60aaee3547e" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" dependencies = [ - "backtrace", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", "curve25519-dalek", + "ecdsa", "ed25519-dalek", + "elliptic-curve", + "generic-array", "getrandom", "hex-literal", "hmac", @@ -992,8 +1093,10 @@ dependencies = [ "num-derive", "num-integer", "num-traits", + "p256", "rand", "rand_chacha", + "sec1", "sha2", "sha3", "soroban-builtin-sdk-macros", @@ -1001,13 +1104,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-strkey", + "wasmparser", ] [[package]] name = "soroban-env-macros" -version = "20.0.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0536648cea69ab3bae1801d35f92c0a31e7449cd2c7d14a18fb5e413f43279" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" dependencies = [ "itertools", "proc-macro2", @@ -1015,14 +1119,14 @@ dependencies = [ "serde", "serde_json", "stellar-xdr", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-ledger-snapshot" -version = "20.0.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37960eec21d7dc5dbd976fa16e38c056429663a89243798486b07afbb263c9b5" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" dependencies = [ "serde", "serde_json", @@ -1034,15 +1138,17 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "20.0.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f08e1fdb18dbee88160ea6640962faf021a49f22eb1bd212c4d8b0cef32c582c" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" dependencies = [ "arbitrary", "bytes-lit", "ctor", + "derive_arbitrary", "ed25519-dalek", "rand", + "rustc_version", "serde", "serde_json", "soroban-env-guest", @@ -1054,9 +1160,9 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "20.0.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5cae44f304f2fd32f9cfa9a31a9b58eb1c10aa07a7d5b591921cf7fa649e44" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" dependencies = [ "crate-git-revision", "darling", @@ -1069,14 +1175,14 @@ dependencies = [ "soroban-spec", "soroban-spec-rust", "stellar-xdr", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-spec" -version = "20.0.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7539cfa0abe36f3d33c49fe1253f6b652c91c9a9841fe83dedc1799b7f4bb55f" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -1086,9 +1192,9 @@ dependencies = [ [[package]] name = "soroban-spec-rust" -version = "20.0.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb6189ef3ede0061db14b0cf9fa2692a2cb6c6e8d941689f0c9ca82b68c47ab2" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" dependencies = [ "prettyplease", "proc-macro2", @@ -1096,15 +1202,15 @@ dependencies = [ "sha2", "soroban-spec", "stellar-xdr", - "syn", + "syn 2.0.104", "thiserror", ] [[package]] name = "soroban-wasmi" -version = "0.31.1-soroban.20.0.0" +version = "0.31.1-soroban.20.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1aaa682a67cbd2173f1d60cb1e7b951d490d7c4e0b7b6f5387cbb952e963c46" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" dependencies = [ "smallvec", "spin", @@ -1144,20 +1250,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stellar-strkey" -version = "0.0.8" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" dependencies = [ - "base32", "crate-git-revision", + "data-encoding", "thiserror", ] [[package]] name = "stellar-xdr" -version = "20.0.0" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9595b775539e475da4179fa46212b11e4575f526d57b13308989a8c1dd59238c" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" dependencies = [ "arbitrary", "base64 0.13.1", @@ -1183,9 +1289,20 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.39" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1209,7 +1326,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1286,7 +1403,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -1308,7 +1425,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1339,11 +1456,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.88.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8cf7dd82407fe68161bedcd57fde15596f32ebf6e9b3bdbf3ae1da20e38e5e" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.1.0", + "semver", ] [[package]] @@ -1421,8 +1539,42 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/contracts/factory-interface/Cargo.toml b/contracts/factory-interface/Cargo.toml index f02ba9c1..22a2fe36 100644 --- a/contracts/factory-interface/Cargo.toml +++ b/contracts/factory-interface/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" publish = false [dependencies] -soroban-sdk = { version = "20.2.0" } +soroban-sdk = { version = "22.0.8" } -[dev_dependencies] -soroban-sdk = { version = "20.2.0", features = ["testutils"] } \ No newline at end of file +[dev-dependencies] +soroban-sdk = { version = "22.0.8", features = ["testutils"] } \ No newline at end of file diff --git a/contracts/factory/Cargo.lock b/contracts/factory/Cargo.lock index 135c8553..2e10f6ca 100644 --- a/contracts/factory/Cargo.lock +++ b/contracts/factory/Cargo.lock @@ -1,22 +1,19 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.21.0" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "gimli", + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -36,37 +33,134 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "ark-bls12-381" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] [[package]] -name = "backtrace" -version = "0.3.69" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", ] [[package]] -name = "base16ct" -version = "0.2.0" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "base32" +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -110,7 +204,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -204,26 +298,25 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f34ba9a9bcb8645379e9de8cb3ecfcf4d1c85ba66d90deb3259206fa5aa193b" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[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", @@ -237,7 +330,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -264,7 +357,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -281,7 +374,7 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -305,7 +398,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -316,9 +409,15 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.104", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "der" version = "0.7.7" @@ -329,6 +428,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -337,7 +447,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -369,7 +479,6 @@ dependencies = [ "elliptic-curve", "rfc6979", "signature", - "spki", ] [[package]] @@ -384,15 +493,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -404,9 +514,9 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -414,7 +524,6 @@ dependencies = [ "ff", "generic-array", "group", - "pkcs8", "rand_core", "sec1", "subtle", @@ -485,12 +594,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "group" version = "0.13.0" @@ -508,6 +611,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -598,9 +710,9 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "itertools" -version = "0.11.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -622,16 +734,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "once_cell", "sha2", - "signature", ] [[package]] @@ -673,21 +783,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "num-bigint" version = "0.4.3" @@ -707,16 +802,15 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[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", ] @@ -730,19 +824,22 @@ dependencies = [ ] [[package]] -name = "object" -version = "0.32.1" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "once_cell" -version = "1.17.1" +name = "p256" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] [[package]] name = "paste" @@ -760,12 +857,6 @@ dependencies = [ "spki", ] -[[package]] -name = "platforms" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -779,23 +870,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b69d39aab54d069e7f2fe8cb970493e7834601ca2d8c65fd7bbd183578080d1" dependencies = [ "proc-macro2", - "syn 2.0.39", + "syn 2.0.104", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -840,17 +940,11 @@ dependencies = [ "subtle", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -876,7 +970,6 @@ dependencies = [ "base16ct", "der", "generic-array", - "pkcs8", "subtle", "zeroize", ] @@ -904,7 +997,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -944,7 +1037,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -986,21 +1079,21 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "soroban-builtin-sdk-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa4d0718c6bb74d5b9f77d54dde6cc08a7eb6ef0e76b524f723a48f1cf5db2c" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] name = "soroban-env-common" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e3c4b5ea7936e814706f2a5da6af574260319bcc66fbf5517b39f19b5fa365" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" dependencies = [ "arbitrary", "crate-git-revision", @@ -1012,13 +1105,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-xdr", + "wasmparser", ] [[package]] name = "soroban-env-guest" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff111936103653515b4471b951b6325b966c3bb31c4c1bd5892ea741aa028ca" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" dependencies = [ "soroban-env-common", "static_assertions", @@ -1026,13 +1120,19 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3d7de1f83760dddf9302dcc32f8adfebaff41946045ea67196511aca8d9f00" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" dependencies = [ - "backtrace", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", "curve25519-dalek", + "ecdsa", "ed25519-dalek", + "elliptic-curve", + "generic-array", "getrandom", "hex-literal", "hmac", @@ -1040,8 +1140,10 @@ dependencies = [ "num-derive", "num-integer", "num-traits", + "p256", "rand", "rand_chacha", + "sec1", "sha2", "sha3", "soroban-builtin-sdk-macros", @@ -1049,13 +1151,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-strkey", + "wasmparser", ] [[package]] name = "soroban-env-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff774562cca63a173127b0b6679dce9afde49fd34474eec041dc5612134dda7" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" dependencies = [ "itertools", "proc-macro2", @@ -1063,14 +1166,14 @@ dependencies = [ "serde", "serde_json", "stellar-xdr", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] name = "soroban-ledger-snapshot" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4166fef4218b0a23d9ef58f48dc57cf56bf7fbe46d410e0f8672e8986b42b" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" dependencies = [ "serde", "serde_json", @@ -1082,15 +1185,17 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf12b257428a9ec762491e76f80f7d7a6fa3b7994adbbdc559c787f64fcebff5" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" dependencies = [ "arbitrary", "bytes-lit", "ctor", + "derive_arbitrary", "ed25519-dalek", "rand", + "rustc_version", "serde", "serde_json", "soroban-env-guest", @@ -1102,9 +1207,9 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e591efb1b5850fb5c95dcac9efcd65fa3168f041fe7204edd4ecf592f01f21" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" dependencies = [ "crate-git-revision", "darling", @@ -1117,14 +1222,14 @@ dependencies = [ "soroban-spec", "soroban-spec-rust", "stellar-xdr", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] name = "soroban-spec" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc6f22d7c303d8cb6e12d2dd04d4dfb38d773292f2721ea5ac15d3b0fd51c6c" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -1134,9 +1239,9 @@ dependencies = [ [[package]] name = "soroban-spec-rust" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffcc7e96ae13c3fdce8b132be2949784fc23d2234e9e591817e1b21ace9aa06" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" dependencies = [ "prettyplease", "proc-macro2", @@ -1144,15 +1249,15 @@ dependencies = [ "sha2", "soroban-spec", "stellar-xdr", - "syn 2.0.39", + "syn 2.0.104", "thiserror", ] [[package]] name = "soroban-wasmi" -version = "0.31.1-soroban.20.0.0" +version = "0.31.1-soroban.20.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1aaa682a67cbd2173f1d60cb1e7b951d490d7c4e0b7b6f5387cbb952e963c46" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" dependencies = [ "smallvec", "spin", @@ -1201,20 +1306,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stellar-strkey" -version = "0.0.8" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" dependencies = [ - "base32", "crate-git-revision", + "data-encoding", "thiserror", ] [[package]] name = "stellar-xdr" -version = "20.0.2" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f00a85bd9b1617d4cb7e741733889c9940e6bdeca360db81752b0ef04fe3a5" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" dependencies = [ "arbitrary", "base64 0.13.1", @@ -1251,9 +1356,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1286,7 +1391,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -1420,11 +1525,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.88.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8cf7dd82407fe68161bedcd57fde15596f32ebf6e9b3bdbf3ae1da20e38e5e" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.1.0", + "semver", ] [[package]] @@ -1533,8 +1639,42 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/contracts/factory/Cargo.toml b/contracts/factory/Cargo.toml index 18ddc076..395b74de 100644 --- a/contracts/factory/Cargo.toml +++ b/contracts/factory/Cargo.toml @@ -9,13 +9,13 @@ publish = false crate-type = ["cdylib"] [dependencies] -soroban-sdk = { version = "20.2.0" } -num-integer = { version = "0.1.45", default-features = false, features = ["i128"] } -soroswap-factory-interface={ path="../factory-interface", version="0.0.1", package="soroswap-factory-interface" } +soroban-sdk = { version = "22.0.8" } +num-integer = { version = "0.1.46", default-features = false, features = ["i128"] } +soroswap-factory-interface = { path = "../factory-interface" } -[dev_dependencies] -soroban-sdk = { version = "20.2.0", features = ["testutils"] } -soroswap-factory-interface={path="../factory-interface"} +[dev-dependencies] +soroban-sdk = { version = "22.0.8", features = ["testutils"] } +soroswap-factory-interface = { path = "../factory-interface" } [profile.release] opt-level = "z" diff --git a/contracts/factory/Makefile b/contracts/factory/Makefile index f2ea874c..0c45e62f 100644 --- a/contracts/factory/Makefile +++ b/contracts/factory/Makefile @@ -8,9 +8,9 @@ test: build build: $(MAKE) -C ../token || break; $(MAKE) -C ../pair || break; - cargo build --target wasm32-unknown-unknown --release - soroban contract optimize --wasm target/wasm32-unknown-unknown/release/soroswap_factory.wasm - @ls -l target/wasm32-unknown-unknown/release/*.wasm + cargo build --target wasm32v1-none --release + stellar contract optimize --wasm target/wasm32v1-none/release/soroswap_factory.wasm + @ls -l target/wasm32v1-none/release/*.wasm fmt: cargo fmt --all --check diff --git a/contracts/factory/src/pair.rs b/contracts/factory/src/pair.rs index 341fc8ee..a58fddcc 100644 --- a/contracts/factory/src/pair.rs +++ b/contracts/factory/src/pair.rs @@ -3,7 +3,7 @@ use soroban_sdk::{contracttype, contracterror, xdr::ToXdr, Address, Bytes, BytesN, Env}; soroban_sdk::contractimport!( - file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" ); #[contracterror] @@ -38,7 +38,7 @@ impl Pair { salt.append(&self.1.clone().to_xdr(e)); // Hash the salt using SHA256 to generate a new BytesN<32> value - e.crypto().sha256(&salt) + e.crypto().sha256(&salt).into() } pub fn token_0(&self) -> &Address { diff --git a/contracts/factory/src/test.rs b/contracts/factory/src/test.rs index ade1b0cb..adeebc88 100644 --- a/contracts/factory/src/test.rs +++ b/contracts/factory/src/test.rs @@ -9,7 +9,7 @@ use crate::{SoroswapFactoryClient}; // **** TOKEN CONTRACT **** mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32-unknown-unknown/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); pub type TokenClient<'a> = Client<'a>; } use token::TokenClient; @@ -25,14 +25,14 @@ fn create_token_contract<'a>(e: &Env) -> TokenClient<'a> { // **** PAIR WASM **** fn pair_token_wasm(e: &Env) -> BytesN<32> { soroban_sdk::contractimport!( - file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" ); e.deployer().upload_contract_wasm(WASM) } // **** TOKEN CONTRACT **** mod pair { - soroban_sdk::contractimport!(file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm"); + soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); pub type SoroswapPairClient<'a> = Client<'a>; } use pair::SoroswapPairClient; diff --git a/contracts/factory/src/test/deterministic.rs b/contracts/factory/src/test/deterministic.rs index c107dae0..be92a095 100644 --- a/contracts/factory/src/test/deterministic.rs +++ b/contracts/factory/src/test/deterministic.rs @@ -25,15 +25,15 @@ use soroban_sdk::{ use core::mem; mod pair { - soroban_sdk::contractimport!(file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm"); + soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); pub type SoroswapPairClient<'a> = Client<'a>; } mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32-unknown-unknown/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); pub type TokenClient<'a> = Client<'a>; } mod factory { - soroban_sdk::contractimport!(file = "./target/wasm32-unknown-unknown/release/soroswap_factory.wasm"); + soroban_sdk::contractimport!(file = "./target/wasm32v1-none/release/soroswap_factory.wasm"); pub type _SoroswapFactoryClient<'a> = Client<'a>; } use pair::SoroswapPairClient; diff --git a/contracts/library/Cargo.lock b/contracts/library/Cargo.lock index bc148a41..94f20bd4 100644 --- a/contracts/library/Cargo.lock +++ b/contracts/library/Cargo.lock @@ -758,11 +758,10 @@ dependencies = [ [[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", ] @@ -1025,9 +1024,9 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "soroban-builtin-sdk-macros" -version = "22.1.2" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ebed97f583127b391cc8137d5e475e66ba4e12f428dd6c9aed7a914bbd2353e" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" dependencies = [ "itertools", "proc-macro2", @@ -1037,9 +1036,9 @@ dependencies = [ [[package]] name = "soroban-env-common" -version = "22.1.2" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ce037307fcd6d775f2b567ae10d5eb9b99eacb2b1110e9b23ed92b351e47f4" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" dependencies = [ "arbitrary", "crate-git-revision", @@ -1056,9 +1055,9 @@ dependencies = [ [[package]] name = "soroban-env-guest" -version = "22.1.2" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b395eaf56d155529a3951c0ad54420599184a810db86d7316b97cc59b97e5b85" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" dependencies = [ "soroban-env-common", "static_assertions", @@ -1066,9 +1065,9 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "22.1.2" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb980b49637cc428fab2442a97800ac2ed9ced39422acf4840f77ab596858cae" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" dependencies = [ "ark-bls12-381", "ark-ec", @@ -1102,9 +1101,9 @@ dependencies = [ [[package]] name = "soroban-env-macros" -version = "22.1.2" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef84a5b3bfffc84250b22454d6ce9df6750afd5ed900faf7d02968400b9c8bd0" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" dependencies = [ "itertools", "proc-macro2", @@ -1117,9 +1116,9 @@ dependencies = [ [[package]] name = "soroban-ledger-snapshot" -version = "22.0.3" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a7247f49dde3127b3afd2cc0431ac83e9402649de6786a3f6ea240688c5e3d" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" dependencies = [ "serde", "serde_json", @@ -1131,9 +1130,9 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "22.0.3" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ec29730d6f006d5649d17586c4d7c1fc350c1fc3c60fc539e06243df3cf507" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" dependencies = [ "arbitrary", "bytes-lit", @@ -1153,9 +1152,9 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "22.0.3" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04415b84ccddb22161cc19b59adf9543a210011a365ae0b89870c1b6f19f185" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" dependencies = [ "crate-git-revision", "darling", @@ -1173,9 +1172,9 @@ dependencies = [ [[package]] name = "soroban-spec" -version = "22.0.3" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06511ba41fa8afb05e4f839d77d2f7caa59acf4405e41deca01b78f7ffb1a466" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -1185,9 +1184,9 @@ dependencies = [ [[package]] name = "soroban-spec-rust" -version = "22.0.3" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27adb57847fd5d3677eaf8013ddf715ec6eb8ec98f4ee656f2d5c2bf731bd120" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" dependencies = [ "prettyplease", "proc-macro2", diff --git a/contracts/library/Cargo.toml b/contracts/library/Cargo.toml index 58d43a9f..4526fec4 100644 --- a/contracts/library/Cargo.toml +++ b/contracts/library/Cargo.toml @@ -15,11 +15,11 @@ publish = true crate-type = ["cdylib", "rlib"] [dependencies] -soroban-sdk = "22.0.0-rc.2.1" -num-integer = { version = "0.1.45", default-features = false, features = ["i128"] } +soroban-sdk = "22.0.8" +num-integer = { version = "0.1.46", default-features = false, features = ["i128"] } [dev-dependencies] -soroban-sdk = { version = "22.0.0-rc.2.1", features = ["testutils"] } +soroban-sdk = { version = "22.0.8", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/contracts/library/Makefile b/contracts/library/Makefile index e46c84cb..a569c3a1 100644 --- a/contracts/library/Makefile +++ b/contracts/library/Makefile @@ -9,10 +9,10 @@ build: $(MAKE) -C ../token || break; $(MAKE) -C ../pair || break; $(MAKE) -C ../factory || break; - cp ../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm ./src # Copy pair wasm to library root - cargo build --target wasm32-unknown-unknown --release - soroban contract optimize --wasm target/wasm32-unknown-unknown/release/soroswap_library.wasm - @ls -l target/wasm32-unknown-unknown/release/*.wasm + cp ../pair/target/wasm32v1-none/release/soroswap_pair.wasm ./src # Copy pair wasm to library root + cargo build --target wasm32v1-none --release + stellar contract optimize --wasm target/wasm32v1-none/release/soroswap_library.wasm + @ls -l target/wasm32v1-none/release/*.wasm fmt: cargo fmt --all --check diff --git a/contracts/library/README.md b/contracts/library/README.md index 6b13075a..33d3d5be 100644 --- a/contracts/library/README.md +++ b/contracts/library/README.md @@ -41,7 +41,7 @@ https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV ## WASM -The WASM target wasm32-unknown-unknown is supported. +The WASM target wasm32v1-none is supported. ## Contributions diff --git a/contracts/library/src/soroswap_pair.wasm b/contracts/library/src/soroswap_pair.wasm index 0fb8dcf45098ff9dfb8454adbebecd4915f3d5cb..6c9f801e3c86d19c36eb362674eec3447033766a 100644 GIT binary patch literal 26808 zcmc(I36LDudEV<|j@_AEG(Zwu0+jS-NL4_agccGBfDCPJ4+)wuNMT8Uhm=$;2D<}d zfW5G@izBs*U6Kn5wj~&fY=?>!33g;rmIZ~15=o8}X?0q(Cpx~s3*xbfQFzP@7Lb$uJJ z!|}TA;OZbK7K_(icU|wsVlmvbVWWR-U*G2S*9N`{d%bJ1Ob`U2S2o{ah@-z@V-#H< zz2-I1Yjc68*5|Ja=Dm1fVM&$dRs6{_=D5UT;heuIKh_wVm^$UF^7O=XeRQZbGdVeW zN)2_@M@J`4)W?S#>Oi4BIXN|PyrJragY{8qJ6N2as*kr0HKx=^k2@VYG&M1%4uuD2 zrpDFdT|Ahk!^M%taC59a+EUGMygt@YNAj&xV+SWj)zR+ecyqd0A8r1Nh8inOPaJKG z5A~}Fd$vtY77o>ir-7n6Rv2kaPPCfSYAS4t5cBeZ1>R6NPW6K)EFNLywcFn;YNLO=wQ9o z2>k9ZzRjB$Q2u~FpndJ_?ol{|5A=9EME`1GVL_>q##Qu;J?8-L=ypHUN(b6IvfWpu zE*1Sp)198}@x1vP(72%D=x8;(QBHLj7mvh>0Cf=k8hdrP#V=O^K*LE9&X)fQj%2FeRaZT!;064367E*jYA>j|}YQ&6mccCBs-q8&leoE3KjLQecinS=h= zk3PbA(ZAz&*(1Q0rL&L)2;K=uf-9P_7-`qIDNutwUfJi|g(rwiDLWT4WvHwjd(m%m zrHYJpJk$QVk}AEXjYH9Ug`OaKg2zpzyW2$MTM_vXfERs`LwqO&h>yLW>!BL>#15QJ z1f#vu%U($Cdh@>Hus&M#45%7#B9Ck5o_XK5zVPzr`fGl4fpB;AsBGJlY^(UOss#Q( zFrb6D?_Ox22VK#@k(y6316)*svMK?M+K;@aYA>jVsHO3*oLK^Uz)fma5d8*W33IAu zT*zVIYg7$o-t#gK4Sm&IrU7bQ(`TRE?)Pb>b31|vhY(V(dE_g44X?FTNiugGmCp!7m-&E6hSyr$#0^8oiTqHkBUq{L_v}AfRvhVy#FWt_B%SXG$8y)%oHbmI|8yP0Gq&{ zfc(KZ*iln73_s4YX->?~AV3tJjeq1FtNQVm6c~lErJw5&m8;$LHUrkH6>%1c!lV81F=fK|#^4LXb!fKF=#*L93Yd*11_ z8A#3=NKT-Lf#{qVELQ|+IXVhx5By?i49N6{whwBr!-`LIbD~^0P_IaX&cSaac5ILb z4d^bS%UN~lpD8298ffKbNzK-NWIyT=z=y7%fgC+>^UPumnt~=ORcX=i30=|KF%e6W zX^vT8z1&#$5L4seKf4E1*KNbBB+u#qlnjd{wMx>7aNgo0aGTtCC zd=td|K_C=>9$@941<0R$dJ*6LSpx=~3yi6HPs2RD#cG}neKqfC9oFtTyI2i%9?V^U z?8s>81sacVRIv(l9wAN-Zr&_x_6LBrR}1$;#l6}R2A-O$d1s%lgzz$u1Q`VizDEkG z992R)EV!C~3_9uQyy>c7QNW|`@xaoH@CXoDNCt>oFrETrIkhi6*b#Cp3m7o5-uJm4 zbS4CLfzcT-1q4ueEnxT_!zjbN(pE)MbYPu}lT#A)5`obQRO!Ap%}tjVeF7E+dZKZu zCYS-K!advRP&|VWaAC~kR~UViYZ4?H4H>bjsNghEM)XJU;H9{BTpHI74Ny=5d?D6} z64Jpd!(=R3o4nlqW1o>FyqU<@245SC3Upg#*jXWg≻_a#ch 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 literal 32421 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 Kw(+cE5C0EBw0+ = Client<'a>; } mod pair { - soroban_sdk::contractimport!(file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm"); + soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); pub type SoroswapPairClient<'a> = Client<'a>; } fn pair_contract_wasm(e: &Env) -> BytesN<32> { soroban_sdk::contractimport!( - file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.optimized.wasm" + file = "../pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm" ); e.deployer().upload_contract_wasm(WASM) } mod factory { - soroban_sdk::contractimport!(file = "../factory/target/wasm32-unknown-unknown/release/soroswap_factory.optimized.wasm"); + soroban_sdk::contractimport!(file = "../factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm"); pub type SoroswapFactoryClient<'a> = Client<'a>; } diff --git a/contracts/pair/Cargo.lock b/contracts/pair/Cargo.lock index 4b37ff30..485f1b47 100644 --- a/contracts/pair/Cargo.lock +++ b/contracts/pair/Cargo.lock @@ -1,22 +1,19 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.21.0" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "gimli", + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -42,37 +39,134 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "ark-bls12-381" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] [[package]] -name = "backtrace" -version = "0.3.69" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", ] [[package]] -name = "base16ct" -version = "0.2.0" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "base32" +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -116,7 +210,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -203,26 +297,25 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f34ba9a9bcb8645379e9de8cb3ecfcf4d1c85ba66d90deb3259206fa5aa193b" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn", + "syn 2.0.104", ] [[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", @@ -236,7 +329,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -260,7 +353,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.104", ] [[package]] @@ -271,9 +364,15 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.104", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "der" version = "0.7.8" @@ -293,6 +392,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -301,7 +411,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -333,7 +443,6 @@ dependencies = [ "elliptic-curve", "rfc6979", "signature", - "spki", ] [[package]] @@ -348,15 +457,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -368,9 +478,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -378,7 +488,6 @@ dependencies = [ "ff", "generic-array", "group", - "pkcs8", "rand_core", "sec1", "subtle", @@ -449,12 +558,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" - [[package]] name = "group" version = "0.13.0" @@ -472,6 +575,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.0" @@ -561,9 +673,9 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "itertools" -version = "0.11.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -585,16 +697,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "once_cell", "sha2", - "signature", ] [[package]] @@ -624,21 +734,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "num-bigint" version = "0.4.4" @@ -658,16 +753,15 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[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", ] @@ -680,21 +774,24 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "paste" version = "1.0.14" @@ -711,12 +808,6 @@ dependencies = [ "spki", ] -[[package]] -name = "platforms" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -730,23 +821,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.104", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -791,17 +891,11 @@ dependencies = [ "subtle", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -821,7 +915,6 @@ dependencies = [ "base16ct", "der", "generic-array", - "pkcs8", "subtle", "zeroize", ] @@ -849,7 +942,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -889,7 +982,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -931,21 +1024,21 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "soroban-builtin-sdk-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa4d0718c6bb74d5b9f77d54dde6cc08a7eb6ef0e76b524f723a48f1cf5db2c" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-env-common" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e3c4b5ea7936e814706f2a5da6af574260319bcc66fbf5517b39f19b5fa365" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" dependencies = [ "arbitrary", "crate-git-revision", @@ -957,13 +1050,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-xdr", + "wasmparser", ] [[package]] name = "soroban-env-guest" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff111936103653515b4471b951b6325b966c3bb31c4c1bd5892ea741aa028ca" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" dependencies = [ "soroban-env-common", "static_assertions", @@ -971,13 +1065,19 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3d7de1f83760dddf9302dcc32f8adfebaff41946045ea67196511aca8d9f00" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" dependencies = [ - "backtrace", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", "curve25519-dalek", + "ecdsa", "ed25519-dalek", + "elliptic-curve", + "generic-array", "getrandom", "hex-literal", "hmac", @@ -985,8 +1085,10 @@ dependencies = [ "num-derive", "num-integer", "num-traits", + "p256", "rand", "rand_chacha", + "sec1", "sha2", "sha3", "soroban-builtin-sdk-macros", @@ -994,13 +1096,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-strkey", + "wasmparser", ] [[package]] name = "soroban-env-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff774562cca63a173127b0b6679dce9afde49fd34474eec041dc5612134dda7" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" dependencies = [ "itertools", "proc-macro2", @@ -1008,14 +1111,14 @@ dependencies = [ "serde", "serde_json", "stellar-xdr", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-ledger-snapshot" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4166fef4218b0a23d9ef58f48dc57cf56bf7fbe46d410e0f8672e8986b42b" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" dependencies = [ "serde", "serde_json", @@ -1027,15 +1130,17 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf12b257428a9ec762491e76f80f7d7a6fa3b7994adbbdc559c787f64fcebff5" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" dependencies = [ "arbitrary", "bytes-lit", "ctor", + "derive_arbitrary", "ed25519-dalek", "rand", + "rustc_version", "serde", "serde_json", "soroban-env-guest", @@ -1047,9 +1152,9 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e591efb1b5850fb5c95dcac9efcd65fa3168f041fe7204edd4ecf592f01f21" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" dependencies = [ "crate-git-revision", "darling", @@ -1062,14 +1167,14 @@ dependencies = [ "soroban-spec", "soroban-spec-rust", "stellar-xdr", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-spec" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc6f22d7c303d8cb6e12d2dd04d4dfb38d773292f2721ea5ac15d3b0fd51c6c" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -1079,9 +1184,9 @@ dependencies = [ [[package]] name = "soroban-spec-rust" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffcc7e96ae13c3fdce8b132be2949784fc23d2234e9e591817e1b21ace9aa06" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" dependencies = [ "prettyplease", "proc-macro2", @@ -1089,24 +1194,24 @@ dependencies = [ "sha2", "soroban-spec", "stellar-xdr", - "syn", + "syn 2.0.104", "thiserror", ] [[package]] name = "soroban-token-sdk" -version = "20.0.2" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81c71f3e58b4497f6d4e5ee66bf7a3900eea53233e85521204c86ccdb76dd58c" +checksum = "1b5d44abd4abb253c0714d28b3b5a9db6aaf9afa1684c3a23778e07a201c3adb" dependencies = [ "soroban-sdk", ] [[package]] name = "soroban-wasmi" -version = "0.31.1-soroban.20.0.0" +version = "0.31.1-soroban.20.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1aaa682a67cbd2173f1d60cb1e7b951d490d7c4e0b7b6f5387cbb952e963c46" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" dependencies = [ "smallvec", "spin", @@ -1156,20 +1261,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stellar-strkey" -version = "0.0.8" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" dependencies = [ - "base32", "crate-git-revision", + "data-encoding", "thiserror", ] [[package]] name = "stellar-xdr" -version = "20.0.2" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f00a85bd9b1617d4cb7e741733889c9940e6bdeca360db81752b0ef04fe3a5" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" dependencies = [ "arbitrary", "base64 0.13.1", @@ -1195,9 +1300,20 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.39" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1221,7 +1337,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1297,7 +1413,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -1319,7 +1435,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1350,11 +1466,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.88.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8cf7dd82407fe68161bedcd57fde15596f32ebf6e9b3bdbf3ae1da20e38e5e" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.0.0", + "semver", ] [[package]] @@ -1432,8 +1549,42 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/contracts/pair/Cargo.toml b/contracts/pair/Cargo.toml index 8d0dd4d5..9a8c5ddb 100644 --- a/contracts/pair/Cargo.toml +++ b/contracts/pair/Cargo.toml @@ -9,15 +9,14 @@ publish = false crate-type = ["cdylib"] [dependencies] -soroban-sdk = { version = "20.2.0" } -soroban-token-sdk = { version = "20.0.0" } -num-integer = { version = "0.1.45", default-features = false, features = ["i128"] } -soroswap-factory-interface={ path="../factory-interface", version="0.0.1", package="soroswap-factory-interface" } +soroban-sdk = { version = "22.0.8" } +soroban-token-sdk = { version = "22.0.8" } +num-integer = { version = "0.1.46", default-features = false, features = ["i128"] } +soroswap-factory-interface = { path = "../factory-interface" } - -[dev_dependencies] -soroban-sdk = { version = "20.2.0", features = ["testutils"] } -soroswap-factory-interface={path="../factory-interface"} +[dev-dependencies] +soroban-sdk = { version = "22.0.8", features = ["testutils"] } +soroswap-factory-interface = { path = "../factory-interface" } [profile.release] opt-level = "z" diff --git a/contracts/pair/Makefile b/contracts/pair/Makefile index b440c154..4742b156 100644 --- a/contracts/pair/Makefile +++ b/contracts/pair/Makefile @@ -7,9 +7,9 @@ test: build build: $(MAKE) -C ../token || break; - cargo build --target wasm32-unknown-unknown --release - soroban contract optimize --wasm target/wasm32-unknown-unknown/release/soroswap_pair.wasm - @ls -l target/wasm32-unknown-unknown/release/*.wasm + cargo build --target wasm32v1-none --release + stellar contract optimize --wasm target/wasm32v1-none/release/soroswap_pair.wasm + @ls -l target/wasm32v1-none/release/*.wasm fmt: cargo fmt --all --check diff --git a/contracts/pair/src/lib.rs b/contracts/pair/src/lib.rs index 944ad651..cfe959d0 100644 --- a/contracts/pair/src/lib.rs +++ b/contracts/pair/src/lib.rs @@ -17,7 +17,7 @@ mod strings; // ANY TOKEN CONTRACT // TODO: Simplify this and use a any_token_interface pub mod any_token { - soroban_sdk::contractimport!(file = "../token/target/wasm32-unknown-unknown/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); pub type TokenClient<'a> = Client<'a>; } diff --git a/contracts/pair/src/test.rs b/contracts/pair/src/test.rs index 4d38fac2..826058a1 100644 --- a/contracts/pair/src/test.rs +++ b/contracts/pair/src/test.rs @@ -17,7 +17,7 @@ use soroban_sdk::{ // TOKEN CONTRACT mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32-unknown-unknown/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); pub type TokenClient<'a> = Client<'a>; } use token::TokenClient; @@ -29,7 +29,7 @@ fn create_token_contract<'a>(e: &Env) -> TokenClient<'a> { // FACTORY CONTRACT mod factory { - soroban_sdk::contractimport!(file = "../factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm"); + soroban_sdk::contractimport!(file = "../factory/target/wasm32v1-none/release/soroswap_factory.wasm"); pub type SoroswapFactoryClient<'a> = Client<'a>; } use factory::SoroswapFactoryClient; @@ -45,13 +45,13 @@ fn create_factory_contract<'a>(e: & Env, setter: & Address,pair_wasm_hash: & Byt // WASM fn pair_token_wasm(e: &Env) -> BytesN<32> { soroban_sdk::contractimport!( - file = "./target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + file = "./target/wasm32v1-none/release/soroswap_pair.wasm" ); e.deployer().upload_contract_wasm(WASM) } pub mod pair { - soroban_sdk::contractimport!(file = "./target/wasm32-unknown-unknown/release/soroswap_pair.wasm"); + soroban_sdk::contractimport!(file = "./target/wasm32v1-none/release/soroswap_pair.wasm"); pub type SoroswapPairClient<'a> = Client<'a>; } use pair::SoroswapPairClient; diff --git a/contracts/router/Cargo.lock b/contracts/router/Cargo.lock index e15c471b..c1776bd4 100644 --- a/contracts/router/Cargo.lock +++ b/contracts/router/Cargo.lock @@ -1,22 +1,19 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.21.0" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "gimli", + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -42,37 +39,134 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "ark-bls12-381" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] [[package]] -name = "backtrace" -version = "0.3.69" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", ] [[package]] -name = "base16ct" -version = "0.2.0" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "base32" +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -116,7 +210,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -203,26 +297,25 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn", + "syn 2.0.104", ] [[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", @@ -236,7 +329,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -260,7 +353,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.104", ] [[package]] @@ -271,9 +364,15 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.104", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "der" version = "0.7.8" @@ -294,6 +393,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -302,7 +412,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -334,7 +444,6 @@ dependencies = [ "elliptic-curve", "rfc6979", "signature", - "spki", ] [[package]] @@ -349,15 +458,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -369,9 +479,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -379,7 +489,6 @@ dependencies = [ "ff", "generic-array", "group", - "pkcs8", "rand_core", "sec1", "subtle", @@ -450,12 +559,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" - [[package]] name = "group" version = "0.13.0" @@ -473,6 +576,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.1" @@ -562,9 +674,9 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "itertools" -version = "0.11.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -586,16 +698,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "once_cell", "sha2", - "signature", ] [[package]] @@ -625,21 +735,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "num-bigint" version = "0.4.4" @@ -659,16 +754,15 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[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", ] @@ -681,21 +775,24 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "paste" version = "1.0.14" @@ -712,12 +809,6 @@ dependencies = [ "spki", ] -[[package]] -name = "platforms" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" - [[package]] name = "powerfmt" version = "0.2.0" @@ -737,23 +828,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.104", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -798,17 +898,11 @@ dependencies = [ "subtle", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -828,7 +922,6 @@ dependencies = [ "base16ct", "der", "generic-array", - "pkcs8", "subtle", "zeroize", ] @@ -856,7 +949,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -896,7 +989,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -938,21 +1031,21 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "soroban-builtin-sdk-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa4d0718c6bb74d5b9f77d54dde6cc08a7eb6ef0e76b524f723a48f1cf5db2c" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-env-common" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e3c4b5ea7936e814706f2a5da6af574260319bcc66fbf5517b39f19b5fa365" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" dependencies = [ "arbitrary", "crate-git-revision", @@ -964,13 +1057,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-xdr", + "wasmparser", ] [[package]] name = "soroban-env-guest" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff111936103653515b4471b951b6325b966c3bb31c4c1bd5892ea741aa028ca" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" dependencies = [ "soroban-env-common", "static_assertions", @@ -978,13 +1072,19 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3d7de1f83760dddf9302dcc32f8adfebaff41946045ea67196511aca8d9f00" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" dependencies = [ - "backtrace", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", "curve25519-dalek", + "ecdsa", "ed25519-dalek", + "elliptic-curve", + "generic-array", "getrandom", "hex-literal", "hmac", @@ -992,8 +1092,10 @@ dependencies = [ "num-derive", "num-integer", "num-traits", + "p256", "rand", "rand_chacha", + "sec1", "sha2", "sha3", "soroban-builtin-sdk-macros", @@ -1001,13 +1103,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-strkey", + "wasmparser", ] [[package]] name = "soroban-env-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff774562cca63a173127b0b6679dce9afde49fd34474eec041dc5612134dda7" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" dependencies = [ "itertools", "proc-macro2", @@ -1015,14 +1118,14 @@ dependencies = [ "serde", "serde_json", "stellar-xdr", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-ledger-snapshot" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4166fef4218b0a23d9ef58f48dc57cf56bf7fbe46d410e0f8672e8986b42b" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" dependencies = [ "serde", "serde_json", @@ -1034,15 +1137,17 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf12b257428a9ec762491e76f80f7d7a6fa3b7994adbbdc559c787f64fcebff5" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" dependencies = [ "arbitrary", "bytes-lit", "ctor", + "derive_arbitrary", "ed25519-dalek", "rand", + "rustc_version", "serde", "serde_json", "soroban-env-guest", @@ -1054,9 +1159,9 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e591efb1b5850fb5c95dcac9efcd65fa3168f041fe7204edd4ecf592f01f21" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" dependencies = [ "crate-git-revision", "darling", @@ -1069,14 +1174,14 @@ dependencies = [ "soroban-spec", "soroban-spec-rust", "stellar-xdr", - "syn", + "syn 2.0.104", ] [[package]] name = "soroban-spec" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc6f22d7c303d8cb6e12d2dd04d4dfb38d773292f2721ea5ac15d3b0fd51c6c" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -1086,9 +1191,9 @@ dependencies = [ [[package]] name = "soroban-spec-rust" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffcc7e96ae13c3fdce8b132be2949784fc23d2234e9e591817e1b21ace9aa06" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" dependencies = [ "prettyplease", "proc-macro2", @@ -1096,15 +1201,15 @@ dependencies = [ "sha2", "soroban-spec", "stellar-xdr", - "syn", + "syn 2.0.104", "thiserror", ] [[package]] name = "soroban-wasmi" -version = "0.31.1-soroban.20.0.0" +version = "0.31.1-soroban.20.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1aaa682a67cbd2173f1d60cb1e7b951d490d7c4e0b7b6f5387cbb952e963c46" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" dependencies = [ "smallvec", "spin", @@ -1115,9 +1220,7 @@ dependencies = [ [[package]] name = "soroswap-library" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26352158999f8f2bbbc70481c0218d6e9cd8cc39f1d3eaa54a133e6b914f4dec" +version = "2.0.0" dependencies = [ "num-integer", "soroban-sdk", @@ -1156,20 +1259,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stellar-strkey" -version = "0.0.8" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" dependencies = [ - "base32", "crate-git-revision", + "data-encoding", "thiserror", ] [[package]] name = "stellar-xdr" -version = "20.0.2" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f00a85bd9b1617d4cb7e741733889c9940e6bdeca360db81752b0ef04fe3a5" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" dependencies = [ "arbitrary", "base64 0.13.1", @@ -1195,9 +1298,20 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.39" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1221,7 +1335,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1298,7 +1412,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -1320,7 +1434,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1351,11 +1465,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.88.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8cf7dd82407fe68161bedcd57fde15596f32ebf6e9b3bdbf3ae1da20e38e5e" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.0.2", + "semver", ] [[package]] @@ -1433,8 +1548,42 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 6aa11373..05a16374 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -10,21 +10,16 @@ readme = "README.md" keywords = ["no_std", "wasm", "soroswap", "amm", "soroban"] publish = true - - [lib] crate-type = ["cdylib"] [dependencies] -soroban-sdk = { version = "20.2.0" } -num-integer = { version = "0.1.45", default-features = false, features = [ - "i128", -] } -soroswap-library = "0.3.0" - +soroban-sdk = { version = "22.0.8" } +num-integer = { version = "0.1.46", default-features = false, features = ["i128"] } +soroswap-library = { path = "../library" } -[dev_dependencies] -soroban-sdk = { version = "20.2.0", features = ["testutils"] } +[dev-dependencies] +soroban-sdk = { version = "22.0.8", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/contracts/router/Makefile b/contracts/router/Makefile index 4721d5c6..ad2e7e12 100644 --- a/contracts/router/Makefile +++ b/contracts/router/Makefile @@ -9,9 +9,9 @@ build: $(MAKE) -C ../token || break; $(MAKE) -C ../pair || break; $(MAKE) -C ../factory || break; - cargo build --target wasm32-unknown-unknown --release - soroban contract optimize --wasm target/wasm32-unknown-unknown/release/soroswap_router.wasm - @ls -l target/wasm32-unknown-unknown/release/*.wasm + cargo build --target wasm32v1-none --release + stellar contract optimize --wasm target/wasm32v1-none/release/soroswap_router.wasm + @ls -l target/wasm32v1-none/release/*.wasm fmt: cargo fmt --all --check diff --git a/contracts/router/src/factory.rs b/contracts/router/src/factory.rs index ac5092b9..6a7c7c0f 100644 --- a/contracts/router/src/factory.rs +++ b/contracts/router/src/factory.rs @@ -1,4 +1,4 @@ soroban_sdk::contractimport!( - file = "../factory/target/wasm32-unknown-unknown/release/soroswap_factory.optimized.wasm" + file = "../factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm" ); pub type SoroswapFactoryClient<'a> = Client<'a>; \ No newline at end of file diff --git a/contracts/router/src/lib.rs b/contracts/router/src/lib.rs index 8f622f9e..2df04aef 100644 --- a/contracts/router/src/lib.rs +++ b/contracts/router/src/lib.rs @@ -81,7 +81,7 @@ fn add_liquidity_amounts( factory_client.create_pair(&token_a, &token_b); } - let (reserve_a, reserve_b) = soroswap_library::get_reserves( + let (reserve_a, reserve_b) = soroswap_library::get_reserves_with_factory( e.clone(), factory.clone(), token_a.clone(), diff --git a/contracts/router/src/pair.rs b/contracts/router/src/pair.rs index c64158cd..b1492e0a 100644 --- a/contracts/router/src/pair.rs +++ b/contracts/router/src/pair.rs @@ -1,4 +1,4 @@ soroban_sdk::contractimport!( - file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" ); pub type SoroswapPairClient<'a> = Client<'a>; \ No newline at end of file diff --git a/contracts/router/src/test.rs b/contracts/router/src/test.rs index 444bce03..5b919b28 100644 --- a/contracts/router/src/test.rs +++ b/contracts/router/src/test.rs @@ -12,7 +12,7 @@ use soroban_sdk::{ // Token Contract mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32-unknown-unknown/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); pub type TokenClient<'a> = Client<'a>; } use token::TokenClient; @@ -23,7 +23,7 @@ pub fn create_token_contract<'a>(e: &Env, admin: & Address) -> TokenClient<'a> { // Pair Contract mod pair { - soroban_sdk::contractimport!(file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm"); + soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); pub type SoroswapPairClient<'a> = Client<'a>; } use pair::SoroswapPairClient; @@ -31,14 +31,14 @@ use pair::SoroswapPairClient; fn pair_contract_wasm(e: &Env) -> BytesN<32> { soroban_sdk::contractimport!( - file = "../pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" ); e.deployer().upload_contract_wasm(WASM) } // SoroswapFactory Contract mod factory { - soroban_sdk::contractimport!(file = "../factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm"); + soroban_sdk::contractimport!(file = "../factory/target/wasm32v1-none/release/soroswap_factory.wasm"); pub type SoroswapFactoryClient<'a> = Client<'a>; } use factory::SoroswapFactoryClient; diff --git a/contracts/token/Cargo.lock b/contracts/token/Cargo.lock index 3dd34fac..eacb1bea 100644 --- a/contracts/token/Cargo.lock +++ b/contracts/token/Cargo.lock @@ -1,22 +1,19 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.21.0" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "gimli", + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -36,37 +33,134 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "ark-bls12-381" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] [[package]] -name = "backtrace" -version = "0.3.69" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", ] [[package]] -name = "base16ct" -version = "0.2.0" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "base32" +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -110,7 +204,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -204,26 +298,25 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.2" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1586fa608b1dab41f667475b4a41faec5ba680aee428bfa5de4ea520fdc6e901" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[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", @@ -237,7 +330,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -264,7 +357,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -281,7 +374,7 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -305,7 +398,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -316,9 +409,15 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.104", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "der" version = "0.7.6" @@ -329,6 +428,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -337,7 +447,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -360,16 +470,15 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest", "elliptic-curve", "rfc6979", "signature", - "spki", ] [[package]] @@ -384,15 +493,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -404,9 +514,9 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -414,7 +524,6 @@ dependencies = [ "ff", "generic-array", "group", - "pkcs8", "rand_core", "sec1", "subtle", @@ -485,12 +594,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "group" version = "0.13.0" @@ -508,6 +611,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -598,9 +710,9 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "itertools" -version = "0.11.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -622,16 +734,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "once_cell", "sha2", - "signature", ] [[package]] @@ -673,21 +783,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "num-bigint" version = "0.4.3" @@ -707,7 +802,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -730,19 +825,22 @@ dependencies = [ ] [[package]] -name = "object" -version = "0.32.1" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "once_cell" -version = "1.17.1" +name = "p256" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] [[package]] name = "paste" @@ -760,12 +858,6 @@ dependencies = [ "spki", ] -[[package]] -name = "platforms" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -779,23 +871,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058" dependencies = [ "proc-macro2", - "syn 2.0.39", + "syn 2.0.104", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -840,17 +941,11 @@ dependencies = [ "subtle", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -876,7 +971,6 @@ dependencies = [ "base16ct", "der", "generic-array", - "pkcs8", "subtle", "zeroize", ] @@ -904,7 +998,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -944,7 +1038,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -986,21 +1080,21 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "soroban-builtin-sdk-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa4d0718c6bb74d5b9f77d54dde6cc08a7eb6ef0e76b524f723a48f1cf5db2c" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] name = "soroban-env-common" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e3c4b5ea7936e814706f2a5da6af574260319bcc66fbf5517b39f19b5fa365" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" dependencies = [ "arbitrary", "crate-git-revision", @@ -1012,13 +1106,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-xdr", + "wasmparser", ] [[package]] name = "soroban-env-guest" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff111936103653515b4471b951b6325b966c3bb31c4c1bd5892ea741aa028ca" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" dependencies = [ "soroban-env-common", "static_assertions", @@ -1026,13 +1121,19 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3d7de1f83760dddf9302dcc32f8adfebaff41946045ea67196511aca8d9f00" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" dependencies = [ - "backtrace", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", "curve25519-dalek", + "ecdsa", "ed25519-dalek", + "elliptic-curve", + "generic-array", "getrandom", "hex-literal", "hmac", @@ -1040,8 +1141,10 @@ dependencies = [ "num-derive", "num-integer", "num-traits", + "p256", "rand", "rand_chacha", + "sec1", "sha2", "sha3", "soroban-builtin-sdk-macros", @@ -1049,13 +1152,14 @@ dependencies = [ "soroban-wasmi", "static_assertions", "stellar-strkey", + "wasmparser", ] [[package]] name = "soroban-env-macros" -version = "20.1.0" +version = "22.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff774562cca63a173127b0b6679dce9afde49fd34474eec041dc5612134dda7" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" dependencies = [ "itertools", "proc-macro2", @@ -1063,14 +1167,14 @@ dependencies = [ "serde", "serde_json", "stellar-xdr", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] name = "soroban-ledger-snapshot" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4166fef4218b0a23d9ef58f48dc57cf56bf7fbe46d410e0f8672e8986b42b" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" dependencies = [ "serde", "serde_json", @@ -1082,15 +1186,17 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf12b257428a9ec762491e76f80f7d7a6fa3b7994adbbdc559c787f64fcebff5" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" dependencies = [ "arbitrary", "bytes-lit", "ctor", + "derive_arbitrary", "ed25519-dalek", "rand", + "rustc_version", "serde", "serde_json", "soroban-env-guest", @@ -1102,9 +1208,9 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e591efb1b5850fb5c95dcac9efcd65fa3168f041fe7204edd4ecf592f01f21" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" dependencies = [ "crate-git-revision", "darling", @@ -1117,14 +1223,14 @@ dependencies = [ "soroban-spec", "soroban-spec-rust", "stellar-xdr", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] name = "soroban-spec" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc6f22d7c303d8cb6e12d2dd04d4dfb38d773292f2721ea5ac15d3b0fd51c6c" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -1134,9 +1240,9 @@ dependencies = [ [[package]] name = "soroban-spec-rust" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffcc7e96ae13c3fdce8b132be2949784fc23d2234e9e591817e1b21ace9aa06" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" dependencies = [ "prettyplease", "proc-macro2", @@ -1144,7 +1250,7 @@ dependencies = [ "sha2", "soroban-spec", "stellar-xdr", - "syn 2.0.39", + "syn 2.0.104", "thiserror", ] @@ -1158,18 +1264,18 @@ dependencies = [ [[package]] name = "soroban-token-sdk" -version = "20.2.0" +version = "22.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a34c82ea70ff681aebeb3db80caf7f096160288c0c644d266e05a0fbabcc01" +checksum = "1b5d44abd4abb253c0714d28b3b5a9db6aaf9afa1684c3a23778e07a201c3adb" dependencies = [ "soroban-sdk", ] [[package]] name = "soroban-wasmi" -version = "0.31.1-soroban.20.0.0" +version = "0.31.1-soroban.20.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1aaa682a67cbd2173f1d60cb1e7b951d490d7c4e0b7b6f5387cbb952e963c46" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" dependencies = [ "smallvec", "spin", @@ -1202,20 +1308,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stellar-strkey" -version = "0.0.8" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" dependencies = [ - "base32", "crate-git-revision", + "data-encoding", "thiserror", ] [[package]] name = "stellar-xdr" -version = "20.0.2" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f00a85bd9b1617d4cb7e741733889c9940e6bdeca360db81752b0ef04fe3a5" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" dependencies = [ "arbitrary", "base64 0.13.1", @@ -1252,9 +1358,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1287,7 +1393,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.104", ] [[package]] @@ -1421,11 +1527,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.88.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8cf7dd82407fe68161bedcd57fde15596f32ebf6e9b3bdbf3ae1da20e38e5e" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.1.0", + "semver", ] [[package]] @@ -1534,8 +1641,42 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/contracts/token/Cargo.toml b/contracts/token/Cargo.toml index 8c2c4925..6e5fb91c 100644 --- a/contracts/token/Cargo.toml +++ b/contracts/token/Cargo.toml @@ -8,11 +8,11 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -soroban-sdk = { version = "20.2.0" } -soroban-token-sdk = { version = "20.2.0" } +soroban-sdk = { version = "22.0.8" } +soroban-token-sdk = { version = "22.0.8" } -[dev_dependencies] -soroban-sdk = { version = "20.2.0", features = ["testutils"] } +[dev-dependencies] +soroban-sdk = { version = "22.0.8", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/contracts/token/Makefile b/contracts/token/Makefile index fec387b1..8d7951e1 100644 --- a/contracts/token/Makefile +++ b/contracts/token/Makefile @@ -6,9 +6,9 @@ test: build cargo test build: - soroban contract build - @ls -l target/wasm32-unknown-unknown/release/*.wasm - soroban contract optimize --wasm target/wasm32-unknown-unknown/release/soroban_token_contract.wasm + stellar contract build + @ls -l target/wasm32v1-none/release/*.wasm + stellar contract optimize --wasm target/wasm32v1-none/release/soroban_token_contract.wasm fmt: diff --git a/scripts/initialize_scripts/initialize.sh b/scripts/initialize_scripts/initialize.sh index 6fa5766b..bbcf8ead 100755 --- a/scripts/initialize_scripts/initialize.sh +++ b/scripts/initialize_scripts/initialize.sh @@ -85,8 +85,8 @@ echo -n "$TOKEN_0_ID" > .soroban/token_1_id echo Build the SoroswapPair and SoroswapFactory contract make build -FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm" -PAIR_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" +FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.wasm" +PAIR_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_pair.wasm" echo "--" echo "--" echo Install the Pair contract WASM diff --git a/scripts/initialize_scripts/initialize_factory.sh b/scripts/initialize_scripts/initialize_factory.sh index 778100ee..81b08e5c 100755 --- a/scripts/initialize_scripts/initialize_factory.sh +++ b/scripts/initialize_scripts/initialize_factory.sh @@ -70,7 +70,7 @@ mkdir -p .soroban echo "--" echo "--" -PAIR_WASM="/workspace/contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" +PAIR_WASM="/workspace/contracts/pair/target/wasm32v1-none/release/soroswap_pair.wasm" TOKEN_WASM="token/soroban_token_contract.wasm" #TOKEN_WASM="soroban_token_spec.wasm" @@ -172,8 +172,8 @@ echo Build the SoroswapPair and SoroswapFactory contract cd pair make build cd .. - FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm" - PAIR_WASM="/workspace/contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.wasm" + PAIR_WASM="/workspace/contracts/pair/target/wasm32v1-none/release/soroswap_pair.wasm" echo "--" echo "--" diff --git a/scripts/initialize_scripts/initialize_pair.sh b/scripts/initialize_scripts/initialize_pair.sh index 495f001d..4c16fcd7 100755 --- a/scripts/initialize_scripts/initialize_pair.sh +++ b/scripts/initialize_scripts/initialize_pair.sh @@ -168,8 +168,8 @@ cd .. cd /workspace/contracts/factory make build cd .. -PAIR_WASM="/workspace/contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" -FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm" +PAIR_WASM="/workspace/contracts/pair/target/wasm32v1-none/release/soroswap_pair.wasm" +FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.wasm" echo "--" echo "--" @@ -325,7 +325,7 @@ Calling: ARGS="--network $NETWORK --source token-admin" -PAIR_WASM="/workspace/contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" +PAIR_WASM="/workspace/contracts/pair/target/wasm32v1-none/release/soroswap_pair.wasm" PAIR_ID=$(cat /workspace/.soroban/pair_wasm_hash) TOKEN_ADMIN_ADDRESS=$(cat /workspace/.soroban/token_admin_address) USER_ADDRESS=$(cat /workspace/.soroban/user_address) diff --git a/scripts/initialize_scripts/interact_futurenet.sh b/scripts/initialize_scripts/interact_futurenet.sh index d39699cf..0766b065 100755 --- a/scripts/initialize_scripts/interact_futurenet.sh +++ b/scripts/initialize_scripts/interact_futurenet.sh @@ -142,8 +142,8 @@ echo -n "$TOKEN_B_ID" > .soroban/token_b_id echo Build the SoroswapPair and SoroswapFactory contract make build - FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm" - PAIR_WASM="/workspace/contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.wasm" + FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.wasm" + PAIR_WASM="/workspace/contracts/pair/target/wasm32v1-none/release/soroswap_pair.wasm" echo "--" echo "--" diff --git a/scripts/old_bash/add_liquidity.sh b/scripts/old_bash/add_liquidity.sh index db1fb8b4..39fe081e 100644 --- a/scripts/old_bash/add_liquidity.sh +++ b/scripts/old_bash/add_liquidity.sh @@ -6,7 +6,7 @@ echo "TOKEN_ADMIN_ADDRESS: $TOKEN_ADMIN_ADDRESS" ROUTER_CONTRACT="CCSP6PGXMA26QRCOCVPILATP2MTY75HGQDVEAB3CYCUAMKFGBIGCD5CQ" -ROUTER_WASM="/workspace/contracts/router/target/wasm32-unknown-unknown/release/soroswap_router.optimized.wasm" +ROUTER_WASM="/workspace/contracts/router/target/wasm32v1-none/release/soroswap_router.optimized.wasm" NETWORK="standalone" diff --git a/scripts/old_bash/check_how_many_pairs.sh b/scripts/old_bash/check_how_many_pairs.sh index 66f0cfc8..d68f1bca 100644 --- a/scripts/old_bash/check_how_many_pairs.sh +++ b/scripts/old_bash/check_how_many_pairs.sh @@ -27,7 +27,7 @@ fi ARGS="--network $NETWORK --source token-admin" # Define the path to the compiled Soroban Factory Contract WebAssembly (WASM) file -FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.wasm" +FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.wasm" # Extract the factory ID from the JSON file using 'jq' # The '.factory' syntax specifies the 'factory' key in the JSON file diff --git a/scripts/old_bash/create_pair.sh b/scripts/old_bash/create_pair.sh index 8c40658f..2c737860 100644 --- a/scripts/old_bash/create_pair.sh +++ b/scripts/old_bash/create_pair.sh @@ -12,7 +12,7 @@ TOKEN_B_ADDRESS="$(node /workspace/scripts/address_workaround.js $TOKEN_B_ID)" ARGS="--network $NETWORK --source token-admin" -FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.optimized.wasm" +FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm" # Extract FACTORY_ID from JSON file FACTORY_ID=$(jq -r --arg network "$NETWORK" '.[] | select(.network == $network) | .factory_id' /workspace/.soroban/factory.json) diff --git a/scripts/old_bash/create_token.sh b/scripts/old_bash/create_token.sh index ce0fce8d..81403232 100644 --- a/scripts/old_bash/create_token.sh +++ b/scripts/old_bash/create_token.sh @@ -22,7 +22,7 @@ echo "Compile token contract" cd /workspace/contracts/token make build cd /workspace/ -TOKEN_WASM="/workspace/contracts/token/target/wasm32-unknown-unknown/release/soroban_token_contract.optimized.wasm" +TOKEN_WASM="/workspace/contracts/token/target/wasm32v1-none/release/soroban_token_contract.optimized.wasm" echo Deploying token to network $NETWORK echo $NETWORK @@ -31,7 +31,7 @@ echo Will deploy the token now echo using WASM: $TOKEN_WASM TOKEN_A_ID="$( soroban contract deploy \ - --wasm /workspace/contracts/token/target/wasm32-unknown-unknown/release/soroban_token_contract.optimized.wasm \ + --wasm /workspace/contracts/token/target/wasm32v1-none/release/soroban_token_contract.optimized.wasm \ --source token-admin \ --network $NETWORK )" diff --git a/scripts/old_bash/deploy_initialize_factory.sh b/scripts/old_bash/deploy_initialize_factory.sh index f819a0ab..1ff2632d 100644 --- a/scripts/old_bash/deploy_initialize_factory.sh +++ b/scripts/old_bash/deploy_initialize_factory.sh @@ -64,8 +64,8 @@ echo "--" echo "--" # Define the paths to the compiled WASM files -FACTORY_WASM="/workspace/contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.optimized.wasm" -PAIR_WASM="/workspace/contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.optimized.wasm" +FACTORY_WASM="/workspace/contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm" +PAIR_WASM="/workspace/contracts/pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm" TOKEN_WASM="/workspace/contracts/token/soroban_token_contract.optimized.wasm" # Install the Pair contract WASM diff --git a/scripts/old_bash/deploy_initialize_router.sh b/scripts/old_bash/deploy_initialize_router.sh index ca6c0dd4..0c0e851d 100644 --- a/scripts/old_bash/deploy_initialize_router.sh +++ b/scripts/old_bash/deploy_initialize_router.sh @@ -55,7 +55,7 @@ echo "--" echo "--" # Define the paths to the compiled WASM files -ROUTER_WASM="/workspace/contracts/router/target/wasm32-unknown-unknown/release/soroswap_router.optimized.wasm" +ROUTER_WASM="/workspace/contracts/router/target/wasm32v1-none/release/soroswap_router.optimized.wasm" # Deploy the Router contract echo "Deploy the router contract" diff --git a/scripts/old_bash/deploy_random_tokens.sh b/scripts/old_bash/deploy_random_tokens.sh index cfb18146..7f2a3987 100644 --- a/scripts/old_bash/deploy_random_tokens.sh +++ b/scripts/old_bash/deploy_random_tokens.sh @@ -64,7 +64,7 @@ do # Extract the first 4 letters of the name for the shorter version and uppercase SYMBOL=$(echo ${NAME:0:4} | tr '[:lower:]' '[:upper:]') - TOKEN_WASM="/workspace/contracts/token/target/wasm32-unknown-unknown/release/soroban_token_contract.optimized.wasm" + TOKEN_WASM="/workspace/contracts/token/target/wasm32v1-none/release/soroban_token_contract.optimized.wasm" TOKEN_ID="$( soroban contract deploy --network $NETWORK --source token-admin \ diff --git a/utils/contract.ts b/utils/contract.ts index 04e0b75d..5211bb66 100644 --- a/utils/contract.ts +++ b/utils/contract.ts @@ -10,11 +10,11 @@ import { createTxBuilder, invoke, invokeTransaction } from './tx.js'; // Relative paths from __dirname const CONTRACT_REL_PATH: object = { - pair: '../../contracts/pair/target/wasm32-unknown-unknown/release/soroswap_pair.optimized.wasm', + pair: '../../contracts/pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm', factory: - '../../contracts/factory/target/wasm32-unknown-unknown/release/soroswap_factory.optimized.wasm', - router: '../../contracts/router/target/wasm32-unknown-unknown/release/soroswap_router.optimized.wasm', - token: '../../contracts/token/target/wasm32-unknown-unknown/release/soroban_token_contract.optimized.wasm', + '../../contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm', + router: '../../contracts/router/target/wasm32v1-none/release/soroswap_router.optimized.wasm', + token: '../../contracts/token/target/wasm32v1-none/release/soroban_token_contract.optimized.wasm', }; const network = process.argv[2]; From b643775d3c4da3d009299f5d4507037743cd3f4b Mon Sep 17 00:00:00 2001 From: kalepail Date: Mon, 4 Aug 2025 10:39:54 -0400 Subject: [PATCH 2/4] fixed event testing error and fmt --- contracts/factory-interface/src/error.rs | 1 - contracts/factory-interface/src/lib.rs | 29 +- contracts/factory/src/event.rs | 68 +- contracts/factory/src/lib.rs | 489 +++++++------ contracts/factory/src/pair.rs | 7 +- contracts/factory/src/storage.rs | 81 +-- contracts/factory/src/test.rs | 66 +- contracts/factory/src/test/deterministic.rs | 181 +++-- contracts/factory/src/test/events.rs | 67 +- contracts/factory/src/test/fee_to_setter.rs | 198 +++-- contracts/factory/src/test/initialize.rs | 82 +-- contracts/factory/src/test/pairs.rs | 86 ++- contracts/library/src/error.rs | 4 +- contracts/library/src/lib.rs | 170 +++-- contracts/library/src/math.rs | 2 +- contracts/library/src/quotes.rs | 85 ++- contracts/library/src/reserves.rs | 53 +- contracts/library/src/test.rs | 34 +- contracts/library/src/test/get.rs | 137 ++-- contracts/library/src/test/quote.rs | 6 +- contracts/library/src/test/tokens.rs | 52 +- contracts/library/src/tokens.rs | 17 +- contracts/pair/src/balances.rs | 7 +- contracts/pair/src/error.rs | 3 - contracts/pair/src/event.rs | 30 +- contracts/pair/src/lib.rs | 190 +++-- contracts/pair/src/math.rs | 2 +- .../pair/src/soroswap_pair_token/allowance.rs | 1 - .../pair/src/soroswap_pair_token/balance.rs | 7 +- .../pair/src/soroswap_pair_token/contract.rs | 28 +- .../pair/src/soroswap_pair_token/metadata.rs | 2 +- contracts/pair/src/soroswap_pair_token/mod.rs | 4 +- .../src/soroswap_pair_token/storage_types.rs | 4 +- .../src/soroswap_pair_token/total_supply.rs | 10 +- contracts/pair/src/storage.rs | 59 +- contracts/pair/src/strings.rs | 5 +- contracts/pair/src/test.rs | 49 +- contracts/pair/src/test/deposit.rs | 113 ++- contracts/pair/src/test/events.rs | 147 ++-- contracts/pair/src/test/fee.rs | 354 ++++++--- contracts/pair/src/test/initialize.rs | 60 +- contracts/pair/src/test/skim.rs | 72 +- .../pair/src/test/soroswap_pair_token.rs | 37 +- contracts/pair/src/test/swap.rs | 240 ++++-- contracts/pair/src/test/sync.rs | 87 ++- contracts/pair/src/test/withdraw.rs | 56 +- contracts/router/src/error.rs | 51 +- contracts/router/src/event.rs | 67 +- contracts/router/src/factory.rs | 2 +- contracts/router/src/lib.rs | 218 +++--- contracts/router/src/pair.rs | 6 +- contracts/router/src/storage.rs | 2 +- contracts/router/src/test.rs | 52 +- contracts/router/src/test/add_liquidity.rs | 421 ++++++----- contracts/router/src/test/budget.rs | 65 +- contracts/router/src/test/events.rs | 101 +-- contracts/router/src/test/initialize.rs | 4 +- .../router/src/test/library_functions.rs | 94 ++- contracts/router/src/test/remove_liquidity.rs | 683 ++++++++++-------- .../src/test/swap_exact_tokens_for_tokens.rs | 179 +++-- .../src/test/swap_tokens_for_exact_tokens.rs | 258 ++++--- 61 files changed, 3300 insertions(+), 2385 deletions(-) diff --git a/contracts/factory-interface/src/error.rs b/contracts/factory-interface/src/error.rs index ab2dbbff..067dbd66 100644 --- a/contracts/factory-interface/src/error.rs +++ b/contracts/factory-interface/src/error.rs @@ -21,4 +21,3 @@ pub enum FactoryError { /// SoroswapFactory: index does not exist IndexDoesNotExist = 206, } - diff --git a/contracts/factory-interface/src/lib.rs b/contracts/factory-interface/src/lib.rs index 9f361acc..4fbac2e1 100644 --- a/contracts/factory-interface/src/lib.rs +++ b/contracts/factory-interface/src/lib.rs @@ -1,7 +1,7 @@ #![deny(warnings)] #![no_std] -use soroban_sdk::{contractclient, contractspecfn, Address, Env, BytesN}; +use soroban_sdk::{contractclient, contractspecfn, Address, BytesN, Env}; pub struct Spec; mod error; @@ -13,7 +13,6 @@ pub use error::FactoryError; /// Trait defining the interface for a Soroswap Factory contract. pub trait SoroswapFactoryTrait { - /* *** Read-only functions: *** */ /// Returns the recipient of the fee. @@ -40,42 +39,42 @@ pub trait SoroswapFactoryTrait { /* *** State-Changing Functions: *** */ /// Sets the `fee_to_setter` address and initializes the factory. - /// + /// /// # Arguments - /// + /// /// * `e` - An instance of the `Env` struct. /// * `setter` - The address to set as the `fee_to_setter`. /// * `pair_wasm_hash` - The Wasm hash of the SoroswapPair contract. fn initialize(e: Env, setter: Address, pair_wasm_hash: BytesN<32>) -> Result<(), FactoryError>; /// Sets the `fee_to` address. - /// + /// /// # Arguments - /// + /// /// * `e` - An instance of the `Env` struct. /// * `to` - The address to set as the `fee_to`. - fn set_fee_to(e: Env, to: Address)-> Result<(), FactoryError>; + fn set_fee_to(e: Env, to: Address) -> Result<(), FactoryError>; /// Sets the `fee_to_setter` address. - /// + /// /// # Arguments - /// + /// /// * `e` - An instance of the `Env` struct. /// * `new_setter` - The address to set as the new `fee_to_setter`. - fn set_fee_to_setter(e: Env, new_setter: Address)-> Result<(), FactoryError>; + fn set_fee_to_setter(e: Env, new_setter: Address) -> Result<(), FactoryError>; /// Sets whether fees are enabled or disabled. - /// + /// /// # Arguments - /// + /// /// * `e` - An instance of the `Env` struct. /// * `is_enabled` - A boolean indicating whether fees are enabled or disabled. - fn set_fees_enabled(e: Env, is_enabled: bool)-> Result<(), FactoryError>; + fn set_fees_enabled(e: Env, is_enabled: bool) -> Result<(), FactoryError>; /// Creates a pair for `token_a` and `token_b` if one doesn't exist already. - /// + /// /// # Arguments - /// + /// /// * `e` - An instance of the `Env` struct. /// * `token_a` - The address of the first token in the pair. /// * `token_b` - The address of the second token in the pair. diff --git a/contracts/factory/src/event.rs b/contracts/factory/src/event.rs index e77bed1c..ec6e5cdd 100644 --- a/contracts/factory/src/event.rs +++ b/contracts/factory/src/event.rs @@ -1,19 +1,17 @@ //! Definition of the Events used in the contract -use soroban_sdk::{contracttype, symbol_short, Env, Address}; +use soroban_sdk::{contracttype, symbol_short, Address, Env}; // INITIALIZED #[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct InitializedEvent { - pub setter: Address + pub setter: Address, } pub(crate) fn initialized(e: &Env, setter: Address) { - - let event: InitializedEvent = InitializedEvent { - setter: setter - }; - e.events().publish(("SoroswapFactory", symbol_short!("init")), event); + let event: InitializedEvent = InitializedEvent { setter: setter }; + e.events() + .publish(("SoroswapFactory", symbol_short!("init")), event); } // NEW PAIR CREATED EVENT: new_pair @@ -23,86 +21,70 @@ pub struct NewPairEvent { pub token_0: Address, pub token_1: Address, pub pair: Address, - pub new_pairs_length: u32 + pub new_pairs_length: u32, } pub(crate) fn new_pair( - e: &Env, + e: &Env, token_0: Address, token_1: Address, pair: Address, - new_pairs_length: u32) { - + new_pairs_length: u32, +) { let event: NewPairEvent = NewPairEvent { token_0: token_0, token_1: token_1, pair: pair, new_pairs_length: new_pairs_length, }; - e.events().publish(("SoroswapFactory", symbol_short!("new_pair")), event); + e.events() + .publish(("SoroswapFactory", symbol_short!("new_pair")), event); } - - // NEW "FEE TO" SETTED: new_fee_to // Event is "fee_to" #[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct FeeToSettedEvent { pub setter: Address, pub old: Address, - pub new: Address + pub new: Address, } -pub(crate) fn new_fee_to( - e: &Env, - setter: Address, - old: Address, - new: Address) { - +pub(crate) fn new_fee_to(e: &Env, setter: Address, old: Address, new: Address) { let event: FeeToSettedEvent = FeeToSettedEvent { setter: setter, old: old, - new: new + new: new, }; - e.events().publish(("SoroswapFactory", symbol_short!("fee_to")), event); + e.events() + .publish(("SoroswapFactory", symbol_short!("fee_to")), event); } - // NEW "SETTER" #[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct NewSetterEvent { pub old: Address, - pub new: Address + pub new: Address, } -pub(crate) fn new_setter( - e: &Env, - old: Address, - new: Address) { - - let event: NewSetterEvent = NewSetterEvent { - old: old, - new: new - }; - e.events().publish(("SoroswapFactory", symbol_short!("setter")), event); +pub(crate) fn new_setter(e: &Env, old: Address, new: Address) { + let event: NewSetterEvent = NewSetterEvent { old: old, new: new }; + e.events() + .publish(("SoroswapFactory", symbol_short!("setter")), event); } - - // NEW "FEES ENABLED" BOOL #[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct NewFeesEnabledEvent { - pub fees_enabled: bool + pub fees_enabled: bool, } -pub(crate) fn new_fees_enabled( - e: &Env, - fees_enabled: bool) { - +pub(crate) fn new_fees_enabled(e: &Env, fees_enabled: bool) { let event: NewFeesEnabledEvent = NewFeesEnabledEvent { fees_enabled: fees_enabled, }; - e.events().publish(("SoroswapFactory", symbol_short!("fees")), event); + e.events() + .publish(("SoroswapFactory", symbol_short!("fees")), event); } diff --git a/contracts/factory/src/lib.rs b/contracts/factory/src/lib.rs index 635c1a89..d6b918e0 100644 --- a/contracts/factory/src/lib.rs +++ b/contracts/factory/src/lib.rs @@ -2,16 +2,12 @@ mod event; mod pair; -mod test; mod storage; +mod test; -use soroban_sdk::{ - contract, - contractimpl, - Address, BytesN, Env, -}; -use soroswap_factory_interface::{SoroswapFactoryTrait, FactoryError}; use pair::{create_contract, Pair, PairError}; +use soroban_sdk::{contract, contractimpl, Address, BytesN, Env}; +use soroswap_factory_interface::{FactoryError, SoroswapFactoryTrait}; use storage::*; impl From for FactoryError { @@ -23,283 +19,284 @@ impl From for FactoryError { } } - #[contract] struct SoroswapFactory; #[contractimpl] impl SoroswapFactoryTrait for SoroswapFactory { - -/* *** Read-only functions: *** */ - -/// Returns the recipient of the fee. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized. -fn fee_to(e: Env) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); - } - extend_instance_ttl(&e); - Ok(get_fee_to(&e)) -} - -/// Returns the address allowed to change the fee recipient. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized. -fn fee_to_setter(e: Env) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /* *** Read-only functions: *** */ + + /// Returns the recipient of the fee. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized. + fn fee_to(e: Env) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + Ok(get_fee_to(&e)) } - extend_instance_ttl(&e); - Ok(get_fee_to_setter(&e)) -} -/// Checks if fees are enabled. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized. -fn fees_enabled(e: Env) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /// Returns the address allowed to change the fee recipient. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized. + fn fee_to_setter(e: Env) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + Ok(get_fee_to_setter(&e)) } - extend_instance_ttl(&e); - Ok(get_fees_enabled(&e)) -} -/// Returns the total number of pairs created through the factory so far. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized. -fn all_pairs_length(e: Env) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /// Checks if fees are enabled. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized. + fn fees_enabled(e: Env) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + Ok(get_fees_enabled(&e)) } - extend_instance_ttl(&e); - Ok(get_total_pairs(&e)) -} -/// Returns the address of the pair for `token_a` and `token_b`, if it has been created. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `token_a` - The address of the first token in the pair. -/// * `token_b` - The address of the second token in the pair. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized or if the pair does not exist -fn get_pair(e: Env, token_a: Address, token_b: Address) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /// Returns the total number of pairs created through the factory so far. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized. + fn all_pairs_length(e: Env) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + Ok(get_total_pairs(&e)) } - extend_instance_ttl(&e); - let token_pair = Pair::new(token_a, token_b)?; - get_pair_address_by_token_pair(&e, token_pair) -} -/// Returns the address of the nth pair (0-indexed) created through the factory, or address(0) if not enough pairs have been created yet. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `n` - The index of the pair to retrieve. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized or if index `n` does not exist. -fn all_pairs(e: Env, n: u32) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /// Returns the address of the pair for `token_a` and `token_b`, if it has been created. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `token_a` - The address of the first token in the pair. + /// * `token_b` - The address of the second token in the pair. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized or if the pair does not exist + fn get_pair(e: Env, token_a: Address, token_b: Address) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + let token_pair = Pair::new(token_a, token_b)?; + get_pair_address_by_token_pair(&e, token_pair) } - extend_instance_ttl(&e); - get_all_pairs(e,n) -} -/// Checks if a pair exists for the given `token_a` and `token_b`. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `token_a` - The address of the first token in the pair. -/// * `token_b` - The address of the second token in the pair. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized. -fn pair_exists(e: Env, token_a: Address, token_b: Address) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /// Returns the address of the nth pair (0-indexed) created through the factory, or address(0) if not enough pairs have been created yet. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `n` - The index of the pair to retrieve. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized or if index `n` does not exist. + fn all_pairs(e: Env, n: u32) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + get_all_pairs(e, n) } - extend_instance_ttl(&e); - let token_pair = Pair::new(token_a, token_b)?; - - // Proceed with the existence check - Ok(get_pair_exists(&e, token_pair)) -} + /// Checks if a pair exists for the given `token_a` and `token_b`. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `token_a` - The address of the first token in the pair. + /// * `token_b` - The address of the second token in the pair. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized. + fn pair_exists(e: Env, token_a: Address, token_b: Address) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } + extend_instance_ttl(&e); + let token_pair = Pair::new(token_a, token_b)?; -/* *** State-Changing Functions: *** */ - -/// Sets the `fee_to_setter` address and initializes the factory. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `setter` - The address to set as the current `fee_to_setter`. -/// * `pair_wasm_hash` - The Wasm hash of the pair. -/// -/// # Errors -/// -/// Returns an error if the Factory is already initialized. -fn initialize(e: Env, setter: Address, pair_wasm_hash: BytesN<32>) -> Result<(), FactoryError> { - if has_total_pairs(&e) { - return Err(FactoryError::InitializeAlreadyInitialized); + // Proceed with the existence check + Ok(get_pair_exists(&e, token_pair)) } - put_fee_to_setter(&e, &setter); - put_fee_to(&e, setter.clone()); - put_pair_wasm_hash(&e, pair_wasm_hash); - put_total_pairs(&e, 0); - event::initialized(&e, setter); - extend_instance_ttl(&e); - Ok(()) -} -/// Sets the `fee_to` address. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `to` - The address to set as the `fee_to`. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized or if the caller is not the current `fee_to_setter`. -fn set_fee_to(e: Env, to: Address) -> Result<(), FactoryError> { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); - } - - extend_instance_ttl(&e); - let setter = get_fee_to_setter(&e); - setter.require_auth(); - - let old = get_fee_to(&e); - put_fee_to(&e, to.clone()); - event::new_fee_to(&e, setter, old, to); - Ok(()) -} - -/// Sets the `fee_to_setter` address. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `new_setter` - The address to set as the new `fee_to_setter`. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized or if the caller is not the existing `fee_to_setter`. -fn set_fee_to_setter(e: Env, new_setter: Address) -> Result<(), FactoryError> { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + /* *** State-Changing Functions: *** */ + + /// Sets the `fee_to_setter` address and initializes the factory. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `setter` - The address to set as the current `fee_to_setter`. + /// * `pair_wasm_hash` - The Wasm hash of the pair. + /// + /// # Errors + /// + /// Returns an error if the Factory is already initialized. + fn initialize(e: Env, setter: Address, pair_wasm_hash: BytesN<32>) -> Result<(), FactoryError> { + if has_total_pairs(&e) { + return Err(FactoryError::InitializeAlreadyInitialized); + } + put_fee_to_setter(&e, &setter); + put_fee_to(&e, setter.clone()); + put_pair_wasm_hash(&e, pair_wasm_hash); + put_total_pairs(&e, 0); + event::initialized(&e, setter); + extend_instance_ttl(&e); + Ok(()) } - extend_instance_ttl(&e); - let setter = get_fee_to_setter(&e); - setter.require_auth(); + /// Sets the `fee_to` address. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `to` - The address to set as the `fee_to`. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized or if the caller is not the current `fee_to_setter`. + fn set_fee_to(e: Env, to: Address) -> Result<(), FactoryError> { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } - put_fee_to_setter(&e, &new_setter); - event::new_setter(&e, setter, new_setter); - Ok(()) -} + extend_instance_ttl(&e); + let setter = get_fee_to_setter(&e); + setter.require_auth(); -/// Sets whether fees are enabled or disabled. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `is_enabled` - A boolean indicating whether fees are enabled or disabled. -/// -/// # Errors -/// -/// Returns an error if the Factory is not yet initialized or if the caller is not the current `fee_to_setter`. -fn set_fees_enabled(e: Env, is_enabled: bool) -> Result<(), FactoryError> { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + let old = get_fee_to(&e); + put_fee_to(&e, to.clone()); + event::new_fee_to(&e, setter, old, to); + Ok(()) } - extend_instance_ttl(&e); - let setter = get_fee_to_setter(&e); - setter.require_auth(); + /// Sets the `fee_to_setter` address. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `new_setter` - The address to set as the new `fee_to_setter`. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized or if the caller is not the existing `fee_to_setter`. + fn set_fee_to_setter(e: Env, new_setter: Address) -> Result<(), FactoryError> { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } - put_fees_enabled(&e, &is_enabled); - event::new_fees_enabled(&e, is_enabled); - Ok(()) -} + extend_instance_ttl(&e); + let setter = get_fee_to_setter(&e); + setter.require_auth(); -/// Creates a pair for `token_a` and `token_b` if one doesn't exist already. -/// -/// # Arguments -/// -/// * `e` - An instance of the `Env` struct. -/// * `token_a` - The address of the first token in the pair. -/// * `token_b` - The address of the second token in the pair. -/// -/// # Errors -/// -/// Returns an error if the pair is not yet initialized, if `token_a` and `token_b` have identical addresses, or if the pair already exists between `token_a` and `token_b`. -fn create_pair(e: Env, token_a: Address, token_b: Address) -> Result { - if !has_total_pairs(&e) { - return Err(FactoryError::NotInitialized); + put_fee_to_setter(&e, &new_setter); + event::new_setter(&e, setter, new_setter); + Ok(()) } - extend_instance_ttl(&e); - let token_pair = Pair::new(token_a, token_b)?; + /// Sets whether fees are enabled or disabled. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `is_enabled` - A boolean indicating whether fees are enabled or disabled. + /// + /// # Errors + /// + /// Returns an error if the Factory is not yet initialized or if the caller is not the current `fee_to_setter`. + fn set_fees_enabled(e: Env, is_enabled: bool) -> Result<(), FactoryError> { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } - if get_pair_exists(&e, token_pair.clone()) { - return Err(FactoryError::CreatePairAlreadyExists); + extend_instance_ttl(&e); + let setter = get_fee_to_setter(&e); + setter.require_auth(); + + put_fees_enabled(&e, &is_enabled); + event::new_fees_enabled(&e, is_enabled); + Ok(()) } - let pair_wasm_hash = get_pair_wasm_hash(&e)?; - let pair_address = create_contract(&e, pair_wasm_hash, &token_pair); + /// Creates a pair for `token_a` and `token_b` if one doesn't exist already. + /// + /// # Arguments + /// + /// * `e` - An instance of the `Env` struct. + /// * `token_a` - The address of the first token in the pair. + /// * `token_b` - The address of the second token in the pair. + /// + /// # Errors + /// + /// Returns an error if the pair is not yet initialized, if `token_a` and `token_b` have identical addresses, or if the pair already exists between `token_a` and `token_b`. + fn create_pair(e: Env, token_a: Address, token_b: Address) -> Result { + if !has_total_pairs(&e) { + return Err(FactoryError::NotInitialized); + } - pair::Client::new(&e, &pair_address).initialize( - &e.current_contract_address(), - &token_pair.token_0(), - &token_pair.token_1() - ); + extend_instance_ttl(&e); + let token_pair = Pair::new(token_a, token_b)?; - put_pair_address_by_token_pair(&e, token_pair.clone(), &pair_address); - add_pair_to_all_pairs(&e, &pair_address); + if get_pair_exists(&e, token_pair.clone()) { + return Err(FactoryError::CreatePairAlreadyExists); + } - event::new_pair(&e, token_pair.token_0().clone(), token_pair.token_1().clone(), pair_address.clone(), get_total_pairs(&e)); + let pair_wasm_hash = get_pair_wasm_hash(&e)?; + let pair_address = create_contract(&e, pair_wasm_hash, &token_pair); - Ok(pair_address) -} + pair::Client::new(&e, &pair_address).initialize( + &e.current_contract_address(), + &token_pair.token_0(), + &token_pair.token_1(), + ); + put_pair_address_by_token_pair(&e, token_pair.clone(), &pair_address); + add_pair_to_all_pairs(&e, &pair_address); + event::new_pair( + &e, + token_pair.token_0().clone(), + token_pair.token_1().clone(), + pair_address.clone(), + get_total_pairs(&e), + ); + + Ok(pair_address) + } } diff --git a/contracts/factory/src/pair.rs b/contracts/factory/src/pair.rs index a58fddcc..b9544443 100644 --- a/contracts/factory/src/pair.rs +++ b/contracts/factory/src/pair.rs @@ -1,10 +1,8 @@ // Import necessary types from the Soroban SDK #![allow(unused)] -use soroban_sdk::{contracttype, contracterror, xdr::ToXdr, Address, Bytes, BytesN, Env}; +use soroban_sdk::{contracterror, contracttype, xdr::ToXdr, Address, Bytes, BytesN, Env}; -soroban_sdk::contractimport!( - file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" -); +soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); #[contracterror] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] @@ -14,7 +12,6 @@ pub enum PairError { CreatePairIdenticalTokens = 901, } - #[contracttype] #[derive(Clone)] pub struct Pair(Address, Address); diff --git a/contracts/factory/src/storage.rs b/contracts/factory/src/storage.rs index 4dac46f7..17444d60 100644 --- a/contracts/factory/src/storage.rs +++ b/contracts/factory/src/storage.rs @@ -1,24 +1,19 @@ -use soroban_sdk::{ - contracttype, Address, BytesN, Env, Val, TryFromVal -}; -use soroswap_factory_interface::{FactoryError}; -use crate::pair::{Pair}; - - +use crate::pair::Pair; +use soroban_sdk::{contracttype, Address, BytesN, Env, TryFromVal, Val}; +use soroswap_factory_interface::FactoryError; #[derive(Clone)] #[contracttype] pub enum DataKey { - FeeTo, // Address. Instance storage - FeeToSetter, // Address. Instance storage - PairWasmHash, // BytesN<32>. Persistent storage - FeesEnabled, // Bool. Instance storage - TotalPairs, // Total pairs created by the Factory. u32, Instance storage + FeeTo, // Address. Instance storage + FeeToSetter, // Address. Instance storage + PairWasmHash, // BytesN<32>. Persistent storage + FeesEnabled, // Bool. Instance storage + TotalPairs, // Total pairs created by the Factory. u32, Instance storage PairAddressesNIndexed(u32), // Addresses of pairs created by the Factory. Persistent Storage - PairAddressesByTokens(Pair) + PairAddressesByTokens(Pair), } - const DAY_IN_LEDGERS: u32 = 17280; const INSTANCE_BUMP_AMOUNT: u32 = 30 * DAY_IN_LEDGERS; const INSTANCE_LIFETIME_THRESHOLD: u32 = INSTANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; @@ -36,12 +31,14 @@ pub fn extend_instance_ttl(e: &Env) { fn get_persistent_extend_or_error>( e: &Env, key: &DataKey, - error: FactoryError + error: FactoryError, ) -> Result { if let Some(result) = e.storage().persistent().get(key) { - e.storage() - .persistent() - .extend_ttl(key, PERSISTENT_LIFETIME_THRESHOLD, PERSISTENT_BUMP_AMOUNT); + e.storage().persistent().extend_ttl( + key, + PERSISTENT_LIFETIME_THRESHOLD, + PERSISTENT_BUMP_AMOUNT, + ); result } else { return Err(error); @@ -55,20 +52,20 @@ pub fn put_total_pairs(e: &Env, n: u32) { e.storage().instance().set(&DataKey::TotalPairs, &n); } pub fn get_total_pairs(e: &Env) -> u32 { - e.storage().instance().get(&DataKey::TotalPairs).unwrap_or(0) + e.storage() + .instance() + .get(&DataKey::TotalPairs) + .unwrap_or(0) } // Helper function in order to know if the contract has been initialized or not pub fn has_total_pairs(e: &Env) -> bool { e.storage().instance().has(&DataKey::TotalPairs) } - // PairAddressesByTokens(Address, Address) pub fn put_pair_address_by_token_pair(e: &Env, token_pair: Pair, pair_address: &Address) { - let key = DataKey::PairAddressesByTokens(token_pair); - e.storage() - .persistent() - .set(&key, &pair_address); + let key = DataKey::PairAddressesByTokens(token_pair); + e.storage().persistent().set(&key, &pair_address); e.storage() .persistent() .extend_ttl(&key, PERSISTENT_LIFETIME_THRESHOLD, PERSISTENT_BUMP_AMOUNT) @@ -79,24 +76,23 @@ pub fn get_pair_address_by_token_pair(e: &Env, token_pair: Pair) -> Result bool { - let key:DataKey = DataKey::PairAddressesByTokens(token_pair); + let key: DataKey = DataKey::PairAddressesByTokens(token_pair); if e.storage().persistent().has(&key) { - e.storage() - .persistent() - .extend_ttl(&key, PERSISTENT_LIFETIME_THRESHOLD, PERSISTENT_BUMP_AMOUNT); + e.storage().persistent().extend_ttl( + &key, + PERSISTENT_LIFETIME_THRESHOLD, + PERSISTENT_BUMP_AMOUNT, + ); true } else { false } - } - pub fn get_fee_to(e: &Env) -> Address { e.storage().instance().get(&DataKey::FeeTo).unwrap() } - pub fn get_fees_enabled(e: &Env) -> bool { let key = DataKey::FeesEnabled; if let Some(state) = e.storage().instance().get(&key) { @@ -110,8 +106,7 @@ pub fn get_fee_to_setter(e: &Env) -> Address { e.storage().instance().get(&DataKey::FeeToSetter).unwrap() } - -pub fn get_pair_wasm_hash(e: &Env) -> Result, FactoryError>{ +pub fn get_pair_wasm_hash(e: &Env) -> Result, FactoryError> { let key = DataKey::PairWasmHash; get_persistent_extend_or_error(&e, &key, FactoryError::NotInitialized) } @@ -125,15 +120,17 @@ pub fn put_fee_to_setter(e: &Env, setter: &Address) { } pub fn put_fees_enabled(e: &Env, is_enabled: &bool) { - e.storage().instance().set(&DataKey::FeesEnabled, is_enabled); + e.storage() + .instance() + .set(&DataKey::FeesEnabled, is_enabled); } pub fn put_pair_wasm_hash(e: &Env, pair_wasm_hash: BytesN<32>) { let key = DataKey::PairWasmHash; e.storage().persistent().set(&key, &pair_wasm_hash); e.storage() - .persistent() - .extend_ttl(&key, PERSISTENT_LIFETIME_THRESHOLD, PERSISTENT_BUMP_AMOUNT) + .persistent() + .extend_ttl(&key, PERSISTENT_LIFETIME_THRESHOLD, PERSISTENT_BUMP_AMOUNT) } pub fn add_pair_to_all_pairs(e: &Env, pair_address: &Address) { @@ -143,10 +140,12 @@ pub fn add_pair_to_all_pairs(e: &Env, pair_address: &Address) { let key = DataKey::PairAddressesNIndexed(total_pairs); e.storage().persistent().set(&key, &pair_address); - - e.storage() - .persistent() - .extend_ttl(&key, PERSISTENT_LIFETIME_THRESHOLD, PERSISTENT_BUMP_AMOUNT); + + e.storage().persistent().extend_ttl( + &key, + PERSISTENT_LIFETIME_THRESHOLD, + PERSISTENT_BUMP_AMOUNT, + ); total_pairs = total_pairs.checked_add(1).unwrap(); put_total_pairs(&e, total_pairs); @@ -155,4 +154,4 @@ pub fn add_pair_to_all_pairs(e: &Env, pair_address: &Address) { pub fn get_all_pairs(e: Env, n: u32) -> Result { let key = DataKey::PairAddressesNIndexed(n); get_persistent_extend_or_error(&e, &key, FactoryError::IndexDoesNotExist) -} \ No newline at end of file +} diff --git a/contracts/factory/src/test.rs b/contracts/factory/src/test.rs index adeebc88..b4f45594 100644 --- a/contracts/factory/src/test.rs +++ b/contracts/factory/src/test.rs @@ -1,15 +1,13 @@ #![cfg(test)] extern crate std; -use soroban_sdk::{testutils::{Address as _}, - Address, - BytesN, - Env, - String}; -use crate::{SoroswapFactoryClient}; +use crate::SoroswapFactoryClient; +use soroban_sdk::{testutils::Address as _, Address, BytesN, Env, String}; // **** TOKEN CONTRACT **** mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!( + file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm" + ); pub type TokenClient<'a> = Client<'a>; } use token::TokenClient; @@ -24,9 +22,7 @@ fn create_token_contract<'a>(e: &Env) -> TokenClient<'a> { // **** PAIR WASM **** fn pair_token_wasm(e: &Env) -> BytesN<32> { - soroban_sdk::contractimport!( - file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" - ); + soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); e.deployer().upload_contract_wasm(WASM) } @@ -37,14 +33,13 @@ mod pair { } use pair::SoroswapPairClient; - -// **** FACTORY CONTRACT (TO BE TESTED) **** -fn create_factory_contract<'a>(e: & Env) -> SoroswapFactoryClient<'a> { - let factory = SoroswapFactoryClient::new(e, &e.register_contract(None, crate::SoroswapFactory {})); +// **** FACTORY CONTRACT (TO BE TESTED) **** +fn create_factory_contract<'a>(e: &Env) -> SoroswapFactoryClient<'a> { + let factory = + SoroswapFactoryClient::new(e, &e.register_contract(None, crate::SoroswapFactory {})); factory } - // THE TEST pub struct SoroswapFactoryTest<'a> { env: Env, @@ -60,7 +55,6 @@ pub struct SoroswapFactoryTest<'a> { impl<'a> SoroswapFactoryTest<'a> { fn setup() -> Self { - let env = Env::default(); env.mock_all_auths(); let admin = Address::generate(&env); @@ -77,18 +71,36 @@ impl<'a> SoroswapFactoryTest<'a> { std::mem::swap(&mut token_2, &mut token_3); } - token_0.initialize(&admin, &7, &String::from_str(&env, "Token 0"), &String::from_str(&env, "TOKEN0")); - token_1.initialize(&admin, &7, &String::from_str(&env, "Token 1"), &String::from_str(&env, "TOKEN1")); - token_2.initialize(&admin, &7, &String::from_str(&env, "Token 2"), &String::from_str(&env, "TOKEN2")); - token_3.initialize(&admin, &7, &String::from_str(&env, "Token 3"), &String::from_str(&env, "TOKEN3")); - - - let pair_wasm = pair_token_wasm(&env); + token_0.initialize( + &admin, + &7, + &String::from_str(&env, "Token 0"), + &String::from_str(&env, "TOKEN0"), + ); + token_1.initialize( + &admin, + &7, + &String::from_str(&env, "Token 1"), + &String::from_str(&env, "TOKEN1"), + ); + token_2.initialize( + &admin, + &7, + &String::from_str(&env, "Token 2"), + &String::from_str(&env, "TOKEN2"), + ); + token_3.initialize( + &admin, + &7, + &String::from_str(&env, "Token 3"), + &String::from_str(&env, "TOKEN3"), + ); + + let pair_wasm = pair_token_wasm(&env); let contract = create_factory_contract(&env); // TODO: Get rid of this hack? env.budget().reset_unlimited(); - SoroswapFactoryTest { env, @@ -104,9 +116,9 @@ impl<'a> SoroswapFactoryTest<'a> { } } -mod initialize; +mod events; mod fee_to_setter; +mod initialize; mod pairs; -mod events; -pub mod deterministic; \ No newline at end of file +pub mod deterministic; diff --git a/contracts/factory/src/test/deterministic.rs b/contracts/factory/src/test/deterministic.rs index be92a095..18d687c3 100644 --- a/contracts/factory/src/test/deterministic.rs +++ b/contracts/factory/src/test/deterministic.rs @@ -1,45 +1,36 @@ +use core::mem; use soroban_sdk::{ - Env, - Address, - testutils::{ - Address as _, - AuthorizedFunction, - AuthorizedInvocation, - MockAuth, - MockAuthInvoke, - }, - IntoVal, - Symbol, + testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, MockAuth, MockAuthInvoke}, xdr::{ - ToXdr, - ScAddress, - ScVal, + AccountId, // ScObject, PublicKey, - AccountId, - Uint256 + ScAddress, + ScVal, + ToXdr, + Uint256, }, - Bytes, - TryFromVal, + Address, Bytes, Env, IntoVal, Symbol, TryFromVal, }; -use core::mem; mod pair { soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); pub type SoroswapPairClient<'a> = Client<'a>; } mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!( + file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm" + ); pub type TokenClient<'a> = Client<'a>; } mod factory { soroban_sdk::contractimport!(file = "./target/wasm32v1-none/release/soroswap_factory.wasm"); - pub type _SoroswapFactoryClient<'a> = Client<'a>; + pub type _SoroswapFactoryClient<'a> = Client<'a>; } use pair::SoroswapPairClient; use token::TokenClient; // use factory::SoroswapFactoryClient; -use crate::{ SoroswapFactory, SoroswapFactoryClient}; +use crate::{SoroswapFactory, SoroswapFactoryClient}; struct SoroswapFactoryTest<'a> { env: Env, @@ -48,27 +39,27 @@ struct SoroswapFactoryTest<'a> { factory: SoroswapFactoryClient<'a>, token_0: TokenClient<'a>, token_1: TokenClient<'a>, - pair: SoroswapPairClient<'a> + pair: SoroswapPairClient<'a>, } impl<'a> SoroswapFactoryTest<'a> { fn new() -> Self { - let env: Env = Default::default(); env.mock_all_auths(); let alice = Address::generate(&env); let bob = Address::generate(&env); - let mut token_0: TokenClient<'a> = TokenClient::new(&env, &env.register_stellar_asset_contract(alice.clone())); - let mut token_1: TokenClient<'a> = TokenClient::new(&env, &env.register_stellar_asset_contract(alice.clone())); + let mut token_0: TokenClient<'a> = + TokenClient::new(&env, &env.register_stellar_asset_contract(alice.clone())); + let mut token_1: TokenClient<'a> = + TokenClient::new(&env, &env.register_stellar_asset_contract(alice.clone())); if &token_1.address < &token_0.address { mem::swap(&mut token_0, &mut token_1); - } else - if &token_1.address == &token_0.address { + } else if &token_1.address == &token_0.address { panic!("token contract ids are equal"); } // The other form for registering the contract with the environment // interface is directly calling the WASM code: - // + // // let factory_address = &env.register_contract_wasm(None, factory::WASM); // let factory_address = &env.register_contract(None, SoroswapFactory); @@ -86,7 +77,7 @@ impl<'a> SoroswapFactoryTest<'a> { factory, token_0, token_1, - pair + pair, } } } @@ -143,10 +134,10 @@ pub fn authorize_bob() { function: AuthorizedFunction::Contract(( factory_address, Symbol::new(&factory.env, "set_fee_to_setter"), - (bob.clone(),).into_val(&factory.env) + (bob.clone(),).into_val(&factory.env), )), - sub_invocations:[].into() - } + sub_invocations: [].into(), + }, )]; assert_eq!(factory.env.auths(), auths); } @@ -174,8 +165,14 @@ pub fn pair_exists_both_directions() { let factory = factory_test.factory; let token_0 = factory_test.token_0; let token_1 = factory_test.token_1; - assert_eq!(factory.pair_exists(&token_0.address, &token_1.address), true); - assert_eq!(factory.pair_exists(&token_1.address, &token_0.address), true); + assert_eq!( + factory.pair_exists(&token_0.address, &token_1.address), + true + ); + assert_eq!( + factory.pair_exists(&token_1.address, &token_0.address), + true + ); } #[test] @@ -183,10 +180,22 @@ pub fn pair_does_not_exists_both_directions() { let factory_test = SoroswapFactoryTest::new(); let factory = factory_test.factory; let alice = factory_test.alice.clone(); - let token_a = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); - let token_b = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); - assert_eq!(factory.pair_exists(&token_a.address, &token_b.address), false); - assert_eq!(factory.pair_exists(&token_b.address, &token_a.address), false); + let token_a = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); + let token_b = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); + assert_eq!( + factory.pair_exists(&token_a.address, &token_b.address), + false + ); + assert_eq!( + factory.pair_exists(&token_b.address, &token_a.address), + false + ); } #[test] @@ -194,11 +203,23 @@ pub fn add_pair() { let factory_test = SoroswapFactoryTest::new(); let factory = factory_test.factory; let alice = factory_test.alice.clone(); - let token_a = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); - let token_b = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); + let token_a = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); + let token_b = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); factory.create_pair(&token_a.address, &token_b.address); - assert_eq!(factory.pair_exists(&token_a.address, &token_b.address), true); - assert_eq!(factory.pair_exists(&token_b.address, &token_a.address), true); + assert_eq!( + factory.pair_exists(&token_a.address, &token_b.address), + true + ); + assert_eq!( + factory.pair_exists(&token_b.address, &token_a.address), + true + ); } #[test] @@ -212,8 +233,12 @@ pub fn pair_address_eq_both_directions() { let factory_test = SoroswapFactoryTest::new(); let token_0_address = factory_test.token_0.address; let token_1_address = factory_test.token_1.address; - let a = factory_test.factory.get_pair(&token_0_address, &token_1_address); - let b = factory_test.factory.get_pair(&token_1_address, &token_0_address); + let a = factory_test + .factory + .get_pair(&token_0_address, &token_1_address); + let b = factory_test + .factory + .get_pair(&token_1_address, &token_0_address); assert_eq!(a, b) } @@ -222,7 +247,9 @@ pub fn compare_pair_address() { let factory_test = SoroswapFactoryTest::new(); let token_0_address = factory_test.token_0.address; let token_1_address = factory_test.token_1.address; - let pair_address = factory_test.factory.get_pair(&token_0_address, &token_1_address); + let pair_address = factory_test + .factory + .get_pair(&token_0_address, &token_1_address); assert_eq!(pair_address, factory_test.pair.address); } @@ -235,12 +262,18 @@ pub fn compare_deterministic_address() { // Calculating pair address: let mut salt = Bytes::new(&env); // Append the bytes of token_0 and token_1 to the salt - salt.append(&factory_test.token_0.address.clone().to_xdr(&env)); + salt.append(&factory_test.token_0.address.clone().to_xdr(&env)); salt.append(&factory_test.token_1.address.clone().to_xdr(&env)); // Hash the salt using SHA256 to generate a new BytesN<32> value - let bytes_n_32_salt=env.crypto().sha256(&salt); - - let calculated_pair_address = env.deployer().with_address(factory_test.factory.address.clone(), bytes_n_32_salt.clone()).deployed_address(); + let bytes_n_32_salt = env.crypto().sha256(&salt); + + let calculated_pair_address = env + .deployer() + .with_address( + factory_test.factory.address.clone(), + bytes_n_32_salt.clone(), + ) + .deployed_address(); assert_eq!(&factory_test.pair.address, &calculated_pair_address); } @@ -253,17 +286,23 @@ pub fn compare_deterministic_address_inverted() { // Calculating pair address: let mut salt = Bytes::new(&env); // Append the bytes of token_0 and token_1 to the salt - salt.append(&factory_test.token_1.address.clone().to_xdr(&env)); + salt.append(&factory_test.token_1.address.clone().to_xdr(&env)); salt.append(&factory_test.token_0.address.clone().to_xdr(&env)); // Hash the salt using SHA256 to generate a new BytesN<32> value - let bytes_n_32_salt=env.crypto().sha256(&salt); - - let calculated_pair_address = env.deployer().with_address(factory_test.factory.address.clone(), bytes_n_32_salt.clone()).deployed_address(); + let bytes_n_32_salt = env.crypto().sha256(&salt); + + let calculated_pair_address = env + .deployer() + .with_address( + factory_test.factory.address.clone(), + bytes_n_32_salt.clone(), + ) + .deployed_address(); assert_ne!(&factory_test.pair.address, &calculated_pair_address); } #[test] -fn set_fee_to_address_from_zero_u8() { +fn set_fee_to_address_from_zero_u8() { let factory_test = SoroswapFactoryTest::new(); let env = factory_test.env; let public_key = PublicKey::PublicKeyTypeEd25519(Uint256([0u8; 32])); @@ -283,8 +322,14 @@ pub fn pair_is_unique_and_unequivocal_same_order() { let factory_test = SoroswapFactoryTest::new(); let factory = factory_test.factory; let alice = factory_test.alice.clone(); - let token_a = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); - let token_b = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); + let token_a = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); + let token_b = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); factory.create_pair(&token_a.address, &token_b.address); factory.create_pair(&token_a.address, &token_b.address); } @@ -295,8 +340,14 @@ pub fn pair_is_unique_and_unequivocal_inverted_order() { let factory_test = SoroswapFactoryTest::new(); let factory = factory_test.factory; let alice = factory_test.alice.clone(); - let token_a = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); - let token_b = TokenClient::new(&factory.env, &factory.env.register_stellar_asset_contract(alice.clone())); + let token_a = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); + let token_b = TokenClient::new( + &factory.env, + &factory.env.register_stellar_asset_contract(alice.clone()), + ); factory.create_pair(&token_a.address, &token_b.address); factory.create_pair(&token_b.address, &token_a.address); } @@ -320,9 +371,9 @@ pub fn authorized_invocation() { assert_eq!(alice, factory.fee_to_setter()); // e.x. - // let authorization = + // let authorization = // AuthorizedInvocation { - // function: + // function: // AuthorizedFunction::Contract(( // factory.address.clone(), // Symbol::new(&factory.env, "set_fee_to_setter"), @@ -361,9 +412,9 @@ pub fn non_authorized_invocation() { assert_eq!(alice, factory.fee_to_setter()); // e.x. - // let authorization = + // let authorization = // AuthorizedInvocation { - // function: + // function: // AuthorizedFunction::Contract(( // factory.address.clone(), // Symbol::new(&factory.env, "set_fee_to_setter"), @@ -383,7 +434,7 @@ pub fn non_authorized_invocation() { }, }]) .set_fee_to_setter(&bob); - + // setter is bob assert_eq!(bob, factory.fee_to_setter()); -} \ No newline at end of file +} diff --git a/contracts/factory/src/test/events.rs b/contracts/factory/src/test/events.rs index 0ca6cfef..6119ccbb 100644 --- a/contracts/factory/src/test/events.rs +++ b/contracts/factory/src/test/events.rs @@ -1,13 +1,9 @@ -use soroban_sdk::{testutils::{Events}, vec, IntoVal, symbol_short}; -use soroban_sdk::{xdr::{ToXdr}, Bytes}; // For determinisitic address -use crate::test::{SoroswapFactoryTest}; use crate::event::{ - InitializedEvent, - NewPairEvent, - FeeToSettedEvent, - NewSetterEvent, - NewFeesEnabledEvent}; - + FeeToSettedEvent, InitializedEvent, NewFeesEnabledEvent, NewPairEvent, NewSetterEvent, +}; +use crate::test::SoroswapFactoryTest; +use soroban_sdk::{symbol_short, testutils::Events, vec, IntoVal}; +use soroban_sdk::{xdr::ToXdr, Bytes}; // For determinisitic address #[test] fn initialized_event() { @@ -17,7 +13,7 @@ fn initialized_event() { let initialized_event = test.env.events().all().last().unwrap(); let expected_initialized_event: InitializedEvent = InitializedEvent { - setter: test.admin.clone() + setter: test.admin.clone(), }; assert_eq!( @@ -32,9 +28,7 @@ fn initialized_event() { ] ); - let false_initialized_event: InitializedEvent = InitializedEvent { - setter: test.user, - }; + let false_initialized_event: InitializedEvent = InitializedEvent { setter: test.user }; assert_ne!( vec![&test.env, initialized_event.clone()], @@ -48,7 +42,6 @@ fn initialized_event() { ] ); - // Wront symbol_short assert_ne!( vec![&test.env, initialized_event.clone()], @@ -74,22 +67,25 @@ fn initialized_event() { ), ] ); - } - #[test] fn new_pair_event() { let test = SoroswapFactoryTest::setup(); test.contract.initialize(&test.admin, &test.pair_wasm); - test.contract.create_pair(&test.token_0.address, &test.token_1.address); + test.contract + .create_pair(&test.token_0.address, &test.token_1.address); // Calculating pair address: let mut salt = Bytes::new(&test.env); - salt.append(&test.token_0.address.clone().to_xdr(&test.env)); + salt.append(&test.token_0.address.clone().to_xdr(&test.env)); salt.append(&test.token_1.address.clone().to_xdr(&test.env)); - let bytes_n_32_salt=test.env.crypto().sha256(&salt); - let deterministic_pair_address = test.env.deployer().with_address(test.contract.address.clone(), bytes_n_32_salt.clone()).deployed_address(); + let bytes_n_32_salt = test.env.crypto().sha256(&salt); + let deterministic_pair_address = test + .env + .deployer() + .with_address(test.contract.address.clone(), bytes_n_32_salt.clone()) + .deployed_address(); let new_pair_event = test.env.events().all().last().unwrap(); @@ -131,7 +127,6 @@ fn new_pair_event() { ] ); - // Wront symbol_short assert_ne!( vec![&test.env, new_pair_event.clone()], @@ -159,14 +154,18 @@ fn new_pair_event() { ); // new pair - test.contract.create_pair(&test.token_2.address, &test.token_3.address); + test.contract + .create_pair(&test.token_2.address, &test.token_3.address); // Calculating pair address: let mut new_salt = Bytes::new(&test.env); - new_salt.append(&test.token_2.address.clone().to_xdr(&test.env)); + new_salt.append(&test.token_2.address.clone().to_xdr(&test.env)); new_salt.append(&test.token_3.address.clone().to_xdr(&test.env)); - let new_bytes_n_32_salt=test.env.crypto().sha256(&new_salt); - let new_deterministic_pair_address = test.env.deployer().with_address(test.contract.address.clone(), new_bytes_n_32_salt.clone()).deployed_address(); - + let new_bytes_n_32_salt = test.env.crypto().sha256(&new_salt); + let new_deterministic_pair_address = test + .env + .deployer() + .with_address(test.contract.address.clone(), new_bytes_n_32_salt.clone()) + .deployed_address(); let new_expected_new_pair_event: NewPairEvent = NewPairEvent { token_0: test.token_2.address.clone(), @@ -189,7 +188,6 @@ fn new_pair_event() { ); } - #[test] fn fee_to_event() { let test = SoroswapFactoryTest::setup(); @@ -234,7 +232,6 @@ fn fee_to_event() { ] ); - // Wrong symbol_short assert_ne!( vec![&test.env, fee_to_event.clone()], @@ -260,10 +257,8 @@ fn fee_to_event() { ), ] ); - } - #[test] fn setter_event() { let test = SoroswapFactoryTest::setup(); @@ -306,7 +301,6 @@ fn setter_event() { ] ); - // Wrong symbol_short assert_ne!( vec![&test.env, new_setter_event.clone()], @@ -332,10 +326,8 @@ fn setter_event() { ), ] ); - } - #[test] fn fees_enabled_event() { let test = SoroswapFactoryTest::setup(); @@ -344,9 +336,8 @@ fn fees_enabled_event() { let fees_enabled_event = test.env.events().all().last().unwrap(); - let expected_fees_enabled_event: NewFeesEnabledEvent = NewFeesEnabledEvent { - fees_enabled: true, - }; + let expected_fees_enabled_event: NewFeesEnabledEvent = + NewFeesEnabledEvent { fees_enabled: true }; assert_eq!( vec![&test.env, fees_enabled_event.clone()], @@ -376,7 +367,6 @@ fn fees_enabled_event() { ] ); - // Wrong symbol_short assert_ne!( vec![&test.env, fees_enabled_event.clone()], @@ -402,5 +392,4 @@ fn fees_enabled_event() { ), ] ); - -} \ No newline at end of file +} diff --git a/contracts/factory/src/test/fee_to_setter.rs b/contracts/factory/src/test/fee_to_setter.rs index bcfd16db..3fc0e11b 100644 --- a/contracts/factory/src/test/fee_to_setter.rs +++ b/contracts/factory/src/test/fee_to_setter.rs @@ -1,14 +1,8 @@ extern crate std; -use crate::test::{SoroswapFactoryTest}; +use crate::test::SoroswapFactoryTest; use soroban_sdk::{ - IntoVal, - testutils::{ - MockAuth, - MockAuthInvoke, - AuthorizedInvocation, - AuthorizedFunction - }, - Symbol + testutils::{AuthorizedFunction, AuthorizedInvocation, MockAuth, MockAuthInvoke}, + IntoVal, Symbol, }; #[test] @@ -28,54 +22,48 @@ fn changing_with_mock_auth() { // MOCK THE SPECIFIC AUTHORIZATION test.contract - .mock_auths(&[ - MockAuth { + .mock_auths(&[MockAuth { address: &test.admin.clone(), - invoke: - &MockAuthInvoke { - contract: &test.contract.address.clone(), - fn_name: "set_fee_to_setter", - args: (test.user.clone(),).into_val(&test.env), - sub_invokes: &[], - }, - } - ]) - .set_fee_to_setter(&test.user); - + invoke: &MockAuthInvoke { + contract: &test.contract.address.clone(), + fn_name: "set_fee_to_setter", + args: (test.user.clone(),).into_val(&test.env), + sub_invokes: &[], + }, + }]) + .set_fee_to_setter(&test.user); + // CHECK THAT WE SAW IT IN THE PREVIOUS AUTORIZED TXS assert_eq!( test.env.auths(), std::vec![( test.admin.clone(), AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - test.contract.address.clone(), - Symbol::new(&test.env, "set_fee_to_setter"), - (test.user.clone(),).into_val(&test.env) - )), - sub_invocations: std::vec![] - } + function: AuthorizedFunction::Contract(( + test.contract.address.clone(), + Symbol::new(&test.env, "set_fee_to_setter"), + (test.user.clone(),).into_val(&test.env) + )), + sub_invocations: std::vec![] + } )] - ); + ); assert_eq!(test.contract.fee_to_setter(), test.user); assert_ne!(test.contract.fee_to_setter(), test.admin); // MOCK THE SPECIFIC AUTHORIZATION test.contract - .mock_auths(&[ - MockAuth { + .mock_auths(&[MockAuth { address: &test.user.clone(), - invoke: - &MockAuthInvoke { - contract: &test.contract.address.clone(), - fn_name: "set_fee_to", - args: (test.user.clone(),).into_val(&test.env), - sub_invokes: &[], - }, - } - ]) - .set_fee_to(&test.user); + invoke: &MockAuthInvoke { + contract: &test.contract.address.clone(), + fn_name: "set_fee_to", + args: (test.user.clone(),).into_val(&test.env), + sub_invokes: &[], + }, + }]) + .set_fee_to(&test.user); // CHECK THAT WE SAW IT IN THE PREVIOUS AUTORIZED TXS assert_eq!( @@ -83,34 +71,31 @@ fn changing_with_mock_auth() { std::vec![( test.user.clone(), AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - test.contract.address.clone(), - Symbol::new(&test.env, "set_fee_to"), - (test.user.clone(),).into_val(&test.env) - )), - sub_invocations: std::vec![] - } + function: AuthorizedFunction::Contract(( + test.contract.address.clone(), + Symbol::new(&test.env, "set_fee_to"), + (test.user.clone(),).into_val(&test.env) + )), + sub_invocations: std::vec![] + } )] - ); + ); assert_eq!(test.contract.fee_to(), test.user); assert_ne!(test.contract.fee_to(), test.admin); // MOCK THE SPECIFIC AUTHORIZATION test.contract - .mock_auths(&[ - MockAuth { + .mock_auths(&[MockAuth { address: &test.user.clone(), - invoke: - &MockAuthInvoke { - contract: &test.contract.address.clone(), - fn_name: "set_fees_enabled", - args: (true,).into_val(&test.env), - sub_invokes: &[], - }, - } - ]) - .set_fees_enabled(&true); + invoke: &MockAuthInvoke { + contract: &test.contract.address.clone(), + fn_name: "set_fees_enabled", + args: (true,).into_val(&test.env), + sub_invokes: &[], + }, + }]) + .set_fees_enabled(&true); // CHECK THAT WE SAW IT IN THE PREVIOUS AUTORIZED TXS assert_eq!( @@ -118,18 +103,17 @@ fn changing_with_mock_auth() { std::vec![( test.user.clone(), AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - test.contract.address.clone(), - Symbol::new(&test.env, "set_fees_enabled"), - (true,).into_val(&test.env) - )), - sub_invocations: std::vec![] - } + function: AuthorizedFunction::Contract(( + test.contract.address.clone(), + Symbol::new(&test.env, "set_fees_enabled"), + (true,).into_val(&test.env) + )), + sub_invocations: std::vec![] + } )] - ); - - assert_eq!(test.contract.fees_enabled(), true); + ); + assert_eq!(test.contract.fees_enabled(), true); } #[test] @@ -139,23 +123,18 @@ fn changing_fee_to_setter_with_mock_auth_not_allowed() { test.contract.initialize(&test.admin, &test.pair_wasm); test.contract - .mock_auths(&[ - MockAuth { + .mock_auths(&[MockAuth { address: &test.user.clone(), - invoke: - &MockAuthInvoke { - contract: &test.contract.address.clone(), - fn_name: "set_fee_to_setter", - args: (test.user.clone(),).into_val(&test.env), - sub_invokes: &[], - }, - } - ]) - .set_fee_to_setter(&test.user); - + invoke: &MockAuthInvoke { + contract: &test.contract.address.clone(), + fn_name: "set_fee_to_setter", + args: (test.user.clone(),).into_val(&test.env), + sub_invokes: &[], + }, + }]) + .set_fee_to_setter(&test.user); } - #[test] #[should_panic] fn changing_fee_to_with_mock_auth_not_allowed() { @@ -163,23 +142,18 @@ fn changing_fee_to_with_mock_auth_not_allowed() { test.contract.initialize(&test.admin, &test.pair_wasm); test.contract - .mock_auths(&[ - MockAuth { + .mock_auths(&[MockAuth { address: &test.user.clone(), - invoke: - &MockAuthInvoke { - contract: &test.contract.address.clone(), - fn_name: "set_fee_to", - args: (test.user.clone(),).into_val(&test.env), - sub_invokes: &[], - }, - } - ]) - .set_fee_to(&test.user); - + invoke: &MockAuthInvoke { + contract: &test.contract.address.clone(), + fn_name: "set_fee_to", + args: (test.user.clone(),).into_val(&test.env), + sub_invokes: &[], + }, + }]) + .set_fee_to(&test.user); } - #[test] #[should_panic] fn changing_fees_enabled_with_mock_auth_not_allowed() { @@ -187,18 +161,14 @@ fn changing_fees_enabled_with_mock_auth_not_allowed() { test.contract.initialize(&test.admin, &test.pair_wasm); test.contract - .mock_auths(&[ - MockAuth { + .mock_auths(&[MockAuth { address: &test.user.clone(), - invoke: - &MockAuthInvoke { - contract: &test.contract.address.clone(), - fn_name: "set_fees_enabled", - args: (false,).into_val(&test.env), - sub_invokes: &[], - }, - } - ]) - .set_fees_enabled(&false); - -} \ No newline at end of file + invoke: &MockAuthInvoke { + contract: &test.contract.address.clone(), + fn_name: "set_fees_enabled", + args: (false,).into_val(&test.env), + sub_invokes: &[], + }, + }]) + .set_fees_enabled(&false); +} diff --git a/contracts/factory/src/test/initialize.rs b/contracts/factory/src/test/initialize.rs index 69674a0f..284d171f 100644 --- a/contracts/factory/src/test/initialize.rs +++ b/contracts/factory/src/test/initialize.rs @@ -1,16 +1,11 @@ extern crate std; -use crate::test::{SoroswapFactoryTest}; +use crate::test::SoroswapFactoryTest; use soroban_sdk::{ - IntoVal, - testutils::{ - AuthorizedInvocation, - AuthorizedFunction - }, - Symbol + testutils::{AuthorizedFunction, AuthorizedInvocation}, + IntoVal, Symbol, }; //use super::*; // Import the necessary modules and types -use soroswap_factory_interface::{FactoryError}; - +use soroswap_factory_interface::FactoryError; #[test] fn not_yet_initialized_fee_to() { @@ -43,7 +38,9 @@ fn not_yet_initialized_all_pairs_length() { #[test] fn not_yet_initialized_get_pair() { let test = SoroswapFactoryTest::setup(); - let res = test.contract.try_get_pair(&test.token_0.address, &test.token_1.address); + let res = test + .contract + .try_get_pair(&test.token_0.address, &test.token_1.address); assert_eq!(res, Err(Ok(FactoryError::NotInitialized))); } @@ -78,7 +75,9 @@ fn not_yet_initialized_set_fees_enabled() { #[test] fn not_yet_initialized_create_pair() { let test = SoroswapFactoryTest::setup(); - let res = test.contract.try_create_pair(&test.token_0.address, &test.token_1.address); + let res = test + .contract + .try_create_pair(&test.token_0.address, &test.token_1.address); assert_eq!(res, Err(Ok(FactoryError::NotInitialized))); } @@ -108,10 +107,10 @@ fn initialize_basic_info() { test.contract.set_fee_to_setter(&test.user); assert_eq!( - test.env.auths(), - std::vec![( - test.admin.clone(), - AuthorizedInvocation { + test.env.auths(), + std::vec![( + test.admin.clone(), + AuthorizedInvocation { function: AuthorizedFunction::Contract(( test.contract.address.clone(), Symbol::new(&test.env, "set_fee_to_setter"), @@ -119,13 +118,12 @@ fn initialize_basic_info() { )), sub_invocations: std::vec![] } - )] + )] ); assert_eq!(test.contract.fee_to_setter(), test.user); assert_ne!(test.contract.fee_to_setter(), test.admin); - test.contract.set_fee_to(&test.user); assert_eq!( @@ -133,15 +131,15 @@ fn initialize_basic_info() { std::vec![( test.user.clone(), AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - test.contract.address.clone(), - Symbol::new(&test.env, "set_fee_to"), - (test.user.clone(),).into_val(&test.env) - )), - sub_invocations: std::vec![] - } + function: AuthorizedFunction::Contract(( + test.contract.address.clone(), + Symbol::new(&test.env, "set_fee_to"), + (test.user.clone(),).into_val(&test.env) + )), + sub_invocations: std::vec![] + } )] - ); + ); assert_eq!(test.contract.fee_to(), test.user); assert_ne!(test.contract.fee_to(), test.admin); @@ -153,16 +151,15 @@ fn initialize_basic_info() { std::vec![( test.user.clone(), AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - test.contract.address.clone(), - Symbol::new(&test.env, "set_fees_enabled"), - (true,).into_val(&test.env) - )), - sub_invocations: std::vec![] - } + function: AuthorizedFunction::Contract(( + test.contract.address.clone(), + Symbol::new(&test.env, "set_fees_enabled"), + (true,).into_val(&test.env) + )), + sub_invocations: std::vec![] + } )] - ); - + ); assert_eq!(test.contract.fees_enabled(), true); @@ -173,16 +170,15 @@ fn initialize_basic_info() { std::vec![( test.user.clone(), AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - test.contract.address.clone(), - Symbol::new(&test.env, "set_fees_enabled"), - (false,).into_val(&test.env) - )), - sub_invocations: std::vec![] - } + function: AuthorizedFunction::Contract(( + test.contract.address.clone(), + Symbol::new(&test.env, "set_fees_enabled"), + (false,).into_val(&test.env) + )), + sub_invocations: std::vec![] + } )] - ); + ); assert_eq!(test.contract.fees_enabled(), false); } - diff --git a/contracts/factory/src/test/pairs.rs b/contracts/factory/src/test/pairs.rs index b90f18a4..eff4537d 100644 --- a/contracts/factory/src/test/pairs.rs +++ b/contracts/factory/src/test/pairs.rs @@ -1,9 +1,6 @@ use crate::test::{SoroswapFactoryTest, SoroswapPairClient}; -use soroban_sdk::{xdr::{ToXdr}, - Bytes, -}; -use soroswap_factory_interface::{FactoryError}; - +use soroban_sdk::{xdr::ToXdr, Bytes}; +use soroswap_factory_interface::FactoryError; #[test] fn create_pair_one_way() { @@ -11,24 +8,49 @@ fn create_pair_one_way() { test.contract.initialize(&test.admin, &test.pair_wasm); assert_eq!(test.contract.all_pairs_length(), 0); - assert_eq!(test.contract.pair_exists(&test.token_0.address, &test.token_1.address), false); - assert_eq!(test.contract.pair_exists(&test.token_1.address, &test.token_0.address), false); - - test.contract.create_pair(&test.token_0.address, &test.token_1.address); + assert_eq!( + test.contract + .pair_exists(&test.token_0.address, &test.token_1.address), + false + ); + assert_eq!( + test.contract + .pair_exists(&test.token_1.address, &test.token_0.address), + false + ); + + test.contract + .create_pair(&test.token_0.address, &test.token_1.address); assert_eq!(test.contract.all_pairs_length(), 1); - assert_eq!(test.contract.pair_exists(&test.token_0.address, &test.token_1.address), true); - assert_eq!(test.contract.pair_exists(&test.token_1.address, &test.token_0.address), true); + assert_eq!( + test.contract + .pair_exists(&test.token_0.address, &test.token_1.address), + true + ); + assert_eq!( + test.contract + .pair_exists(&test.token_1.address, &test.token_0.address), + true + ); // Calculating pair address: let mut salt = Bytes::new(&test.env); - salt.append(&test.token_0.address.clone().to_xdr(&test.env)); + salt.append(&test.token_0.address.clone().to_xdr(&test.env)); salt.append(&test.token_1.address.clone().to_xdr(&test.env)); - let bytes_n_32_salt=test.env.crypto().sha256(&salt); - let deterministic_pair_address = test.env.deployer().with_address(test.contract.address.clone(), bytes_n_32_salt.clone()).deployed_address(); - - let pair_address = test.contract.get_pair(&test.token_0.address, &test.token_1.address); - let pair_address_other_way = test.contract.get_pair(&test.token_0.address, &test.token_1.address); + let bytes_n_32_salt = test.env.crypto().sha256(&salt); + let deterministic_pair_address = test + .env + .deployer() + .with_address(test.contract.address.clone(), bytes_n_32_salt.clone()) + .deployed_address(); + + let pair_address = test + .contract + .get_pair(&test.token_0.address, &test.token_1.address); + let pair_address_other_way = test + .contract + .get_pair(&test.token_0.address, &test.token_1.address); assert_eq!(pair_address, deterministic_pair_address); assert_eq!(pair_address_other_way, deterministic_pair_address); @@ -42,14 +64,16 @@ fn create_pair_one_way() { assert_eq!(&pair_client.token_1(), &test.token_1.address); } - #[test] fn double_pair_creation() { let test = SoroswapFactoryTest::setup(); test.contract.initialize(&test.admin, &test.pair_wasm); - test.contract.create_pair(&test.token_0.address, &test.token_1.address); - let res = test.contract.try_create_pair(&test.token_0.address, &test.token_1.address); + test.contract + .create_pair(&test.token_0.address, &test.token_1.address); + let res = test + .contract + .try_create_pair(&test.token_0.address, &test.token_1.address); assert_eq!(res, Err(Ok(FactoryError::CreatePairAlreadyExists))); } @@ -59,8 +83,11 @@ fn double_pair_creation_other_way() { let test = SoroswapFactoryTest::setup(); test.contract.initialize(&test.admin, &test.pair_wasm); - test.contract.create_pair(&test.token_0.address, &test.token_1.address); - let res = test.contract.try_create_pair(&test.token_1.address, &test.token_0.address); + test.contract + .create_pair(&test.token_0.address, &test.token_1.address); + let res = test + .contract + .try_create_pair(&test.token_1.address, &test.token_0.address); assert_eq!(res, Err(Ok(FactoryError::CreatePairAlreadyExists))); } @@ -70,32 +97,34 @@ fn get_pair_does_not_exist() { let test = SoroswapFactoryTest::setup(); test.contract.initialize(&test.admin, &test.pair_wasm); - let res = test.contract.try_get_pair(&test.token_0.address, &test.token_1.address); + let res = test + .contract + .try_get_pair(&test.token_0.address, &test.token_1.address); assert_eq!(res, Err(Ok(FactoryError::PairDoesNotExist))); } - #[test] fn create_identical_tokens() { let test = SoroswapFactoryTest::setup(); test.contract.initialize(&test.admin, &test.pair_wasm); - let res = test.contract.try_create_pair(&test.token_0.address, &test.token_0.address); + let res = test + .contract + .try_create_pair(&test.token_0.address, &test.token_0.address); assert_eq!(res, Err(Ok(FactoryError::CreatePairIdenticalTokens))); } - #[test] fn create_pair_index_does_not_exist() { let test = SoroswapFactoryTest::setup(); test.contract.initialize(&test.admin, &test.pair_wasm); - test.contract.create_pair(&test.token_0.address, &test.token_1.address); + test.contract + .create_pair(&test.token_0.address, &test.token_1.address); let res = test.contract.try_all_pairs(&1); assert_eq!(res, Err(Ok(FactoryError::IndexDoesNotExist))); - } #[test] @@ -104,5 +133,4 @@ fn no_pair_index_does_not_exist() { test.contract.initialize(&test.admin, &test.pair_wasm); let res = test.contract.try_all_pairs(&0); assert_eq!(res, Err(Ok(FactoryError::IndexDoesNotExist))); - } diff --git a/contracts/library/src/error.rs b/contracts/library/src/error.rs index a97d007e..61787827 100644 --- a/contracts/library/src/error.rs +++ b/contracts/library/src/error.rs @@ -4,7 +4,7 @@ use soroban_sdk::{self, contracterror}; #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[repr(u32)] pub enum SoroswapLibraryError { - /// SoroswapLibrary: insufficient amount + /// SoroswapLibrary: insufficient amount InsufficientAmount = 301, /// SoroswapLibrary: insufficient liquidity @@ -21,4 +21,4 @@ pub enum SoroswapLibraryError { /// SoroswapLibrary: token_a and token_b have identical addresses SortIdenticalTokens = 306, -} \ No newline at end of file +} diff --git a/contracts/library/src/lib.rs b/contracts/library/src/lib.rs index 3098608d..46f6816e 100644 --- a/contracts/library/src/lib.rs +++ b/contracts/library/src/lib.rs @@ -1,40 +1,19 @@ -#![no_std] -use soroban_sdk::{ - contract, contractimpl, - Address, Env, Vec, -}; +#![no_std] +use soroban_sdk::{contract, contractimpl, Address, Env, Vec}; -mod test; -mod tokens; -mod reserves; -mod quotes; mod error; mod math; +mod quotes; +mod reserves; +mod test; +mod tokens; - -pub use tokens::{ - sort_tokens, - pair_for -}; -pub use reserves::{ - get_reserves_with_factory, - get_reserves_with_pair -}; -pub use quotes::{ - quote, - get_amount_out, - get_amount_in, - get_amounts_out, - get_amounts_in -}; pub use error::SoroswapLibraryError; - - - - +pub use quotes::{get_amount_in, get_amount_out, get_amounts_in, get_amounts_out, quote}; +pub use reserves::{get_reserves_with_factory, get_reserves_with_pair}; +pub use tokens::{pair_for, sort_tokens}; pub trait SoroswapLibraryTrait { - /// Sorts two token addresses in a consistent order. /// /// # Arguments @@ -45,7 +24,10 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result<(Address, Address), SoroswapLibraryError>` where `Ok` contains a tuple with the sorted token addresses, and `Err` indicates an error such as identical tokens. - fn sort_tokens(token_a: Address, token_b: Address) -> Result<(Address, Address), SoroswapLibraryError>; + fn sort_tokens( + token_a: Address, + token_b: Address, + ) -> Result<(Address, Address), SoroswapLibraryError>; /// Calculates the deterministic address for a pair without making any external calls. /// check @@ -60,7 +42,12 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn pair_for(e: Env, factory: Address, token_a: Address, token_b: Address) -> Result; + fn pair_for( + e: Env, + factory: Address, + token_a: Address, + token_b: Address, + ) -> Result; /// Fetches and sorts the reserves for a pair of tokens. /// @@ -74,7 +61,12 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn get_reserves_with_factory(e: Env,factory: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError>; + fn get_reserves_with_factory( + e: Env, + factory: Address, + token_a: Address, + token_b: Address, + ) -> Result<(i128, i128), SoroswapLibraryError>; /// Fetches and sorts the reserves for a pair of tokens knowing the pair address /// @@ -88,7 +80,12 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn get_reserves_with_pair(e: Env, pair: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError>; + fn get_reserves_with_pair( + e: Env, + pair: Address, + token_a: Address, + token_b: Address, + ) -> Result<(i128, i128), SoroswapLibraryError>; /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset. /// @@ -101,7 +98,11 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity - fn quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result; + fn quote( + amount_a: i128, + reserve_a: i128, + reserve_b: i128, + ) -> Result; /// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset. /// @@ -114,7 +115,11 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity. - fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result; + fn get_amount_out( + amount_in: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result; /// Given an output amount of an asset and pair reserves, returns a required input amount of the other asset. /// @@ -127,7 +132,11 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity. - fn get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result; + fn get_amount_in( + amount_out: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result; /// Performs chained get_amount_out calculations on any number of pairs. /// @@ -141,8 +150,13 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn get_amounts_out(e: Env, factory: Address, amount_in: i128, path: Vec
) -> Result, SoroswapLibraryError>; - + fn get_amounts_out( + e: Env, + factory: Address, + amount_in: i128, + path: Vec
, + ) -> Result, SoroswapLibraryError>; + /// Performs chained get_amount_in calculations on any number of pairs. /// /// # Arguments @@ -155,11 +169,12 @@ pub trait SoroswapLibraryTrait { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn get_amounts_in(e: Env, factory: Address, amount_out: i128, path: Vec
) -> Result, SoroswapLibraryError>; - - - - + fn get_amounts_in( + e: Env, + factory: Address, + amount_out: i128, + path: Vec
, + ) -> Result, SoroswapLibraryError>; } #[contract] @@ -167,7 +182,6 @@ pub struct SoroswapLibrary; #[contractimpl] impl SoroswapLibraryTrait for SoroswapLibrary { - /// Sorts two token addresses in a consistent order. /// /// # Arguments @@ -178,11 +192,13 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result<(Address, Address), SoroswapLibraryError>` where `Ok` contains a tuple with the sorted token addresses, and `Err` indicates an error such as identical tokens. - fn sort_tokens(token_a: Address, token_b: Address) -> Result<(Address, Address), SoroswapLibraryError> { + fn sort_tokens( + token_a: Address, + token_b: Address, + ) -> Result<(Address, Address), SoroswapLibraryError> { sort_tokens(token_a, token_b) } - /// Calculates the deterministic address for a pair without making any external calls. /// check /// @@ -196,11 +212,15 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn pair_for(e: Env, factory: Address, token_a: Address, token_b: Address) -> Result { + fn pair_for( + e: Env, + factory: Address, + token_a: Address, + token_b: Address, + ) -> Result { pair_for(e, factory, token_a, token_b) } - /// Fetches and sorts the reserves for a pair of tokens using the factory address. /// /// # Arguments @@ -213,9 +233,13 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn get_reserves_with_factory(e: Env,factory: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError> { + fn get_reserves_with_factory( + e: Env, + factory: Address, + token_a: Address, + token_b: Address, + ) -> Result<(i128, i128), SoroswapLibraryError> { get_reserves_with_factory(e, factory, token_a, token_b) - } /// Fetches and sorts the reserves for a pair of tokens using the pair address. @@ -230,9 +254,13 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn get_reserves_with_pair(e: Env,pair: Address, token_a: Address, token_b: Address) -> Result<(i128, i128), SoroswapLibraryError> { + fn get_reserves_with_pair( + e: Env, + pair: Address, + token_a: Address, + token_b: Address, + ) -> Result<(i128, i128), SoroswapLibraryError> { get_reserves_with_pair(e, pair, token_a, token_b) - } /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset. @@ -246,10 +274,13 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity - fn quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result { + fn quote( + amount_a: i128, + reserve_a: i128, + reserve_b: i128, + ) -> Result { quote(amount_a, reserve_a, reserve_b) } - /// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset. /// @@ -262,7 +293,11 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity. - fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result { + fn get_amount_out( + amount_in: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result { get_amount_out(amount_in, reserve_in, reserve_out) } @@ -277,7 +312,11 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity. - fn get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result { + fn get_amount_in( + amount_out: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result { get_amount_in(amount_out, reserve_in, reserve_out) } @@ -293,7 +332,12 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn get_amounts_out(e: Env, factory: Address, amount_in: i128, path: Vec
) -> Result, SoroswapLibraryError> { + fn get_amounts_out( + e: Env, + factory: Address, + amount_in: i128, + path: Vec
, + ) -> Result, SoroswapLibraryError> { get_amounts_out(e, factory, amount_in, path) } @@ -309,10 +353,12 @@ impl SoroswapLibraryTrait for SoroswapLibrary { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn get_amounts_in(e: Env, factory: Address, amount_out: i128, path: Vec
) -> Result, SoroswapLibraryError> { + fn get_amounts_in( + e: Env, + factory: Address, + amount_out: i128, + path: Vec
, + ) -> Result, SoroswapLibraryError> { get_amounts_in(e, factory, amount_out, path) } - - - } diff --git a/contracts/library/src/math.rs b/contracts/library/src/math.rs index a29d2d9d..14335f6b 100644 --- a/contracts/library/src/math.rs +++ b/contracts/library/src/math.rs @@ -11,4 +11,4 @@ impl CheckedCeilingDiv for i128 { Some(result) } } -} \ No newline at end of file +} diff --git a/contracts/library/src/quotes.rs b/contracts/library/src/quotes.rs index 43d300ed..7509467a 100644 --- a/contracts/library/src/quotes.rs +++ b/contracts/library/src/quotes.rs @@ -1,8 +1,7 @@ -use soroban_sdk::{Address, Env, Vec}; -use crate::reserves::{get_reserves_with_factory}; use crate::error::SoroswapLibraryError; use crate::math::CheckedCeilingDiv; - +use crate::reserves::get_reserves_with_factory; +use soroban_sdk::{Address, Env, Vec}; /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset. /// @@ -15,14 +14,22 @@ use crate::math::CheckedCeilingDiv; /// # Returns /// /// Returns `Result` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity -pub fn quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result { +pub fn quote( + amount_a: i128, + reserve_a: i128, + reserve_b: i128, +) -> Result { if amount_a <= 0 { return Err(SoroswapLibraryError::InsufficientAmount); } if reserve_a <= 0 || reserve_b <= 0 { return Err(SoroswapLibraryError::InsufficientLiquidity); } - Ok(amount_a.checked_mul(reserve_b).ok_or(SoroswapLibraryError::InsufficientLiquidity)?.checked_div(reserve_a).ok_or(SoroswapLibraryError::InsufficientLiquidity)?) + Ok(amount_a + .checked_mul(reserve_b) + .ok_or(SoroswapLibraryError::InsufficientLiquidity)? + .checked_div(reserve_a) + .ok_or(SoroswapLibraryError::InsufficientLiquidity)?) } /// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset. @@ -36,7 +43,11 @@ pub fn quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity. -pub fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result { +pub fn get_amount_out( + amount_in: i128, + reserve_in: i128, + reserve_out: i128, +) -> Result { if amount_in <= 0 { return Err(SoroswapLibraryError::InsufficientInputAmount); } @@ -44,7 +55,9 @@ pub fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> R return Err(SoroswapLibraryError::InsufficientLiquidity); } - let fee = (amount_in.checked_mul(3).unwrap()).checked_ceiling_div(1000).unwrap(); + let fee = (amount_in.checked_mul(3).unwrap()) + .checked_ceiling_div(1000) + .unwrap(); let amount_in_less_fee = amount_in.checked_sub(fee).unwrap(); let numerator = amount_in_less_fee.checked_mul(reserve_out).unwrap(); @@ -65,16 +78,32 @@ pub fn get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> R /// # Returns /// /// Returns `Result` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity. -pub fn get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result { +pub fn get_amount_in( + amount_out: i128, + reserve_in: i128, + reserve_out: i128, +) -> Result { if amount_out <= 0 { return Err(SoroswapLibraryError::InsufficientOutputAmount); } if reserve_in <= 0 || reserve_out <= 0 { return Err(SoroswapLibraryError::InsufficientLiquidity); } - let numerator = reserve_in.checked_mul(amount_out).unwrap().checked_mul(1000).unwrap(); - let denominator = reserve_out.checked_sub(amount_out).unwrap().checked_mul(997).unwrap(); - Ok(numerator.checked_ceiling_div(denominator).unwrap().checked_add(1).unwrap()) + let numerator = reserve_in + .checked_mul(amount_out) + .unwrap() + .checked_mul(1000) + .unwrap(); + let denominator = reserve_out + .checked_sub(amount_out) + .unwrap() + .checked_mul(997) + .unwrap(); + Ok(numerator + .checked_ceiling_div(denominator) + .unwrap() + .checked_add(1) + .unwrap()) } /// Performs chained getAmountOut calculations on any number of pairs. @@ -89,7 +118,12 @@ pub fn get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> R /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. -pub fn get_amounts_out(e: Env, factory: Address, amount_in: i128, path: Vec
) -> Result, SoroswapLibraryError> { +pub fn get_amounts_out( + e: Env, + factory: Address, + amount_in: i128, + path: Vec
, +) -> Result, SoroswapLibraryError> { if path.len() < 2 { return Err(SoroswapLibraryError::InvalidPath); } @@ -98,8 +132,17 @@ pub fn get_amounts_out(e: Env, factory: Address, amount_in: i128, path: Vec, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. -pub fn get_amounts_in(e: Env, factory: Address, amount_out: i128, path: Vec
) -> Result, SoroswapLibraryError> { +pub fn get_amounts_in( + e: Env, + factory: Address, + amount_out: i128, + path: Vec
, +) -> Result, SoroswapLibraryError> { if path.len() < 2 { return Err(SoroswapLibraryError::InvalidPath); } @@ -126,7 +174,12 @@ pub fn get_amounts_in(e: Env, factory: Address, amount_out: i128, path: Vec` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting. -pub fn get_reserves_with_factory(e: Env,factory: Address, token_a: Address, token_b: Address) -> Result<(i128,i128), SoroswapLibraryError>{ - let (token_0,token_1) = sort_tokens(token_a.clone(), token_b.clone())?; +pub fn get_reserves_with_factory( + e: Env, + factory: Address, + token_a: Address, + token_b: Address, +) -> Result<(i128, i128), SoroswapLibraryError> { + let (token_0, token_1) = sort_tokens(token_a.clone(), token_b.clone())?; let pair_address = pair_for(e.clone(), factory, token_0.clone(), token_1.clone())?; let pair_client = SoroswapPairClient::new(&e, &pair_address); let (reserve_0, reserve_1) = pair_client.get_reserves(); - - let (reserve_a, reseve_b) = - if token_a == token_0 { - (reserve_0, reserve_1) - } else { - (reserve_1, reserve_0) }; + + let (reserve_a, reseve_b) = if token_a == token_0 { + (reserve_0, reserve_1) + } else { + (reserve_1, reserve_0) + }; Ok((reserve_a, reseve_b)) } @@ -49,16 +51,21 @@ pub fn get_reserves_with_factory(e: Env,factory: Address, token_a: Address, toke /// # Returns /// /// Returns `Result<(i128, i128), SoroswapLibraryError>` where `Ok` contains a tuple of sorted reserves, and `Err` indicates an error such as identical tokens or an issue with sorting. -pub fn get_reserves_with_pair(e: Env, pair: Address, token_a: Address, token_b: Address) -> Result<(i128,i128), SoroswapLibraryError>{ - let (token_0,token_1) = sort_tokens(token_a.clone(), token_b.clone())?; +pub fn get_reserves_with_pair( + e: Env, + pair: Address, + token_a: Address, + token_b: Address, +) -> Result<(i128, i128), SoroswapLibraryError> { + let (token_0, token_1) = sort_tokens(token_a.clone(), token_b.clone())?; let pair_client = SoroswapPairClient::new(&e, &pair); let (reserve_0, reserve_1) = pair_client.get_reserves(); - - let (reserve_a, reseve_b) = - if token_a == token_0 { - (reserve_0, reserve_1) - } else { - (reserve_1, reserve_0) }; + + let (reserve_a, reseve_b) = if token_a == token_0 { + (reserve_0, reserve_1) + } else { + (reserve_1, reserve_0) + }; Ok((reserve_a, reseve_b)) -} \ No newline at end of file +} diff --git a/contracts/library/src/test.rs b/contracts/library/src/test.rs index 0ce7c29a..826d7bce 100644 --- a/contracts/library/src/test.rs +++ b/contracts/library/src/test.rs @@ -1,11 +1,13 @@ #![cfg(test)] extern crate std; -use soroban_sdk::{Env, BytesN, Address, testutils::Address as _}; use crate::{SoroswapLibrary, SoroswapLibraryClient}; +use soroban_sdk::{testutils::Address as _, Address, BytesN, Env}; mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!( + file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm" + ); pub type TokenClient<'a> = Client<'a>; } @@ -14,7 +16,6 @@ mod pair { pub type SoroswapPairClient<'a> = Client<'a>; } - fn pair_contract_wasm(e: &Env) -> BytesN<32> { soroban_sdk::contractimport!( file = "../pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm" @@ -23,18 +24,19 @@ fn pair_contract_wasm(e: &Env) -> BytesN<32> { } mod factory { - soroban_sdk::contractimport!(file = "../factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm"); + soroban_sdk::contractimport!( + file = "../factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm" + ); pub type SoroswapFactoryClient<'a> = Client<'a>; } -use token::TokenClient; -use pair::SoroswapPairClient; use factory::SoroswapFactoryClient; +use pair::SoroswapPairClient; +use token::TokenClient; // Useful functions to create contracts - -fn create_token_contract<'a>(e: &Env, admin: & Address) -> TokenClient<'a> { +fn create_token_contract<'a>(e: &Env, admin: &Address) -> TokenClient<'a> { TokenClient::new( e, &e.register_stellar_asset_contract_v2(admin.clone()) @@ -42,11 +44,10 @@ fn create_token_contract<'a>(e: &Env, admin: & Address) -> TokenClient<'a> { ) } - -fn create_soroswap_factory<'a>(e: & Env, setter: & Address) -> SoroswapFactoryClient<'a> { - let pair_hash = pair_contract_wasm(&e); +fn create_soroswap_factory<'a>(e: &Env, setter: &Address) -> SoroswapFactoryClient<'a> { + let pair_hash = pair_contract_wasm(&e); let factory_address = &e.register(factory::WASM, ()); - let factory = SoroswapFactoryClient::new(e, factory_address); + let factory = SoroswapFactoryClient::new(e, factory_address); factory.initialize(&setter, &pair_hash); factory } @@ -68,7 +69,6 @@ struct SoroswapLibraryTest<'a> { impl<'a> SoroswapLibraryTest<'a> { fn setup() -> Self { - let env = Env::default(); env.mock_all_auths(); let contract = create_soroswap_library_contract(&env); @@ -105,7 +105,7 @@ impl<'a> SoroswapLibraryTest<'a> { //pair.deposit(&user, &10000, &0, &10000, &0); env.budget().reset_unlimited(); - + SoroswapLibraryTest { env, contract, @@ -113,11 +113,11 @@ impl<'a> SoroswapLibraryTest<'a> { token_1, factory, pair, - user + user, } } } -mod quote; mod get; -mod tokens; \ No newline at end of file +mod quote; +mod tokens; diff --git a/contracts/library/src/test/get.rs b/contracts/library/src/test/get.rs index 0c7308de..37552a84 100644 --- a/contracts/library/src/test/get.rs +++ b/contracts/library/src/test/get.rs @@ -1,31 +1,31 @@ -use soroban_sdk::{Address, vec, Vec}; -use crate::test::{SoroswapLibraryTest}; use crate::error::SoroswapLibraryError; - +use crate::test::SoroswapLibraryTest; +use soroban_sdk::{vec, Address, Vec}; #[test] fn get_amount_out() { let test = SoroswapLibraryTest::setup(); - - + // 100/101 = 0 - assert_eq!(0,test.contract.get_amount_out(&2, &100, &100)); + assert_eq!(0, test.contract.get_amount_out(&2, &100, &100)); // 200/102 = 1.9 = 1 - assert_eq!(1,test.contract.get_amount_out(&3, &100, &100)); + assert_eq!(1, test.contract.get_amount_out(&3, &100, &100)); //300/103 = 2.9 = 2 - assert_eq!(2,test.contract.get_amount_out(&4, &100, &100)); + assert_eq!(2, test.contract.get_amount_out(&4, &100, &100)); //1001/1002 = 0 - assert_eq!(0,test.contract.get_amount_out(&2, &1001, &1001)); + assert_eq!(0, test.contract.get_amount_out(&2, &1001, &1001)); //2002/1003 = 1.9 = 1 - assert_eq!(1,test.contract.get_amount_out(&3, &1001, &1001)); + assert_eq!(1, test.contract.get_amount_out(&3, &1001, &1001)); // Make real pair quotes: let amount_0: i128 = 123456789; let amount_1: i128 = 987654321; - + // Add Liquidity: - test.token_0.transfer(&test.user, &test.pair.address, &amount_0); - test.token_1.transfer(&test.user, &test.pair.address, &amount_1); + test.token_0 + .transfer(&test.user, &test.pair.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.pair.address, &amount_1); test.pair.deposit(&test.user); assert_eq!(test.pair.get_reserves(), (amount_0, amount_1)); @@ -34,22 +34,28 @@ fn get_amount_out() { //Deposit to do the swap let swap_amount_0: i128 = 584244; - let expected_output_amount_1 = test.contract.get_amount_out(&swap_amount_0, &amount_0, &amount_1); - test.token_0.transfer(&test.user, &test.pair.address, &swap_amount_0); + let expected_output_amount_1 = + test.contract + .get_amount_out(&swap_amount_0, &amount_0, &amount_1); + test.token_0 + .transfer(&test.user, &test.pair.address, &swap_amount_0); test.pair.swap(&0, &expected_output_amount_1, &test.user); // Check new balances: let real_out_1 = test.token_1.balance(&test.user) - initial_1; - assert_eq!(real_out_1,expected_output_amount_1); + assert_eq!(real_out_1, expected_output_amount_1); let real_in_0 = initial_0 - test.token_0.balance(&test.user); - assert_eq!(real_in_0,swap_amount_0); + assert_eq!(real_in_0, swap_amount_0); } #[test] fn get_amount_out_insufficient_input_amount() { let test = SoroswapLibraryTest::setup(); let result = test.contract.try_get_amount_out(&0, &100, &100); - assert_eq!(result, Err(Ok(SoroswapLibraryError::InsufficientInputAmount))); + assert_eq!( + result, + Err(Ok(SoroswapLibraryError::InsufficientInputAmount)) + ); } #[test] @@ -66,21 +72,22 @@ fn get_amount_out_insufficient_liquidity_1() { assert_eq!(result, Err(Ok(SoroswapLibraryError::InsufficientLiquidity))); } - #[test] fn get_amount_in() { let test = SoroswapLibraryTest::setup(); - assert_eq!(3,test.contract.get_amount_in(&1, &100, &100)); - assert_eq!(4,test.contract.get_amount_in(&2, &100, &100)); - assert_eq!(3,test.contract.get_amount_in(&1, &1001, &1001)); + assert_eq!(3, test.contract.get_amount_in(&1, &100, &100)); + assert_eq!(4, test.contract.get_amount_in(&2, &100, &100)); + assert_eq!(3, test.contract.get_amount_in(&1, &1001, &1001)); // Make real pair quotes: let amount_0: i128 = 123456789; let amount_1: i128 = 987654321; - + // Add Liquidity: - test.token_0.transfer(&test.user, &test.pair.address, &amount_0); - test.token_1.transfer(&test.user, &test.pair.address, &amount_1); + test.token_0 + .transfer(&test.user, &test.pair.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.pair.address, &amount_1); test.pair.deposit(&test.user); assert_eq!(test.pair.get_reserves(), (amount_0, amount_1)); @@ -89,21 +96,28 @@ fn get_amount_in() { //Deposit to do the swap let swap_expected_output_amount_1 = 76543; - let swap_required_amount_0: i128 = test.contract.get_amount_in(&swap_expected_output_amount_1, &amount_0, &amount_1); - test.token_0.transfer(&test.user, &test.pair.address, &swap_required_amount_0); - test.pair.swap(&0, &swap_expected_output_amount_1, &test.user); + let swap_required_amount_0: i128 = + test.contract + .get_amount_in(&swap_expected_output_amount_1, &amount_0, &amount_1); + test.token_0 + .transfer(&test.user, &test.pair.address, &swap_required_amount_0); + test.pair + .swap(&0, &swap_expected_output_amount_1, &test.user); // Check new balances: let real_out_1 = test.token_1.balance(&test.user) - initial_1; let real_in_0 = initial_0 - test.token_0.balance(&test.user); - assert_eq!(real_out_1,swap_expected_output_amount_1); - assert_eq!(real_in_0,swap_required_amount_0); + assert_eq!(real_out_1, swap_expected_output_amount_1); + assert_eq!(real_in_0, swap_required_amount_0); } #[test] fn get_amount_in_insufficient_output_amount() { let test = SoroswapLibraryTest::setup(); let result = test.contract.try_get_amount_in(&0, &100, &100); - assert_eq!(result, Err(Ok(SoroswapLibraryError::InsufficientOutputAmount))); + assert_eq!( + result, + Err(Ok(SoroswapLibraryError::InsufficientOutputAmount)) + ); } #[test] @@ -120,27 +134,36 @@ fn get_amount_in_insufficient_liquidity_1() { assert_eq!(result, Err(Ok(SoroswapLibraryError::InsufficientLiquidity))); } - #[test] fn get_amounts_out() { let test = SoroswapLibraryTest::setup(); - - let path: Vec
= vec![&test.env, test.token_0.address.clone(), test.token_1.address.clone()]; + + let path: Vec
= vec![ + &test.env, + test.token_0.address.clone(), + test.token_1.address.clone(), + ]; // User needs to send these tokens first to the contract - test.token_0.transfer(&test.user, &test.pair.address, &10000); - test.token_1.transfer(&test.user, &test.pair.address, &10000); + test.token_0 + .transfer(&test.user, &test.pair.address, &10000); + test.token_1 + .transfer(&test.user, &test.pair.address, &10000); test.pair.deposit(&test.user); let expected_amounts_out = vec![&test.env, 3, 1]; - let amounts_out = test.contract.get_amounts_out(&test.factory.address, &3, &path); - assert_eq!(expected_amounts_out,amounts_out); + let amounts_out = test + .contract + .get_amounts_out(&test.factory.address, &3, &path); + assert_eq!(expected_amounts_out, amounts_out); } #[test] fn get_amounts_out_invalid_path() { let test = SoroswapLibraryTest::setup(); let path: Vec
= vec![&test.env, test.token_0.address.clone()]; - let result = test.contract.try_get_amounts_out(&test.factory.address, &2, &path); + let result = test + .contract + .try_get_amounts_out(&test.factory.address, &2, &path); assert_eq!(result, Err(Ok(SoroswapLibraryError::InvalidPath))); } @@ -148,37 +171,49 @@ fn get_amounts_out_invalid_path() { fn get_amounts_in() { let test = SoroswapLibraryTest::setup(); - let path: Vec
= vec![&test.env, test.token_0.address.clone(), test.token_1.address.clone()]; + let path: Vec
= vec![ + &test.env, + test.token_0.address.clone(), + test.token_1.address.clone(), + ]; // User needs to send these tokens first to the contract - test.token_0.transfer(&test.user, &test.pair.address, &10000); - test.token_1.transfer(&test.user, &test.pair.address, &10000); + test.token_0 + .transfer(&test.user, &test.pair.address, &10000); + test.token_1 + .transfer(&test.user, &test.pair.address, &10000); test.pair.deposit(&test.user); - + let expected_amounts_in = vec![&test.env, 3, 1]; - let amounts_out = test.contract.get_amounts_in(&test.factory.address, &1, &path); - assert_eq!(expected_amounts_in,amounts_out); + let amounts_out = test + .contract + .get_amounts_in(&test.factory.address, &1, &path); + assert_eq!(expected_amounts_in, amounts_out); } #[test] fn get_amounts_in_invalid_path() { let test = SoroswapLibraryTest::setup(); let path: Vec
= vec![&test.env, test.token_0.address.clone()]; - let result = test.contract.try_get_amounts_in(&test.factory.address, &1, &path); + let result = test + .contract + .try_get_amounts_in(&test.factory.address, &1, &path); assert_eq!(result, Err(Ok(SoroswapLibraryError::InvalidPath))); } #[test] fn get_reserves_with_pair() { let test = SoroswapLibraryTest::setup(); - + // Make real pair quotes: let amount_0: i128 = 123456789; let amount_1: i128 = 987654321; - + // Add Liquidity: - test.token_0.transfer(&test.user, &test.pair.address, &amount_0); - test.token_1.transfer(&test.user, &test.pair.address, &amount_1); + test.token_0 + .transfer(&test.user, &test.pair.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.pair.address, &amount_1); test.pair.deposit(&test.user); assert_eq!(test.pair.get_reserves(), (amount_0, amount_1)); -} \ No newline at end of file +} diff --git a/contracts/library/src/test/quote.rs b/contracts/library/src/test/quote.rs index e71fa9dd..dbc27220 100644 --- a/contracts/library/src/test/quote.rs +++ b/contracts/library/src/test/quote.rs @@ -1,5 +1,5 @@ -use crate::test::{SoroswapLibraryTest}; use crate::error::SoroswapLibraryError; +use crate::test::SoroswapLibraryTest; #[test] fn quote_insufficient_amount() { @@ -25,6 +25,6 @@ fn quote_insufficient_liquidity_1() { #[test] fn quote() { let test = SoroswapLibraryTest::setup(); - assert_eq!(2,test.contract.quote(&1, &100, &200)); - assert_eq!(1,test.contract.quote(&2, &200, &100)); + assert_eq!(2, test.contract.quote(&1, &100, &200)); + assert_eq!(1, test.contract.quote(&2, &200, &100)); } diff --git a/contracts/library/src/test/tokens.rs b/contracts/library/src/test/tokens.rs index 0235775a..866d143e 100644 --- a/contracts/library/src/test/tokens.rs +++ b/contracts/library/src/test/tokens.rs @@ -1,13 +1,14 @@ -use soroban_sdk::{Address, String}; -use crate::test::{SoroswapLibraryTest}; use crate::error::SoroswapLibraryError; - - +use crate::test::SoroswapLibraryTest; +use soroban_sdk::{Address, String}; #[test] fn sort_tokens_same_address() { let test = SoroswapLibraryTest::setup(); - let address_0 = Address::from_string(&String::from_str(&test.env, "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC")); + let address_0 = Address::from_string(&String::from_str( + &test.env, + "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", + )); let result = test.contract.try_sort_tokens(&address_0, &address_0); assert_eq!(result, Err(Ok(SoroswapLibraryError::SortIdenticalTokens))); } @@ -15,16 +16,41 @@ fn sort_tokens_same_address() { #[test] fn sort_tokens_correct_order() { let test = SoroswapLibraryTest::setup(); - let address_0 = Address::from_string(&String::from_str(&test.env, "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC")); - let address_1 = Address::from_string(&String::from_str(&test.env, "CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4")); - assert_eq!((address_0.clone(), address_1.clone()),test.contract.sort_tokens(&address_0, &address_1)); - assert_eq!((address_0.clone(), address_1.clone()),test.contract.sort_tokens(&address_1, &address_0)); + let address_0 = Address::from_string(&String::from_str( + &test.env, + "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", + )); + let address_1 = Address::from_string(&String::from_str( + &test.env, + "CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4", + )); + assert_eq!( + (address_0.clone(), address_1.clone()), + test.contract.sort_tokens(&address_0, &address_1) + ); + assert_eq!( + (address_0.clone(), address_1.clone()), + test.contract.sort_tokens(&address_1, &address_0) + ); } - #[test] fn pair_for() { let test = SoroswapLibraryTest::setup(); - assert_eq!(test.pair.address,test.contract.pair_for(&test.factory.address, &test.token_0.address, &test.token_1.address)); - assert_eq!(test.pair.address,test.contract.pair_for(&test.factory.address, &test.token_1.address, &test.token_0.address)); -} \ No newline at end of file + assert_eq!( + test.pair.address, + test.contract.pair_for( + &test.factory.address, + &test.token_0.address, + &test.token_1.address + ) + ); + assert_eq!( + test.pair.address, + test.contract.pair_for( + &test.factory.address, + &test.token_1.address, + &test.token_0.address + ) + ); +} diff --git a/contracts/library/src/tokens.rs b/contracts/library/src/tokens.rs index 2a591b51..c2d16907 100644 --- a/contracts/library/src/tokens.rs +++ b/contracts/library/src/tokens.rs @@ -1,6 +1,5 @@ -use soroban_sdk::{Address, Env, xdr::ToXdr, BytesN, Bytes}; use crate::error::SoroswapLibraryError; - +use soroban_sdk::{xdr::ToXdr, Address, Bytes, BytesN, Env}; /// Generates a unique cryptographic salt value for a pair of token addresses. /// @@ -34,7 +33,10 @@ fn pair_salt(e: &Env, token_a: Address, token_b: Address) -> BytesN<32> { /// # Returns /// /// Returns `Result<(Address, Address), SoroswapLibraryError>` where `Ok` contains a tuple with the sorted token addresses, and `Err` indicates an error such as identical tokens. -pub fn sort_tokens(token_a: Address, token_b: Address) -> Result<(Address, Address), SoroswapLibraryError> { +pub fn sort_tokens( + token_a: Address, + token_b: Address, +) -> Result<(Address, Address), SoroswapLibraryError> { if token_a == token_b { return Err(SoroswapLibraryError::SortIdenticalTokens); } @@ -59,10 +61,15 @@ pub fn sort_tokens(token_a: Address, token_b: Address) -> Result<(Address, Addre /// # Returns /// /// Returns `Result` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting. -pub fn pair_for(e: Env, factory: Address, token_a: Address, token_b: Address) -> Result { +pub fn pair_for( + e: Env, + factory: Address, + token_a: Address, + token_b: Address, +) -> Result { let (token_0, token_1) = sort_tokens(token_a, token_b)?; let salt = pair_salt(&e, token_0, token_1); let deployer_with_address = e.deployer().with_address(factory.clone(), salt); let deterministic_address = deployer_with_address.deployed_address(); Ok(deterministic_address) -} \ No newline at end of file +} diff --git a/contracts/pair/src/balances.rs b/contracts/pair/src/balances.rs index f418bb22..9757f914 100644 --- a/contracts/pair/src/balances.rs +++ b/contracts/pair/src/balances.rs @@ -1,8 +1,7 @@ -use soroban_sdk::{Address, Env}; -use crate::{soroswap_pair_token::{SoroswapPairToken}, any_token}; use crate::storage::*; +use crate::{any_token, soroswap_pair_token::SoroswapPairToken}; use soroban_sdk::token::Interface; - +use soroban_sdk::{Address, Env}; pub fn get_balance(e: &Env, contract_id: Address) -> i128 { // How many "contract_id" tokens does this contract holds? @@ -24,4 +23,4 @@ pub fn get_balance_shares(e: &Env) -> i128 { // How many "SHARE" tokens does the Liquidity pool holds? // This shares should have been sent by the user when burning their LP positions (withdraw) SoroswapPairToken::balance(e.clone(), e.current_contract_address()) -} \ No newline at end of file +} diff --git a/contracts/pair/src/error.rs b/contracts/pair/src/error.rs index 717ce4ab..d5a0daf8 100644 --- a/contracts/pair/src/error.rs +++ b/contracts/pair/src/error.rs @@ -21,7 +21,6 @@ pub enum SoroswapPairError { /// SoroswapPair: insufficient liquidity minted while doing deposit DepositInsufficientLiquidityMinted = 107, /// SoroswapPair: insufficient output amount while doing deposDepositit - SwapInsufficientOutputAmount = 108, /// SoroswapPair: negatives amounts out dont supported while doing swap SwapNegativesOutNotSupported = 109, @@ -46,5 +45,3 @@ pub enum SoroswapPairError { /// SoroswapPair: OVERFLOW while updating UpdateOverflow = 118, } - - diff --git a/contracts/pair/src/event.rs b/contracts/pair/src/event.rs index 883fe75f..bb863e0c 100644 --- a/contracts/pair/src/event.rs +++ b/contracts/pair/src/event.rs @@ -1,5 +1,5 @@ //! Definition of the Events used in the contract -use soroban_sdk::{contracttype, symbol_short, Env, Address}; +use soroban_sdk::{contracttype, symbol_short, Address, Env}; // DEPOSIT EVENT #[contracttype] @@ -14,26 +14,26 @@ pub struct DepositEvent { } pub(crate) fn deposit( - e: &Env, + e: &Env, to: Address, amount_0: i128, amount_1: i128, liquidity: i128, new_reserve_0: i128, - new_reserve_1: i128) { - + new_reserve_1: i128, +) { let event: DepositEvent = DepositEvent { to: to, amount_0: amount_0, amount_1: amount_1, liquidity: liquidity, new_reserve_0: new_reserve_0, - new_reserve_1: new_reserve_1 + new_reserve_1: new_reserve_1, }; - e.events().publish(("SoroswapPair", symbol_short!("deposit")), event); + e.events() + .publish(("SoroswapPair", symbol_short!("deposit")), event); } - // SWAP EVENT #[contracttype] @@ -61,12 +61,12 @@ pub(crate) fn swap( amount_0_out: amount_0_out, amount_1_out: amount_1_out, }; - e.events().publish(("SoroswapPair", symbol_short!("swap")), event); + e.events() + .publish(("SoroswapPair", symbol_short!("swap")), event); } // WITHDRAW EVENT - #[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct WithdrawEvent { @@ -95,7 +95,8 @@ pub(crate) fn withdraw( new_reserve_0: new_reserve_0, new_reserve_1: new_reserve_1, }; - e.events().publish(("SoroswapPair", symbol_short!("withdraw")), event); + e.events() + .publish(("SoroswapPair", symbol_short!("withdraw")), event); } // SYNC EVENT @@ -112,10 +113,10 @@ pub(crate) fn sync(e: &Env, new_reserve_0: i128, new_reserve_1: i128) { new_reserve_0: new_reserve_0, new_reserve_1: new_reserve_1, }; - e.events().publish(("SoroswapPair", symbol_short!("sync")), event); + e.events() + .publish(("SoroswapPair", symbol_short!("sync")), event); } - // SKIM EVENT #[contracttype] @@ -130,5 +131,6 @@ pub(crate) fn skim(e: &Env, skimmed_0: i128, skimmed_1: i128) { skimmed_0: skimmed_0, skimmed_1: skimmed_1, }; - e.events().publish(("SoroswapPair", symbol_short!("skim")), event); -} \ No newline at end of file + e.events() + .publish(("SoroswapPair", symbol_short!("skim")), event); +} diff --git a/contracts/pair/src/lib.rs b/contracts/pair/src/lib.rs index cfe959d0..6a08116a 100644 --- a/contracts/pair/src/lib.rs +++ b/contracts/pair/src/lib.rs @@ -1,31 +1,32 @@ #![no_std] -use soroban_sdk::{contract, contractimpl, contractmeta, Address, Env, String}; -use num_integer::Roots; -use soroswap_factory_interface::SoroswapFactoryClient; +use num_integer::Roots; +use soroban_sdk::{contract, contractimpl, contractmeta, Address, Env, String}; use soroban_token_sdk::metadata::TokenMetadata; +use soroswap_factory_interface::SoroswapFactoryClient; - -mod soroswap_pair_token; -mod storage; mod balances; +mod error; mod event; -mod error; -mod test; mod math; +mod soroswap_pair_token; +mod storage; mod strings; +mod test; // ANY TOKEN CONTRACT // TODO: Simplify this and use a any_token_interface pub mod any_token { - soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!( + file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm" + ); pub type TokenClient<'a> = Client<'a>; } -use storage::*; use balances::*; -use soroswap_pair_token::{SoroswapPairToken, internal_mint, internal_burn, write_metadata}; use error::SoroswapPairError; use math::CheckedCeilingDiv; +use soroswap_pair_token::{internal_burn, internal_mint, write_metadata, SoroswapPairToken}; +use storage::*; use strings::TakeFirstNCharsAndConcat; static MINIMUM_LIQUIDITY: i128 = 1000; @@ -35,7 +36,10 @@ fn create_symbol(e: &Env, symbol_0: &String, symbol_1: &String) -> String { let symbol_1_short = symbol_1.take_first_n_chars(&e, 6); let hyphen = String::from_str(&e, "-"); let end = String::from_str(&e, "-SOROSWAP-LP"); - symbol_0_short.concat(&e, hyphen).concat(&e, symbol_1_short).concat(&e, end) + symbol_0_short + .concat(&e, hyphen) + .concat(&e, symbol_1_short) + .concat(&e, end) } fn create_name(e: &Env, symbol_0: &String, symbol_1: &String) -> String { @@ -43,7 +47,10 @@ fn create_name(e: &Env, symbol_0: &String, symbol_1: &String) -> String { let symbol_1_short = symbol_1.take_first_n_chars(&e, 6); let hyphen = String::from_str(&e, "-"); let end = String::from_str(&e, " Soroswap LP Token"); - symbol_0_short.concat(&e, hyphen).concat(&e, symbol_1_short).concat(&e, end) + symbol_0_short + .concat(&e, hyphen) + .concat(&e, symbol_1_short) + .concat(&e, end) } // Metadata that is added on to the WASM custom section @@ -52,19 +59,29 @@ contractmeta!( val = "Soroswap.Finance Protocol - Constant product AMM with a .3% swap fee" ); -pub trait SoroswapPairTrait{ +pub trait SoroswapPairTrait { // Sets the token contract addresses for this pool - fn initialize(e: Env, factory: Address, token_0: Address, token_1: Address)-> Result<(), SoroswapPairError>; + fn initialize( + e: Env, + factory: Address, + token_0: Address, + token_1: Address, + ) -> Result<(), SoroswapPairError>; - fn deposit(e:Env, to: Address) -> Result; + fn deposit(e: Env, to: Address) -> Result; // Swaps. This function should be called from another contract that has already sent tokens to the pair contract - fn swap(e: Env, amount_0_out: i128, amount_1_out: i128, to: Address) -> Result<(), SoroswapPairError>; + fn swap( + e: Env, + amount_0_out: i128, + amount_1_out: i128, + to: Address, + ) -> Result<(), SoroswapPairError>; fn withdraw(e: Env, to: Address) -> Result<(i128, i128), SoroswapPairError>; - // transfers the excess token balances from the pair to the specified to address, - // ensuring that the balances match the reserves by subtracting the reserve amounts + // transfers the excess token balances from the pair to the specified to address, + // ensuring that the balances match the reserves by subtracting the reserve amounts // from the current balances. fn skim(e: Env, to: Address); @@ -80,7 +97,6 @@ pub trait SoroswapPairTrait{ fn k_last(e: Env) -> i128; fn get_reserves(e: Env) -> (i128, i128); - } #[contract] @@ -88,7 +104,6 @@ struct SoroswapPair; #[contractimpl] impl SoroswapPairTrait for SoroswapPair { - /// Initializes a new Soroswap pair by setting token addresses, factory, and initial reserves. /// /// # Arguments @@ -96,7 +111,12 @@ impl SoroswapPairTrait for SoroswapPair { /// * `factory` - The address of the Soroswap factory contract. /// * `token_0` - The address of the first token in the pair. /// * `token_1` - The address of the second token in the pair. - fn initialize(e: Env, factory: Address, token_0: Address, token_1: Address) -> Result<(), SoroswapPairError> { + fn initialize( + e: Env, + factory: Address, + token_0: Address, + token_1: Address, + ) -> Result<(), SoroswapPairError> { if has_token_0(&e) { return Err(SoroswapPairError::InitializeAlreadyInitialized); } @@ -109,15 +129,15 @@ impl SoroswapPairTrait for SoroswapPair { let symbol_0: String = any_token::TokenClient::new(&e, &token_0).symbol(); let symbol_1: String = any_token::TokenClient::new(&e, &token_1).symbol(); - + let decimal: u32 = 7; let name: String = create_name(&e, &symbol_0, &symbol_1); let symbol: String = create_symbol(&e, &symbol_0, &symbol_1); - + write_metadata( &e, TokenMetadata { - decimal , + decimal, name, symbol, }, @@ -167,15 +187,19 @@ impl SoroswapPairTrait for SoroswapPair { /// - `SoroswapPairError::UpdateOverflow`: Overflow occurred during update. fn deposit(e: Env, to: Address) -> Result { extend_instance_ttl(&e); - - if !has_token_0(&e){ - return Err(SoroswapPairError::NotInitialized) + + if !has_token_0(&e) { + return Err(SoroswapPairError::NotInitialized); } let (mut reserve_0, mut reserve_1) = (get_reserve_0(&e), get_reserve_1(&e)); let (balance_0, balance_1) = (get_balance_0(&e), get_balance_1(&e)); - let amount_0 = balance_0.checked_sub(reserve_0).ok_or(SoroswapPairError::DepositInsufficientAmountToken0)?; - let amount_1 = balance_1.checked_sub(reserve_1).ok_or(SoroswapPairError::DepositInsufficientAmountToken1)?; + let amount_0 = balance_0 + .checked_sub(reserve_0) + .ok_or(SoroswapPairError::DepositInsufficientAmountToken0)?; + let amount_1 = balance_1 + .checked_sub(reserve_1) + .ok_or(SoroswapPairError::DepositInsufficientAmountToken1)?; if amount_0 <= 0 { return Err(SoroswapPairError::DepositInsufficientAmountToken0); @@ -197,8 +221,12 @@ impl SoroswapPairTrait for SoroswapPair { } (previous_liquidity).checked_sub(MINIMUM_LIQUIDITY).unwrap() } else { - let shares_0 = (amount_0.checked_mul(total_supply).unwrap()).checked_div(reserve_0).unwrap(); - let shares_1 = (amount_1.checked_mul(total_supply).unwrap()).checked_div(reserve_1).unwrap(); + let shares_0 = (amount_0.checked_mul(total_supply).unwrap()) + .checked_div(reserve_0) + .unwrap(); + let shares_1 = (amount_1.checked_mul(total_supply).unwrap()) + .checked_div(reserve_1) + .unwrap(); shares_0.min(shares_1) }; @@ -216,7 +244,7 @@ impl SoroswapPairTrait for SoroswapPair { event::deposit(&e, to, amount_0, amount_1, liquidity, reserve_0, reserve_1); - Ok(liquidity) + Ok(liquidity) } /// Executes a token swap within the Soroswap pair. @@ -236,15 +264,20 @@ impl SoroswapPairTrait for SoroswapPair { /// - `SoroswapPairError::SwapInsufficientInputAmount` /// - `SoroswapPairError::SwapNegativesInNotSupported` /// - `SoroswapPairError::SwapKConstantNotMet`: If the K constant condition is not met after the swap. - fn swap(e: Env, amount_0_out: i128, amount_1_out: i128, to: Address) -> Result<(), SoroswapPairError> { + fn swap( + e: Env, + amount_0_out: i128, + amount_1_out: i128, + to: Address, + ) -> Result<(), SoroswapPairError> { extend_instance_ttl(&e); if !has_token_0(&e) { return Err(SoroswapPairError::NotInitialized); } - + let (reserve_0, reserve_1) = (get_reserve_0(&e), get_reserve_1(&e)); - + if amount_0_out == 0 && amount_1_out == 0 { return Err(SoroswapPairError::SwapInsufficientOutputAmount); } @@ -268,12 +301,16 @@ impl SoroswapPairTrait for SoroswapPair { let (balance_0, balance_1) = (get_balance_0(&e), get_balance_1(&e)); let amount_0_in = if balance_0 > reserve_0.checked_sub(amount_0_out).unwrap() { - balance_0.checked_sub(reserve_0.checked_sub(amount_0_out).unwrap()).unwrap() + balance_0 + .checked_sub(reserve_0.checked_sub(amount_0_out).unwrap()) + .unwrap() } else { 0 }; let amount_1_in = if balance_1 > reserve_1.checked_sub(amount_1_out).unwrap() { - balance_1.checked_sub(reserve_1.checked_sub(amount_1_out).unwrap()).unwrap() + balance_1 + .checked_sub(reserve_1.checked_sub(amount_1_out).unwrap()) + .unwrap() } else { 0 }; @@ -285,25 +322,31 @@ impl SoroswapPairTrait for SoroswapPair { return Err(SoroswapPairError::SwapNegativesInNotSupported); } - let fee_0 = (amount_0_in.checked_mul(3).unwrap()).checked_ceiling_div(1000).unwrap(); - let fee_1 = (amount_1_in.checked_mul(3).unwrap()).checked_ceiling_div(1000).unwrap(); + let fee_0 = (amount_0_in.checked_mul(3).unwrap()) + .checked_ceiling_div(1000) + .unwrap(); + let fee_1 = (amount_1_in.checked_mul(3).unwrap()) + .checked_ceiling_div(1000) + .unwrap(); let balance_0_minus_fee = balance_0.checked_sub(fee_0).unwrap(); let balance_1_minus_fee = balance_1.checked_sub(fee_1).unwrap(); - if balance_0_minus_fee.checked_mul(balance_1_minus_fee).unwrap() < - reserve_0.checked_mul(reserve_1).unwrap() { + if balance_0_minus_fee + .checked_mul(balance_1_minus_fee) + .unwrap() + < reserve_0.checked_mul(reserve_1).unwrap() + { return Err(SoroswapPairError::SwapKConstantNotMet); } update(&e, balance_0, balance_1); - + event::swap(&e, to, amount_0_in, amount_1_in, amount_0_out, amount_1_out); Ok(()) } - /// Withdraws liquidity from the Soroswap pair, burning LP tokens and returning the corresponding tokens to the user. /// /// # Arguments @@ -318,7 +361,7 @@ impl SoroswapPairTrait for SoroswapPair { if !has_token_0(&e) { return Err(SoroswapPairError::NotInitialized); } - + let balance_shares = get_balance_shares(&e); if balance_shares == 0 { return Err(SoroswapPairError::WithdrawLiquidityNotInitialized); @@ -331,13 +374,16 @@ impl SoroswapPairTrait for SoroswapPair { if user_sent_shares <= 0 { return Err(SoroswapPairError::WithdrawInsufficientSentShares); } - let fee_on: bool = mint_fee(&e, reserve_0, reserve_1); let total_supply = SoroswapPairToken::total_supply(e.clone()); - let amount_0 = (balance_0.checked_mul(user_sent_shares).unwrap()).checked_div(total_supply).unwrap(); - let amount_1 = (balance_1.checked_mul(user_sent_shares).unwrap()).checked_div(total_supply).unwrap(); + let amount_0 = (balance_0.checked_mul(user_sent_shares).unwrap()) + .checked_div(total_supply) + .unwrap(); + let amount_1 = (balance_1.checked_mul(user_sent_shares).unwrap()) + .checked_div(total_supply) + .unwrap(); if amount_0 <= 0 || amount_1 <= 0 { return Err(SoroswapPairError::WithdrawInsufficientLiquidityBurned); @@ -357,7 +403,15 @@ impl SoroswapPairTrait for SoroswapPair { put_klast(&e, reserve_0.checked_mul(reserve_1).unwrap()); } - event::withdraw(&e, to, user_sent_shares, amount_0, amount_1, reserve_0, reserve_1); + event::withdraw( + &e, + to, + user_sent_shares, + amount_0, + amount_1, + reserve_0, + reserve_1, + ); Ok((amount_0, amount_1)) } @@ -402,7 +456,6 @@ impl SoroswapPairTrait for SoroswapPair { (get_reserve_0(&e), get_reserve_1(&e)) } - /// Returns the value of the last product of reserves (`K`) stored in the contract. /// /// # Arguments @@ -412,15 +465,17 @@ impl SoroswapPairTrait for SoroswapPair { /// The value of the last product of reserves (`K`). fn k_last(e: Env) -> i128 { extend_instance_ttl(&e); - + get_klast(&e) } - - } fn transfer(e: &Env, contract_id: Address, to: &Address, amount: i128) { - any_token::TokenClient::new(e, &contract_id).transfer(&e.current_contract_address(), &to, &amount); + any_token::TokenClient::new(e, &contract_id).transfer( + &e.current_contract_address(), + &to, + &amount, + ); } fn transfer_token_0_from_pair(e: &Env, to: &Address, amount: i128) { @@ -432,29 +487,34 @@ fn transfer_token_1_from_pair(e: &Env, to: &Address, amount: i128) { transfer(e, get_token_1(e), &to, amount); } -fn mint_fee(e: &Env, reserve_0: i128, reserve_1: i128) -> bool{ - +fn mint_fee(e: &Env, reserve_0: i128, reserve_1: i128) -> bool { /* - accumulated fees are collected only when liquidity is deposited + accumulated fees are collected only when liquidity is deposited or withdrawn. The contract computes the accumulated fees, and mints new liquidity tokens - to the fee beneficiary, immediately before any tokens are minted or burned + to the fee beneficiary, immediately before any tokens are minted or burned */ let factory = get_factory(&e); let factory_client = SoroswapFactoryClient::new(&e, &factory); let fee_on = factory_client.fees_enabled(); let klast = get_klast(&e); - - if fee_on{ + + if fee_on { let fee_to: Address = factory_client.fee_to(); if klast != 0 { let root_k = (reserve_0.checked_mul(reserve_1).unwrap()).sqrt(); let root_klast = (klast).sqrt(); - if root_k > root_klast{ + if root_k > root_klast { let total_supply = SoroswapPairToken::total_supply(e.clone()); - let numerator = total_supply.checked_mul(root_k.checked_sub(root_klast).unwrap()).unwrap(); - let denominator = root_k.checked_mul(5_i128).unwrap().checked_add(root_klast).unwrap(); + let numerator = total_supply + .checked_mul(root_k.checked_sub(root_klast).unwrap()) + .unwrap(); + let denominator = root_k + .checked_mul(5_i128) + .unwrap() + .checked_add(root_klast) + .unwrap(); let liquidity_pool_shares_fees = numerator.checked_div(denominator).unwrap(); if liquidity_pool_shares_fees > 0 { @@ -462,7 +522,7 @@ fn mint_fee(e: &Env, reserve_0: i128, reserve_1: i128) -> bool{ } } } - } else if klast != 0{ + } else if klast != 0 { put_klast(&e, 0); } @@ -473,4 +533,4 @@ fn update(e: &Env, balance_0: i128, balance_1: i128) { put_reserve_0(&e, balance_0); put_reserve_1(&e, balance_1); event::sync(&e, balance_0, balance_1); -} \ No newline at end of file +} diff --git a/contracts/pair/src/math.rs b/contracts/pair/src/math.rs index a29d2d9d..14335f6b 100644 --- a/contracts/pair/src/math.rs +++ b/contracts/pair/src/math.rs @@ -11,4 +11,4 @@ impl CheckedCeilingDiv for i128 { Some(result) } } -} \ No newline at end of file +} diff --git a/contracts/pair/src/soroswap_pair_token/allowance.rs b/contracts/pair/src/soroswap_pair_token/allowance.rs index 6b6df57a..7afdd2aa 100644 --- a/contracts/pair/src/soroswap_pair_token/allowance.rs +++ b/contracts/pair/src/soroswap_pair_token/allowance.rs @@ -62,5 +62,4 @@ pub fn spend_allowance(e: &Env, from: Address, spender: Address, amount: i128) { allowance.expiration_ledger, ); } - } diff --git a/contracts/pair/src/soroswap_pair_token/balance.rs b/contracts/pair/src/soroswap_pair_token/balance.rs index 6753b42e..dfbfaed9 100644 --- a/contracts/pair/src/soroswap_pair_token/balance.rs +++ b/contracts/pair/src/soroswap_pair_token/balance.rs @@ -1,4 +1,6 @@ -use crate::soroswap_pair_token::storage_types::{DataKey, BALANCE_BUMP_AMOUNT, BALANCE_LIFETIME_THRESHOLD}; +use crate::soroswap_pair_token::storage_types::{ + DataKey, BALANCE_BUMP_AMOUNT, BALANCE_LIFETIME_THRESHOLD, +}; use soroban_sdk::{Address, Env}; pub fn read_balance(e: &Env, addr: Address) -> i128 { @@ -24,7 +26,8 @@ fn write_balance(e: &Env, addr: Address, amount: i128) { pub fn receive_balance(e: &Env, addr: Address, amount: i128) { let balance = read_balance(e, addr.clone()); - let new_balance = balance.checked_add(amount) + let new_balance = balance + .checked_add(amount) .expect("Integer overflow occurred while adding balance."); write_balance(e, addr, new_balance); diff --git a/contracts/pair/src/soroswap_pair_token/contract.rs b/contracts/pair/src/soroswap_pair_token/contract.rs index 1e155dc7..c5efd3a8 100644 --- a/contracts/pair/src/soroswap_pair_token/contract.rs +++ b/contracts/pair/src/soroswap_pair_token/contract.rs @@ -3,11 +3,15 @@ use crate::soroswap_pair_token::allowance::{read_allowance, spend_allowance, write_allowance}; use crate::soroswap_pair_token::balance::{read_balance, receive_balance, spend_balance}; use crate::soroswap_pair_token::metadata::{read_decimal, read_name, read_symbol}; -use crate::soroswap_pair_token::total_supply::{read_total_supply, increase_total_supply, decrease_total_supply}; +use crate::soroswap_pair_token::total_supply::{ + decrease_total_supply, increase_total_supply, read_total_supply, +}; #[cfg(test)] use crate::soroswap_pair_token::storage_types::{AllowanceDataKey, AllowanceValue, DataKey}; -use crate::soroswap_pair_token::storage_types::{INSTANCE_BUMP_AMOUNT, INSTANCE_LIFETIME_THRESHOLD}; +use crate::soroswap_pair_token::storage_types::{ + INSTANCE_BUMP_AMOUNT, INSTANCE_LIFETIME_THRESHOLD, +}; use soroban_sdk::token::{self, Interface as _}; use soroban_sdk::{contract, contractimpl, Address, Env, String}; use soroban_token_sdk::TokenUtils; @@ -20,16 +24,16 @@ fn check_nonnegative_amount(amount: i128) { pub fn internal_burn(e: Env, from: Address, amount: i128) { check_nonnegative_amount(amount); - + e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - + .instance() + .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); + spend_balance(&e, from.clone(), amount); decrease_total_supply(&e, amount); TokenUtils::new(&e).events().burn(from, amount); -} +} pub fn internal_mint(e: Env, to: Address, amount: i128) { check_nonnegative_amount(amount); @@ -37,20 +41,20 @@ pub fn internal_mint(e: Env, to: Address, amount: i128) { e.storage() .instance() .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - + receive_balance(&e, to.clone(), amount); increase_total_supply(&e, amount); - TokenUtils::new(&e).events().mint(e.current_contract_address(), to, amount); + TokenUtils::new(&e) + .events() + .mint(e.current_contract_address(), to, amount); } - #[contract] pub struct SoroswapPairToken; #[contractimpl] impl SoroswapPairToken { - pub fn total_supply(e: Env) -> i128 { read_total_supply(&e) } @@ -64,7 +68,7 @@ impl SoroswapPairToken { } #[contractimpl] -impl token::Interface for SoroswapPairToken { +impl token::Interface for SoroswapPairToken { fn allowance(e: Env, from: Address, spender: Address) -> i128 { e.storage() .instance() diff --git a/contracts/pair/src/soroswap_pair_token/metadata.rs b/contracts/pair/src/soroswap_pair_token/metadata.rs index 79777789..715feeea 100644 --- a/contracts/pair/src/soroswap_pair_token/metadata.rs +++ b/contracts/pair/src/soroswap_pair_token/metadata.rs @@ -19,4 +19,4 @@ pub fn read_symbol(e: &Env) -> String { pub fn write_metadata(e: &Env, metadata: TokenMetadata) { let util = TokenUtils::new(e); util.metadata().set_metadata(&metadata); -} \ No newline at end of file +} diff --git a/contracts/pair/src/soroswap_pair_token/mod.rs b/contracts/pair/src/soroswap_pair_token/mod.rs index 0e15b648..3388da73 100644 --- a/contracts/pair/src/soroswap_pair_token/mod.rs +++ b/contracts/pair/src/soroswap_pair_token/mod.rs @@ -7,7 +7,7 @@ mod metadata; mod storage_types; mod total_supply; -pub use contract::SoroswapPairTokenClient; pub use contract::SoroswapPairToken; -pub use contract::{internal_mint, internal_burn}; +pub use contract::SoroswapPairTokenClient; +pub use contract::{internal_burn, internal_mint}; pub use metadata::write_metadata; diff --git a/contracts/pair/src/soroswap_pair_token/storage_types.rs b/contracts/pair/src/soroswap_pair_token/storage_types.rs index 7b547911..1c12064c 100644 --- a/contracts/pair/src/soroswap_pair_token/storage_types.rs +++ b/contracts/pair/src/soroswap_pair_token/storage_types.rs @@ -25,5 +25,5 @@ pub struct AllowanceValue { pub enum DataKey { Allowance(AllowanceDataKey), Balance(Address), - TotalSupply -} \ No newline at end of file + TotalSupply, +} diff --git a/contracts/pair/src/soroswap_pair_token/total_supply.rs b/contracts/pair/src/soroswap_pair_token/total_supply.rs index 8949ba8b..86ddef94 100644 --- a/contracts/pair/src/soroswap_pair_token/total_supply.rs +++ b/contracts/pair/src/soroswap_pair_token/total_supply.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{Env}; +use soroban_sdk::Env; use crate::soroswap_pair_token::storage_types::DataKey; @@ -14,7 +14,8 @@ pub fn write_total_supply(e: &Env, id: &i128) { pub fn increase_total_supply(e: &Env, amount: i128) { let total_supply = read_total_supply(&e); - let new_total_supply = total_supply.checked_add(amount) + let new_total_supply = total_supply + .checked_add(amount) .expect("Integer overflow occurred while increasing total supply."); write_total_supply(&e, &new_total_supply); } @@ -24,7 +25,8 @@ pub fn decrease_total_supply(e: &Env, amount: i128) { if total_supply < amount { panic!("insufficient total supply"); } - let new_total_supply = total_supply.checked_sub(amount) + let new_total_supply = total_supply + .checked_sub(amount) .expect("Integer underflow occurred while decreasing total supply."); write_total_supply(&e, &new_total_supply); -} \ No newline at end of file +} diff --git a/contracts/pair/src/storage.rs b/contracts/pair/src/storage.rs index 9d144de0..6968fef3 100644 --- a/contracts/pair/src/storage.rs +++ b/contracts/pair/src/storage.rs @@ -1,17 +1,15 @@ -use soroban_sdk::{ Env, Address, ConversionError, - TryFromVal, Val}; +use soroban_sdk::{Address, ConversionError, Env, TryFromVal, Val}; -#[derive(Clone, Copy)] +#[derive(Clone, Copy)] #[repr(u32)] pub enum DataKey { - Token0 = 0, // token0, instance type of data; - Token1 = 1, // token1, instance type of data; + Token0 = 0, // token0, instance type of data; + Token1 = 1, // token1, instance type of data; Reserve0 = 2, // reserve0, instance type of data; Reserve1 = 3, // reserve1, instance type of data; - Factory = 4, // factory, instance type of data; - KLast = 5 // last k, instance type of data; - + Factory = 4, // factory, instance type of data; + KLast = 5, // last k, instance type of data; } // We will follow the token standar for instance bumping @@ -30,13 +28,12 @@ impl TryFromVal for Val { pub fn extend_instance_ttl(e: &Env) { e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); + .instance() + .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); } pub fn get_factory(e: &Env) -> Address { - e.storage().instance(). -get(&DataKey::Factory).unwrap() + e.storage().instance().get(&DataKey::Factory).unwrap() } // Helper function in order to know if the contract has been initialized or not @@ -45,30 +42,23 @@ pub fn has_token_0(e: &Env) -> bool { } pub fn get_token_0(e: &Env) -> Address { - e.storage().instance(). -get(&DataKey::Token0).unwrap() + e.storage().instance().get(&DataKey::Token0).unwrap() } pub fn get_token_1(e: &Env) -> Address { - e.storage().instance(). -get(&DataKey::Token1).unwrap() + e.storage().instance().get(&DataKey::Token1).unwrap() } pub fn get_reserve_0(e: &Env) -> i128 { - e.storage().instance(). -get(&DataKey::Reserve0).unwrap() + e.storage().instance().get(&DataKey::Reserve0).unwrap() } pub fn get_reserve_1(e: &Env) -> i128 { - e.storage().instance(). -get(&DataKey::Reserve1).unwrap() + e.storage().instance().get(&DataKey::Reserve1).unwrap() } - - pub fn get_klast(e: &Env) -> i128 { - if let Some(klast) = e.storage().instance(). -get(&DataKey::KLast) { + if let Some(klast) = e.storage().instance().get(&DataKey::KLast) { klast } else { 0 @@ -76,38 +66,31 @@ get(&DataKey::KLast) { } pub fn put_factory(e: &Env, factory: Address) { - e.storage().instance(). -set(&DataKey::Factory, &factory); + e.storage().instance().set(&DataKey::Factory, &factory); } pub fn put_token_0(e: &Env, contract_id: Address) { - e.storage().instance(). -set(&DataKey::Token0, &contract_id); + e.storage().instance().set(&DataKey::Token0, &contract_id); } pub fn put_token_1(e: &Env, contract_id: Address) { - e.storage().instance(). -set(&DataKey::Token1, &contract_id); + e.storage().instance().set(&DataKey::Token1, &contract_id); } pub fn put_reserve_0(e: &Env, amount: i128) { if amount < 0 { panic!("put_reserve_0: amount cannot be negative") } - e.storage().instance(). -set(&DataKey::Reserve0, &amount) + e.storage().instance().set(&DataKey::Reserve0, &amount) } pub fn put_reserve_1(e: &Env, amount: i128) { if amount < 0 { panic!("put_reserve_1: amount cannot be negative") } - e.storage().instance(). -set(&DataKey::Reserve1, &amount) + e.storage().instance().set(&DataKey::Reserve1, &amount) } - pub fn put_klast(e: &Env, klast: i128) { - e.storage().instance(). -set(&DataKey::KLast, &klast); -} \ No newline at end of file + e.storage().instance().set(&DataKey::KLast, &klast); +} diff --git a/contracts/pair/src/strings.rs b/contracts/pair/src/strings.rs index 119a1b43..98bc3a37 100644 --- a/contracts/pair/src/strings.rs +++ b/contracts/pair/src/strings.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{Env, String}; +use soroban_sdk::{Env, String}; pub trait TakeFirstNCharsAndConcat { fn take_first_n_chars(&self, e: &Env, n: usize) -> String; @@ -7,7 +7,6 @@ pub trait TakeFirstNCharsAndConcat { impl TakeFirstNCharsAndConcat for String { fn take_first_n_chars(&self, e: &Env, n: usize) -> String { - let len = self.len() as usize; let mut slice: [u8; 100] = [0; 100]; let min_len = len.min(n); @@ -27,4 +26,4 @@ impl TakeFirstNCharsAndConcat for String { String::from_str(&e, core::str::from_utf8(&slice[..combined_len]).unwrap()) } -} \ No newline at end of file +} diff --git a/contracts/pair/src/test.rs b/contracts/pair/src/test.rs index 826058a1..7caab889 100644 --- a/contracts/pair/src/test.rs +++ b/contracts/pair/src/test.rs @@ -6,9 +6,9 @@ use soroban_sdk::{ // Vec, // Val, // vec, - testutils::{Address as _}, - Address, - BytesN, + testutils::Address as _, + Address, + BytesN, Env, String, // Symbol @@ -17,7 +17,9 @@ use soroban_sdk::{ // TOKEN CONTRACT mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!( + file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm" + ); pub type TokenClient<'a> = Client<'a>; } use token::TokenClient; @@ -29,12 +31,18 @@ fn create_token_contract<'a>(e: &Env) -> TokenClient<'a> { // FACTORY CONTRACT mod factory { - soroban_sdk::contractimport!(file = "../factory/target/wasm32v1-none/release/soroswap_factory.wasm"); + soroban_sdk::contractimport!( + file = "../factory/target/wasm32v1-none/release/soroswap_factory.wasm" + ); pub type SoroswapFactoryClient<'a> = Client<'a>; } use factory::SoroswapFactoryClient; -fn create_factory_contract<'a>(e: & Env, setter: & Address,pair_wasm_hash: & BytesN<32>) -> SoroswapFactoryClient<'a> { +fn create_factory_contract<'a>( + e: &Env, + setter: &Address, + pair_wasm_hash: &BytesN<32>, +) -> SoroswapFactoryClient<'a> { let factory_address = &e.register_contract_wasm(None, factory::WASM); let factory = SoroswapFactoryClient::new(e, factory_address); factory.initialize(&setter, pair_wasm_hash); @@ -44,9 +52,7 @@ fn create_factory_contract<'a>(e: & Env, setter: & Address,pair_wasm_hash: & Byt // PAIR CONTRACT // WASM fn pair_token_wasm(e: &Env) -> BytesN<32> { - soroban_sdk::contractimport!( - file = "./target/wasm32v1-none/release/soroswap_pair.wasm" - ); + soroban_sdk::contractimport!(file = "./target/wasm32v1-none/release/soroswap_pair.wasm"); e.deployer().upload_contract_wasm(WASM) } @@ -56,10 +62,7 @@ pub mod pair { } use pair::SoroswapPairClient; - -fn create_pair_contract<'a>( - e: & Env -) -> SoroswapPairClient<'a> { +fn create_pair_contract<'a>(e: &Env) -> SoroswapPairClient<'a> { let pair_address = &e.register_contract_wasm(None, pair::WASM); let pair_client = SoroswapPairClient::new(e, pair_address); pair_client @@ -78,7 +81,6 @@ pub struct SoroswapPairTest<'a> { impl<'a> SoroswapPairTest<'a> { fn setup() -> Self { - let env = Env::default(); env.mock_all_auths(); let user = Address::generate(&env); @@ -88,7 +90,7 @@ impl<'a> SoroswapPairTest<'a> { if &token_1.address < &token_0.address { std::mem::swap(&mut token_0, &mut token_1); } - + let name_0 = String::from_str(&env, "Token 0"); let symbol_0 = String::from_str(&env, "TOK0"); let name_1 = String::from_str(&env, "Token 1"); @@ -101,16 +103,13 @@ impl<'a> SoroswapPairTest<'a> { token_0.mint(&user, &123_000_000_000_000_000_000); token_1.mint(&user, &321_000_000_000_000_000_000); - let pair_token_wasm_binding = pair_token_wasm(&env); + let pair_token_wasm_binding = pair_token_wasm(&env); let factory = create_factory_contract(&env, &admin, &pair_token_wasm_binding); - let contract = create_pair_contract( - &env, - ); + let contract = create_pair_contract(&env); // TODO: Get rid of this hack? env.budget().reset_unlimited(); - SoroswapPairTest { env, @@ -123,17 +122,16 @@ impl<'a> SoroswapPairTest<'a> { } } } - // Tests written by esteblock -mod initialize; mod deposit; -mod swap; -mod withdraw; +mod events; mod fee; +mod initialize; mod skim; +mod swap; mod sync; -mod events; +mod withdraw; // mod decode; // wont be used for now // Test forked by stellar/soroban-examples @@ -144,4 +142,3 @@ mod soroswap_pair_token; // mod operations_helpers; // mod operations; // mod helpers; - diff --git a/contracts/pair/src/test/deposit.rs b/contracts/pair/src/test/deposit.rs index 51c1d52c..e8f75ae8 100644 --- a/contracts/pair/src/test/deposit.rs +++ b/contracts/pair/src/test/deposit.rs @@ -1,19 +1,18 @@ -use crate::test::{SoroswapPairTest}; -use soroban_sdk::{testutils::{Ledger}}; use crate::test::pair::SoroswapPairError; +use crate::test::SoroswapPairTest; +use soroban_sdk::testutils::Ledger; - - // Pub function that will be used in other tests: pub fn add_liquidity(test: &SoroswapPairTest, amount_0: &i128, amount_1: &i128) -> i128 { - // User needs to send these tokens first to the contract - test.token_0.transfer(&test.user, &test.contract.address, &amount_0); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1); test.contract.deposit(&test.user) } - + #[test] // #[should_panic(expected = "SoroswapPair: not yet initialized")] fn deposit_not_yet_initialized() { @@ -28,9 +27,16 @@ fn deposit_not_yet_initialized() { fn deposit_zero_tokens_sent() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let res = test.contract.try_deposit(&test.user); - assert_eq!(res, Err(Ok(SoroswapPairError::DepositInsufficientAmountToken0))); + assert_eq!( + res, + Err(Ok(SoroswapPairError::DepositInsufficientAmountToken0)) + ); } #[test] @@ -39,10 +45,18 @@ fn deposit_only_token_0_sent() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); let amount_0: i128 = 1_000_000; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); - test.token_0.transfer(&test.user, &test.contract.address, &amount_0); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0); let res = test.contract.try_deposit(&test.user); - assert_eq!(res, Err(Ok(SoroswapPairError::DepositInsufficientAmountToken1))); + assert_eq!( + res, + Err(Ok(SoroswapPairError::DepositInsufficientAmountToken1)) + ); } #[test] @@ -53,15 +67,22 @@ fn deposit_insufficient_first_liquidity() { // If we just send 1,000 of each, the liq to be minted will be sqrt(1000*1000) - 1000 = 0, not enough let amount_0: i128 = 1_000; let amount_1: i128 = 1_000; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); - test.token_0.transfer(&test.user, &test.contract.address, &amount_0); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1); let res = test.contract.try_deposit(&test.user); - assert_eq!(res, Err(Ok(SoroswapPairError::DepositInsufficientFirstLiquidity))); + assert_eq!( + res, + Err(Ok(SoroswapPairError::DepositInsufficientFirstLiquidity)) + ); } - - #[test] fn deposit_sufficient_first_liquidity() { let test = SoroswapPairTest::setup(); @@ -69,9 +90,15 @@ fn deposit_sufficient_first_liquidity() { // If we just send 1,000 of each, the liq to be minted will be sqrt(1000*1000) - 1000 = 0, not enough let amount_0: i128 = 1_001; // let amount_1: i128 = 1_001; // - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); - test.token_0.transfer(&test.user, &test.contract.address, &amount_0); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1); test.contract.deposit(&test.user); } @@ -80,7 +107,7 @@ fn deposit_basic() { let test = SoroswapPairTest::setup(); // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - + let init_time = 12345; test.env.ledger().with_mut(|li| { li.timestamp = init_time; @@ -93,39 +120,55 @@ fn deposit_basic() { let expected_liquidity: i128 = 2_000_000; let minimum_liquidity: i128 = 1_000; - // User needs to send these tokens first to the contract - test.token_0.transfer(&test.user, &test.contract.address, &amount_0); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); - // User does not hold any LP token first + // User does not hold any LP token first assert_eq!(test.contract.balance(&test.user), 0); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); test.contract.deposit(&test.user); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); // New LP balance: - assert_eq!(test.contract.balance(&test.user), expected_liquidity- minimum_liquidity); + assert_eq!( + test.contract.balance(&test.user), + expected_liquidity - minimum_liquidity + ); // Reserves assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); } - - #[test] fn deposit_basic_2() { let test = SoroswapPairTest::setup(); // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0 = 1_000_000_000_000_000_000; let amount_1 = 4_000_000_000_000_000_000; add_liquidity(&test, &amount_0, &amount_1); -} \ No newline at end of file +} diff --git a/contracts/pair/src/test/events.rs b/contracts/pair/src/test/events.rs index 0350f897..34beb875 100644 --- a/contracts/pair/src/test/events.rs +++ b/contracts/pair/src/test/events.rs @@ -1,9 +1,13 @@ extern crate std; -use crate::test::{SoroswapPairTest}; -use crate::event::{DepositEvent, SwapEvent, WithdrawEvent, SyncEvent, SkimEvent}; -use crate::soroswap_pair_token::{SoroswapPairTokenClient}; +use crate::event::{DepositEvent, SkimEvent, SwapEvent, SyncEvent, WithdrawEvent}; +use crate::soroswap_pair_token::SoroswapPairTokenClient; use crate::test::deposit::add_liquidity; -use soroban_sdk::{testutils::{Ledger, Events}, vec, IntoVal, symbol_short}; +use crate::test::SoroswapPairTest; +use soroban_sdk::{ + symbol_short, + testutils::{Events, Ledger}, + vec, IntoVal, +}; #[test] fn deposit_event() { @@ -12,9 +16,15 @@ fn deposit_event() { let amount_0: i128 = 1_001; // let amount_1: i128 = 1_001; // let expected_liquidity: i128 = 1; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); - test.token_0.transfer(&test.user, &test.contract.address, &amount_0); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1); let executed_liquidity = test.contract.deposit(&test.user); assert_eq!(expected_liquidity, executed_liquidity); @@ -27,7 +37,7 @@ fn deposit_event() { amount_1: amount_1.clone(), liquidity: expected_liquidity.clone(), new_reserve_0: amount_1.clone(), - new_reserve_1: amount_1.clone() + new_reserve_1: amount_1.clone(), }; assert_eq!( @@ -48,7 +58,7 @@ fn deposit_event() { amount_1: amount_1, liquidity: expected_liquidity, new_reserve_0: amount_1, - new_reserve_1: amount_1 + new_reserve_1: amount_1, }; assert_ne!( @@ -62,10 +72,8 @@ fn deposit_event() { ), ] ); - } - #[test] fn swap_event() { let test = SoroswapPairTest::setup(); @@ -73,7 +81,11 @@ fn swap_event() { let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); add_liquidity(&test, &amount_0, &amount_1); let init_time = 12345; @@ -85,9 +97,11 @@ fn swap_event() { let expected_output_amount_1: i128 = 16624979; // The user sends the token first: - test.token_0.transfer(&test.user, &test.contract.address, &swap_amount_0); - test.contract.swap(&0, &expected_output_amount_1, &test.user); - + test.token_0 + .transfer(&test.user, &test.contract.address, &swap_amount_0); + test.contract + .swap(&0, &expected_output_amount_1, &test.user); + let swap_event = test.env.events().all().last().unwrap(); let expected_swap_event: SwapEvent = SwapEvent { @@ -131,30 +145,39 @@ fn swap_event() { ); } - #[test] fn withdraw_event() { - let test = SoroswapPairTest::setup(); + let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 3_000_000; let amount_1: i128 = 3_000_000; - let expected_liquidity: i128 = 3_000_000; + let expected_liquidity: i128 = 3_000_000; let minimum_liquidity: i128 = 1_000; - let user_liquidity = expected_liquidity.checked_sub(minimum_liquidity).unwrap(); + let user_liquidity = expected_liquidity.checked_sub(minimum_liquidity).unwrap(); add_liquidity(&test, &amount_0, &amount_1); // Now we need to treat the contract as a SoroswapPairTokenClient - let pair_token_client = SoroswapPairTokenClient::new(&test.env, &test.env.register_contract(&test.contract.address, crate::SoroswapPairToken {})); + let pair_token_client = SoroswapPairTokenClient::new( + &test.env, + &test + .env + .register_contract(&test.contract.address, crate::SoroswapPairToken {}), + ); pair_token_client.transfer(&test.user, &test.contract.address, &user_liquidity); // And now we need to treat it again as a SoroswapPairClient - test.env.register_contract(&test.contract.address, crate::SoroswapPair {}); - + test.env + .register_contract(&test.contract.address, crate::SoroswapPair {}); + // Now the env has that address again as a SoroswapPairClient - + let (amount_0_out, amount_1_out) = test.contract.withdraw(&test.user); - + let withdraw_event = test.env.events().all().last().unwrap(); let expected_withdraw_event: WithdrawEvent = WithdrawEvent { @@ -163,7 +186,7 @@ fn withdraw_event() { amount_0: amount_0_out, amount_1: amount_1_out, new_reserve_0: minimum_liquidity, - new_reserve_1: minimum_liquidity + new_reserve_1: minimum_liquidity, }; assert_eq!( @@ -184,7 +207,7 @@ fn withdraw_event() { amount_0: 0, amount_1: amount_1_out, new_reserve_0: minimum_liquidity, - new_reserve_1: minimum_liquidity + new_reserve_1: minimum_liquidity, }; assert_ne!( @@ -200,12 +223,15 @@ fn withdraw_event() { ); } - #[test] fn sync_event() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -214,8 +240,14 @@ fn sync_event() { add_liquidity(&test, &amount_0, &amount_1); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); @@ -223,10 +255,18 @@ fn sync_event() { //extra tokens sent to skim: let amount_0_extra: i128 = 123_000_000; let amount_1_extra: i128 = 4_586_000; - test.token_0.transfer(&test.user, &test.contract.address, &amount_0_extra); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1_extra); - assert_eq!(test.token_0.balance(&test.contract.address), amount_0 + amount_0_extra); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1 + amount_1_extra); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0_extra); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1_extra); + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0 + amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1 + amount_1_extra + ); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); test.contract.sync(); @@ -266,17 +306,18 @@ fn sync_event() { ), ] ); - } - - #[test] fn skim_event() { // zero tokens are being sent let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -285,8 +326,14 @@ fn skim_event() { add_liquidity(&test, &amount_0, &amount_1); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); @@ -294,10 +341,18 @@ fn skim_event() { //extra tokens sent to skim: let amount_0_extra: i128 = 123_000_000; let amount_1_extra: i128 = 4_586_000; - test.token_0.transfer(&test.user, &test.contract.address, &amount_0_extra); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1_extra); - assert_eq!(test.token_0.balance(&test.contract.address), amount_0 + amount_0_extra); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1 + amount_1_extra); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0_extra); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1_extra); + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0 + amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1 + amount_1_extra + ); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); test.contract.skim(&test.admin); @@ -337,4 +392,4 @@ fn skim_event() { ), ] ); -} \ No newline at end of file +} diff --git a/contracts/pair/src/test/fee.rs b/contracts/pair/src/test/fee.rs index b888a882..a389543a 100644 --- a/contracts/pair/src/test/fee.rs +++ b/contracts/pair/src/test/fee.rs @@ -1,83 +1,119 @@ -use crate::test::{SoroswapPairTest}; use crate::test::deposit::add_liquidity; -use num_integer::Roots; - - +use crate::test::SoroswapPairTest; +use num_integer::Roots; #[test] fn fee_off() { - let test = SoroswapPairTest::setup(); + let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; - let expected_liquidity: i128 = 70_710_678; + let expected_liquidity: i128 = 70_710_678; let minimum_liquidity: i128 = 1_000; assert_eq!(test.contract.k_last(), 0); add_liquidity(&test, &amount_0, &amount_1); - assert_eq!(test.contract.get_reserves(), (amount_0,amount_1,)); + assert_eq!(test.contract.get_reserves(), (amount_0, amount_1,)); assert_eq!(test.contract.k_last(), 0); let swap_amount_0 = 10_000_000; let expected_output_amount_1 = 16624979; - test.token_0.transfer(&test.user, &test.contract.address, &swap_amount_0); - test.contract.swap(&0, &expected_output_amount_1, &test.user); - assert_eq!(test.contract.get_reserves(), (amount_0+swap_amount_0,amount_1-expected_output_amount_1,)); + test.token_0 + .transfer(&test.user, &test.contract.address, &swap_amount_0); + test.contract + .swap(&0, &expected_output_amount_1, &test.user); + assert_eq!( + test.contract.get_reserves(), + ( + amount_0 + swap_amount_0, + amount_1 - expected_output_amount_1, + ) + ); assert_eq!(test.contract.k_last(), 0); - test.contract.transfer(&test.user, &test.contract.address, &expected_liquidity.checked_sub(minimum_liquidity).unwrap()); + test.contract.transfer( + &test.user, + &test.contract.address, + &expected_liquidity.checked_sub(minimum_liquidity).unwrap(), + ); test.contract.withdraw(&test.user); assert_eq!(test.contract.k_last(), 0); assert_eq!(test.contract.balance(&test.user), 0); - assert_eq!(test.contract.total_supply(), minimum_liquidity); - assert_eq!(test.contract.balance(&test.contract.address), minimum_liquidity); - assert_eq!(test.token_0.balance(&test.contract.address), 849); - assert_eq!(test.token_1.balance(&test.contract.address), 1180); - assert_eq!(test.contract.get_reserves(), (849,1180,)); - + assert_eq!(test.contract.total_supply(), minimum_liquidity); + assert_eq!( + test.contract.balance(&test.contract.address), + minimum_liquidity + ); + assert_eq!(test.token_0.balance(&test.contract.address), 849); + assert_eq!(test.token_1.balance(&test.contract.address), 1180); + assert_eq!(test.contract.get_reserves(), (849, 1180,)); } // Testing fee when doing add_liquiquidity/swap/remove_liquidity #[test] fn fee_on_add_swap_remove() { - let test = SoroswapPairTest::setup(); + let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); test.factory.set_fees_enabled(&true); assert_eq!(test.factory.fees_enabled(), true); assert_eq!(test.factory.fee_to(), test.admin); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; let minimum_liquidity: i128 = 1_000; - let expected_liquidity: i128 = 70_710_678; + let expected_liquidity: i128 = 70_710_678; assert_eq!(test.contract.k_last(), 0); add_liquidity(&test, &amount_0, &amount_1); // If we deposit with fee on, we should see a change in the klast paramenter //klast should be the new reserves (amount0 and amount1) - assert_eq!(test.contract.k_last(), amount_0.checked_mul(amount_1).unwrap()); + assert_eq!( + test.contract.k_last(), + amount_0.checked_mul(amount_1).unwrap() + ); assert_eq!(test.contract.total_supply(), expected_liquidity); - let swap_amount_0 = 10_000_000; // Amount does not changes... only the fee is splitted differently let expected_output_amount_1 = 16624979; - test.token_0.transfer(&test.user, &test.contract.address, &swap_amount_0); - test.contract.swap(&0, &expected_output_amount_1, &test.user); + test.token_0 + .transfer(&test.user, &test.contract.address, &swap_amount_0); + test.contract + .swap(&0, &expected_output_amount_1, &test.user); //klast does not gets updated in swaps - assert_eq!(test.contract.k_last(), amount_0.checked_mul(amount_1).unwrap()); - let new_expected_reserve_0= amount_0+swap_amount_0; // 60000000 - let new_expected_reserve_1= amount_1-expected_output_amount_1; // 83375021 - assert_eq!(test.contract.get_reserves(), (new_expected_reserve_0,new_expected_reserve_1)); - - let k2_root=70728362; // new_expected_reserve_0.checked_mul(new_expected_reserve_1).unwrap().sqrt(); - assert_eq!(new_expected_reserve_0.checked_mul(new_expected_reserve_1).unwrap().sqrt(), k2_root); + assert_eq!( + test.contract.k_last(), + amount_0.checked_mul(amount_1).unwrap() + ); + let new_expected_reserve_0 = amount_0 + swap_amount_0; // 60000000 + let new_expected_reserve_1 = amount_1 - expected_output_amount_1; // 83375021 + assert_eq!( + test.contract.get_reserves(), + (new_expected_reserve_0, new_expected_reserve_1) + ); + + let k2_root = 70728362; // new_expected_reserve_0.checked_mul(new_expected_reserve_1).unwrap().sqrt(); + assert_eq!( + new_expected_reserve_0 + .checked_mul(new_expected_reserve_1) + .unwrap() + .sqrt(), + k2_root + ); let k1_root = 70_710_678; // amount_0.checked_mul(amount_1).unwrap().sqrt(); assert_eq!(amount_0.checked_mul(amount_1).unwrap().sqrt(), k1_root); @@ -85,91 +121,137 @@ fn fee_on_add_swap_remove() { // After the swap, k2 should be greater than k1 assert_eq!(k2_root > k1_root, true); - test.contract.transfer(&test.user, &test.contract.address, &expected_liquidity.checked_sub(minimum_liquidity).unwrap()); + test.contract.transfer( + &test.user, + &test.contract.address, + &expected_liquidity.checked_sub(minimum_liquidity).unwrap(), + ); assert_eq!(test.contract.total_supply(), expected_liquidity); test.contract.withdraw(&test.user); // n = expected_liquidity*(k2_root-k1_root)/(5k2_root + k1_root) // = 2946,719213655 --> 2946 let n = 2946; - let numerator = expected_liquidity.checked_mul(k2_root-k1_root).unwrap(); //1250447629752 + let numerator = expected_liquidity.checked_mul(k2_root - k1_root).unwrap(); //1250447629752 assert_eq!(numerator, 1250447629752); - let denominator = (5_i128).checked_mul(k2_root).unwrap().checked_add(k1_root).unwrap(); + let denominator = (5_i128) + .checked_mul(k2_root) + .unwrap() + .checked_add(k1_root) + .unwrap(); assert_eq!(denominator, 424352488); - assert_eq!(n, numerator/denominator); + assert_eq!(n, numerator / denominator); assert_eq!(numerator.checked_div(denominator).unwrap(), n); - + // whe should have minted n shares to the admin: - assert_eq!(test.contract.total_supply(), minimum_liquidity.checked_add(n).unwrap()); - assert_eq!(test.contract.balance(&test.contract.address), minimum_liquidity); + assert_eq!( + test.contract.total_supply(), + minimum_liquidity.checked_add(n).unwrap() + ); + assert_eq!( + test.contract.balance(&test.contract.address), + minimum_liquidity + ); assert_eq!(test.contract.balance(&test.admin), n); - - // TEST USER TOKEN BALANCES: // Because this is done before the withdraw, the user will see a difference in the total amount // that received while withdrawing: // the user had a liquidity position equal to (expected_liquidity-minimum_liquidity) let user_lp = 70709678; // (expected_liquidity-minimum_liquidity) - assert_eq!(user_lp, (expected_liquidity-minimum_liquidity)); + assert_eq!(user_lp, (expected_liquidity - minimum_liquidity)); // and it should have received: new_expected_reserve_0*(user_lp/(expected_liquidity+n)) // (60000000*70709678)/(70710678+2946) = 59996651 assert_eq!(new_expected_reserve_0, 60000000); let expected_user_out_token_0 = 59996651; - assert_eq!(expected_user_out_token_0, (new_expected_reserve_0*user_lp)/(expected_liquidity+n)); + assert_eq!( + expected_user_out_token_0, + (new_expected_reserve_0 * user_lp) / (expected_liquidity + n) + ); // similar for token 1: // (83375021*70709678)/(70710678+2946) =83370368 let expected_user_out_token_1 = 83370368; - assert_eq!(expected_user_out_token_1, (new_expected_reserve_1*user_lp)/(expected_liquidity+n)); + assert_eq!( + expected_user_out_token_1, + (new_expected_reserve_1 * user_lp) / (expected_liquidity + n) + ); let original_total_supply_0: i128 = 123_000_000_000_000_000_000; // from the test file let original_total_supply_1: i128 = 321_000_000_000_000_000_000; // from the test file - assert_eq!(test.token_0.balance(&test.user), original_total_supply_0-amount_0-swap_amount_0+expected_user_out_token_0); - assert_eq!(test.token_1.balance(&test.user), original_total_supply_1-amount_1+expected_output_amount_1+expected_user_out_token_1); - - - let after_withdraw_expected_reserve_0= 3349; // amount_0+swap_amount_0-expected_user_out_token_0; // 3349 - let after_withdraw_expected_reserve_1= 4653; //amount_1-expected_output_amount_1-expected_user_out_token_1; // 4653 - assert_eq!(after_withdraw_expected_reserve_0, amount_0+swap_amount_0-expected_user_out_token_0); - assert_eq!(after_withdraw_expected_reserve_1, amount_1-expected_output_amount_1-expected_user_out_token_1); - assert_eq!(test.contract.get_reserves(), (after_withdraw_expected_reserve_0,after_withdraw_expected_reserve_1,)); - assert_eq!(test.contract.k_last(), after_withdraw_expected_reserve_0.checked_mul(after_withdraw_expected_reserve_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_total_supply_0 - amount_0 - swap_amount_0 + expected_user_out_token_0 + ); + assert_eq!( + test.token_1.balance(&test.user), + original_total_supply_1 - amount_1 + expected_output_amount_1 + expected_user_out_token_1 + ); + + let after_withdraw_expected_reserve_0 = 3349; // amount_0+swap_amount_0-expected_user_out_token_0; // 3349 + let after_withdraw_expected_reserve_1 = 4653; //amount_1-expected_output_amount_1-expected_user_out_token_1; // 4653 + assert_eq!( + after_withdraw_expected_reserve_0, + amount_0 + swap_amount_0 - expected_user_out_token_0 + ); + assert_eq!( + after_withdraw_expected_reserve_1, + amount_1 - expected_output_amount_1 - expected_user_out_token_1 + ); + assert_eq!( + test.contract.get_reserves(), + ( + after_withdraw_expected_reserve_0, + after_withdraw_expected_reserve_1, + ) + ); + assert_eq!( + test.contract.k_last(), + after_withdraw_expected_reserve_0 + .checked_mul(after_withdraw_expected_reserve_1) + .unwrap() + ); // assert_eq!(test.contract.balance(&test.user), 0); - - // // TEST ADMIN TOKEN BALANCES (IN N SHARES) - + let expected_admin_out_token_0 = 2500; // (3349*2946)/(1000+2946) = 2500 let expected_admin_out_token_1 = 3473; // (4653*2946)/(1000+2946) = 3473 - test.contract.transfer(&test.admin, &test.contract.address, &n); + test.contract + .transfer(&test.admin, &test.contract.address, &n); - assert_eq!(test.contract.total_supply(), 1000+2946); + assert_eq!(test.contract.total_supply(), 1000 + 2946); test.contract.withdraw(&test.admin); - assert_eq!(test.token_0.balance(&test.admin), expected_admin_out_token_0); - assert_eq!(test.token_1.balance(&test.admin), expected_admin_out_token_1); - - + assert_eq!( + test.token_0.balance(&test.admin), + expected_admin_out_token_0 + ); + assert_eq!( + test.token_1.balance(&test.admin), + expected_admin_out_token_1 + ); } - // Testing fee when doing add_liquiquidity/swap/add_liquidity #[test] fn fee_on_add_swap_add() { - let test = SoroswapPairTest::setup(); + let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); test.factory.set_fees_enabled(&true); assert_eq!(test.factory.fees_enabled(), true); assert_eq!(test.factory.fee_to(), test.admin); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; let minimum_liquidity: i128 = 1_000; - let expected_liquidity: i128 = 70_710_678; + let expected_liquidity: i128 = 70_710_678; let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -179,10 +261,19 @@ fn fee_on_add_swap_add() { // If we deposit with fee on, we should see a change in the klast paramenter //klast should be the new reserves (amount0 and amount1) - assert_eq!(test.contract.k_last(), amount_0.checked_mul(amount_1).unwrap()); + assert_eq!( + test.contract.k_last(), + amount_0.checked_mul(amount_1).unwrap() + ); assert_eq!(test.contract.total_supply(), expected_liquidity); - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); // ***************** SWAP ***************** @@ -190,23 +281,43 @@ fn fee_on_add_swap_add() { // Amount does not changes... only the fee is splitted differently let expected_output_amount_1 = 16624979; - test.token_0.transfer(&test.user, &test.contract.address, &swap_amount_0); - test.contract.swap(&0, &expected_output_amount_1, &test.user); + test.token_0 + .transfer(&test.user, &test.contract.address, &swap_amount_0); + test.contract + .swap(&0, &expected_output_amount_1, &test.user); //klast does not gets updated in swaps - assert_eq!(test.contract.k_last(), amount_0.checked_mul(amount_1).unwrap()); - - let new_expected_reserve_0= 60000000; //amount_0+swap_amount_0 - assert_eq!(new_expected_reserve_0, amount_0+swap_amount_0); - - let new_expected_reserve_1= 83375021; // amount_1-expected_output_amount_1; // 83375021 - assert_eq!(new_expected_reserve_1, amount_1-expected_output_amount_1); - - assert_eq!(test.contract.get_reserves(), (new_expected_reserve_0,new_expected_reserve_1)); - assert_eq!(test.token_0.balance(&test.user), original_0-amount_0-swap_amount_0); - assert_eq!(test.token_1.balance(&test.user), original_1-amount_1+expected_output_amount_1); - - let k2_root=70728362; // new_expected_reserve_0.checked_mul(new_expected_reserve_1).unwrap().sqrt(); - assert_eq!(new_expected_reserve_0.checked_mul(new_expected_reserve_1).unwrap().sqrt(), k2_root); + assert_eq!( + test.contract.k_last(), + amount_0.checked_mul(amount_1).unwrap() + ); + + let new_expected_reserve_0 = 60000000; //amount_0+swap_amount_0 + assert_eq!(new_expected_reserve_0, amount_0 + swap_amount_0); + + let new_expected_reserve_1 = 83375021; // amount_1-expected_output_amount_1; // 83375021 + assert_eq!(new_expected_reserve_1, amount_1 - expected_output_amount_1); + + assert_eq!( + test.contract.get_reserves(), + (new_expected_reserve_0, new_expected_reserve_1) + ); + assert_eq!( + test.token_0.balance(&test.user), + original_0 - amount_0 - swap_amount_0 + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1 - amount_1 + expected_output_amount_1 + ); + + let k2_root = 70728362; // new_expected_reserve_0.checked_mul(new_expected_reserve_1).unwrap().sqrt(); + assert_eq!( + new_expected_reserve_0 + .checked_mul(new_expected_reserve_1) + .unwrap() + .sqrt(), + k2_root + ); let k1_root = 70_710_678; // amount_0.checked_mul(amount_1).unwrap().sqrt(); assert_eq!(amount_0.checked_mul(amount_1).unwrap().sqrt(), k1_root); @@ -214,29 +325,48 @@ fn fee_on_add_swap_add() { // After the swap, k2 should be greater than k1 assert_eq!(k2_root > k1_root, true); - - // ***************** DEPOSIT AGAIN! ***************** assert_eq!(test.contract.total_supply(), expected_liquidity); - assert_eq!(test.contract.get_reserves(), (new_expected_reserve_0,new_expected_reserve_1)); + assert_eq!( + test.contract.get_reserves(), + (new_expected_reserve_0, new_expected_reserve_1) + ); let new_amount_0: i128 = 1_000_000; let new_amount_1: i128 = 1389583; //(new_amount_0*new_expected_reserve_1)/new_expected_reserve_0); - assert_eq!(new_amount_1, (new_amount_0*new_expected_reserve_1)/new_expected_reserve_0); + assert_eq!( + new_amount_1, + (new_amount_0 * new_expected_reserve_1) / new_expected_reserve_0 + ); let new_got_liquidity = add_liquidity(&test, &new_amount_0, &new_amount_1); - assert_eq!(test.token_0.balance(&test.user), original_0-amount_0-swap_amount_0-new_amount_0); - assert_eq!(test.token_1.balance(&test.user), original_1-amount_1+expected_output_amount_1-new_amount_1); + assert_eq!( + test.token_0.balance(&test.user), + original_0 - amount_0 - swap_amount_0 - new_amount_0 + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1 - amount_1 + expected_output_amount_1 - new_amount_1 + ); + + assert_eq!( + test.contract.k_last(), + (new_expected_reserve_0 + new_amount_0) + .checked_mul(new_expected_reserve_1 + new_amount_1) + .unwrap() + ); - assert_eq!(test.contract.k_last(), (new_expected_reserve_0+new_amount_0).checked_mul(new_expected_reserve_1+new_amount_1).unwrap()); - // We have the new liquidity minted to the admin = n // n = expected_liquidity*(k2_root-k1_root)/(5k2_root + k1_root) // = 2946,719213655 --> 2946 let n = 2946; - let numerator = expected_liquidity.checked_mul(k2_root-k1_root).unwrap(); //1250447629752 + let numerator = expected_liquidity.checked_mul(k2_root - k1_root).unwrap(); //1250447629752 assert_eq!(numerator, 1250447629752); - let denominator = (5_i128).checked_mul(k2_root).unwrap().checked_add(k1_root).unwrap(); + let denominator = (5_i128) + .checked_mul(k2_root) + .unwrap() + .checked_add(k1_root) + .unwrap(); assert_eq!(denominator, 424352488); - assert_eq!(n, numerator/denominator); + assert_eq!(n, numerator / denominator); assert_eq!(numerator.checked_div(denominator).unwrap(), n); // We have the new liquidity minted to the user: @@ -250,24 +380,34 @@ fn fee_on_add_swap_add() { // shares_0 = (1000000 * (70710678+2946)) / 60000000 = 1178560 let shares_0 = 1178560; //new_amount_0 * (expected_liquidity+n) / new_expected_reserve_0; - assert_eq!(shares_0, (new_amount_0 * (expected_liquidity+n)) / new_expected_reserve_0); - + assert_eq!( + shares_0, + (new_amount_0 * (expected_liquidity + n)) / new_expected_reserve_0 + ); // (1389583 * (70710678+2946)) / 83375021 = 1178559 let shares_1 = 1178559; //new_amount_1 * (expected_liquidity+n) / new_expected_reserve_1; - assert_eq!(shares_1, (new_amount_1 * (expected_liquidity+n)) / new_expected_reserve_1); + assert_eq!( + shares_1, + (new_amount_1 * (expected_liquidity + n)) / new_expected_reserve_1 + ); // min (shares_0, shares_1) = 1178559; let expected_minted_liquidity = 1178559; assert_eq!(new_got_liquidity, expected_minted_liquidity); - - // whe should have minted n shares to the admin: - assert_eq!(test.contract.total_supply(), expected_liquidity+n+expected_minted_liquidity); - assert_eq!(test.contract.balance(&test.contract.address), minimum_liquidity); + assert_eq!( + test.contract.total_supply(), + expected_liquidity + n + expected_minted_liquidity + ); + assert_eq!( + test.contract.balance(&test.contract.address), + minimum_liquidity + ); assert_eq!(test.contract.balance(&test.admin), n); - assert_eq!(test.contract.balance(&test.user), expected_minted_liquidity+ (expected_liquidity-minimum_liquidity)); - - + assert_eq!( + test.contract.balance(&test.user), + expected_minted_liquidity + (expected_liquidity - minimum_liquidity) + ); } diff --git a/contracts/pair/src/test/initialize.rs b/contracts/pair/src/test/initialize.rs index fb5a4e99..cc98e33a 100644 --- a/contracts/pair/src/test/initialize.rs +++ b/contracts/pair/src/test/initialize.rs @@ -1,51 +1,75 @@ -use crate::test::{SoroswapPairTest}; -use soroban_sdk::{String}; use crate::test::pair::SoroswapPairError; +use crate::test::SoroswapPairTest; +use soroban_sdk::String; #[test] // #[should_panic(expected = "SoroswapPair: token_0 must be less than token_1")] fn initialize_token_1_less_than_token_0() { let test = SoroswapPairTest::setup(); - let res = test.contract.try_initialize(&test.factory.address, &test.token_1.address, &test.token_0.address); - assert_eq!(res, Err(Ok(SoroswapPairError::InitializeTokenOrderInvalid))); - + let res = test.contract.try_initialize( + &test.factory.address, + &test.token_1.address, + &test.token_0.address, + ); + assert_eq!(res, Err(Ok(SoroswapPairError::InitializeTokenOrderInvalid))); } - #[test] // #[should_panic(expected = "SoroswapPair: already initialized")] fn double_initialize() { let test = SoroswapPairTest::setup(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); - let res = test.contract.try_initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); - assert_eq!(res, Err(Ok(SoroswapPairError::InitializeAlreadyInitialized))); - + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); + let res = test.contract.try_initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); + assert_eq!( + res, + Err(Ok(SoroswapPairError::InitializeAlreadyInitialized)) + ); } - #[test] fn initialize_initial_values_0() { let test = SoroswapPairTest::setup(); assert_eq!(test.factory.fee_to(), test.admin); assert_eq!(test.factory.fee_to_setter(), test.admin); assert_eq!(test.factory.fees_enabled(), false); - + assert_eq!(test.token_0.symbol(), String::from_str(&test.env, "TOK0")); - assert_eq!(test.token_1.symbol(), String::from_str(&test.env, "ABCDEFGHIJ")); + assert_eq!( + test.token_1.symbol(), + String::from_str(&test.env, "ABCDEFGHIJ") + ); assert_eq!(test.token_0.name(), String::from_str(&test.env, "Token 0")); assert_eq!(test.token_1.name(), String::from_str(&test.env, "Token 1")); // Test liqpool initial values: - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); assert_eq!(test.contract.token_0(), test.token_0.address); assert_eq!(test.contract.token_1(), test.token_1.address); assert_eq!(test.contract.factory(), test.factory.address); - assert_eq!(test.contract.get_reserves(), (0,0)); + assert_eq!(test.contract.get_reserves(), (0, 0)); assert_eq!(test.contract.k_last(), 0); assert_eq!(test.contract.total_supply(), 0); assert_eq!(test.contract.k_last(), 0); - - assert_eq!(test.contract.symbol(), String::from_str(&test.env, "TOK0-ABCDEF-SOROSWAP-LP")); - assert_eq!(test.contract.name(), String::from_str(&test.env, "TOK0-ABCDEF Soroswap LP Token")); + + assert_eq!( + test.contract.symbol(), + String::from_str(&test.env, "TOK0-ABCDEF-SOROSWAP-LP") + ); + assert_eq!( + test.contract.name(), + String::from_str(&test.env, "TOK0-ABCDEF Soroswap LP Token") + ); assert_eq!(test.contract.decimals(), 7); } diff --git a/contracts/pair/src/test/skim.rs b/contracts/pair/src/test/skim.rs index 23e08c14..1d50f298 100644 --- a/contracts/pair/src/test/skim.rs +++ b/contracts/pair/src/test/skim.rs @@ -1,5 +1,5 @@ use crate::test::deposit::add_liquidity; -use crate::test::{SoroswapPairTest}; +use crate::test::SoroswapPairTest; #[test] #[should_panic] fn skim_nothing() { @@ -14,7 +14,11 @@ fn skim_with_liquidity_nothing_to_skim() { // zero tokens are being sent let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -23,29 +27,43 @@ fn skim_with_liquidity_nothing_to_skim() { add_liquidity(&test, &amount_0, &amount_1); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); test.contract.skim(&test.user); //no tokens where sent to the user, nothing changed - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); } - - #[test] fn skim() { // zero tokens are being sent let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -54,8 +72,14 @@ fn skim() { add_liquidity(&test, &amount_0, &amount_1); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); @@ -63,15 +87,29 @@ fn skim() { //extra tokens sent to skim: let amount_0_extra: i128 = 123_000_000; let amount_1_extra: i128 = 4_586_000; - test.token_0.transfer(&test.user, &test.contract.address, &amount_0_extra); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1_extra); - assert_eq!(test.token_0.balance(&test.contract.address), amount_0 + amount_0_extra); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1 + amount_1_extra); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0_extra); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1_extra); + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0 + amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1 + amount_1_extra + ); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); test.contract.skim(&test.admin); - assert_eq!(test.token_0.balance(&test.user), original_0 - amount_0 - amount_0_extra); - assert_eq!(test.token_1.balance(&test.user), original_1 - amount_1 - amount_1_extra); + assert_eq!( + test.token_0.balance(&test.user), + original_0 - amount_0 - amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1 - amount_1 - amount_1_extra + ); assert_eq!(test.token_0.balance(&test.admin), amount_0_extra); assert_eq!(test.token_1.balance(&test.admin), amount_1_extra); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); diff --git a/contracts/pair/src/test/soroswap_pair_token.rs b/contracts/pair/src/test/soroswap_pair_token.rs index 08528cc1..c667fbae 100644 --- a/contracts/pair/src/test/soroswap_pair_token.rs +++ b/contracts/pair/src/test/soroswap_pair_token.rs @@ -1,7 +1,7 @@ #![cfg(test)] extern crate std; -use crate::test::{SoroswapPairTest, deposit::add_liquidity }; use crate::soroswap_pair_token::{SoroswapPairToken, SoroswapPairTokenClient}; +use crate::test::{deposit::add_liquidity, SoroswapPairTest}; use soroban_sdk::{ symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation}, @@ -16,8 +16,12 @@ fn test() { let user1 = test.user.clone(); let user2 = Address::generate(&test.env); let user3 = Address::generate(&test.env); - - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0 = 2000; let amount_1 = 2000; add_liquidity(&test, &amount_0, &amount_1); @@ -111,7 +115,11 @@ fn test_burn() { let user1 = test.user.clone(); let user2 = Address::generate(&test.env); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0 = 2000; let amount_1 = 2000; add_liquidity(&test, &amount_0, &amount_1); @@ -176,7 +184,11 @@ fn transfer_insufficient_balance() { let user1 = test.user.clone(); let user2 = Address::generate(&test.env); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0 = 2000; let amount_1 = 2000; add_liquidity(&test, &amount_0, &amount_1); @@ -199,8 +211,12 @@ fn transfer_from_insufficient_allowance() { let user1 = test.user.clone(); let user2 = Address::generate(&test.env); let user3 = Address::generate(&test.env); - - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0 = 2000; let amount_1 = 2000; add_liquidity(&test, &amount_0, &amount_1); @@ -224,7 +240,12 @@ fn test_zero_allowance() { let spender = Address::generate(&test.env); let from = Address::generate(&test.env); - let token_client = SoroswapPairTokenClient::new(&test.env, &test.env.register_contract(&test.contract.address, SoroswapPairToken {})); + let token_client = SoroswapPairTokenClient::new( + &test.env, + &test + .env + .register_contract(&test.contract.address, SoroswapPairToken {}), + ); test.contract.transfer_from(&spender, &from, &spender, &0); assert!(token_client.get_allowance(&from, &spender).is_none()); diff --git a/contracts/pair/src/test/swap.rs b/contracts/pair/src/test/swap.rs index 3cb5901b..7f71a526 100644 --- a/contracts/pair/src/test/swap.rs +++ b/contracts/pair/src/test/swap.rs @@ -1,9 +1,8 @@ use crate::test::deposit::add_liquidity; -use crate::test::{SoroswapPairTest}; -use soroban_sdk::{testutils::{Ledger}}; use crate::test::pair::SoroswapPairError; +use crate::test::SoroswapPairTest; +use soroban_sdk::testutils::Ledger; - #[test] // #[should_panic(expected = "SoroswapPair: not yet initialized")] fn try_swap_not_yet_initialized() { @@ -16,11 +15,18 @@ fn try_swap_not_yet_initialized() { #[test] // #[should_panic(expected = "SoroswapPair: insufficient output amount")] fn try_swap_amounts_zero() { - let test = SoroswapPairTest::setup(); + let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let result = test.contract.try_swap(&0, &0, &test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::SwapInsufficientOutputAmount))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::SwapInsufficientOutputAmount)) + ); } #[test] @@ -28,9 +34,16 @@ fn try_swap_amounts_zero() { fn try_swap_amount_0_negative() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let result = test.contract.try_swap(&-1, &1, &test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::SwapNegativesOutNotSupported))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::SwapNegativesOutNotSupported)) + ); } #[test] @@ -38,9 +51,16 @@ fn try_swap_amount_0_negative() { fn try_swap_amount_1_negative() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let result = test.contract.try_swap(&1, &-1, &test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::SwapNegativesOutNotSupported))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::SwapNegativesOutNotSupported)) + ); } #[test] @@ -48,9 +68,16 @@ fn try_swap_amount_1_negative() { fn try_swap_no_liquidity() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let result = test.contract.try_swap(&1, &1, &test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::SwapInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::SwapInsufficientLiquidity)) + ); } #[test] @@ -58,7 +85,11 @@ fn try_swap_no_liquidity() { fn try_swap_to_token_0() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); @@ -71,7 +102,11 @@ fn try_swap_to_token_0() { fn try_swap_to_token_1() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); @@ -79,18 +114,24 @@ fn try_swap_to_token_1() { assert_eq!(result, Err(Ok(SoroswapPairError::SwapInvalidTo))); } - #[test] // #[should_panic(expected = "SoroswapPair: insufficient input amount")] fn try_swap_token_0_insufficient_input() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); let result = test.contract.try_swap(&1000, &0, &test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::SwapInsufficientInputAmount))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::SwapInsufficientInputAmount)) + ); } #[test] @@ -98,12 +139,19 @@ fn try_swap_token_0_insufficient_input() { fn try_swap_token_1_insufficient_input() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); let result = test.contract.try_swap(&0, &1000, &test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::SwapInsufficientInputAmount))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::SwapInsufficientInputAmount)) + ); } #[test] @@ -111,11 +159,16 @@ fn try_swap_token_1_insufficient_input() { fn try_swap_token_0_low_sent() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); - test.token_0.transfer(&test.user, &test.contract.address, &1); + test.token_0 + .transfer(&test.user, &test.contract.address, &1); let result = test.contract.try_swap(&0, &1000, &test.user); assert_eq!(result, Err(Ok(SoroswapPairError::SwapKConstantNotMet))); } @@ -125,29 +178,36 @@ fn try_swap_token_0_low_sent() { fn try_swap_token_1_low_sent() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); - test.token_1.transfer(&test.user, &test.contract.address, &1); + test.token_1 + .transfer(&test.user, &test.contract.address, &1); let result = test.contract.try_swap(&1000, &0, &test.user); assert_eq!(result, Err(Ok(SoroswapPairError::SwapKConstantNotMet))); } - - #[test] fn swap_token_0() { let test = SoroswapPairTest::setup(); // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - + let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); add_liquidity(&test, &amount_0, &amount_1); let init_time = 12345; @@ -159,33 +219,61 @@ fn swap_token_0() { let expected_output_amount_1: i128 = 16624979; // The user sends the token first: - test.token_0.transfer(&test.user, &test.contract.address, &swap_amount_0); - - test.contract.swap(&0, &expected_output_amount_1, &test.user); - - assert_eq!(test.contract.get_reserves(), - (amount_0.checked_add(swap_amount_0).unwrap(), - amount_1.checked_sub(expected_output_amount_1).unwrap())); - - assert_eq!(test.token_0.balance(&test.contract.address), amount_0.checked_add(swap_amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1.checked_sub(expected_output_amount_1).unwrap()); - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap().checked_sub(swap_amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap().checked_add(expected_output_amount_1).unwrap()); - + test.token_0 + .transfer(&test.user, &test.contract.address, &swap_amount_0); + + test.contract + .swap(&0, &expected_output_amount_1, &test.user); + + assert_eq!( + test.contract.get_reserves(), + ( + amount_0.checked_add(swap_amount_0).unwrap(), + amount_1.checked_sub(expected_output_amount_1).unwrap() + ) + ); + + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0.checked_add(swap_amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1.checked_sub(expected_output_amount_1).unwrap() + ); + assert_eq!( + test.token_0.balance(&test.user), + original_0 + .checked_sub(amount_0) + .unwrap() + .checked_sub(swap_amount_0) + .unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1 + .checked_sub(amount_1) + .unwrap() + .checked_add(expected_output_amount_1) + .unwrap() + ); } - #[test] fn swap_token_1() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - + let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); add_liquidity(&test, &amount_0, &amount_1); let init_time = 12345; test.env.ledger().with_mut(|li| { @@ -196,19 +284,44 @@ fn swap_token_1() { let expected_output_amount_0: i128 = 4533054; // The user sends the token first: - test.token_1.transfer(&test.user, &test.contract.address, &swap_amount_1); - - test.contract.swap(&expected_output_amount_0, &0, &test.user); - - assert_eq!(test.contract.get_reserves(), - (amount_0.checked_sub(expected_output_amount_0).unwrap(), - amount_1.checked_add(swap_amount_1).unwrap())); - - assert_eq!(test.token_0.balance(&test.contract.address), amount_0.checked_sub(expected_output_amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1.checked_add(swap_amount_1).unwrap()); - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap().checked_add(expected_output_amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap().checked_sub(swap_amount_1).unwrap()); - + test.token_1 + .transfer(&test.user, &test.contract.address, &swap_amount_1); + + test.contract + .swap(&expected_output_amount_0, &0, &test.user); + + assert_eq!( + test.contract.get_reserves(), + ( + amount_0.checked_sub(expected_output_amount_0).unwrap(), + amount_1.checked_add(swap_amount_1).unwrap() + ) + ); + + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0.checked_sub(expected_output_amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1.checked_add(swap_amount_1).unwrap() + ); + assert_eq!( + test.token_0.balance(&test.user), + original_0 + .checked_sub(amount_0) + .unwrap() + .checked_add(expected_output_amount_0) + .unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1 + .checked_sub(amount_1) + .unwrap() + .checked_sub(swap_amount_1) + .unwrap() + ); } #[test] @@ -216,10 +329,14 @@ fn swap_token_1() { fn try_swap_token_1_optimal_plus_1() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - + let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); add_liquidity(&test, &amount_0, &amount_1); let init_time = 12345; test.env.ledger().with_mut(|li| { @@ -230,8 +347,11 @@ fn try_swap_token_1_optimal_plus_1() { let expected_output_amount_0: i128 = 4533054 + 1; // The user sends the token first: - test.token_1.transfer(&test.user, &test.contract.address, &swap_amount_1); + test.token_1 + .transfer(&test.user, &test.contract.address, &swap_amount_1); - let result = test.contract.try_swap(&expected_output_amount_0, &0, &test.user); + let result = test + .contract + .try_swap(&expected_output_amount_0, &0, &test.user); assert_eq!(result, Err(Ok(SoroswapPairError::SwapKConstantNotMet))); } diff --git a/contracts/pair/src/test/sync.rs b/contracts/pair/src/test/sync.rs index 637c6c9c..1de7d2de 100644 --- a/contracts/pair/src/test/sync.rs +++ b/contracts/pair/src/test/sync.rs @@ -1,5 +1,5 @@ use crate::test::deposit::add_liquidity; -use crate::test::{SoroswapPairTest}; +use crate::test::SoroswapPairTest; #[test] #[should_panic] fn sync_not_initialized() { @@ -13,7 +13,11 @@ fn sync_not_initialized() { fn sync_with_liquidity_nothing_to_sync() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -22,28 +26,42 @@ fn sync_with_liquidity_nothing_to_sync() { add_liquidity(&test, &amount_0, &amount_1); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); test.contract.sync(); //no tokens where sent to the user, nothing changed - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); } - - #[test] fn sync() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let original_0: i128 = test.token_0.balance(&test.user); let original_1: i128 = test.token_1.balance(&test.user); @@ -52,8 +70,14 @@ fn sync() { add_liquidity(&test, &amount_0, &amount_1); // New balances: - assert_eq!(test.token_0.balance(&test.user), original_0.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_1.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + original_0.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&test.contract.address), amount_0); assert_eq!(test.token_1.balance(&test.contract.address), amount_1); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); @@ -61,17 +85,40 @@ fn sync() { //extra tokens sent to skim: let amount_0_extra: i128 = 123_000_000; let amount_1_extra: i128 = 4_586_000; - test.token_0.transfer(&test.user, &test.contract.address, &amount_0_extra); - test.token_1.transfer(&test.user, &test.contract.address, &amount_1_extra); - assert_eq!(test.token_0.balance(&test.contract.address), amount_0 + amount_0_extra); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1 + amount_1_extra); + test.token_0 + .transfer(&test.user, &test.contract.address, &amount_0_extra); + test.token_1 + .transfer(&test.user, &test.contract.address, &amount_1_extra); + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0 + amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1 + amount_1_extra + ); assert_eq!(test.contract.get_reserves(), (amount_0, amount_1)); test.contract.sync(); //no tokens where sent to the user, nothing changed -- only reserves! - assert_eq!(test.token_0.balance(&test.user), original_0 - amount_0 - amount_0_extra); - assert_eq!(test.token_1.balance(&test.user), original_1 - amount_1 - amount_1_extra); - assert_eq!(test.token_0.balance(&test.contract.address), amount_0 + amount_0_extra); - assert_eq!(test.token_1.balance(&test.contract.address), amount_1 + amount_1_extra); - assert_eq!(test.contract.get_reserves(), (amount_0 + amount_0_extra, amount_1 + amount_1_extra,)); + assert_eq!( + test.token_0.balance(&test.user), + original_0 - amount_0 - amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.user), + original_1 - amount_1 - amount_1_extra + ); + assert_eq!( + test.token_0.balance(&test.contract.address), + amount_0 + amount_0_extra + ); + assert_eq!( + test.token_1.balance(&test.contract.address), + amount_1 + amount_1_extra + ); + assert_eq!( + test.contract.get_reserves(), + (amount_0 + amount_0_extra, amount_1 + amount_1_extra,) + ); } diff --git a/contracts/pair/src/test/withdraw.rs b/contracts/pair/src/test/withdraw.rs index 18019c5b..740ee336 100644 --- a/contracts/pair/src/test/withdraw.rs +++ b/contracts/pair/src/test/withdraw.rs @@ -1,7 +1,6 @@ -use crate::test::{SoroswapPairTest}; use crate::test::deposit::add_liquidity; use crate::test::pair::SoroswapPairError; - +use crate::test::SoroswapPairTest; #[test] // #[should_panic(expected = "SoroswapPair: not yet initialized")] @@ -17,9 +16,16 @@ fn try_withdraw_not_yet_initialized() { fn try_withdraw_not_yet_deposited() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let result = test.contract.try_withdraw(&test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::WithdrawLiquidityNotInitialized))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::WithdrawLiquidityNotInitialized)) + ); } #[test] @@ -27,29 +33,41 @@ fn try_withdraw_not_yet_deposited() { fn try_withdraw_not_shares_sent() { let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 50_000_000; let amount_1: i128 = 100_000_000; add_liquidity(&test, &amount_0, &amount_1); let result = test.contract.try_withdraw(&test.user); - assert_eq!(result, Err(Ok(SoroswapPairError::WithdrawInsufficientSentShares))); + assert_eq!( + result, + Err(Ok(SoroswapPairError::WithdrawInsufficientSentShares)) + ); } - - - #[test] fn withdraw() { - let test = SoroswapPairTest::setup(); + let test = SoroswapPairTest::setup(); test.env.budget().reset_unlimited(); - test.contract.initialize(&test.factory.address, &test.token_0.address, &test.token_1.address); + test.contract.initialize( + &test.factory.address, + &test.token_0.address, + &test.token_1.address, + ); let amount_0: i128 = 3_000_000; let amount_1: i128 = 3_000_000; - let expected_liquidity: i128 = 3_000_000; + let expected_liquidity: i128 = 3_000_000; let minimum_liquidity: i128 = 1_000; add_liquidity(&test, &amount_0, &amount_1); - test.contract.transfer(&test.user, &test.contract.address, &expected_liquidity.checked_sub(minimum_liquidity).unwrap()); + test.contract.transfer( + &test.user, + &test.contract.address, + &expected_liquidity.checked_sub(minimum_liquidity).unwrap(), + ); test.contract.withdraw(&test.user); assert_eq!(test.contract.balance(&test.user), 0); @@ -60,8 +78,12 @@ fn withdraw() { let original_total_supply_0: i128 = 123_000_000_000_000_000_000; // from the test file let original_total_supply_1: i128 = 321_000_000_000_000_000_000; // from the test file - assert_eq!(test.token_0.balance(&test.user), original_total_supply_0.checked_sub(1000).unwrap()); - assert_eq!(test.token_1.balance(&test.user), original_total_supply_1.checked_sub(1000).unwrap()); - - + assert_eq!( + test.token_0.balance(&test.user), + original_total_supply_0.checked_sub(1000).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + original_total_supply_1.checked_sub(1000).unwrap() + ); } diff --git a/contracts/router/src/error.rs b/contracts/router/src/error.rs index 4adcc544..ff411004 100644 --- a/contracts/router/src/error.rs +++ b/contracts/router/src/error.rs @@ -1,6 +1,5 @@ use soroban_sdk::{self, contracterror}; -use soroswap_library::{SoroswapLibraryError}; - +use soroswap_library::SoroswapLibraryError; #[contracterror] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] @@ -14,7 +13,7 @@ pub enum SoroswapRouterError { /// SoroswapRouter: deadline expired DeadlineExpired = 403, - + /// SoroswapRouter: already initialized InitializeAlreadyInitialized = 404, @@ -32,10 +31,8 @@ pub enum SoroswapRouterError { /// SoroswapRouter: pair does not exist PairDoesNotExist = 409, - } - #[contracterror] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[repr(u32)] @@ -62,12 +59,22 @@ pub enum CombinedRouterError { impl From for CombinedRouterError { fn from(err: SoroswapLibraryError) -> Self { match err { - SoroswapLibraryError::InsufficientAmount => CombinedRouterError::LibraryInsufficientAmount, - SoroswapLibraryError::InsufficientLiquidity => CombinedRouterError::LibraryInsufficientLiquidity, - SoroswapLibraryError::InsufficientInputAmount => CombinedRouterError::LibraryInsufficientInputAmount, - SoroswapLibraryError::InsufficientOutputAmount => CombinedRouterError::LibraryInsufficientOutputAmount, + SoroswapLibraryError::InsufficientAmount => { + CombinedRouterError::LibraryInsufficientAmount + } + SoroswapLibraryError::InsufficientLiquidity => { + CombinedRouterError::LibraryInsufficientLiquidity + } + SoroswapLibraryError::InsufficientInputAmount => { + CombinedRouterError::LibraryInsufficientInputAmount + } + SoroswapLibraryError::InsufficientOutputAmount => { + CombinedRouterError::LibraryInsufficientOutputAmount + } SoroswapLibraryError::InvalidPath => CombinedRouterError::LibraryInvalidPath, - SoroswapLibraryError::SortIdenticalTokens => CombinedRouterError::LibrarySortIdenticalTokens, + SoroswapLibraryError::SortIdenticalTokens => { + CombinedRouterError::LibrarySortIdenticalTokens + } } } } @@ -76,13 +83,25 @@ impl From for CombinedRouterError { fn from(err: SoroswapRouterError) -> Self { match err { SoroswapRouterError::NotInitialized => CombinedRouterError::RouterNotInitialized, - SoroswapRouterError::NegativeNotAllowed => CombinedRouterError::RouterNegativeNotAllowed, + SoroswapRouterError::NegativeNotAllowed => { + CombinedRouterError::RouterNegativeNotAllowed + } SoroswapRouterError::DeadlineExpired => CombinedRouterError::RouterDeadlineExpired, - SoroswapRouterError::InitializeAlreadyInitialized => CombinedRouterError::RouterInitializeAlreadyInitialized, - SoroswapRouterError::InsufficientAAmount => CombinedRouterError::RouterInsufficientAAmount, - SoroswapRouterError::InsufficientBAmount => CombinedRouterError::RouterInsufficientBAmount, - SoroswapRouterError::InsufficientOutputAmount => CombinedRouterError::RouterInsufficientOutputAmount, - SoroswapRouterError::ExcessiveInputAmount => CombinedRouterError::RouterExcessiveInputAmount, + SoroswapRouterError::InitializeAlreadyInitialized => { + CombinedRouterError::RouterInitializeAlreadyInitialized + } + SoroswapRouterError::InsufficientAAmount => { + CombinedRouterError::RouterInsufficientAAmount + } + SoroswapRouterError::InsufficientBAmount => { + CombinedRouterError::RouterInsufficientBAmount + } + SoroswapRouterError::InsufficientOutputAmount => { + CombinedRouterError::RouterInsufficientOutputAmount + } + SoroswapRouterError::ExcessiveInputAmount => { + CombinedRouterError::RouterExcessiveInputAmount + } SoroswapRouterError::PairDoesNotExist => CombinedRouterError::RouterPairDoesNotExist, } } diff --git a/contracts/router/src/event.rs b/contracts/router/src/event.rs index ed41b888..59a9abe8 100644 --- a/contracts/router/src/event.rs +++ b/contracts/router/src/event.rs @@ -1,23 +1,21 @@ //! Definition of the Events used in the contract -use soroban_sdk::{contracttype, symbol_short, Env, Address, Vec}; +use soroban_sdk::{contracttype, symbol_short, Address, Env, Vec}; // INITIALIZED #[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct InitializedEvent { - pub factory: Address + pub factory: Address, } pub(crate) fn initialized(e: &Env, factory: Address) { - - let event: InitializedEvent = InitializedEvent { - factory: factory - }; - e.events().publish(("SoroswapRouter", symbol_short!("init")), event); + let event: InitializedEvent = InitializedEvent { factory: factory }; + e.events() + .publish(("SoroswapRouter", symbol_short!("init")), event); } // ADD LIQUIDITY EVENT -#[contracttype] +#[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct AddLiquidityEvent { pub token_a: Address, @@ -26,13 +24,13 @@ pub struct AddLiquidityEvent { pub amount_a: i128, pub amount_b: i128, pub liquidity: i128, - pub to: Address + pub to: Address, } /// Publishes an `AddLiquidityEvent` to the event stream. -/// +/// /// # Arguments -/// +/// /// * `e` - An instance of the `Env` struct. /// * `token_a` - The address of the first token in the liquidity pair. /// * `token_b` - The address of the second token in the liquidity pair. @@ -61,13 +59,12 @@ pub(crate) fn add_liquidity( to, }; - e.events().publish(("SoroswapRouter", symbol_short!("add")), event); + e.events() + .publish(("SoroswapRouter", symbol_short!("add")), event); } - - // REMOVE LIQUIDITY EVENT -#[contracttype] +#[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct RemoveLiquidityEvent { pub token_a: Address, @@ -76,14 +73,13 @@ pub struct RemoveLiquidityEvent { pub amount_a: i128, pub amount_b: i128, pub liquidity: i128, - pub to: Address + pub to: Address, } - /// Publishes an `RemoveLiquidityEvent` to the event stream. -/// +/// /// # Arguments -/// +/// /// * `e` - An instance of the `Env` struct. /// * `token_a` - The address of the first token in the liquidity pair. /// * `token_b` - The address of the second token in the liquidity pair. @@ -112,40 +108,31 @@ pub(crate) fn remove_liquidity( to, }; - e.events().publish(("SoroswapRouter", symbol_short!("remove")), event); + e.events() + .publish(("SoroswapRouter", symbol_short!("remove")), event); } - - // SWAP EVENT -#[contracttype] +#[contracttype] #[derive(Clone, Debug, Eq, PartialEq)] pub struct SwapEvent { pub path: Vec
, pub amounts: Vec, - pub to: Address + pub to: Address, } /// Publishes an `SwapEvent` to the event stream. -/// +/// /// # Arguments -/// +/// /// * `e` - An instance of the `Env` struct. -/// * `path` - A vector representing the trading route, where the first element is the input token +/// * `path` - A vector representing the trading route, where the first element is the input token /// and the last is the output token. Intermediate elements represent pairs to trade through. /// * `amounts` - A vector containing the amounts of tokens traded at each step of the trading route. /// * `to` - The address where the output tokens will be sent to. -pub(crate) fn swap( - e: &Env, - path: Vec
, - amounts: Vec, - to: Address -) { - let event = SwapEvent { - path, - amounts, - to, - }; +pub(crate) fn swap(e: &Env, path: Vec
, amounts: Vec, to: Address) { + let event = SwapEvent { path, amounts, to }; - e.events().publish(("SoroswapRouter", symbol_short!("swap")), event); -} \ No newline at end of file + e.events() + .publish(("SoroswapRouter", symbol_short!("swap")), event); +} diff --git a/contracts/router/src/factory.rs b/contracts/router/src/factory.rs index 6a7c7c0f..e9c313c0 100644 --- a/contracts/router/src/factory.rs +++ b/contracts/router/src/factory.rs @@ -1,4 +1,4 @@ soroban_sdk::contractimport!( file = "../factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm" ); -pub type SoroswapFactoryClient<'a> = Client<'a>; \ No newline at end of file +pub type SoroswapFactoryClient<'a> = Client<'a>; diff --git a/contracts/router/src/lib.rs b/contracts/router/src/lib.rs index 2df04aef..323d6e51 100644 --- a/contracts/router/src/lib.rs +++ b/contracts/router/src/lib.rs @@ -1,19 +1,19 @@ #![no_std] use soroban_sdk::token::Client as TokenClient; use soroban_sdk::{contract, contractimpl, Address, Env, Vec}; -use soroswap_library::{SoroswapLibraryError}; +use soroswap_library::SoroswapLibraryError; -mod pair; -mod factory; -mod test; +mod error; mod event; +mod factory; +mod pair; mod storage; -mod error; +mod test; +pub use error::{CombinedRouterError, SoroswapRouterError}; use factory::SoroswapFactoryClient; use pair::SoroswapPairClient; -use storage::{put_factory, has_factory, get_factory, extend_instance_ttl}; -pub use error::{SoroswapRouterError, CombinedRouterError}; +use storage::{extend_instance_ttl, get_factory, has_factory, put_factory}; pub fn check_nonnegative_amount(amount: i128) -> Result<(), CombinedRouterError> { if amount < 0 { @@ -23,7 +23,6 @@ pub fn check_nonnegative_amount(amount: i128) -> Result<(), CombinedRouterError> } } - /// Panics if the specified deadline has passed. /// /// # Arguments @@ -38,7 +37,6 @@ fn ensure_deadline(e: &Env, timestamp: u64) -> Result<(), CombinedRouterError> { } } - fn check_initialized(e: &Env) -> Result<(), CombinedRouterError> { if has_factory(e) { Ok(()) @@ -47,7 +45,6 @@ fn check_initialized(e: &Env) -> Result<(), CombinedRouterError> { } } - /// Given a pair of tokens, a desired and minimum amount of tokens to provide as liquidity, this function calculates /// the correct amounts of tokens to add to the pool. If the pool doesn't exist, it creates one. /// @@ -107,7 +104,8 @@ fn add_liquidity_amounts( } // If not, we can try with the amount b desired else { - let amount_a_optimal = soroswap_library::quote(amount_b_desired, reserve_b, reserve_a).map_err(SoroswapLibraryError::from)?; + let amount_a_optimal = soroswap_library::quote(amount_b_desired, reserve_b, reserve_a) + .map_err(SoroswapLibraryError::from)?; // This should happen anyway. Because if we were not able to fulfill with our amount_b_desired for our amount_a_desired // It is to expect that the amount_a_optimal for that lower amount_b_desired to be lower than the amount_a_desired @@ -130,15 +128,21 @@ fn add_liquidity_amounts( /// * `amounts` - A vector containing the output amounts for each step of the trading route. /// * `path` - A vector representing the trading route, where each element is a token address. /// * `_to` - The final destination address for the swapped tokens. -fn swap(e: &Env, factory_address: &Address, amounts: &Vec, path: &Vec
, _to: &Address) -> Result<(), CombinedRouterError>{ +fn swap( + e: &Env, + factory_address: &Address, + amounts: &Vec, + path: &Vec
, + _to: &Address, +) -> Result<(), CombinedRouterError> { for i in 0..path.len() - 1 { // represents a half-open range, which includes the start value (0) but excludes the end value (path.len() - 1) let (input, output): (Address, Address) = (path.get(i).unwrap(), path.get(i + 1).unwrap()); let (token_0, _token_1): (Address, Address) = (soroswap_library::sort_tokens(input.clone(), output.clone()))?; - - let amount_out: i128 = amounts.get(i + 1).unwrap(); + + let amount_out: i128 = amounts.get(i + 1).unwrap(); let (amount_0_out, amount_1_out): (i128, i128) = if input == token_0 { (0, amount_out) @@ -163,19 +167,16 @@ fn swap(e: &Env, factory_address: &Address, amounts: &Vec, path: &Vec Result<(), CombinedRouterError>; @@ -239,13 +240,13 @@ pub trait SoroswapRouterTrait { /// Swaps an exact amount of input tokens for as many output tokens as possible /// along the specified trading route. The route is determined by the `path` vector, - /// where the first element is the input token, the last is the output token, + /// where the first element is the input token, the last is the output token, /// and any intermediate elements represent pairs to trade through if a direct pair does not exist. /// /// # Arguments /// * `amount_in` - The exact amount of input tokens to be swapped. /// * `amount_out_min` - The minimum required amount of output tokens to receive. - /// * `path` - A vector representing the trading route, where the first element is the input token + /// * `path` - A vector representing the trading route, where the first element is the input token /// and the last is the output token. Intermediate elements represent pairs to trade through. /// * `to` - The address where the output tokens will be sent to. /// * `deadline` - The deadline for executing the operation. @@ -268,7 +269,7 @@ pub trait SoroswapRouterTrait { /// # Arguments /// * `amount_out` - The exact amount of output token to be received. /// * `amount_in_max` - The maximum allowed amount of input tokens to be swapped. - /// * `path` - A vector representing the trading route, where the first element is the input token + /// * `path` - A vector representing the trading route, where the first element is the input token /// and the last is the output token. Intermediate elements represent pairs to trade through. /// * `to` - The address where the output tokens will be sent to. /// * `deadline` - The deadline for executing the operation. @@ -310,7 +311,11 @@ pub trait SoroswapRouterTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn router_pair_for(e: Env, token_a: Address, token_b: Address) -> Result; + fn router_pair_for( + e: Env, + token_a: Address, + token_b: Address, + ) -> Result; /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset. /// @@ -323,7 +328,11 @@ pub trait SoroswapRouterTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity - fn router_quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result; + fn router_quote( + amount_a: i128, + reserve_a: i128, + reserve_b: i128, + ) -> Result; /// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset. /// @@ -336,7 +345,11 @@ pub trait SoroswapRouterTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity. - fn router_get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result; + fn router_get_amount_out( + amount_in: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result; /// Given an output amount of an asset and pair reserves, returns a required input amount of the other asset. /// @@ -349,7 +362,11 @@ pub trait SoroswapRouterTrait { /// # Returns /// /// Returns `Result` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity. - fn router_get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result; + fn router_get_amount_in( + amount_out: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result; /// Performs chained get_amount_out calculations on any number of pairs. /// @@ -362,8 +379,12 @@ pub trait SoroswapRouterTrait { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn router_get_amounts_out(e: Env, amount_in: i128, path: Vec
) -> Result, CombinedRouterError>; - + fn router_get_amounts_out( + e: Env, + amount_in: i128, + path: Vec
, + ) -> Result, CombinedRouterError>; + /// Performs chained get_amount_in calculations on any number of pairs. /// /// # Arguments @@ -375,10 +396,11 @@ pub trait SoroswapRouterTrait { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn router_get_amounts_in(e: Env, amount_out: i128, path: Vec
) -> Result, CombinedRouterError>; - - - + fn router_get_amounts_in( + e: Env, + amount_out: i128, + path: Vec
, + ) -> Result, CombinedRouterError>; } #[contract] @@ -395,9 +417,8 @@ impl SoroswapRouterTrait for SoroswapRouter { Ok(()) } else { Err(SoroswapRouterError::InitializeAlreadyInitialized.into()) - } - - } + } + } /// Adds liquidity to a token pair's pool, creating it if it doesn't exist. Ensures that exactly the desired amounts /// of both tokens are added, subject to minimum requirements. @@ -447,12 +468,9 @@ impl SoroswapRouterTrait for SoroswapRouter { amount_b_min, )?; - let pair: Address = soroswap_library::pair_for( - e.clone(), - factory, - token_a.clone(), - token_b.clone(), - ).map_err(SoroswapLibraryError::from)?; + let pair: Address = + soroswap_library::pair_for(e.clone(), factory, token_a.clone(), token_b.clone()) + .map_err(SoroswapLibraryError::from)?; TokenClient::new(&e, &token_a).transfer(&to, &pair, &amount_a); TokenClient::new(&e, &token_b).transfer(&to, &pair, &amount_b); @@ -460,15 +478,9 @@ impl SoroswapRouterTrait for SoroswapRouter { let liquidity = SoroswapPairClient::new(&e, &pair).deposit(&to); event::add_liquidity( - &e, - token_a, - token_b, - pair, - amount_a, - amount_b, - liquidity, - to); - + &e, token_a, token_b, pair, amount_a, amount_b, liquidity, to, + ); + Ok((amount_a, amount_b, liquidity)) } @@ -525,7 +537,7 @@ impl SoroswapRouterTrait for SoroswapRouter { // Transfer LP tokens from the caller to the pair contract TokenClient::new(&e, &pair).transfer(&to, &pair, &liquidity); - + // Withdraw paired tokens from the pool let (amount_0, amount_1) = SoroswapPairClient::new(&e, &pair).withdraw(&to); @@ -546,14 +558,8 @@ impl SoroswapRouterTrait for SoroswapRouter { } event::remove_liquidity( - &e, - token_a, - token_b, - pair, - amount_a, - amount_b, - liquidity, - to); + &e, token_a, token_b, pair, amount_a, amount_b, liquidity, to, + ); // Return the amounts of paired tokens withdrawn Ok((amount_a, amount_b)) @@ -561,13 +567,13 @@ impl SoroswapRouterTrait for SoroswapRouter { /// Swaps an exact amount of input tokens for as many output tokens as possible /// along the specified trading route. The route is determined by the `path` vector, - /// where the first element is the input token, the last is the output token, + /// where the first element is the input token, the last is the output token, /// and any intermediate elements represent pairs to trade through if a direct pair does not exist. /// /// # Arguments /// * `amount_in` - The exact amount of input tokens to be swapped. /// * `amount_out_min` - The minimum required amount of output tokens to receive. - /// * `path` - A vector representing the trading route, where the first element is the input token + /// * `path` - A vector representing the trading route, where the first element is the input token /// and the last is the output token. Intermediate elements represent pairs to trade through. /// * `to` - The address where the output tokens will be sent to. /// * `deadline` - The deadline for executing the operation. @@ -589,7 +595,7 @@ impl SoroswapRouterTrait for SoroswapRouter { to.require_auth(); ensure_deadline(&e, deadline)?; - // Get the expected output amounts for each step of the trading route + // Get the expected output amounts for each step of the trading route let factory_address = get_factory(&e); let amounts = soroswap_library::get_amounts_out( e.clone(), @@ -598,11 +604,11 @@ impl SoroswapRouterTrait for SoroswapRouter { path.clone(), )?; - // Ensure that the final output amount meets the minimum requirement + // Ensure that the final output amount meets the minimum requirement if amounts.get(amounts.len() - 1).unwrap() < amount_out_min { return Err(SoroswapRouterError::InsufficientOutputAmount.into()); } - + // Determine the pair contract address for the first step of the trading route let pair = soroswap_library::pair_for( e.clone(), @@ -610,7 +616,7 @@ impl SoroswapRouterTrait for SoroswapRouter { path.get(0).unwrap(), path.get(1).unwrap(), )?; - + // Transfer input tokens to the pair contract // If the pair does not exist, this will fail here: Should be implement factory.pair_exists? // If we implement, we will include an additional cross-contract call... @@ -618,12 +624,8 @@ impl SoroswapRouterTrait for SoroswapRouter { // Execute the tokens swap swap(&e, &factory_address, &amounts, &path, &to)?; - - event::swap( - &e, - path, - amounts.clone(), - to); + + event::swap(&e, path, amounts.clone(), to); // Return the amounts of tokens received at each step of the trading route Ok(amounts) @@ -636,7 +638,7 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Arguments /// * `amount_out` - The exact amount of output token to be received. /// * `amount_in_max` - The maximum allowed amount of input tokens to be swapped. - /// * `path` - A vector representing the trading route, where the first element is the input token + /// * `path` - A vector representing the trading route, where the first element is the input token /// and the last is the output token. Intermediate elements represent pairs to trade through. /// * `to` - The address where the output tokens will be sent to. /// * `deadline` - The deadline for executing the operation. @@ -655,7 +657,7 @@ impl SoroswapRouterTrait for SoroswapRouter { check_nonnegative_amount(amount_out)?; check_nonnegative_amount(amount_in_max)?; extend_instance_ttl(&e); - to.require_auth(); + to.require_auth(); ensure_deadline(&e, deadline)?; // Get the expected input amounts for each step of the trading route @@ -666,7 +668,7 @@ impl SoroswapRouterTrait for SoroswapRouter { amount_out, path.clone(), )?; - + // Ensure that the input amount does not exceed the maximum allowed if amounts.get(0).unwrap() > amount_in_max { return Err(SoroswapRouterError::ExcessiveInputAmount.into()); @@ -686,12 +688,8 @@ impl SoroswapRouterTrait for SoroswapRouter { // Execute the token swap swap(&e, &factory_address, &amounts, &path, &to)?; - - event::swap( - &e, - path, - amounts.clone(), - to); + + event::swap(&e, path, amounts.clone(), to); // Return the amounts of tokens used at each step of the trading route Ok(amounts) @@ -699,7 +697,6 @@ impl SoroswapRouterTrait for SoroswapRouter { /* *** Read only functions: *** */ - /// This function retrieves the factory contract's address associated with the provided environment. /// It also checks if the factory has been initialized and raises an assertion error if not. /// If the factory is not initialized, this code will raise an assertion error with the message "SoroswapRouter: not yet initialized". @@ -707,13 +704,12 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Arguments /// * `e` - The contract environment (`Env`) in which the contract is executing. fn get_factory(e: Env) -> Result { - check_initialized(&e)?; + check_initialized(&e)?; extend_instance_ttl(&e); let factory_address = get_factory(&e); Ok(factory_address) } - /// Calculates the deterministic address for a pair without making any external calls. /// check /// @@ -726,7 +722,11 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Returns /// /// Returns `Result` where `Ok` contains the deterministic address for the pair, and `Err` indicates an error such as identical tokens or an issue with sorting. - fn router_pair_for(e: Env, token_a: Address, token_b: Address) -> Result { + fn router_pair_for( + e: Env, + token_a: Address, + token_b: Address, + ) -> Result { extend_instance_ttl(&e); Ok(soroswap_library::pair_for( e.clone(), @@ -736,7 +736,6 @@ impl SoroswapRouterTrait for SoroswapRouter { )?) } - /// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset. /// /// # Arguments @@ -748,7 +747,11 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated equivalent amount, and `Err` indicates an error such as insufficient amount or liquidity - fn router_quote(amount_a: i128, reserve_a: i128, reserve_b: i128) -> Result { + fn router_quote( + amount_a: i128, + reserve_a: i128, + reserve_b: i128, + ) -> Result { Ok(soroswap_library::quote(amount_a, reserve_a, reserve_b)?) } @@ -763,8 +766,16 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Returns /// /// Returns `Result` where `Ok` contains the calculated maximum output amount, and `Err` indicates an error such as insufficient input amount or liquidity. - fn router_get_amount_out(amount_in: i128, reserve_in: i128, reserve_out: i128) -> Result { - Ok(soroswap_library::get_amount_out(amount_in, reserve_in, reserve_out)?) + fn router_get_amount_out( + amount_in: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result { + Ok(soroswap_library::get_amount_out( + amount_in, + reserve_in, + reserve_out, + )?) } /// Given an output amount of an asset and pair reserves, returns a required input amount of the other asset. @@ -778,11 +789,18 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Returns /// /// Returns `Result` where `Ok` contains the required input amount, and `Err` indicates an error such as insufficient output amount or liquidity. - fn router_get_amount_in(amount_out: i128, reserve_in: i128, reserve_out: i128) -> Result { - Ok(soroswap_library::get_amount_in(amount_out, reserve_in, reserve_out)?) + fn router_get_amount_in( + amount_out: i128, + reserve_in: i128, + reserve_out: i128, + ) -> Result { + Ok(soroswap_library::get_amount_in( + amount_out, + reserve_in, + reserve_out, + )?) } - /// Performs chained get_amount_out calculations on any number of pairs. /// /// # Arguments @@ -794,11 +812,17 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn router_get_amounts_out(e: Env, amount_in: i128, path: Vec
) -> Result, CombinedRouterError> { + fn router_get_amounts_out( + e: Env, + amount_in: i128, + path: Vec
, + ) -> Result, CombinedRouterError> { check_initialized(&e)?; extend_instance_ttl(&e); let factory = get_factory(&e); - Ok(soroswap_library::get_amounts_out(e, factory, amount_in, path)?) + Ok(soroswap_library::get_amounts_out( + e, factory, amount_in, path, + )?) } /// Performs chained get_amount_in calculations on any number of pairs. @@ -812,12 +836,16 @@ impl SoroswapRouterTrait for SoroswapRouter { /// # Returns /// /// Returns `Result, SoroswapLibraryError>` where `Ok` contains a vector of calculated amounts, and `Err` indicates an error such as an invalid path. - fn router_get_amounts_in(e: Env, amount_out: i128, path: Vec
) -> Result, CombinedRouterError> { + fn router_get_amounts_in( + e: Env, + amount_out: i128, + path: Vec
, + ) -> Result, CombinedRouterError> { check_initialized(&e)?; extend_instance_ttl(&e); let factory = get_factory(&e); - Ok(soroswap_library::get_amounts_in(e, factory, amount_out, path)?) + Ok(soroswap_library::get_amounts_in( + e, factory, amount_out, path, + )?) } - - } diff --git a/contracts/router/src/pair.rs b/contracts/router/src/pair.rs index b1492e0a..3713774a 100644 --- a/contracts/router/src/pair.rs +++ b/contracts/router/src/pair.rs @@ -1,4 +1,2 @@ -soroban_sdk::contractimport!( - file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" -); -pub type SoroswapPairClient<'a> = Client<'a>; \ No newline at end of file +soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); +pub type SoroswapPairClient<'a> = Client<'a>; diff --git a/contracts/router/src/storage.rs b/contracts/router/src/storage.rs index 917ebc35..2c6f2b8f 100644 --- a/contracts/router/src/storage.rs +++ b/contracts/router/src/storage.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{contracttype, Env, Address}; +use soroban_sdk::{contracttype, Address, Env}; #[derive(Clone)] #[contracttype] diff --git a/contracts/router/src/test.rs b/contracts/router/src/test.rs index 5b919b28..bbb5d411 100644 --- a/contracts/router/src/test.rs +++ b/contracts/router/src/test.rs @@ -1,52 +1,46 @@ #![cfg(test)] extern crate std; use crate::{SoroswapRouter, SoroswapRouterClient}; -use soroban_sdk::{ - Env, - BytesN, - Address, - testutils::{ - Address as _, - }, -}; +use soroban_sdk::{testutils::Address as _, Address, BytesN, Env}; // Token Contract mod token { - soroban_sdk::contractimport!(file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm"); + soroban_sdk::contractimport!( + file = "../token/target/wasm32v1-none/release/soroban_token_contract.wasm" + ); pub type TokenClient<'a> = Client<'a>; } use token::TokenClient; -pub fn create_token_contract<'a>(e: &Env, admin: & Address) -> TokenClient<'a> { +pub fn create_token_contract<'a>(e: &Env, admin: &Address) -> TokenClient<'a> { TokenClient::new(&e, &e.register_stellar_asset_contract(admin.clone())) } // Pair Contract mod pair { soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); - pub type SoroswapPairClient<'a> = Client<'a>; + pub type SoroswapPairClient<'a> = Client<'a>; } use pair::SoroswapPairClient; - fn pair_contract_wasm(e: &Env) -> BytesN<32> { - soroban_sdk::contractimport!( - file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm" - ); + soroban_sdk::contractimport!(file = "../pair/target/wasm32v1-none/release/soroswap_pair.wasm"); e.deployer().upload_contract_wasm(WASM) } // SoroswapFactory Contract mod factory { - soroban_sdk::contractimport!(file = "../factory/target/wasm32v1-none/release/soroswap_factory.wasm"); + soroban_sdk::contractimport!( + file = "../factory/target/wasm32v1-none/release/soroswap_factory.wasm" + ); pub type SoroswapFactoryClient<'a> = Client<'a>; } use factory::SoroswapFactoryClient; -fn create_soroswap_factory<'a>(e: & Env, setter: & Address) -> SoroswapFactoryClient<'a> { - let pair_hash = pair_contract_wasm(&e); +fn create_soroswap_factory<'a>(e: &Env, setter: &Address) -> SoroswapFactoryClient<'a> { + let pair_hash = pair_contract_wasm(&e); let factory_address = &e.register_contract_wasm(None, factory::WASM); - let factory = SoroswapFactoryClient::new(e, factory_address); + let factory = SoroswapFactoryClient::new(e, factory_address); factory.initialize(&setter, &pair_hash); factory } @@ -65,12 +59,11 @@ pub struct SoroswapRouterTest<'a> { token_1: TokenClient<'a>, factory: SoroswapFactoryClient<'a>, user: Address, - admin: Address + admin: Address, } impl<'a> SoroswapRouterTest<'a> { fn setup() -> Self { - let env = Env::default(); env.mock_all_auths(); let contract = create_soroswap_router(&env); @@ -97,12 +90,11 @@ impl<'a> SoroswapRouterTest<'a> { token_1, factory, user, - admin + admin, } } fn setup_deducted_reserve() -> Self { - let env = Env::default(); env.mock_all_auths(); let contract = create_soroswap_router(&env); @@ -116,7 +108,7 @@ impl<'a> SoroswapRouterTest<'a> { if &token_1.address < &token_0.address { std::mem::swap(&mut token_0, &mut token_1); } - + let initial_user_balance = 24_995_705_032_704; token_0.mint(&user, &initial_user_balance); @@ -131,23 +123,21 @@ impl<'a> SoroswapRouterTest<'a> { token_1, factory, user, - admin + admin, } } } // Test mods: -pub mod initialize; pub mod add_liquidity; +pub mod initialize; //pub mod swap; -pub mod remove_liquidity; +pub mod events; pub mod library_functions; -pub mod swap_tokens_for_exact_tokens; +pub mod remove_liquidity; pub mod swap_exact_tokens_for_tokens; -pub mod events; +pub mod swap_tokens_for_exact_tokens; // BUDGET TEST MOD mod budget; - - diff --git a/contracts/router/src/test/add_liquidity.rs b/contracts/router/src/test/add_liquidity.rs index c982ec90..7d176010 100644 --- a/contracts/router/src/test/add_liquidity.rs +++ b/contracts/router/src/test/add_liquidity.rs @@ -1,26 +1,19 @@ -use crate::test::{SoroswapRouterTest, SoroswapPairClient}; +use crate::test::{SoroswapPairClient, SoroswapRouterTest}; extern crate std; -use crate::error::{CombinedRouterError}; - +use crate::error::CombinedRouterError; use soroban_sdk::{ - Address, - testutils::{ - Address as _, - MockAuth, - MockAuthInvoke, - Ledger}, - vec, - IntoVal}; - + testutils::{Address as _, Ledger, MockAuth, MockAuthInvoke}, + vec, Address, IntoVal, +}; // Pub function that will be used in other tests: - pub fn add_liquidity( - test: &SoroswapRouterTest, + test: &SoroswapRouterTest, amount_0: &i128, - amount_1: &i128) -> (i128, i128, i128){ + amount_1: &i128, +) -> (i128, i128, i128) { let ledger_timestamp = 100; let desired_deadline = 1000; assert!(desired_deadline > ledger_timestamp); @@ -28,53 +21,53 @@ pub fn add_liquidity( li.timestamp = ledger_timestamp; }); - - test.env.budget().reset_unlimited(); - test.contract.add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, - ) - + test.env.budget().reset_unlimited(); + test.contract.add_liquidity( + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ) } #[test] fn test_add_liquidity_not_yet_initialized() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &10000, // amount_a_desired: i128, - &10000, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &10000, // amount_a_desired: i128, + &10000, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, ); assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); } - #[test] fn test_add_liquidity_amount_a_desired_negative() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &-1, // amount_a_desired: i128, - &10000, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &-1, // amount_a_desired: i128, + &10000, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); } #[test] @@ -82,16 +75,19 @@ fn test_add_liquidity_amount_b_desired_negative() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &10000, // amount_a_desired: i128, - &-1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &10000, // amount_a_desired: i128, + &-1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); } #[test] @@ -99,16 +95,19 @@ fn test_add_liquidity_amount_a_min_negative() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &10000, // amount_a_desired: i128, - &10000, // amount_b_desired: i128, - &-1, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &10000, // amount_a_desired: i128, + &10000, // amount_b_desired: i128, + &-1, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); } #[test] @@ -116,19 +115,21 @@ fn test_add_liquidity_amount_b_min_negative() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &10000, // amount_a_desired: i128, - &10000, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &-1, // amount_b_min: i128, - &test.user, // to: Address, - &0, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &10000, // amount_a_desired: i128, + &10000, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &-1, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); } - #[test] #[should_panic(expected = "Unauthorized function call for address")] fn test_add_liquidity_not_authorized() { @@ -149,34 +150,32 @@ fn test_add_liquidity_not_authorized() { invoke: &MockAuthInvoke { contract: &test.contract.address, fn_name: "add_liquidity", - args: vec![& - &test.env, + args: vec![ + &&test.env, test.token_0.address.into_val(&test.env), // token_a: Address, test.token_1.address.into_val(&test.env), // token_b: Address, - 0.into_val(&test.env), // amount_a_desired: i128, - 0.into_val(&test.env), // amount_b_desired: i128, - 0.into_val(&test.env), // amount_a_min: i128, - 0.into_val(&test.env) , // amount_b_min: i128, - (&bob,).into_val(&test.env), // to: Address, - 0.into_val(&test.env)// deadline: u64, - ], + 0.into_val(&test.env), // amount_a_desired: i128, + 0.into_val(&test.env), // amount_b_desired: i128, + 0.into_val(&test.env), // amount_a_min: i128, + 0.into_val(&test.env), // amount_b_min: i128, + (&bob,).into_val(&test.env), // to: Address, + 0.into_val(&test.env), // deadline: u64, + ], sub_invokes: &[], }, }]) .add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &0, // amount_a_desired: i128, - &0, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &bob, // to: Address, - &0// deadline: u64, + &0, // amount_a_desired: i128, + &0, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &bob, // to: Address, + &0, // deadline: u64, ); - } - // #[test] // fn test_add_liquidity_authorized() { // let test = SoroswapRouterTest::setup(); @@ -291,24 +290,23 @@ fn test_add_liquidity_deadline_expired() { let result = test.contract.try_add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &0, // amount_a_desired: i128, - &0, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &bob, // to: Address, - &desired_deadline, // deadline: u64, + &0, // amount_a_desired: i128, + &0, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &bob, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!(result, Err(Ok(CombinedRouterError::RouterDeadlineExpired))); } // test pair exist, pair does not exist - #[test] fn test_add_liquidity() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -327,42 +325,59 @@ fn test_add_liquidity() { assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); - assert_eq!(test.factory.pair_exists(&test.token_0.address, &test.token_1.address), false); - let deterministic_pair_address = test.contract.router_pair_for(&test.token_0.address, &test.token_1.address); + assert_eq!( + test.factory + .pair_exists(&test.token_0.address, &test.token_1.address), + false + ); + let deterministic_pair_address = test + .contract + .router_pair_for(&test.token_0.address, &test.token_1.address); let (added_token_0, added_token_1, added_liquidity) = test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!(added_token_0, amount_0); assert_eq!(added_token_1, amount_1); - assert_eq!(added_liquidity, expected_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap()); + assert_eq!( + added_liquidity, + expected_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap() + ); // TODO: Test events: // We test that the pair now exist - assert_eq!(test.factory.pair_exists(&test.token_0.address, &test.token_1.address), true); + assert_eq!( + test.factory + .pair_exists(&test.token_0.address, &test.token_1.address), + true + ); // We test that the pair was created succesfully - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); - let pair_address_other_way = test.factory.get_pair(&test.token_1.address, &test.token_0.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); + let pair_address_other_way = test + .factory + .get_pair(&test.token_1.address, &test.token_0.address); // We test that the addresses where correctly generated assert_eq!(pair_address, pair_address_other_way); assert_eq!(pair_address, deterministic_pair_address); - + // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); // We test that factory has only 1 pair - assert_eq!(test.factory.all_pairs(&0), pair_address); + assert_eq!(test.factory.all_pairs(&0), pair_address); assert_eq!(test.factory.all_pairs_length(), 1); - + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // We test that pair contract has assigned correctly the factory and tokens assert_eq!(pair_client.factory(), test.factory.address); @@ -370,11 +385,17 @@ fn test_add_liquidity() { assert_eq!(pair_client.token_1(), test.token_1.address); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); - + // Check initial reserves assert_eq!(pair_client.get_reserves(), (amount_0, amount_1)); @@ -383,18 +404,21 @@ fn test_add_liquidity() { // Check user LP balance static MINIMUM_LIQUIDITY: i128 = 1000; - assert_eq!(pair_client.balance(&test.user), expected_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap()); + assert_eq!( + pair_client.balance(&test.user), + expected_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap() + ); // We can provide liquidity again and should not panic let (new_added_token_0, new_added_token_1, new_added_liquidity) = test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!(new_added_token_0, amount_0); @@ -408,7 +432,7 @@ fn test_add_liquidity_deducted_amount_reserve() { let test = SoroswapRouterTest::setup_deducted_reserve(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -427,35 +451,47 @@ fn test_add_liquidity_deducted_amount_reserve() { assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); - assert_eq!(test.factory.pair_exists(&test.token_0.address, &test.token_1.address), false); - + assert_eq!( + test.factory + .pair_exists(&test.token_0.address, &test.token_1.address), + false + ); + // Parameters are set as sent on frontend test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &amount_0, // amount_a_min: i128, - &amount_1 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &amount_0, // amount_a_min: i128, + &amount_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); // We test that the pair now exist - assert_eq!(test.factory.pair_exists(&test.token_0.address, &test.token_1.address), true); + assert_eq!( + test.factory + .pair_exists(&test.token_0.address, &test.token_1.address), + true + ); test.env.budget().reset_unlimited(); // We test that the pair was created succesfully - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); - let pair_address_other_way = test.factory.get_pair(&test.token_1.address, &test.token_0.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); + let pair_address_other_way = test + .factory + .get_pair(&test.token_1.address, &test.token_0.address); assert_eq!(pair_address, pair_address_other_way); - + // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); // We test that factory has only 1 pair - assert_eq!(test.factory.all_pairs(&0), pair_address); + assert_eq!(test.factory.all_pairs(&0), pair_address); assert_eq!(test.factory.all_pairs_length(), 1); - + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // We test that pair contract has assigned correctly the factory and tokens assert_eq!(pair_client.factory(), test.factory.address); @@ -464,14 +500,19 @@ fn test_add_liquidity_deducted_amount_reserve() { test.env.budget().reset_unlimited(); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); - + // Check initial reserves assert_eq!(pair_client.get_reserves(), (amount_0, amount_1)); - } // insufficient ammount (a and b) @@ -480,7 +521,7 @@ fn test_add_liquidity_deducted_amount_reserve() { fn insufficient_b_amount() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -492,28 +533,31 @@ fn insufficient_b_amount() { let amount_0: i128 = 1_000_000_000_000_000_000; let amount_1: i128 = 4_000_000_000_000_000_000; - + add_liquidity(&test, &amount_0, &amount_1); - + // We can provide liquidity again and should not panic let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &(amount_0), // amount_a_min: i128, - &(amount_1 + 1), // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &(amount_0), // amount_a_min: i128, + &(amount_1 + 1), // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterInsufficientBAmount)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::RouterInsufficientBAmount))); } #[test] fn insufficient_a_amount() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -525,29 +569,31 @@ fn insufficient_a_amount() { let amount_0: i128 = 1_000_000_000_000_000_000; let amount_1: i128 = 4_000_000_000_000_000_000; - + add_liquidity(&test, &amount_0, &amount_1); - + // We can provide liquidity again and should not panic let result = test.contract.try_add_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &(amount_0 + 1), // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &(amount_0 + 1), // amount_a_min: i128, - &amount_1, // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline, // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &(amount_0 + 1), // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &(amount_0 + 1), // amount_a_min: i128, + &amount_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterInsufficientAAmount)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::RouterInsufficientAAmount))); } - #[test] fn amount_a_desired_higher() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -559,31 +605,30 @@ fn amount_a_desired_higher() { let amount_0: i128 = 1_000_000_000_000_000_000; let amount_1: i128 = 4_000_000_000_000_000_000; - + add_liquidity(&test, &amount_0, &amount_1); - + // We can provide liquidity again and should not panic let (new_added_token_0, new_added_token_1, _new_added_liquidity) = test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &(amount_0+1), // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &(amount_0 + 1), // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!(new_added_token_0, amount_0); assert_eq!(new_added_token_1, amount_1); } - #[test] fn amount_b_desired_higher() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -595,21 +640,21 @@ fn amount_b_desired_higher() { let amount_0: i128 = 1_000_000_000_000_000_000; let amount_1: i128 = 4_000_000_000_000_000_000; - + add_liquidity(&test, &amount_0, &amount_1); - + // We can provide liquidity again and should not panic let (new_added_token_0, new_added_token_1, _new_added_liquidity) = test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &(amount_0), // amount_a_desired: i128, - &(amount_1+1), // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &(amount_0), // amount_a_desired: i128, + &(amount_1 + 1), // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!(new_added_token_0, amount_0); assert_eq!(new_added_token_1, amount_1); -} \ No newline at end of file +} diff --git a/contracts/router/src/test/budget.rs b/contracts/router/src/test/budget.rs index 3d1eb663..b1c0b957 100644 --- a/contracts/router/src/test/budget.rs +++ b/contracts/router/src/test/budget.rs @@ -1,20 +1,16 @@ // ONLY TO CHECK BUDGET -use crate::test::{SoroswapRouterTest}; +use crate::test::SoroswapRouterTest; extern crate std; -use num_integer::Roots; use crate::test::add_liquidity::add_liquidity; +use num_integer::Roots; - - -use soroban_sdk::{ - testutils::{ - Ledger},}; +use soroban_sdk::testutils::Ledger; #[test] fn budget_add_liquidity() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - + let ledger_timestamp = 100; let desired_deadline = 1000; @@ -31,26 +27,27 @@ fn budget_add_liquidity() { test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ); + std::println!( + "add_liquidity / cpu_instruction_cost: {:?}", + test.env.budget().cpu_instruction_cost() ); - std::println!("add_liquidity / cpu_instruction_cost: {:?}", test.env.budget().cpu_instruction_cost()); std::println!("add_liquidity / test.env.budget(): {:?}", test.env.budget()); test.env.budget().reset_unlimited(); } - - #[test] fn budget_remove_liquidity_equal_amount_exact_minimum_out() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let amount_0: i128 = 10_000_000_000; let amount_1: i128 = 10_000_000_000; @@ -59,7 +56,9 @@ fn budget_remove_liquidity_equal_amount_exact_minimum_out() { // Check LP token balance let expected_total_liquidity: i128 = (amount_0 * amount_1).sqrt(); // sqrt(amount_0, amount_1); static MINIMUM_LIQUIDITY: i128 = 1000; - let expected_liquidity: i128 = expected_total_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap(); + let expected_liquidity: i128 = expected_total_liquidity + .checked_sub(MINIMUM_LIQUIDITY) + .unwrap(); let ledger_timestamp = 200; let desired_deadline = 1000; @@ -68,22 +67,26 @@ fn budget_remove_liquidity_equal_amount_exact_minimum_out() { li.timestamp = ledger_timestamp; }); - let expected_to_remove_0 = (amount_0*expected_liquidity) / expected_total_liquidity; - let expected_to_remove_1 = (amount_1*expected_liquidity) / expected_total_liquidity; - + let expected_to_remove_0 = (amount_0 * expected_liquidity) / expected_total_liquidity; + let expected_to_remove_1 = (amount_1 * expected_liquidity) / expected_total_liquidity; + test.env.budget().reset_unlimited(); test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &expected_liquidity, // liquidity: i128, + &expected_liquidity, // liquidity: i128, &expected_to_remove_0, // amount_a_min: i128, - &expected_to_remove_1 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &expected_to_remove_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ); + std::println!( + "remove_liquidity / cpu_instruction_cost: {:?}", + test.env.budget().cpu_instruction_cost() + ); + std::println!( + "remove_liquidity / test.env.budget(): {:?}", + test.env.budget() ); - std::println!("remove_liquidity / cpu_instruction_cost: {:?}", test.env.budget().cpu_instruction_cost()); - std::println!("remove_liquidity / test.env.budget(): {:?}", test.env.budget()); test.env.budget().reset_unlimited(); - - -} \ No newline at end of file +} diff --git a/contracts/router/src/test/events.rs b/contracts/router/src/test/events.rs index 5fc6b09c..9a54a204 100644 --- a/contracts/router/src/test/events.rs +++ b/contracts/router/src/test/events.rs @@ -1,20 +1,12 @@ +use crate::event::{AddLiquidityEvent, InitializedEvent, RemoveLiquidityEvent, SwapEvent}; +use crate::test::add_liquidity::add_liquidity; +use crate::test::SoroswapRouterTest; use soroban_sdk::{ - testutils::{Events, Ledger}, - vec, - IntoVal, symbol_short, - Vec, - Address}; -use crate::test::{SoroswapRouterTest}; -use crate::test::add_liquidity::add_liquidity; -use crate::event::{ - InitializedEvent, - AddLiquidityEvent, - RemoveLiquidityEvent, - SwapEvent + testutils::{Events, Ledger}, + vec, Address, IntoVal, Vec, }; - #[test] fn initialized_event() { let test = SoroswapRouterTest::setup(); @@ -23,7 +15,7 @@ fn initialized_event() { let initialized_event = test.env.events().all().last().unwrap(); let expected_initialized_event: InitializedEvent = InitializedEvent { - factory: test.factory.address.clone() + factory: test.factory.address.clone(), }; assert_eq!( @@ -38,9 +30,7 @@ fn initialized_event() { ] ); - let false_initialized_event: InitializedEvent = InitializedEvent { - factory: test.user, - }; + let false_initialized_event: InitializedEvent = InitializedEvent { factory: test.user }; assert_ne!( vec![&test.env, initialized_event.clone()], @@ -54,7 +44,6 @@ fn initialized_event() { ] ); - // Wront symbol_short assert_ne!( vec![&test.env, initialized_event.clone()], @@ -80,11 +69,8 @@ fn initialized_event() { ), ] ); - } - - #[test] fn add_liquidity_event() { let test = SoroswapRouterTest::setup(); @@ -93,11 +79,11 @@ fn add_liquidity_event() { let amount_0: i128 = 1_000_000_000_000_000_000; let amount_1: i128 = 4_000_000_000_000_000_000; - let (deposited_amount_0, - deposited_amount_1, - received_liquidity) =add_liquidity(&test, &amount_0, &amount_1); - let deterministic_pair_address = test.contract.router_pair_for(&test.token_0.address, &test.token_1.address); - + let deterministic_pair_address = test + .contract + .router_pair_for(&test.token_0.address, &test.token_1.address); + let (deposited_amount_0, deposited_amount_1, received_liquidity) = + add_liquidity(&test, &amount_0, &amount_1); let add_liquidity_event = test.env.events().all().last().unwrap(); @@ -172,9 +158,6 @@ fn add_liquidity_event() { ); } - - - #[test] fn remove_liquidity_event() { let test = SoroswapRouterTest::setup(); @@ -191,10 +174,11 @@ fn remove_liquidity_event() { let amount_1: i128 = 20_000_000_000; // let expected_liquidity: i128 = 14142134623;//14142135623,7 - 1000; - let (_deposited_amount_0, - _deposited_amount_1, - received_liquidity) = add_liquidity(&test, &amount_0, &amount_1); - + let deterministic_pair_address = test + .contract + .router_pair_for(&test.token_0.address, &test.token_1.address); + let (_deposited_amount_0, _deposited_amount_1, received_liquidity) = + add_liquidity(&test, &amount_0, &amount_1); // let expected_to_remove_0 = (amount_0*expected_liquidity) / expected_total_liquidity; // let expected_to_remove_1 = (amount_1*expected_liquidity) / expected_total_liquidity; @@ -208,14 +192,12 @@ fn remove_liquidity_event() { test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &received_liquidity, // liquidity: i128, + &received_liquidity, // liquidity: i128, &expected_to_remove_0, // amount_a_min: i128, - &expected_to_remove_1 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &expected_to_remove_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); - let deterministic_pair_address = test.contract.router_pair_for(&test.token_0.address, &test.token_1.address); - let remove_liquidity_event = test.env.events().all().last().unwrap(); @@ -245,7 +227,7 @@ fn remove_liquidity_event() { token_a: test.token_0.address.clone(), token_b: test.token_1.address.clone(), pair: deterministic_pair_address.clone(), - amount_a: (expected_to_remove_0.clone()+1), + amount_a: (expected_to_remove_0.clone() + 1), amount_b: expected_to_remove_1.clone(), liquidity: received_liquidity, to: test.user.clone(), @@ -290,13 +272,11 @@ fn remove_liquidity_event() { ); } - - #[test] fn swap_exact_tokens_for_tokens_event() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); @@ -314,11 +294,12 @@ fn swap_exact_tokens_for_tokens_event() { test.env.budget().reset_unlimited(); let executed_amounts = test.contract.swap_exact_tokens_for_tokens( - &amount_in, //amount_in - &(expected_amount_out), // amount_out_min - &path, // path - &test.user, // to - &deadline); // deadline + &amount_in, //amount_in + &(expected_amount_out), // amount_out_min + &path, // path + &test.user, // to + &deadline, + ); // deadline assert_eq!(executed_amounts.get(0).unwrap(), amount_in); assert_eq!(executed_amounts.get(1).unwrap(), expected_amount_out); @@ -343,12 +324,10 @@ fn swap_exact_tokens_for_tokens_event() { ] ); - let mut false_path: Vec
= Vec::new(&test.env); false_path.push_back(test.token_1.address.clone()); false_path.push_back(test.token_0.address.clone()); - let false_swap_event: SwapEvent = SwapEvent { path: false_path.clone(), amounts: executed_amounts.clone(), @@ -392,17 +371,14 @@ fn swap_exact_tokens_for_tokens_event() { ), ] ); - } - - #[test] fn swap_tokens_for_exact_tokens_event() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); @@ -414,14 +390,19 @@ fn swap_tokens_for_exact_tokens_event() { add_liquidity(&test, &amount_0, &amount_1); let expected_amount_out = 5_000_000; - let amount_in_should = test.contract.router_get_amounts_in(&expected_amount_out, &path).get(0).unwrap(); + let amount_in_should = test + .contract + .router_get_amounts_in(&expected_amount_out, &path) + .get(0) + .unwrap(); let executed_amounts = test.contract.swap_tokens_for_exact_tokens( &expected_amount_out, //amount_out &(amount_in_should), // amount_in_max - &path, // path - &test.user, // to - &deadline); // deadline + &path, // path + &test.user, // to + &deadline, + ); // deadline let swap_event = test.env.events().all().last().unwrap(); @@ -443,12 +424,10 @@ fn swap_tokens_for_exact_tokens_event() { ] ); - let mut false_path: Vec
= Vec::new(&test.env); false_path.push_back(test.token_1.address.clone()); false_path.push_back(test.token_0.address.clone()); - let false_swap_event: SwapEvent = SwapEvent { path: false_path.clone(), amounts: executed_amounts.clone(), @@ -492,4 +471,4 @@ fn swap_tokens_for_exact_tokens_event() { ), ] ); -} \ No newline at end of file +} diff --git a/contracts/router/src/test/initialize.rs b/contracts/router/src/test/initialize.rs index cd6724f2..798e3e30 100644 --- a/contracts/router/src/test/initialize.rs +++ b/contracts/router/src/test/initialize.rs @@ -1,10 +1,8 @@ -use soroban_sdk::{Address, testutils::Address as _}; +use soroban_sdk::{testutils::Address as _, Address}; use crate::error::CombinedRouterError; use crate::test::SoroswapRouterTest; - - #[test] fn test_initialize_and_get_factory() { let test = SoroswapRouterTest::setup(); diff --git a/contracts/router/src/test/library_functions.rs b/contracts/router/src/test/library_functions.rs index 71b8fc42..a62119ca 100644 --- a/contracts/router/src/test/library_functions.rs +++ b/contracts/router/src/test/library_functions.rs @@ -1,105 +1,125 @@ -use soroban_sdk::{vec}; +use soroban_sdk::vec; -use crate::test::{SoroswapRouterTest}; -use crate::test::add_liquidity::add_liquidity; use crate::error::CombinedRouterError; - - +use crate::test::add_liquidity::add_liquidity; +use crate::test::SoroswapRouterTest; // router_quote #[test] fn test_quote() { let test = SoroswapRouterTest::setup(); - assert_eq!(2,test.contract.router_quote(&1, &100, &200)); - assert_eq!(1,test.contract.router_quote(&2, &200, &100)); + assert_eq!(2, test.contract.router_quote(&1, &100, &200)); + assert_eq!(1, test.contract.router_quote(&2, &200, &100)); } #[test] fn test_quote_insufficient_amount() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_quote(&0, &100, &200); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientAmount))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientAmount)) + ); } #[test] fn test_quote_insufficient_liquidity_0() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_quote(&1, &0, &200); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity)) + ); } #[test] fn test_quote_insufficient_liquidity_1() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_quote(&1, &100, &0); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity)) + ); } // router_get_amount_out - #[test] fn test_get_amount_out() { let test = SoroswapRouterTest::setup(); - assert_eq!(1,test.contract.router_get_amount_out(&3, &100, &100)); + assert_eq!(1, test.contract.router_get_amount_out(&3, &100, &100)); } #[test] fn try_router_get_amount_out_insufficient_input_amount() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_get_amount_out(&0, &100, &100); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientInputAmount))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientInputAmount)) + ); } #[test] fn try_router_get_amount_out_insufficient_liquidity_0() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_get_amount_out(&2, &0, &100); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity)) + ); } #[test] fn try_router_get_amount_out_insufficient_liquidity_1() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_get_amount_out(&2, &100, &0); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity)) + ); } - // router_get_amount_in - #[test] fn test_get_amount_in() { let test = SoroswapRouterTest::setup(); - assert_eq!(3,test.contract.router_get_amount_in(&1, &100, &100)); + assert_eq!(3, test.contract.router_get_amount_in(&1, &100, &100)); } #[test] fn try_router_get_amount_in_insufficient_output_amount() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_get_amount_in(&0, &100, &100); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientOutputAmount))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientOutputAmount)) + ); } #[test] fn try_router_get_amount_in_insufficient_liquidity_0() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_get_amount_in(&1, &0, &100); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity)) + ); } #[test] fn try_router_get_amount_in_insufficient_liquidity_1() { let test = SoroswapRouterTest::setup(); let result = test.contract.try_router_get_amount_in(&1, &100, &0); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity))); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientLiquidity)) + ); } - // router_get_amounts_out - #[test] fn try_router_get_amounts_out_invalid_path() { let test = SoroswapRouterTest::setup(); @@ -111,17 +131,16 @@ fn try_router_get_amounts_out_invalid_path() { #[test] fn test_get_amounts_out_not_yet_initialized() { - let test = SoroswapRouterTest::setup(); + let test = SoroswapRouterTest::setup(); let path = vec![&test.env, test.token_0.address, test.token_1.address]; let result = test.contract.try_router_get_amounts_out(&2, &path); assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); } - #[test] fn test_get_amounts_out() { let test = SoroswapRouterTest::setup(); - + // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); @@ -133,11 +152,12 @@ fn test_get_amounts_out() { add_liquidity(&test, &amount_0, &amount_1); let path = vec![&test.env, test.token_0.address, test.token_1.address]; - assert_eq!(vec![&test.env,3, 1], test.contract.router_get_amounts_out(&3, &path)); + assert_eq!( + vec![&test.env, 3, 1], + test.contract.router_get_amounts_out(&3, &path) + ); } - - // router_get_amounts_in #[test] @@ -151,17 +171,16 @@ fn try_router_get_amounts_in_invalid_path() { #[test] fn test_get_amounts_in_not_yet_initialized() { - let test = SoroswapRouterTest::setup(); + let test = SoroswapRouterTest::setup(); let path = vec![&test.env, test.token_0.address, test.token_1.address]; let result = test.contract.try_router_get_amounts_in(&1, &path); assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); } - #[test] fn test_get_amounts_in() { let test = SoroswapRouterTest::setup(); - + // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); @@ -173,11 +192,8 @@ fn test_get_amounts_in() { add_liquidity(&test, &amount_0, &amount_1); let path = vec![&test.env, test.token_0.address, test.token_1.address]; - assert_eq!(vec![&test.env,3, 1], test.contract.router_get_amounts_in(&1, &path)); + assert_eq!( + vec![&test.env, 3, 1], + test.contract.router_get_amounts_in(&1, &path) + ); } - - - - - - diff --git a/contracts/router/src/test/remove_liquidity.rs b/contracts/router/src/test/remove_liquidity.rs index f07f7875..7a6ff2e8 100644 --- a/contracts/router/src/test/remove_liquidity.rs +++ b/contracts/router/src/test/remove_liquidity.rs @@ -1,95 +1,96 @@ -use crate::test::{SoroswapRouterTest, SoroswapPairClient}; -use crate::test::add_liquidity::add_liquidity; use crate::error::CombinedRouterError; +use crate::test::add_liquidity::add_liquidity; +use crate::test::{SoroswapPairClient, SoroswapRouterTest}; -use num_integer::Roots; +use num_integer::Roots; use soroban_sdk::{ - Address, - testutils::{ - Address as _, - MockAuth, - MockAuthInvoke, - Ledger}, - vec, - IntoVal}; - - - - #[test] - fn test_remove_liquidity_not_yet_initialized() { - let test = SoroswapRouterTest::setup(); - - let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &0, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0 // deadline: u64, - ); - - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); - } - - #[test] - fn test_remove_liquidity_liquidity_negative() { - let test = SoroswapRouterTest::setup(); - test.contract.initialize(&test.factory.address); - - let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &-1, // liquidity: i128, - &0, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0 // deadline: u64, - ); - - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); - } - - #[test] - fn test_remove_liquidity_amount_a_min_negative() { - let test = SoroswapRouterTest::setup(); - test.contract.initialize(&test.factory.address); - - let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &-1, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &0 // deadline: u64, - ); - - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); - } - - #[test] - fn test_remove_liquidity_amount_b_min_negative() { - let test = SoroswapRouterTest::setup(); - test.contract.initialize(&test.factory.address); - - let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &0, // amount_a_min: i128, - &-1, // amount_b_min: i128, - &test.user, // to: Address, - &0 // deadline: u64, - ); - - assert_eq!(result, Err(Ok(CombinedRouterError::RouterNegativeNotAllowed))); - } - + testutils::{Address as _, Ledger, MockAuth, MockAuthInvoke}, + vec, Address, IntoVal, +}; + +#[test] +fn test_remove_liquidity_not_yet_initialized() { + let test = SoroswapRouterTest::setup(); + + let result = test.contract.try_remove_liquidity( + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &0, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + + assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); +} + +#[test] +fn test_remove_liquidity_liquidity_negative() { + let test = SoroswapRouterTest::setup(); + test.contract.initialize(&test.factory.address); + + let result = test.contract.try_remove_liquidity( + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &-1, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) + ); +} + +#[test] +fn test_remove_liquidity_amount_a_min_negative() { + let test = SoroswapRouterTest::setup(); + test.contract.initialize(&test.factory.address); + + let result = test.contract.try_remove_liquidity( + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &0, // liquidity: i128, + &-1, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) + ); +} + +#[test] +fn test_remove_liquidity_amount_b_min_negative() { + let test = SoroswapRouterTest::setup(); + test.contract.initialize(&test.factory.address); + + let result = test.contract.try_remove_liquidity( + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &0, // liquidity: i128, + &0, // amount_a_min: i128, + &-1, // amount_b_min: i128, + &test.user, // to: Address, + &0, // deadline: u64, + ); + + assert_eq!( + result, + Err(Ok(CombinedRouterError::RouterNegativeNotAllowed)) + ); +} // TODO: We don't know if this is corectly done #[test] -#[should_panic(expected = "Unauthorized function call for address")] +#[should_panic(expected = "Unauthorized function call for address")] fn test_remove_liquidity_not_authorized() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); @@ -108,34 +109,30 @@ fn test_remove_liquidity_not_authorized() { invoke: &MockAuthInvoke { contract: &test.contract.address, fn_name: "remove_liquidity", - args: vec![& - &test.env, + args: vec![ + &&test.env, test.token_0.address.into_val(&test.env), // token_a: Address, test.token_1.address.into_val(&test.env), // token_b: Address, - 0.into_val(&test.env), // liquidity: i128, - 0.into_val(&test.env), // amount_a_min: i128, - 0.into_val(&test.env) , // amount_b_min: i128, - (&bob,).into_val(&test.env), // to: Address, - 0.into_val(&test.env)// deadline: u64, - ], + 0.into_val(&test.env), // liquidity: i128, + 0.into_val(&test.env), // amount_a_min: i128, + 0.into_val(&test.env), // amount_b_min: i128, + (&bob,).into_val(&test.env), // to: Address, + 0.into_val(&test.env), // deadline: u64, + ], sub_invokes: &[], }, }]) .remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &bob, // to: Address, - &0// deadline: u64, + &0, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &bob, // to: Address, + &0, // deadline: u64, ); - } - - - #[test] fn test_remove_liquidity_deadline_expired() { let test = SoroswapRouterTest::setup(); @@ -149,23 +146,18 @@ fn test_remove_liquidity_deadline_expired() { }); let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &0, // amount_a_min: i128, - &0, // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline // deadline: u64, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &0, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); - assert_eq!( - result, - Err(Ok(CombinedRouterError::RouterDeadlineExpired)) - ); + assert_eq!(result, Err(Ok(CombinedRouterError::RouterDeadlineExpired))); } - - #[test] fn test_remove_liquidity_pair_does_not_exist() { let test = SoroswapRouterTest::setup(); @@ -182,18 +174,16 @@ fn test_remove_liquidity_pair_does_not_exist() { let result = test.contract.try_remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &0, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!(result, Err(Ok(CombinedRouterError::RouterPairDoesNotExist))); } - - #[test] // #[should_panic(expected = "SoroswapPair: insufficient sent shares")] // Because we are using wasm and panic, we cannot get the message @@ -217,11 +207,11 @@ fn test_remove_liquidity_insufficient_sent_shares() { test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &0, // liquidity: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &0, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); } @@ -240,11 +230,10 @@ fn test_remove_liquidity_sufficient_amount() { let amount_0: i128 = 10_000_000_000; let amount_1: i128 = 20_000_000_000; - let expected_liquidity: i128 = 14142134623;//14142135623,7 - 1000; + let expected_liquidity: i128 = 14142134623; //14142135623,7 - 1000; - let (deposited_amount_0, - deposited_amount_1, - received_liquidity) = add_liquidity(&test, &amount_0, &amount_1); + let (deposited_amount_0, deposited_amount_1, received_liquidity) = + add_liquidity(&test, &amount_0, &amount_1); assert_eq!(deposited_amount_0, amount_0); assert_eq!(deposited_amount_1, amount_1); @@ -262,15 +251,14 @@ fn test_remove_liquidity_sufficient_amount() { test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &received_liquidity, // liquidity: i128, + &received_liquidity, // liquidity: i128, &expected_to_remove_0, // amount_a_min: i128, - &expected_to_remove_1 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &expected_to_remove_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); } - #[test] fn test_remove_liquidity_sufficient_amount_inverse() { let test = SoroswapRouterTest::setup(); @@ -286,11 +274,10 @@ fn test_remove_liquidity_sufficient_amount_inverse() { let amount_0: i128 = 10_000_000_000; let amount_1: i128 = 20_000_000_000; - let expected_liquidity: i128 = 14142134623;//14142135623,7 - 1000; + let expected_liquidity: i128 = 14142134623; //14142135623,7 - 1000; - let (deposited_amount_0, - deposited_amount_1, - received_liquidity) = add_liquidity(&test, &amount_0, &amount_1); + let (deposited_amount_0, deposited_amount_1, received_liquidity) = + add_liquidity(&test, &amount_0, &amount_1); assert_eq!(deposited_amount_0, amount_0); assert_eq!(deposited_amount_1, amount_1); @@ -308,15 +295,14 @@ fn test_remove_liquidity_sufficient_amount_inverse() { test.contract.remove_liquidity( &test.token_1.address, // token_a: Address, &test.token_0.address, // token_b: Address, - &received_liquidity, // liquidity: i128, + &received_liquidity, // liquidity: i128, &expected_to_remove_1, // amount_a_min: i128, - &expected_to_remove_0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &expected_to_remove_0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); } - #[test] fn test_remove_liquidity_insufficient_a_amount() { let test = SoroswapRouterTest::setup(); @@ -345,13 +331,13 @@ fn test_remove_liquidity_insufficient_a_amount() { let expected_to_remove_1 = 19999998585; let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &received_liquidity, // liquidity: i128, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &received_liquidity, // liquidity: i128, &(expected_to_remove_0 + 1), // amount_a_min: i128, - &expected_to_remove_1, // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline // deadline: u64, + &expected_to_remove_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!( @@ -388,13 +374,13 @@ fn test_remove_liquidity_insufficient_b_amount() { let expected_to_remove_1 = 19999998585; let result = test.contract.try_remove_liquidity( - &test.token_0.address, // token_a: Address, - &test.token_1.address, // token_b: Address, - &received_liquidity, // liquidity: i128, - &expected_to_remove_0, // amount_a_min: i128, + &test.token_0.address, // token_a: Address, + &test.token_1.address, // token_b: Address, + &received_liquidity, // liquidity: i128, + &expected_to_remove_0, // amount_a_min: i128, &(expected_to_remove_1 + 1), // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline // deadline: u64, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); assert_eq!( @@ -403,13 +389,12 @@ fn test_remove_liquidity_insufficient_b_amount() { ); } - #[test] fn test_remove_liquidity_equal_amount_0_minimum_out() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let initial_user_balance = 10000000000000000000; assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); @@ -418,23 +403,32 @@ fn test_remove_liquidity_equal_amount_0_minimum_out() { let amount_1: i128 = 10_000_000_000; add_liquidity(&test, &amount_0, &amount_1); - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); - let pair_client = SoroswapPairClient::new(&test.env, &pair_address); + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); // Check LP token balance let expected_total_liquidity: i128 = 10_000_000_000; // sqrt(amount_0, amount_1); static MINIMUM_LIQUIDITY: i128 = 1000; - let expected_liquidity: i128 = expected_total_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap(); + let expected_liquidity: i128 = expected_total_liquidity + .checked_sub(MINIMUM_LIQUIDITY) + .unwrap(); assert_eq!(pair_client.balance(&test.user), expected_liquidity); assert_eq!(pair_client.total_supply(), expected_total_liquidity); - let ledger_timestamp = 200; let desired_deadline = 1000; assert!(desired_deadline > ledger_timestamp); @@ -445,41 +439,51 @@ fn test_remove_liquidity_equal_amount_0_minimum_out() { // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - let (removed_0,removed_1) = test.contract.remove_liquidity( + let (removed_0, removed_1) = test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &expected_liquidity, // liquidity: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, - ); - - assert_eq!(removed_0, (amount_0*expected_liquidity) / expected_total_liquidity); - assert_eq!(removed_1, (amount_1*expected_liquidity) / expected_total_liquidity); - let locked_0 = amount_0- removed_0; - let locked_1 = amount_1- removed_1; - - // TODO: Test events - - // Check that not, the user does not have any LP anymore - assert_eq!(pair_client.balance(&test.user), 0); - - // Check new user token balances, minus the minimum liquiity - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(locked_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(locked_1).unwrap()); - assert_eq!(test.token_0.balance(&pair_address), locked_0); - assert_eq!(test.token_1.balance(&pair_address), locked_1); - -} + &expected_liquidity, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ); + assert_eq!( + removed_0, + (amount_0 * expected_liquidity) / expected_total_liquidity + ); + assert_eq!( + removed_1, + (amount_1 * expected_liquidity) / expected_total_liquidity + ); + let locked_0 = amount_0 - removed_0; + let locked_1 = amount_1 - removed_1; + + // TODO: Test events + + // Check that not, the user does not have any LP anymore + assert_eq!(pair_client.balance(&test.user), 0); + + // Check new user token balances, minus the minimum liquiity + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(locked_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(locked_1).unwrap() + ); + assert_eq!(test.token_0.balance(&pair_address), locked_0); + assert_eq!(test.token_1.balance(&pair_address), locked_1); +} #[test] fn test_remove_liquidity_equal_amount_exact_minimum_out() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let initial_user_balance = 10000000000000000000; assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); @@ -488,23 +492,32 @@ fn test_remove_liquidity_equal_amount_exact_minimum_out() { let amount_1: i128 = 10_000_000_000; add_liquidity(&test, &amount_0, &amount_1); - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); - let pair_client = SoroswapPairClient::new(&test.env, &pair_address); + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); // Check LP token balance let expected_total_liquidity: i128 = (amount_0 * amount_1).sqrt(); // sqrt(amount_0, amount_1); static MINIMUM_LIQUIDITY: i128 = 1000; - let expected_liquidity: i128 = expected_total_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap(); + let expected_liquidity: i128 = expected_total_liquidity + .checked_sub(MINIMUM_LIQUIDITY) + .unwrap(); assert_eq!(pair_client.balance(&test.user), expected_liquidity); assert_eq!(pair_client.total_supply(), expected_total_liquidity); - let ledger_timestamp = 200; let desired_deadline = 1000; assert!(desired_deadline > ledger_timestamp); @@ -514,44 +527,48 @@ fn test_remove_liquidity_equal_amount_exact_minimum_out() { // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - let expected_to_remove_0 = (amount_0*expected_liquidity) / expected_total_liquidity; - let expected_to_remove_1 = (amount_1*expected_liquidity) / expected_total_liquidity; + let expected_to_remove_0 = (amount_0 * expected_liquidity) / expected_total_liquidity; + let expected_to_remove_1 = (amount_1 * expected_liquidity) / expected_total_liquidity; - let (removed_0,removed_1) = test.contract.remove_liquidity( + let (removed_0, removed_1) = test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &expected_liquidity, // liquidity: i128, + &expected_liquidity, // liquidity: i128, &expected_to_remove_0, // amount_a_min: i128, - &expected_to_remove_1 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &expected_to_remove_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); - + assert_eq!(removed_0, expected_to_remove_0); assert_eq!(removed_1, expected_to_remove_1); - let locked_0 = amount_0- removed_0; - let locked_1 = amount_1- removed_1; - - // TODO: Test events - - // Check that not, the user does not have any LP anymore - assert_eq!(pair_client.balance(&test.user), 0); - - // Check new user token balances, minus the minimum liquiity - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(locked_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(locked_1).unwrap()); - assert_eq!(test.token_0.balance(&pair_address), locked_0); - assert_eq!(test.token_1.balance(&pair_address), locked_1); - -} + let locked_0 = amount_0 - removed_0; + let locked_1 = amount_1 - removed_1; + + // TODO: Test events + // Check that not, the user does not have any LP anymore + assert_eq!(pair_client.balance(&test.user), 0); + + // Check new user token balances, minus the minimum liquiity + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(locked_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(locked_1).unwrap() + ); + assert_eq!(test.token_0.balance(&pair_address), locked_0); + assert_eq!(test.token_1.balance(&pair_address), locked_1); +} #[test] fn test_remove_liquidity_inequal_amount_0_minimum_out() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let initial_user_balance = 10000000000000000000; assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); @@ -560,23 +577,32 @@ fn test_remove_liquidity_inequal_amount_0_minimum_out() { let amount_1: i128 = 999_000_000_000_000; add_liquidity(&test, &amount_0, &amount_1); - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); - let pair_client = SoroswapPairClient::new(&test.env, &pair_address); + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); // Check LP token balance let expected_total_liquidity: i128 = (amount_0 * amount_1).sqrt(); // sqrt(amount_0, amount_1); static MINIMUM_LIQUIDITY: i128 = 1000; - let expected_liquidity: i128 = expected_total_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap(); + let expected_liquidity: i128 = expected_total_liquidity + .checked_sub(MINIMUM_LIQUIDITY) + .unwrap(); assert_eq!(pair_client.balance(&test.user), expected_liquidity); assert_eq!(pair_client.total_supply(), expected_total_liquidity); - let ledger_timestamp = 200; let desired_deadline = 1000; assert!(desired_deadline > ledger_timestamp); @@ -587,41 +613,51 @@ fn test_remove_liquidity_inequal_amount_0_minimum_out() { // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - let (removed_0,removed_1) = test.contract.remove_liquidity( + let (removed_0, removed_1) = test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &expected_liquidity, // liquidity: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, - ); - - assert_eq!(removed_0, (amount_0*expected_liquidity) / expected_total_liquidity); - assert_eq!(removed_1, (amount_1*expected_liquidity) / expected_total_liquidity); - let locked_0 = amount_0- removed_0; - let locked_1 = amount_1- removed_1; - - // TODO: Test events - - // Check that not, the user does not have any LP anymore - assert_eq!(pair_client.balance(&test.user), 0); - - // Check new user token balances, minus the minimum liquiity - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(locked_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(locked_1).unwrap()); - assert_eq!(test.token_0.balance(&pair_address), locked_0); - assert_eq!(test.token_1.balance(&pair_address), locked_1); - -} + &expected_liquidity, // liquidity: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, + ); + + assert_eq!( + removed_0, + (amount_0 * expected_liquidity) / expected_total_liquidity + ); + assert_eq!( + removed_1, + (amount_1 * expected_liquidity) / expected_total_liquidity + ); + let locked_0 = amount_0 - removed_0; + let locked_1 = amount_1 - removed_1; + + // TODO: Test events + + // Check that not, the user does not have any LP anymore + assert_eq!(pair_client.balance(&test.user), 0); + // Check new user token balances, minus the minimum liquiity + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(locked_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(locked_1).unwrap() + ); + assert_eq!(test.token_0.balance(&pair_address), locked_0); + assert_eq!(test.token_1.balance(&pair_address), locked_1); +} #[test] fn test_remove_liquidity_inequal_amount_exact_minimum_out() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let initial_user_balance = 10000000000000000000; assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); @@ -630,23 +666,32 @@ fn test_remove_liquidity_inequal_amount_exact_minimum_out() { let amount_1: i128 = 999_000_000_000_000; add_liquidity(&test, &amount_0, &amount_1); - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); - let pair_client = SoroswapPairClient::new(&test.env, &pair_address); + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); // Check LP token balance let expected_total_liquidity: i128 = (amount_0 * amount_1).sqrt(); // sqrt(amount_0, amount_1); static MINIMUM_LIQUIDITY: i128 = 1000; - let expected_liquidity: i128 = expected_total_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap(); + let expected_liquidity: i128 = expected_total_liquidity + .checked_sub(MINIMUM_LIQUIDITY) + .unwrap(); assert_eq!(pair_client.balance(&test.user), expected_liquidity); assert_eq!(pair_client.total_supply(), expected_total_liquidity); - let ledger_timestamp = 200; let desired_deadline = 1000; assert!(desired_deadline > ledger_timestamp); @@ -656,46 +701,48 @@ fn test_remove_liquidity_inequal_amount_exact_minimum_out() { // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - let expected_to_remove_0 = (amount_0*expected_liquidity) / expected_total_liquidity; - let expected_to_remove_1 = (amount_1*expected_liquidity) / expected_total_liquidity; + let expected_to_remove_0 = (amount_0 * expected_liquidity) / expected_total_liquidity; + let expected_to_remove_1 = (amount_1 * expected_liquidity) / expected_total_liquidity; - let (removed_0,removed_1) = test.contract.remove_liquidity( + let (removed_0, removed_1) = test.contract.remove_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &expected_liquidity, // liquidity: i128, + &expected_liquidity, // liquidity: i128, &expected_to_remove_0, // amount_a_min: i128, - &expected_to_remove_1 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &expected_to_remove_1, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); - + assert_eq!(removed_0, expected_to_remove_0); assert_eq!(removed_1, expected_to_remove_1); - let locked_0 = amount_0- removed_0; - let locked_1 = amount_1- removed_1; - - // TODO: Test events - - // Check that not, the user does not have any LP anymore - assert_eq!(pair_client.balance(&test.user), 0); - - // Check new user token balances, minus the minimum liquiity - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(locked_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(locked_1).unwrap()); - assert_eq!(test.token_0.balance(&pair_address), locked_0); - assert_eq!(test.token_1.balance(&pair_address), locked_1); - -} + let locked_0 = amount_0 - removed_0; + let locked_1 = amount_1 - removed_1; + // TODO: Test events + // Check that not, the user does not have any LP anymore + assert_eq!(pair_client.balance(&test.user), 0); + // Check new user token balances, minus the minimum liquiity + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(locked_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(locked_1).unwrap() + ); + assert_eq!(test.token_0.balance(&pair_address), locked_0); + assert_eq!(test.token_1.balance(&pair_address), locked_1); +} #[test] fn test_remove_liquidity_inequal_amount_exact_minimum_out_other_way() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - + let initial_user_balance = 10000000000000000000; assert_eq!(test.token_0.balance(&test.user), initial_user_balance); assert_eq!(test.token_1.balance(&test.user), initial_user_balance); @@ -704,23 +751,32 @@ fn test_remove_liquidity_inequal_amount_exact_minimum_out_other_way() { let amount_1: i128 = 999_000_000_000_000; add_liquidity(&test, &amount_0, &amount_1); - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); - let pair_client = SoroswapPairClient::new(&test.env, &pair_address); + let pair_client = SoroswapPairClient::new(&test.env, &pair_address); // Check new balances: - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(amount_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(amount_1).unwrap()); + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(amount_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(amount_1).unwrap() + ); assert_eq!(test.token_0.balance(&pair_address), amount_0); assert_eq!(test.token_1.balance(&pair_address), amount_1); // Check LP token balance let expected_total_liquidity: i128 = (amount_0 * amount_1).sqrt(); // sqrt(amount_0, amount_1); static MINIMUM_LIQUIDITY: i128 = 1000; - let expected_liquidity: i128 = expected_total_liquidity.checked_sub(MINIMUM_LIQUIDITY).unwrap(); + let expected_liquidity: i128 = expected_total_liquidity + .checked_sub(MINIMUM_LIQUIDITY) + .unwrap(); assert_eq!(pair_client.balance(&test.user), expected_liquidity); assert_eq!(pair_client.total_supply(), expected_total_liquidity); - let ledger_timestamp = 200; let desired_deadline = 1000; assert!(desired_deadline > ledger_timestamp); @@ -730,33 +786,38 @@ fn test_remove_liquidity_inequal_amount_exact_minimum_out_other_way() { // TODO: Get rid of this hack? test.env.budget().reset_unlimited(); - let expected_to_remove_0 = (amount_0*expected_liquidity) / expected_total_liquidity; - let expected_to_remove_1 = (amount_1*expected_liquidity) / expected_total_liquidity; + let expected_to_remove_0 = (amount_0 * expected_liquidity) / expected_total_liquidity; + let expected_to_remove_1 = (amount_1 * expected_liquidity) / expected_total_liquidity; let (removed_1, removed_0) = test.contract.remove_liquidity( &test.token_1.address, // token_b: Address, &test.token_0.address, // token_a: Address, - &expected_liquidity, // liquidity: i128, - &expected_to_remove_1 , // amount_b_min: i128, + &expected_liquidity, // liquidity: i128, + &expected_to_remove_1, // amount_b_min: i128, &expected_to_remove_0, // amount_a_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); - + assert_eq!(removed_0, expected_to_remove_0); assert_eq!(removed_1, expected_to_remove_1); - let locked_0 = amount_0- removed_0; - let locked_1 = amount_1- removed_1; - - // TODO: Test events - - // Check that not, the user does not have any LP anymore - assert_eq!(pair_client.balance(&test.user), 0); - - // Check new user token balances, minus the minimum liquiity - assert_eq!(test.token_0.balance(&test.user), initial_user_balance.checked_sub(locked_0).unwrap()); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance.checked_sub(locked_1).unwrap()); - assert_eq!(test.token_0.balance(&pair_address), locked_0); - assert_eq!(test.token_1.balance(&pair_address), locked_1); - + let locked_0 = amount_0 - removed_0; + let locked_1 = amount_1 - removed_1; + + // TODO: Test events + + // Check that not, the user does not have any LP anymore + assert_eq!(pair_client.balance(&test.user), 0); + + // Check new user token balances, minus the minimum liquiity + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance.checked_sub(locked_0).unwrap() + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance.checked_sub(locked_1).unwrap() + ); + assert_eq!(test.token_0.balance(&pair_address), locked_0); + assert_eq!(test.token_1.balance(&pair_address), locked_1); } diff --git a/contracts/router/src/test/swap_exact_tokens_for_tokens.rs b/contracts/router/src/test/swap_exact_tokens_for_tokens.rs index a346d653..09b21de4 100644 --- a/contracts/router/src/test/swap_exact_tokens_for_tokens.rs +++ b/contracts/router/src/test/swap_exact_tokens_for_tokens.rs @@ -1,8 +1,8 @@ -use soroban_sdk::{Address, vec, Vec}; +use soroban_sdk::{vec, Address, Vec}; -use crate::test::{SoroswapRouterTest, create_token_contract}; -use crate::test::add_liquidity::add_liquidity; use crate::error::CombinedRouterError; +use crate::test::add_liquidity::add_liquidity; +use crate::test::{create_token_contract, SoroswapRouterTest}; #[test] fn swap_exact_tokens_for_tokens_not_initialized() { @@ -11,17 +11,14 @@ fn swap_exact_tokens_for_tokens_not_initialized() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_exact_tokens_for_tokens( - &0, // amount_in - &0, // amount_out_min - &path, // path - &test.user, // to - &0, // deadline + &0, // amount_in + &0, // amount_out_min + &path, // path + &test.user, // to + &0, // deadline ); - assert_eq!( - result, - Err(Ok(CombinedRouterError::RouterNotInitialized)) - ); + assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); } #[test] @@ -33,11 +30,11 @@ fn swap_exact_tokens_for_tokens_amount_in_negative() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_exact_tokens_for_tokens( - &-1, // amount_in - &0, // amount_out_min - &path, // path - &test.user, // to - &0, // deadline + &-1, // amount_in + &0, // amount_out_min + &path, // path + &test.user, // to + &0, // deadline ); assert_eq!( @@ -55,11 +52,11 @@ fn swap_exact_tokens_for_tokens_amount_out_min_negative() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_exact_tokens_for_tokens( - &0, // amount_in - &-1, // amount_out_min - &path, // path - &test.user, // to - &0, // deadline + &0, // amount_in + &-1, // amount_out_min + &path, // path + &test.user, // to + &0, // deadline ); assert_eq!( @@ -75,20 +72,16 @@ fn swap_exact_tokens_for_tokens_expired() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_exact_tokens_for_tokens( - &0, // amount_in - &0, // amount_out_min - &path, // path - &test.user, // to - &0, // deadline + &0, // amount_in + &0, // amount_out_min + &path, // path + &test.user, // to + &0, // deadline ); - assert_eq!( - result, - Err(Ok(CombinedRouterError::RouterDeadlineExpired)) - ); + assert_eq!(result, Err(Ok(CombinedRouterError::RouterDeadlineExpired))); } - #[test] fn try_swap_exact_tokens_for_tokens_invalid_path() { let test = SoroswapRouterTest::setup(); @@ -96,17 +89,15 @@ fn try_swap_exact_tokens_for_tokens_invalid_path() { let deadline: u64 = test.env.ledger().timestamp() + 1000; let path: Vec
= vec![&test.env, test.token_0.address.clone()]; let result = test.contract.try_swap_exact_tokens_for_tokens( - &0, // amount_in - &0, // amount_out_min - &path, // path + &0, // amount_in + &0, // amount_out_min + &path, // path &test.user, // to - &deadline, // deadline + &deadline, // deadline ); assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInvalidPath))); } - - #[test] // Panics because LP does not exist; here panics with a Error(Storage, MissingValue) // We should implement a pair_address.exist() without needing to call the Factory @@ -114,18 +105,19 @@ fn try_swap_exact_tokens_for_tokens_invalid_path() { fn swap_exact_tokens_for_tokens_pair_does_not_exist() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); path.push_back(test.token_1.address.clone()); test.contract.swap_exact_tokens_for_tokens( - &0, //amount_in - &0, // amount_out_min - &path, // path + &0, //amount_in + &0, // amount_out_min + &path, // path &test.user, // to - &deadline); // deadline + &deadline, + ); // deadline } #[test] @@ -145,17 +137,18 @@ fn try_swap_exact_tokens_for_tokens_insufficient_input_amount() { test.env.budget().reset_unlimited(); let result = test.contract.try_swap_exact_tokens_for_tokens( - &0, // amount_in - &0, // amount_out_min - &path, // path + &0, // amount_in + &0, // amount_out_min + &path, // path &test.user, // to - &deadline, // deadline + &deadline, // deadline + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientInputAmount)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientInputAmount))); } - - #[test] fn swap_exact_tokens_for_tokens_insufficient_output_amount() { let test = SoroswapRouterTest::setup(); @@ -179,11 +172,11 @@ fn swap_exact_tokens_for_tokens_insufficient_output_amount() { test.env.budget().reset_unlimited(); let result = test.contract.try_swap_exact_tokens_for_tokens( - &amount_in, // amount_in - &(expected_amount_out + 1), // amount_out_min - &path, // path - &test.user, // to - &deadline, // deadline + &amount_in, // amount_in + &(expected_amount_out + 1), // amount_out_min + &path, // path + &test.user, // to + &deadline, // deadline ); assert_eq!( @@ -192,13 +185,11 @@ fn swap_exact_tokens_for_tokens_insufficient_output_amount() { ); } - - #[test] fn swap_exact_tokens_for_tokens_enough_output_amount() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); @@ -217,26 +208,23 @@ fn swap_exact_tokens_for_tokens_enough_output_amount() { test.env.budget().reset_unlimited(); let executed_amounts = test.contract.swap_exact_tokens_for_tokens( - &amount_in, //amount_in - &(expected_amount_out), // amount_out_min - &path, // path - &test.user, // to - &deadline); // deadline + &amount_in, //amount_in + &(expected_amount_out), // amount_out_min + &path, // path + &test.user, // to + &deadline, + ); // deadline assert_eq!(executed_amounts.get(0).unwrap(), amount_in); assert_eq!(executed_amounts.get(1).unwrap(), expected_amount_out); - } - - - #[test] fn swap_exact_tokens_for_tokens_2_hops() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let initial_user_balance = 10_000_000_000_000_000_000; let token_2 = create_token_contract(&test.env, &test.admin); @@ -247,34 +235,32 @@ fn swap_exact_tokens_for_tokens_2_hops() { test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &deadline// deadline: u64, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &deadline, // deadline: u64, ); let amount_2: i128 = 8_000_000_000; test.contract.add_liquidity( &test.token_1.address, // token_a: Address, - &token_2.address, // token_b: Address, - &amount_1, // amount_a_desired: i128, - &amount_2, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &deadline// deadline: u64, + &token_2.address, // token_b: Address, + &amount_1, // amount_a_desired: i128, + &amount_2, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &deadline, // deadline: u64, ); - - + let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); path.push_back(test.token_1.address.clone()); path.push_back(token_2.address.clone()); - let amount_in = 123_456_789; // fee = 123456789 * 3 /1000 = 370370,367 = 370371 // amount_in less fee = 123456789- 370371 = 123086418 @@ -287,17 +273,26 @@ fn swap_exact_tokens_for_tokens_2_hops() { let executed_amounts = test.contract.swap_exact_tokens_for_tokens( &amount_in, //amount_in - &0, // amount_out_min - &path, // path + &0, // amount_out_min + &path, // path &test.user, // to - &deadline); // deadline + &deadline, + ); // deadline assert_eq!(executed_amounts.get(0).unwrap(), amount_in); assert_eq!(executed_amounts.get(1).unwrap(), first_out); assert_eq!(executed_amounts.get(2).unwrap(), expected_amount_out); - - assert_eq!(test.token_0.balance(&test.user), initial_user_balance - amount_0 - amount_in); - assert_eq!(test.token_1.balance(&test.user), initial_user_balance - amount_1*2); - assert_eq!(token_2.balance(&test.user), initial_user_balance -amount_2 + expected_amount_out); -} + assert_eq!( + test.token_0.balance(&test.user), + initial_user_balance - amount_0 - amount_in + ); + assert_eq!( + test.token_1.balance(&test.user), + initial_user_balance - amount_1 * 2 + ); + assert_eq!( + token_2.balance(&test.user), + initial_user_balance - amount_2 + expected_amount_out + ); +} diff --git a/contracts/router/src/test/swap_tokens_for_exact_tokens.rs b/contracts/router/src/test/swap_tokens_for_exact_tokens.rs index 610815e5..75639617 100644 --- a/contracts/router/src/test/swap_tokens_for_exact_tokens.rs +++ b/contracts/router/src/test/swap_tokens_for_exact_tokens.rs @@ -1,9 +1,8 @@ -use soroban_sdk::{Address, testutils::{Ledger},vec, Vec}; +use soroban_sdk::{testutils::Ledger, vec, Address, Vec}; -use crate::test::{SoroswapRouterTest, create_token_contract}; -use crate::test::add_liquidity::add_liquidity; use crate::error::CombinedRouterError; - +use crate::test::add_liquidity::add_liquidity; +use crate::test::{create_token_contract, SoroswapRouterTest}; #[test] fn swap_tokens_for_exact_tokens_not_initialized() { @@ -12,17 +11,14 @@ fn swap_tokens_for_exact_tokens_not_initialized() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_tokens_for_exact_tokens( - &0, // amount_out - &0, // amount_in_max - &path, // path + &0, // amount_out + &0, // amount_in_max + &path, // path &test.user, // to - &0, // deadline + &0, // deadline ); - assert_eq!( - result, - Err(Ok(CombinedRouterError::RouterNotInitialized)) - ); + assert_eq!(result, Err(Ok(CombinedRouterError::RouterNotInitialized))); } #[test] @@ -33,11 +29,11 @@ fn swap_tokens_for_exact_tokens_amount_out_negative() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_tokens_for_exact_tokens( - &-1, // amount_out - &0, // amount_in_max - &path, // path + &-1, // amount_out + &0, // amount_in_max + &path, // path &test.user, // to - &0, // deadline + &0, // deadline ); assert_eq!( @@ -54,11 +50,11 @@ fn swap_tokens_for_exact_tokens_amount_in_max_negative() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_tokens_for_exact_tokens( - &0, // amount_out - &-1, // amount_in_max - &path, // path + &0, // amount_out + &-1, // amount_in_max + &path, // path &test.user, // to - &0, // deadline + &0, // deadline ); assert_eq!( @@ -74,17 +70,16 @@ fn swap_tokens_for_exact_tokens_expired() { let path: Vec
= Vec::new(&test.env); let result = test.contract.try_swap_tokens_for_exact_tokens( - &0, // amount_out - &0, // amount_in_max - &path, // path + &0, // amount_out + &0, // amount_in_max + &path, // path &test.user, // to - &0, // deadline + &0, // deadline ); assert_eq!(result, Err(Ok(CombinedRouterError::RouterDeadlineExpired))); } - #[test] fn try_swap_tokens_for_exact_tokens_invalid_path() { let test = SoroswapRouterTest::setup(); @@ -93,16 +88,15 @@ fn try_swap_tokens_for_exact_tokens_invalid_path() { let path: Vec
= vec![&test.env, test.token_0.address.clone()]; let result = test.contract.try_swap_tokens_for_exact_tokens( - &0, // amount_out - &0, // amount_in_max - &path, // path + &0, // amount_out + &0, // amount_in_max + &path, // path &test.user, // to - &deadline, // deadline + &deadline, // deadline ); assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInvalidPath))); } - #[test] // Panics because LP does not exist; here panics with a Error(Storage, MissingValue) // We should implement a pair_address.exist() without needing to call the Factory @@ -110,21 +104,21 @@ fn try_swap_tokens_for_exact_tokens_invalid_path() { fn swap_tokens_for_exact_tokens_pair_does_not_exist() { let test = SoroswapRouterTest::setup(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); path.push_back(test.token_1.address.clone()); test.contract.swap_tokens_for_exact_tokens( - &0, //amount_out - &0, // amount_in_max - &path, // path + &0, //amount_out + &0, // amount_in_max + &path, // path &test.user, // to - &deadline); // deadline + &deadline, + ); // deadline } - #[test] fn try_swap_tokens_for_exact_tokens_insufficient_output_amount() { let test = SoroswapRouterTest::setup(); @@ -142,13 +136,16 @@ fn try_swap_tokens_for_exact_tokens_insufficient_output_amount() { test.env.budget().reset_unlimited(); let result = test.contract.try_swap_tokens_for_exact_tokens( - &0, // amount_out - &0, // amount_in_max - &path, // path + &0, // amount_out + &0, // amount_in_max + &path, // path &test.user, // to - &deadline, // deadline + &deadline, // deadline + ); + assert_eq!( + result, + Err(Ok(CombinedRouterError::LibraryInsufficientOutputAmount)) ); - assert_eq!(result, Err(Ok(CombinedRouterError::LibraryInsufficientOutputAmount))); } #[test] @@ -207,11 +204,11 @@ fn swap_tokens_for_exact_tokens_amount_in_max_not_enough_amount_in_should_minus_ .unwrap(); let result = test.contract.try_swap_tokens_for_exact_tokens( - &expected_amount_out, // amount_out + &expected_amount_out, // amount_out &(amount_in_should - 1), // amount_in_max - &path, // path - &test.user, // to - &deadline, // deadline + &path, // path + &test.user, // to + &deadline, // deadline ); assert_eq!( @@ -220,13 +217,12 @@ fn swap_tokens_for_exact_tokens_amount_in_max_not_enough_amount_in_should_minus_ ); } - #[test] fn swap_tokens_for_exact_tokens_amount_in_should() { let test = SoroswapRouterTest::setup(); test.env.budget().reset_unlimited(); test.contract.initialize(&test.factory.address); - let deadline: u64 = test.env.ledger().timestamp() + 1000; + let deadline: u64 = test.env.ledger().timestamp() + 1000; let mut path: Vec
= Vec::new(&test.env); path.push_back(test.token_0.address.clone()); @@ -238,14 +234,19 @@ fn swap_tokens_for_exact_tokens_amount_in_should() { add_liquidity(&test, &amount_0, &amount_1); let expected_amount_out = 5_000_000; - let amount_in_should = test.contract.router_get_amounts_in(&expected_amount_out, &path).get(0).unwrap(); + let amount_in_should = test + .contract + .router_get_amounts_in(&expected_amount_out, &path) + .get(0) + .unwrap(); let amounts = test.contract.swap_tokens_for_exact_tokens( &expected_amount_out, //amount_out &(amount_in_should), // amount_in_max - &path, // path - &test.user, // to - &deadline); // deadline + &path, // path + &test.user, // to + &deadline, + ); // deadline assert_eq!(amounts.get(0).unwrap(), amount_in_should); assert_eq!(amounts.get(1).unwrap(), expected_amount_out); @@ -253,16 +254,28 @@ fn swap_tokens_for_exact_tokens_amount_in_should() { let original_balance: i128 = 10_000_000_000_000_000_000; let expected_amount_0_in = 1255332; assert_eq!(expected_amount_0_in, amount_in_should); - assert_eq!(test.token_0.balance(&test.user), original_balance - amount_0 - expected_amount_0_in); - assert_eq!(test.token_1.balance(&test.user), original_balance - amount_1 + expected_amount_out); - - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); - assert_eq!(test.token_0.balance(&pair_address), amount_0 + expected_amount_0_in); - assert_eq!(test.token_1.balance(&pair_address), amount_1 - expected_amount_out); + assert_eq!( + test.token_0.balance(&test.user), + original_balance - amount_0 - expected_amount_0_in + ); + assert_eq!( + test.token_1.balance(&test.user), + original_balance - amount_1 + expected_amount_out + ); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); + assert_eq!( + test.token_0.balance(&pair_address), + amount_0 + expected_amount_0_in + ); + assert_eq!( + test.token_1.balance(&pair_address), + amount_1 - expected_amount_out + ); } - #[test] fn swap_tokens_for_exact_tokens() { let test = SoroswapRouterTest::setup(); @@ -282,7 +295,7 @@ fn swap_tokens_for_exact_tokens() { // (r_in*amount_out)*1000 / (r_out - amount_out)*997 // (1000000000000000000*5000000)*1000 / ((4000000000000000000 - 5000000)*997) + 1 = 1253762,2 // because cealing div = 1253763 - let amount_in_should =1253763; + let amount_in_should = 1253763; let ledger_timestamp = 100; let desired_deadline = 1000; @@ -293,27 +306,37 @@ fn swap_tokens_for_exact_tokens() { let amounts = test.contract.swap_tokens_for_exact_tokens( &expected_amount_out, //amount_out - &(1253761*2), // amount_in_max - &path, // path - &test.user, // to - &desired_deadline); // deadline - + &(1253761 * 2), // amount_in_max + &path, // path + &test.user, // to + &desired_deadline, + ); // deadline assert_eq!(amounts.get(0).unwrap(), amount_in_should); assert_eq!(amounts.get(1).unwrap(), expected_amount_out); let original_balance: i128 = 10_000_000_000_000_000_000; - assert_eq!(test.token_0.balance(&test.user), original_balance - amount_0 - amount_in_should); - assert_eq!(test.token_1.balance(&test.user), original_balance - amount_1 + expected_amount_out); - let pair_address = test.factory.get_pair(&test.token_0.address, &test.token_1.address); - assert_eq!(test.token_0.balance(&pair_address), amount_0 + amount_in_should); - assert_eq!(test.token_1.balance(&pair_address), amount_1 - expected_amount_out); - + assert_eq!( + test.token_0.balance(&test.user), + original_balance - amount_0 - amount_in_should + ); + assert_eq!( + test.token_1.balance(&test.user), + original_balance - amount_1 + expected_amount_out + ); + let pair_address = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); + assert_eq!( + test.token_0.balance(&pair_address), + amount_0 + amount_in_should + ); + assert_eq!( + test.token_1.balance(&pair_address), + amount_1 - expected_amount_out + ); } - - - #[test] fn swap_tokens_for_exact_tokens_2_hops() { let test = SoroswapRouterTest::setup(); @@ -337,25 +360,25 @@ fn swap_tokens_for_exact_tokens_2_hops() { test.contract.add_liquidity( &test.token_0.address, // token_a: Address, &test.token_1.address, // token_b: Address, - &amount_0, // amount_a_desired: i128, - &amount_1, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &amount_0, // amount_a_desired: i128, + &amount_1, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); let amount_2: i128 = 8_000_000_000; test.contract.add_liquidity( &test.token_1.address, // token_a: Address, - &token_2.address, // token_b: Address, - &amount_1, // amount_a_desired: i128, - &amount_2, // amount_b_desired: i128, - &0, // amount_a_min: i128, - &0 , // amount_b_min: i128, - &test.user, // to: Address, - &desired_deadline// deadline: u64, + &token_2.address, // token_b: Address, + &amount_1, // amount_a_desired: i128, + &amount_2, // amount_b_desired: i128, + &0, // amount_a_min: i128, + &0, // amount_b_min: i128, + &test.user, // to: Address, + &desired_deadline, // deadline: u64, ); let mut path: Vec
= Vec::new(&test.env); @@ -369,37 +392,62 @@ fn swap_tokens_for_exact_tokens_2_hops() { // (r_in*amount_out)*1000 / (r_out - amount_out)*997 // (4000000000*123456789)*1000 / ((8000000000 - 123456789)*997) + 1 = 62884578,9 // ceiling div = 62884579 // 31942963 - let middle_amount_in =62884579; + let middle_amount_in = 62884579; // pair token_0, token_1 // token_0 is r_in, token_1 is r_out - // first amount in = + // first amount in = // (1000000000*62884579)*1000 / ((4000000000 - 62884579)*997) + 1 = 16020308,676218266 = // celing div = 16020309 - let amount_in_should =16020309; + let amount_in_should = 16020309; let amounts = test.contract.swap_tokens_for_exact_tokens( &expected_amount_out, //amount_out - &amount_in_should, // amount_in_max - &path, // path - &test.user, // to - &desired_deadline); // deadline - + &amount_in_should, // amount_in_max + &path, // path + &test.user, // to + &desired_deadline, + ); // deadline - assert_eq!(amounts.get(0).unwrap(), amount_in_should); - assert_eq!(amounts.get(1).unwrap(), middle_amount_in); + assert_eq!(amounts.get(0).unwrap(), amount_in_should); + assert_eq!(amounts.get(1).unwrap(), middle_amount_in); assert_eq!(amounts.get(2).unwrap(), expected_amount_out); let original_balance: i128 = 10_000_000_000_000_000_000; - assert_eq!(test.token_0.balance(&test.user), original_balance - amount_0 - amount_in_should); - assert_eq!(test.token_1.balance(&test.user), original_balance - amount_1*2); - assert_eq!(token_2.balance(&test.user), original_balance - amount_2 + expected_amount_out); + assert_eq!( + test.token_0.balance(&test.user), + original_balance - amount_0 - amount_in_should + ); + assert_eq!( + test.token_1.balance(&test.user), + original_balance - amount_1 * 2 + ); + assert_eq!( + token_2.balance(&test.user), + original_balance - amount_2 + expected_amount_out + ); - let pair_address_0_1 = test.factory.get_pair(&test.token_0.address, &test.token_1.address); - assert_eq!(test.token_0.balance(&pair_address_0_1), amount_0 + amount_in_should); - assert_eq!(test.token_1.balance(&pair_address_0_1), amount_1 - middle_amount_in); + let pair_address_0_1 = test + .factory + .get_pair(&test.token_0.address, &test.token_1.address); + assert_eq!( + test.token_0.balance(&pair_address_0_1), + amount_0 + amount_in_should + ); + assert_eq!( + test.token_1.balance(&pair_address_0_1), + amount_1 - middle_amount_in + ); - let pair_address_1_2 = test.factory.get_pair(&test.token_1.address, &token_2.address); - assert_eq!(test.token_1.balance(&pair_address_1_2), amount_1 + middle_amount_in); - assert_eq!(token_2.balance(&pair_address_1_2), amount_2 - expected_amount_out); + let pair_address_1_2 = test + .factory + .get_pair(&test.token_1.address, &token_2.address); + assert_eq!( + test.token_1.balance(&pair_address_1_2), + amount_1 + middle_amount_in + ); + assert_eq!( + token_2.balance(&pair_address_1_2), + amount_2 - expected_amount_out + ); } From 83845dbcb8501a8aa76160270f35a34223f75794 Mon Sep 17 00:00:00 2001 From: kalepail Date: Mon, 4 Aug 2025 10:40:56 -0400 Subject: [PATCH 3/4] Update soroswap_pair.wasm --- contracts/library/src/soroswap_pair.wasm | Bin 26808 -> 26808 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contracts/library/src/soroswap_pair.wasm b/contracts/library/src/soroswap_pair.wasm index 6c9f801e3c86d19c36eb362674eec3447033766a..169d673295a375109395aa19997f99f985b55a28 100644 GIT binary patch delta 2188 zcmZVf`1ic;9UQ!O#}7C@4n*DqL{1SUr3=`MyEPA2ip({0E|Cp#7$TV#eJFUs zs-*^dVq5g=7y2ne< z8?UA~91gG7Ys*OT;1S3Jk8u$qpbfOOwK1l}F+PA*>P2NDg2}eWvOkGL+gMQ1A*k># zgbM#se4U^X>$eEj*~*l=5#y+>*9HSdWn7Pf*HRn3?Naq4@l`5xr9k092)h_Juqthd z*NVlN&iL0-^Q8D{tFYRao*ZQSL(7mAD2%KIG3v=olIo}Ds$*qJ5=aG{&<-hM5o~s@ zfirmC`EmRipq zAWWI2GaYn=e?WiHnHe&Ej6c_{0hr!lx6%^RG$1GM&kc(_ksTfF}|o(1FX7!kPbf9+jplAHwdW zfNQG27~RgV;q9b?#OqQnf`1?|-eDvq9|zgn0vt`rz|Is8Q4doV5mh9yZWzG#Q}slv zST_sWMaTFtJeqb34BVCe3p_A3ddn3sjPA@OK)g%yjzBxsW-ZqZ5r%0VYYD7g-xgfK zJdJ%>B`}P?XJtMo_o+8H2`{-728tGBKD(ydf_K?AJ|+y53h}SoT}-$6)n@T&XPYQoauy{K@KmQmE8ESSa=vQT6a@q;jm~}g~cTljIMyp$@ zH)!L6(iL6hH}SasX6l`NQTaY>G?D2i(t%I<7Sq6@<$3s?Z<)&+u_9a3kHfxh-`wfg zh0Bosb}v6G0t6pmBqtxP zS`)<$d96!kTLR@|C;2&97D(Lmqewi8>VntdTimxF3+}1lP@ zs8jfZpLPS=7A=FT##f6jL#Esi-J!?onjX)8HeE@#BV?Khqj9zg1;uRZB~1r^hI+6D2`5HLR?$$>Vb%8j`%Tq$nlrP7YWl|4x;qL{Yt5EQ-+;_lT2M%+42tg&a! Q0mV47dO|g_HXKg;4-!UfhyVZp delta 2152 zcmZWqYfMyE5I%G7E-c(#I19_dvPJF!0t*PzN;g1S+5I7yRFs%TO;eEsYETsGBc-;L z6)|n9wUCJkiM1i=!?ca9dWBM-2)+Po1%9+Peek0{8rvqC^hb?WI_KQWLkr2BIp55D zbI#11vjgKWFb-V@ozT9)zK8zW*#_3#^P<)UrA&cFsAtgqPkU~nC&lYcO-M^~r1{dk zK9at8)uXBohr{RdC3qbUTY8cgk3tT3jUng&tuGplGN#2b-iIsIA?0oqlWk9D4nzl| zEUf4dR`{2~g?}Z!PS6OtAH_yng%aIs^xBTupwFm@>rrsI>yR=P#oMkGU|?Rtr}2h} zSm_eX-zT&QTU}x?*`kSA(2pM_E`w8eCvj!UY2l~owy?e_htw!b)Oep!%M$?xaJ@T} zeO7?v!F13S{*74aYM5Kz=H3U~x#az;yR806yI?a3JWQ$5A;MO>WC{~pVzQnWD}GUO zo5(q-i;RQw&`Y=@sS1YibW-(#%Mw>+cQThLT+Yv;FS!Fc@q^@Q|NqI)$WWCJPKJN& zegPf}Ps6JT3Ijz8vw&R;!CkhA-w-yXO8o0~7t?J)b({FKb*^$z|00ZkCp^S7#zYSN zet+=upB4VLfcSoVdBGK8DbZXCudoJ8@~CklH?2nS<{K7Q4(rQN#iHDZCLl9C)(Fc0n1@-#NzRe1{)m zM^-Le!Oya)X)5kzHEXlO#s{z|dt>I~3^wZh%m@no4E~Y*k~J4%v({YTnw<7U^CN-w zWGDOA@>n2slSh&I8B`bUh6}i7;cKBM<3ygBxVij78?@MjehG_m|4Nqq%VLpf*cTaL zb#%?gu_*5axMsYbR|{@gRoSYWB9vdmAM#5V$|IX2rX^U{jmrU>TVBQDU|F2>RI2zj zYzg|xN6qv>^#lY|9fIlr1Z?yYoq$bzY{o{IUD(Jc#(Ah74XXm(H(lMuIcgo7n4fTj#8)}#_)Jib^Oe<@qXh`kqc4>_lgm*l7wTd7qSzx ziqB=wZd`D=SY#i`DQAE=Z5lmVw`jwo2ql6!qvS2OdE5S$zADvr1ivU*4HGy`9+QTD zai%S=w?ibOmWtr8eI}U*NslN*tZFpN{n)UieqPl^mekHwtw&ZXsCLN;iQ6z&HL}q` zq%D@}By1D7s*KWOOBurOsb`%)( zZrQP|X=`KCcE$=BXEw%I3CUQJ4O?1wZQa?_wyk-4!_MZ`t@SNUjT_0ahU_t9uVq+J z6Tk<{%7O<7au9@;JVG*#)*q8}kvwV13%IU2RC Date: Mon, 4 Aug 2025 11:18:39 -0400 Subject: [PATCH 4/4] ensure we include all neccessary files --- .gitignore | 5 ++++- .../release/soroswap_factory.optimized.wasm | Bin 0 -> 10160 bytes .../release/soroswap_pair.optimized.wasm | Bin 0 -> 23190 bytes contracts/router/src/pair.rs | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm create mode 100644 contracts/pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm diff --git a/.gitignore b/.gitignore index f6782233..514ae0ef 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ contracts/*/test_snapshots node_modules/ .env /dist -/scripts/test.ts \ No newline at end of file +/scripts/test.ts + +!contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm +!contracts/pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm \ No newline at end of file diff --git a/contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm b/contracts/factory/target/wasm32v1-none/release/soroswap_factory.optimized.wasm new file mode 100644 index 0000000000000000000000000000000000000000..110b7dbc0a35394efeaf8bb0438c8c2f8b220249 GIT binary patch literal 10160 zcmdT~TWlOx89tZUwX?J9oRFkR+zV$nZezEN>)aeC709!#Q=&>~n+EX&>$P_rukGxb z-Hnq}$aYCu^#N4{f%;G(6$ENklmg`m35jqM^pdKNVX@I9(v;`&TZjy{2&|5N-BTF+u0ni+RF(BCb45=kjH zb|p8+4T)4&x9=y?X@QG@_oU*Sv#yks3CY=}T|V_HglEh3Mx70%%9V1XT%0RE60$uhOkRi<+`lP)af=>MQC+<7 zus>M~i;d7ObP#YIN)-yFVxtJ!N|O79!gN@iFH98cp%kf$H}&7lG*esiJbz&s*BgK6 zvV}|Ubt%^Czbpi4#7-8d*&OdZ=-`ZTrrt~D9ACaCqB)S7m!iMZ9H))!Zd_2O1Ztv{sJlp8DKRza;lqt>mi zRYa|t9S~k#Kc4q4s9VyUI=;E0qa{8|{n>z22W7V{bsv-rCDaE(-KcKCNH9tL1|)kh z!+isVn(1R&_{sonn(|!nUf)NB=4x}EKjdek#=M}G0lWdWF>jRC>)zG}Q24DyoHAB3jpurYoW4q_Y%8vdG7-lH-E@&PVRF6Nx`I1#82~bEp zLXBW833k23JWo*B(wJvH%_*@!AM^J&2MR({a}t68VF6b+X2EsdlIj}Fp!U^3WH&8p z=LH)b1EbYQ0K1tLz#hie5Wor0C4d_E$dYsjK`LJg*fA0xEvE3GrPI(sQ=$rDfOL%o zk97@0xI7E}1-rw7`J1skG~;7AaP?_o?crH}8?%P_y|<(-Jo^u+yk7qaXaL-_7{!3C zISJL;=8fWwN+KtpBcgI5xXg}tqmZ#6y5YLL}fQ*mrLuRDBx@o?5;HXVR3s)#iO1p14{xF zE`cin`dI!7KcDxGXGnrrJP|OT=E}IasJ9<*Nm>IHZwh}qbN~`p;3YXMtSaOrIWn~^ z=K*=Cwh*JFrP_n7192&-fuRs`FPO)ITMzt|pd zsDrk>p4}0tq8N}m3;Ajk`VY!}3o!-|!~h&@nt6iDT6;~3!;LZjlQ70SY#pRp#rYLG4$`<%d5Zt@ z=gngo76}O&CzXfOAe|)-@AsolOT-C8wx)j<9gcnz)D?kAk`+N=V|BR9pbwEwX9bjf zROPJQ9nJ}r>@`-Z4nsDC3C}S`ZXZ5{V)*^lK*(lnoGN@BHOQFaE-KMnf4Ak)~9*ipVm$ z4dR1856I#%gE7VUd(Dnnbj%c83W8E^76P@6#j%+Bkax?$EHjs15%sO&&8gc#AGJ$MK+W3 z5dARILm94+!K!YxK_}_1QrQH|ldK}4(m6oKl#ePec!B^-A*F%U6I<5m`?FoJ(j=^u ze1eHuIstno*CIwGf>p2`{#a0emiCoWF@usMp9?Oe%f=+$z%pfHOk-X^3Cbn%&y4Xs zf=t(}He^>L-vS4&k@*O90|iEPYnGe{oG2l>NmYeEoOd z`4c#$h-(bdIU({&@Y3Xmz#%v%4ryt0#?so0yaTK=_!gOg2X;MUlToLDrMr9pN=hMT zY$_RZNpTY@2nP&0kqY>RYVlCKLG#^c{Twsllkt)^F0@| zHt7_;u}t#u3)v*$HjA|rfG?X!8`53=3zLj?85@1{Y^JP$t=mU_@Hv;u$9pZ! zp}t#l!X!*FI59D*nf_JIr zpFG+mvw5aik}*~Z&#c%S(-yc$)~8WjAF~_#6V*m> zj@s&U3reM0Sg(imV@E5c@N8IGQJFt?f>^4v@7~cfS*A_aJ&jEt3(wGsZVaJBmuiO>b*{~u#{j(3Ty%9suv59M4l?Lm zQ^goHX(jaOl316XZXRjm6Th#;OAmOl$UANr6EqpFwdQp=QNPWYqeWKDiCmwRM>G~= zhYOA0V8E=^sss=&8uy7dH9xE^U`1W5l%n#4o-Qtgx?F(jKhQ~Z`8)ZZCFOEpWy7GbI#A6sdj4*RepsSn}4df%qmxcR!?p#BjiRQb&D zuyMLpsq4mcsB7V5dA8^y|G z=z5QjRTjo|y-_6@Bt7k$|Gd($7tegxTgE7}1F{`ZY7&PMM z+IarjJ=5XjY@LvW(CWHa3w3mW`cbpR+I7E+zARZpLswlcLrRM)F|s#yDox$iu?wqkYs!*;L6KOb-9-|2B=nZ&-Hf+>wh zK6KnT(dcbr{7%w@as%G9t|!8<;*k1};eg#YSK6&lv{;t&6_7^*=7lf~D>jlKA_vK1 z*pUT+jM^h>o3&L9A4TZIG`q-v}Uz_(MV*BceE7BuTkA5!Fq& zIw!w1{1897hWsjxX`{lre`t5vCOiX9MyqM_oy19`1N}n-BwfQs#i+eC1`|13g-srH zJp!*dff)*&n>Rqhjn=|OtsE}c2=Sqa$u2XFWmn3{L;~a#@s}PFLo?>_ig|T$@Ppz5 z-yQqPq7{PuVr1-zV#dibGDoMi#Wu@Y51{{t78GH>;>#M~cDd5^*vcBdp6^1!YLk$0 z#4mgmjK0eOe479o_ZDXdw(pd6_3IId-4i%PcZ)&2(V*cxNgpOp*J_j%wUK6A8(Bl) z40bmKxY}tq4`qGid#78C#*ld(hEkkEu3I|SkrTCk*Cfq%vS{BEP+QMR`lw32gPX=* z?lWd6s*iy_Pfrv8BwS;RyY5i^qRaq&a~-ZB+j0%b~Iv=Lm)`*%*^c~N0ir0gpD(_2e`_-6yjI>)CKP@ zrd&^azgjNbdM?zyU#AnyzK(ODRg@e3dX7~aEysJPVeDo6{TI%a*eh6Pw1dvIz>YMp z^=u1sY>UsY0;}C)_SZ^idli43SU6e6xlalGZi<13=7}q){k2u+GW4#@tf7+a#!eo!zp@9oUAIg;QapXwGcW#BQJ)t2PgG zS2QMS^#%ME%v{MmgCiq@(a9ZZx@+}%Y1TI1wRi8}(BR0Sw;&(PjI`z9tP e4({DMa^S%5@YJDF>Co`d)YPHj($K!r2>UmQmU^H7 literal 0 HcmV?d00001 diff --git a/contracts/pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm b/contracts/pair/target/wasm32v1-none/release/soroswap_pair.optimized.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a68b98ab1227c7631f225f866c31ad907f788ca9 GIT binary patch literal 23190 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 = Client<'a>;