diff --git a/.github/workflows/ci-test-fmt-check.yaml b/.github/workflows/ci-test-fmt-check.yaml index 590ff9b8..a5a59e87 100644 --- a/.github/workflows/ci-test-fmt-check.yaml +++ b/.github/workflows/ci-test-fmt-check.yaml @@ -59,7 +59,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: clippy - args: --locked -- -D warnings + args: --features "token_factory" --locked -- -D warnings #- name: Run cosmwasm linter # run: cargo dylint cw_lint --workspace @@ -73,12 +73,12 @@ jobs: - name: Generate Schemas and Exit on uncommitted changes run: | chmod +x ./scripts/build_schemas.sh - ./scripts/build_schemas.sh true + ./scripts/build_schemas.sh -f token_factory -d true shell: bash test_and_check-token_injective_feature: name: Test and check Injective feature - runs-on: ubuntu-latest + runs-on: ubuntu-latestq steps: # Cancel any existing runs to save on CI time @@ -115,7 +115,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: clippy - args: --locked -- -D warnings + args: --features "injective" --locked -- -D warnings #- name: Run cosmwasm linter # run: cargo dylint cw_lint --workspace diff --git a/Cargo.lock b/Cargo.lock index c7293902..264e5a0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anybuf" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a03eb4d55fa21466cac727930be07f82581223ee04bcaf61f934e98b7ecb859" + [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "autocfg" @@ -20,11 +26,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" -version = "0.13.0" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -32,6 +44,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "bit-set" version = "0.5.3" @@ -71,6 +89,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "byteorder" version = "1.4.3" @@ -97,37 +121,38 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cosmwasm-crypto" -version = "1.2.5" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" +checksum = "d8bb3c77c3b7ce472056968c745eb501c440fbc07be5004eba02782c35bfbbe3" dependencies = [ - "digest 0.10.5", + "digest 0.10.7", + "ecdsa 0.16.8", "ed25519-zebra", - "k256", - "rand_core 0.6.3", + "k256 0.13.1", + "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "fea73e9162e6efde00018d55ed0061e93a108b5d6ec4548b4f8ce3c706249687" dependencies = [ "syn 1.0.99", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "0df41ea55f2946b6b43579659eec048cc2f66e8c8e2e3652fc5e5e476f673856" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -138,9 +163,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "43609e92ce1b9368aa951b334dd354a2d0dd4d484931a5f83ae10e12a26c8ba9" dependencies = [ "proc-macro2", "quote", @@ -149,11 +174,13 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "04d6864742e3a7662d024b51a94ea81c9af21db6faea2f9a6d2232bb97c6e53e" dependencies = [ "base64", + "bech32", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -162,9 +189,9 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", - "sha2 0.10.6", + "sha2 0.10.8", + "static_assertions", "thiserror", - "uint", ] [[package]] @@ -199,7 +226,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -227,6 +266,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cw-address-like" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" +dependencies = [ + "cosmwasm-std", +] + [[package]] name = "cw-controllers" version = "1.1.0" @@ -253,19 +301,65 @@ dependencies = [ "cw-storage-plus", "cw-utils", "derivative", - "itertools", - "k256", + "itertools 0.10.3", + "k256 0.11.6", "prost 0.9.0", "schemars", "serde", "thiserror", ] +[[package]] +name = "cw-multi-test" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fff029689ae89127cf6d7655809a68d712f3edbdb9686c70b018ba438b26ca" +dependencies = [ + "anyhow", + "bech32", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "derivative", + "itertools 0.12.0", + "prost 0.12.3", + "schemars", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cw-ownable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-address-like", + "cw-ownable-derive", + "cw-storage-plus", + "cw-utils", + "thiserror", +] + +[[package]] +name = "cw-ownable-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.99", +] + [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -274,9 +368,9 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -301,9 +395,9 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "9431d14f64f49e41c6ef5561ed11a5391c417d0cb16455dea8cdcb9037a8d197" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -354,6 +448,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -376,11 +480,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] @@ -397,10 +502,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.0", + "elliptic-curve 0.12.3", + "rfc6979 0.3.0", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.8", + "digest 0.10.7", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -411,7 +530,7 @@ checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" dependencies = [ "curve25519-dalek", "hex", - "rand_core 0.6.3", + "rand_core 0.6.4", "serde", "sha2 0.9.9", "thiserror", @@ -430,16 +549,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest 0.10.5", - "ff", + "base16ct 0.1.1", + "crypto-bigint 0.4.8", + "der 0.6.0", + "digest 0.10.7", + "ff 0.12.0", "generic-array", - "group", - "pkcs8", - "rand_core 0.6.3", - "sec1", + "group 0.12.0", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.3", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.1", "subtle", "zeroize", ] @@ -451,7 +589,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "schemars", @@ -498,7 +636,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", - "cw-multi-test", + "cw-multi-test 0.16.5", "cw-storage-plus", "cw2", "schemars", @@ -513,7 +651,7 @@ version = "1.1.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw-utils", "cw2", @@ -540,7 +678,7 @@ version = "0.9.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw-utils", "cw2", @@ -557,7 +695,17 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", "subtle", ] @@ -579,7 +727,7 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "cw20", @@ -603,6 +751,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -633,8 +782,19 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ - "ff", - "rand_core 0.6.3", + "ff 0.12.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", "subtle", ] @@ -656,7 +816,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -666,7 +826,7 @@ dependencies = [ "anyhow", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw-utils", "cw2", @@ -746,6 +906,24 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.3" @@ -759,9 +937,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", - "sha2 0.10.6", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.8", + "signature 2.1.0", ] [[package]] @@ -819,9 +1011,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -835,7 +1027,7 @@ version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4d482a16be198ee04e0f94e10dd9b8d02332dcf33bc5ea4b255e7e25eedc5df" dependencies = [ - "itertools", + "itertools 0.10.3", "proc-macro2", "quote", "syn 1.0.99", @@ -870,8 +1062,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.0", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.2", ] [[package]] @@ -930,6 +1132,16 @@ dependencies = [ "prost-derive 0.11.9", ] +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", +] + [[package]] name = "prost-derive" version = "0.9.0" @@ -937,7 +1149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.3", "proc-macro2", "quote", "syn 1.0.99", @@ -950,12 +1162,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.3", "proc-macro2", "quote", "syn 1.0.99", ] +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "prost-types" version = "0.11.9" @@ -1075,7 +1300,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1085,7 +1310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1099,9 +1324,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom 0.2.7", ] @@ -1112,7 +1337,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1145,11 +1370,21 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88c86280f057430a52f4861551b092a01b419b8eacefc7c995eacb9dc132fe32" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.8", "hmac", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rustix" version = "0.37.19" @@ -1184,9 +1419,9 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -1196,9 +1431,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -1218,10 +1453,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.0", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -1234,9 +1483,9 @@ checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -1252,13 +1501,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.32", ] [[package]] @@ -1298,13 +1547,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -1313,8 +1562,18 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.5", - "rand_core 0.6.3", + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", ] [[package]] @@ -1330,7 +1589,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.0", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.8", ] [[package]] @@ -1387,9 +1656,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" dependencies = [ "proc-macro2", "quote", @@ -1438,7 +1707,7 @@ version = "1.3.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "cw20", @@ -1488,22 +1757,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.32", ] [[package]] @@ -1548,7 +1817,7 @@ version = "1.2.6" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "cw20", @@ -1562,13 +1831,39 @@ dependencies = [ "white-whale", ] +[[package]] +name = "vault-manager" +version = "0.1.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test 0.20.0", + "cw-ownable", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "cw20-base", + "fee_collector", + "schemars", + "semver", + "serde", + "sha2 0.10.8", + "terraswap-pair", + "terraswap-token", + "thiserror", + "whale-lair", + "white-whale", +] + [[package]] name = "vault_factory" version = "1.1.3" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "cw20", @@ -1589,7 +1884,7 @@ version = "1.1.6" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "cw20", @@ -1634,12 +1929,12 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "whale-lair" -version = "0.9.1" +version = "0.9.2" dependencies = [ "anyhow", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "cw-storage-plus", "cw2", "schemars", @@ -1652,10 +1947,13 @@ dependencies = [ [[package]] name = "white-whale" -version = "1.1.1" +version = "1.1.2" dependencies = [ + "anybuf", "cosmwasm-schema", "cosmwasm-std", + "cw-ownable", + "cw-storage-plus", "cw2", "cw20", "osmosis-std-derive", @@ -1673,7 +1971,7 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.20.0", "fee_collector", "fee_distributor", "schemars", diff --git a/Cargo.toml b/Cargo.toml index 5388a2c5..9a810fd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ "contracts/liquidity_hub/whale_lair", "contracts/liquidity_hub/vault-network/*", "contracts/liquidity_hub/epoch-manager", + "contracts/liquidity_hub/vault-manager", ] [workspace.package] @@ -20,28 +21,31 @@ repository = "https://github.com/White-Whale-Defi-Platform/migaloo-core" publish = false [workspace.dependencies] -cosmwasm-schema = "1.1.4" -cosmwasm-std = { version = "1.1.4", features = ["iterator"] } -cw2 = "1.0.1" -cw20 = "1.0.1" +cosmwasm-schema = { version = "1.1.4"} +cosmwasm-std = { version = "1.1.4", features = ["iterator", "cosmwasm_1_2"] } +cw2 = { version = "1.0.1"} +cw20 = { version = "1.0.1"} cw20-base = { version = "1.1.0", features = ["library"] } -cw-storage-plus = "1.1.0" -cw-utils = "1.0.1" +cw-storage-plus = { version = "1.1.0"} +cw-utils = { version = "1.0.1"} protobuf = { version = "3.2.0", features = ["with-bytes"] } -schemars = "0.8.12" -semver = "1.0.12" +schemars = { version = "0.8.12"} +semver = { version = "1.0.12"} serde = { version = "1.0.145", default-features = false, features = ["derive"] } -thiserror = "1.0.43" -osmosis-std-derive = "0.15.3" +thiserror = { version = "1.0.43"} +osmosis-std-derive = { version = "0.15.3"} prost = {version = "0.11.9", default-features = false, features = ["prost-derive"]} prost-types = {version = "0.11.9", default-features = false} white-whale = { path = "./packages/white-whale" } white-whale-testing = { path = "./packages/white-whale-testing" } -cw-multi-test = { version = "0.16.5" } -uint = "0.9.5" -integer-sqrt = "0.1.5" +cw-multi-test = { version = "0.20.0", features = ["cosmwasm_1_2"] } +uint = { version = "0.9.5"} +integer-sqrt = { version = "0.1.5"} anyhow = { version = "1.0.71"} -cw-controllers = "1.1.0" +cw-controllers = { version = "1.1.0"} +cw-ownable = { version = "0.5.1"} +anybuf = { version = "0.3.0"} +sha2 = { version = "0.10.8"} # contracts whale-lair = { path = "./contracts/liquidity_hub/whale_lair" } @@ -50,6 +54,7 @@ fee_distributor = { path = "./contracts/liquidity_hub/fee_distributor" } fee-distributor-mock = { path = "./contracts/liquidity_hub/fee-distributor-mock" } incentive-factory = { path = "./contracts/liquidity_hub/pool-network/incentive_factory" } terraswap-token = { path = "./contracts/liquidity_hub/pool-network/terraswap_token" } +terraswap-pair = { path = "./contracts/liquidity_hub/pool-network/terraswap_pair" } [workspace.metadata.dylint] libraries = [{ git = "https://github.com/0xFable/cw-lint" }] diff --git a/contracts/liquidity_hub/epoch-manager/src/contract.rs b/contracts/liquidity_hub/epoch-manager/src/contract.rs index 0f2fc474..8421f12b 100644 --- a/contracts/liquidity_hub/epoch-manager/src/contract.rs +++ b/contracts/liquidity_hub/epoch-manager/src/contract.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{entry_point, to_binary, StdError}; +use cosmwasm_std::{entry_point, to_json_binary, StdError}; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::{get_contract_version, set_contract_version}; use semver::Version; @@ -79,9 +79,9 @@ pub fn execute( #[entry_point] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::CurrentEpoch {} => Ok(to_binary(&queries::query_current_epoch(deps)?)?), - QueryMsg::Epoch { id } => Ok(to_binary(&queries::query_epoch(deps, id)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::CurrentEpoch {} => Ok(to_json_binary(&queries::query_current_epoch(deps)?)?), + QueryMsg::Epoch { id } => Ok(to_json_binary(&queries::query_epoch(deps, id)?)?), } } diff --git a/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs b/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs index b3e2964c..d2486011 100644 --- a/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs +++ b/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs @@ -1,6 +1,6 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint64, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint64, }; use white_whale::fee_distributor::EpochResponse; @@ -71,7 +71,7 @@ pub fn query( match msg { white_whale::fee_distributor::QueryMsg::Config {} => {} white_whale::fee_distributor::QueryMsg::CurrentEpoch {} => { - return to_binary(&EpochResponse { + return to_json_binary(&EpochResponse { epoch: CURRENT_EPOCH.load(deps.storage)?, }); } @@ -80,5 +80,5 @@ pub fn query( white_whale::fee_distributor::QueryMsg::Claimable { .. } => {} } - to_binary(&"") + to_json_binary(&"") } diff --git a/contracts/liquidity_hub/fee_collector/src/commands.rs b/contracts/liquidity_hub/fee_collector/src/commands.rs index 44047ff3..3a3f082b 100644 --- a/contracts/liquidity_hub/fee_collector/src/commands.rs +++ b/contracts/liquidity_hub/fee_collector/src/commands.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, Addr, BalanceResponse, BankQuery, Coin, CosmosMsg, Decimal, DepsMut, Env, + to_json_binary, Addr, BalanceResponse, BankQuery, Coin, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, QueryRequest, ReplyOn, Response, StdResult, SubMsg, Uint128, WasmMsg, WasmQuery, }; use cw20::{Cw20ExecuteMsg, Cw20QueryMsg}; @@ -49,10 +49,10 @@ pub fn collect_fees(deps: DepsMut, collect_fees_for: FeesFor) -> Result StdResult { let collect_protocol_fees_msg = match contract_type { ContractType::Vault {} => { - to_binary(&white_whale::vault_network::vault::ExecuteMsg::CollectProtocolFees {})? + to_json_binary(&white_whale::vault_network::vault::ExecuteMsg::CollectProtocolFees {})? } ContractType::Pool {} => { - to_binary(&white_whale::pool_network::pair::ExecuteMsg::CollectProtocolFees {})? + to_json_binary(&white_whale::pool_network::pair::ExecuteMsg::CollectProtocolFees {})? } }; @@ -76,7 +76,7 @@ fn collect_fees_for_factory( let response: VaultsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::vault_network::vault_factory::QueryMsg::Vaults { start_after, limit, @@ -95,7 +95,7 @@ fn collect_fees_for_factory( let response: PairsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary(&QueryMsg::Pairs { start_after, limit })?, + msg: to_json_binary(&QueryMsg::Pairs { start_after, limit })?, }))?; for pair in response.pairs { @@ -182,7 +182,7 @@ pub fn aggregate_fees( let response: VaultsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::vault_network::vault_factory::QueryMsg::Vaults { start_after, limit, @@ -198,7 +198,7 @@ pub fn aggregate_fees( let response: PairsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary(&QueryMsg::Pairs { start_after, limit })?, + msg: to_json_binary(&QueryMsg::Pairs { start_after, limit })?, }))?; for pair in response.pairs { @@ -224,7 +224,7 @@ pub fn aggregate_fees( let balance_response: cw20::BalanceResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20QueryMsg::Balance { + msg: to_json_binary(&Cw20QueryMsg::Balance { address: env.contract.address.to_string(), })?, }))?; @@ -234,7 +234,7 @@ pub fn aggregate_fees( // Increase the allowance for the cw20 token so the router can perform the swap aggregate_fees_messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&Cw20ExecuteMsg::IncreaseAllowance { spender: config.pool_router.to_string(), amount: balance_response.balance, expires: None, @@ -261,7 +261,7 @@ pub fn aggregate_fees( let operations_res: StdResult> = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.pool_router.to_string(), - msg: to_binary(&router::QueryMsg::SwapRoute { + msg: to_json_binary(&router::QueryMsg::SwapRoute { offer_asset_info: offer_asset_info.clone(), ask_asset_info: ask_asset_info.clone(), })?, @@ -270,7 +270,7 @@ pub fn aggregate_fees( match operations_res { Ok(operations) => { let execute_swap_operations_msg = - to_binary(&router::ExecuteMsg::ExecuteSwapOperations { + to_json_binary(&router::ExecuteMsg::ExecuteSwapOperations { operations, minimum_receive: None, to: None, @@ -282,7 +282,7 @@ pub fn aggregate_fees( aggregate_fees_messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: config.pool_router.to_string(), amount: balance, msg: execute_swap_operations_msg, @@ -336,7 +336,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::CollectFees { + msg: to_json_binary(&ExecuteMsg::CollectFees { collect_fees_for: FeesFor::Factory { factory_addr: config.vault_factory.to_string(), factory_type: FactoryType::Vault { @@ -355,7 +355,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::CollectFees { + msg: to_json_binary(&ExecuteMsg::CollectFees { collect_fees_for: FeesFor::Factory { factory_addr: config.pool_factory.to_string(), factory_type: FactoryType::Pool { @@ -375,7 +375,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AggregateFees { + msg: to_json_binary(&ExecuteMsg::AggregateFees { aggregate_fees_for: FeesFor::Factory { factory_addr: config.vault_factory.to_string(), factory_type: FactoryType::Vault { @@ -394,7 +394,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AggregateFees { + msg: to_json_binary(&ExecuteMsg::AggregateFees { aggregate_fees_for: FeesFor::Factory { factory_addr: config.pool_factory.to_string(), factory_type: FactoryType::Pool { diff --git a/contracts/liquidity_hub/fee_collector/src/contract.rs b/contracts/liquidity_hub/fee_collector/src/contract.rs index f6e0dfd4..c7e8a1c0 100644 --- a/contracts/liquidity_hub/fee_collector/src/contract.rs +++ b/contracts/liquidity_hub/fee_collector/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Addr, BalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, Deps, DepsMut, Env, - MessageInfo, QueryRequest, Reply, Response, StdResult, Uint128, + to_json_binary, Addr, BalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, Deps, DepsMut, + Env, MessageInfo, QueryRequest, Reply, Response, StdResult, Uint128, }; use cw2::{get_contract_version, set_contract_version}; use semver::Version; @@ -96,7 +96,7 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::query_config(deps)?), + QueryMsg::Config {} => to_json_binary(&queries::query_config(deps)?), QueryMsg::Fees { query_fees_for, all_time, - } => to_binary(&queries::query_fees( + } => to_json_binary(&queries::query_fees( deps, query_fees_for, all_time.unwrap_or(false), diff --git a/contracts/liquidity_hub/fee_collector/src/queries.rs b/contracts/liquidity_hub/fee_collector/src/queries.rs index fb436ee3..050539ed 100644 --- a/contracts/liquidity_hub/fee_collector/src/queries.rs +++ b/contracts/liquidity_hub/fee_collector/src/queries.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, Deps, QueryRequest, StdResult, WasmQuery}; +use cosmwasm_std::{to_json_binary, Addr, Deps, QueryRequest, StdResult, WasmQuery}; use white_whale::fee_collector::{Config, ContractType, FactoryType, FeesFor}; use white_whale::pool_network; @@ -75,7 +75,7 @@ fn query_fees_for_vault(deps: &Deps, vault: String, all_time: bool) -> StdResult .querier .query::(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: vault, - msg: to_binary(&white_whale::vault_network::vault::QueryMsg::ProtocolFees { + msg: to_json_binary(&white_whale::vault_network::vault::QueryMsg::ProtocolFees { all_time, })?, }))? @@ -90,7 +90,7 @@ fn query_fees_for_pair(deps: &Deps, pair: String, all_time: bool) -> StdResult(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair, - msg: to_binary(&pool_network::pair::QueryMsg::ProtocolFees { + msg: to_json_binary(&pool_network::pair::QueryMsg::ProtocolFees { all_time: Some(all_time), asset_id: None, })?, @@ -114,7 +114,7 @@ fn query_fees_for_factory( let response: VaultsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::vault_network::vault_factory::QueryMsg::Vaults { start_after, limit, @@ -131,7 +131,10 @@ fn query_fees_for_factory( let response: PairsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary(&pool_network::factory::QueryMsg::Pairs { start_after, limit })?, + msg: to_json_binary(&pool_network::factory::QueryMsg::Pairs { + start_after, + limit, + })?, }))?; for pair in response.pairs { @@ -151,7 +154,7 @@ pub(crate) fn query_distribution_asset(deps: Deps) -> StdResult { let fee_distributor_config: white_whale::fee_distributor::Config = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.fee_distributor.to_string(), - msg: to_binary(&white_whale::fee_distributor::QueryMsg::Config {})?, + msg: to_json_binary(&white_whale::fee_distributor::QueryMsg::Config {})?, }))?; Ok(fee_distributor_config.distribution_asset) diff --git a/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs b/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs index 5dbd012a..db210ec5 100644 --- a/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs +++ b/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, BankMsg, Coin, Response}; +use cosmwasm_std::{to_json_binary, Addr, BankMsg, Coin, Response}; use cw_multi_test::ContractWrapper; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -28,6 +28,6 @@ pub fn create_dummy_flash_loan_contract( } }, |_deps, _env, _info, _msg| Ok(Response::new()), - |_deps, _env, _query| Ok(to_binary::>(&vec![]).unwrap()), + |_deps, _env, _query| Ok(to_json_binary::>(&vec![]).unwrap()), ) } diff --git a/contracts/liquidity_hub/fee_collector/src/tests/integration.rs b/contracts/liquidity_hub/fee_collector/src/tests/integration.rs index a953f8f1..bb981213 100644 --- a/contracts/liquidity_hub/fee_collector/src/tests/integration.rs +++ b/contracts/liquidity_hub/fee_collector/src/tests/integration.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use cosmwasm_std::{ - coin, coins, to_binary, Addr, BankMsg, BlockInfo, Coin, Decimal, Timestamp, Uint128, Uint256, - Uint64, + coin, coins, to_json_binary, Addr, BankMsg, BlockInfo, Coin, Decimal, Timestamp, Uint128, + Uint256, Uint64, }; use cw20::{BalanceResponse, Cw20Coin, Cw20ExecuteMsg, MinterResponse}; use cw_multi_test::Executor; @@ -256,7 +256,7 @@ fn collect_all_factories_cw20_fees_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i as usize - 1].to_string(), amount: Uint128::new(100_000_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -273,7 +273,7 @@ fn collect_all_factories_cw20_fees_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i as usize].to_string(), amount: Uint128::new(200_000_000_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(20u64)), to: None, @@ -749,7 +749,7 @@ fn collect_cw20_fees_for_specific_contracts_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i - 1].to_string(), amount: Uint128::new(100_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(30u64)), to: None, @@ -766,7 +766,7 @@ fn collect_cw20_fees_for_specific_contracts_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i].to_string(), amount: Uint128::new(200_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(30u64)), to: None, @@ -1229,7 +1229,7 @@ fn collect_pools_native_fees_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i].to_string(), amount: Uint128::new(200_000_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -1768,7 +1768,7 @@ fn collect_fees_with_pagination_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i].to_string(), amount: Uint128::new(200_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(40u64)), to: None, @@ -2088,7 +2088,7 @@ fn collect_fees_for_vault() { vaults[i].clone(), &white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: Uint128::new(flash_loan_value), - msg: to_binary(&BankMsg::Send { + msg: to_json_binary(&BankMsg::Send { to_address: vaults[i].to_string(), // return a higher amount than the flashloan + fees amount: coins(return_flash_loan_value, coin.denom.clone()), @@ -2492,7 +2492,7 @@ fn aggregate_fees_for_vault() { vaults[i].clone(), &white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: Uint128::new(flash_loan_value), - msg: to_binary(&BankMsg::Send { + msg: to_json_binary(&BankMsg::Send { to_address: vaults[i].to_string(), // return a higher amount than the flashloan + fees amount: coins(return_flash_loan_value, coin.denom.clone()), diff --git a/contracts/liquidity_hub/fee_collector/src/tests/testing.rs b/contracts/liquidity_hub/fee_collector/src/tests/testing.rs index e1e6f204..dcfbd99d 100644 --- a/contracts/liquidity_hub/fee_collector/src/tests/testing.rs +++ b/contracts/liquidity_hub/fee_collector/src/tests/testing.rs @@ -1,5 +1,5 @@ use cosmwasm_std::testing::{mock_env, mock_info}; -use cosmwasm_std::{from_binary, Addr, DepsMut, MessageInfo, Response}; +use cosmwasm_std::{from_json, Addr, DepsMut, MessageInfo, Response}; use cw2::{get_contract_version, set_contract_version, ContractVersion}; use std::env; @@ -24,7 +24,7 @@ fn proper_initialization() { instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!("owner".to_string(), config_res.owner); } @@ -35,7 +35,7 @@ fn test_update_config_successfully() { mock_instantiation(deps.as_mut(), info.clone()).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!(config_res.owner, Addr::unchecked("owner")); let msg = ExecuteMsg::UpdateConfig { @@ -49,7 +49,7 @@ fn test_update_config_successfully() { execute(deps.as_mut(), mock_env(), info, msg).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!(config_res.owner, Addr::unchecked("new_owner")); assert_eq!(config_res.pool_router, Addr::unchecked("new_router")); } @@ -61,7 +61,7 @@ fn test_update_config_unsuccessfully_unauthorized() { mock_instantiation(deps.as_mut(), info).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!(config_res.owner, Addr::unchecked("owner")); let info = mock_info("unauthorized", &[]); diff --git a/contracts/liquidity_hub/fee_distributor/src/commands.rs b/contracts/liquidity_hub/fee_distributor/src/commands.rs index 760e37e6..8169abdc 100644 --- a/contracts/liquidity_hub/fee_distributor/src/commands.rs +++ b/contracts/liquidity_hub/fee_distributor/src/commands.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Env, MessageInfo, QueryRequest, ReplyOn, Response, StdError, - SubMsg, Timestamp, Uint64, WasmMsg, WasmQuery, + to_json_binary, CosmosMsg, DepsMut, Env, MessageInfo, QueryRequest, ReplyOn, Response, + StdError, SubMsg, Timestamp, Uint64, WasmMsg, WasmQuery, }; use white_whale::epoch_manager::epoch_manager::EpochConfig; @@ -59,7 +59,7 @@ pub fn create_new_epoch(deps: DepsMut, env: Env) -> Result Result Result Result StdResult { match msg { - QueryMsg::CurrentEpoch {} => Ok(to_binary(&state::get_current_epoch(deps)?)?), - QueryMsg::Epoch { id } => Ok(to_binary(&state::get_epoch(deps, id)?)?), - QueryMsg::ClaimableEpochs {} => Ok(to_binary(&state::get_claimable_epochs(deps)?)?), - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::Claimable { address } => Ok(to_binary(&state::query_claimable( + QueryMsg::CurrentEpoch {} => Ok(to_json_binary(&state::get_current_epoch(deps)?)?), + QueryMsg::Epoch { id } => Ok(to_json_binary(&state::get_epoch(deps, id)?)?), + QueryMsg::ClaimableEpochs {} => Ok(to_json_binary(&state::get_claimable_epochs(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::Claimable { address } => Ok(to_json_binary(&state::query_claimable( deps, &deps.api.addr_validate(&address)?, )?)?), diff --git a/contracts/liquidity_hub/fee_distributor/src/migrations.rs b/contracts/liquidity_hub/fee_distributor/src/migrations.rs index d5f12859..326b6c31 100644 --- a/contracts/liquidity_hub/fee_distributor/src/migrations.rs +++ b/contracts/liquidity_hub/fee_distributor/src/migrations.rs @@ -2,8 +2,8 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Order, QueryRequest, StdError, StdResult, Timestamp, Uint64, - WasmQuery, + to_json_binary, CosmosMsg, DepsMut, Order, QueryRequest, StdError, StdResult, Timestamp, + Uint64, WasmQuery, }; use cw_storage_plus::Map; @@ -47,7 +47,7 @@ pub fn migrate_to_v090(deps: DepsMut) -> Result<(), StdError> { // Query the current global index let global_index: GlobalIndex = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: bonding_contract_addr.to_string(), - msg: to_binary(&LairQueryMsg::GlobalIndex {})?, + msg: to_json_binary(&LairQueryMsg::GlobalIndex {})?, }))?; for epoch in epochs_v08 { diff --git a/contracts/liquidity_hub/fee_distributor/src/state.rs b/contracts/liquidity_hub/fee_distributor/src/state.rs index 930b0eee..782cff7c 100644 --- a/contracts/liquidity_hub/fee_distributor/src/state.rs +++ b/contracts/liquidity_hub/fee_distributor/src/state.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, Deps, Order, QueryRequest, StdResult, Uint64, WasmQuery}; +use cosmwasm_std::{to_json_binary, Addr, Deps, Order, QueryRequest, StdResult, Uint64, WasmQuery}; use cw_storage_plus::{Item, Map}; use white_whale::fee_distributor::{ClaimableEpochsResponse, Config, Epoch, EpochResponse}; @@ -93,7 +93,7 @@ pub fn query_claimable(deps: Deps, address: &Addr) -> StdResult(vec![ WasmMsg::Execute { contract_addr: token_contract_addr.clone(), - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.clone().into_string(), amount: token_amount, @@ -104,7 +105,7 @@ pub fn execute( }, WasmMsg::Execute { contract_addr: token_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { spender: pair_address.clone(), amount: token_amount, expires: None, @@ -131,7 +132,7 @@ pub fn execute( gas_limit: None, msg: WasmMsg::Execute { contract_addr: pair_address, - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::pair::ExecuteMsg::ProvideLiquidity { assets, slippage_tolerance, @@ -186,7 +187,7 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => Ok(to_binary(&CONFIG.load(deps.storage)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&CONFIG.load(deps.storage)?)?), } } diff --git a/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs b/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs index dc5a5cc2..77e7412f 100644 --- a/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs +++ b/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, DepsMut, Env, Reply, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, DepsMut, Env, Reply, Response, WasmMsg}; use white_whale::pool_network::{ asset::AssetInfo, frontend_helper::TempState, incentive::QueryPosition, }; @@ -75,7 +75,7 @@ pub fn deposit_pair(deps: DepsMut, env: Env, msg: Reply) -> Result Result white_whale::pool_network::incentive::ExecuteMsg::ExpandPosition { amount: lp_amount, unbonding_duration, diff --git a/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs b/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs index 2234b0a4..d9cfb155 100644 --- a/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs +++ b/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod tests { use crate::error::ContractError; - use cosmwasm_std::{coin, coins, to_binary, Addr, Uint128, WasmMsg}; + use cosmwasm_std::{coin, coins, to_json_binary, Addr, Uint128, WasmMsg}; use cw_multi_test::Executor; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::pool_network::frontend_helper::ConfigResponse; @@ -129,7 +129,7 @@ mod tests { vec![ WasmMsg::Execute { contract_addr: pool_assets[1].to_string(), - msg: to_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { spender: frontend_helper.clone().into_string(), amount: Uint128::new(5_000), expires: None, @@ -140,7 +140,7 @@ mod tests { .into(), WasmMsg::Execute { contract_addr: frontend_helper.into_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::frontend_helper::ExecuteMsg::Deposit { pair_address: pair_address.into_string(), assets: [ diff --git a/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs b/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs index c0622a54..4e663e79 100644 --- a/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs +++ b/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs @@ -1,6 +1,6 @@ use crate::tests::mock_info::mock_creator; use crate::tests::store_code::fee_distributor_mock_contract; -use cosmwasm_std::{to_binary, Addr, Decimal, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, Decimal, Uint128, WasmMsg}; use cw20::Cw20Coin; use cw_multi_test::{App, Executor}; use white_whale::{ @@ -150,7 +150,7 @@ pub fn app_mock_instantiate(app: &mut App, pool_assets: [AssetInfo; 2]) -> AppIn mock_admin().sender, WasmMsg::Execute { contract_addr: incentive_factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::incentive_factory::ExecuteMsg::CreateIncentive { lp_asset: lp_token.clone(), }, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/claim.rs b/contracts/liquidity_hub/pool-network/incentive/src/claim.rs index 9ba23587..6a510954 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/claim.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/claim.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, Decimal256, DepsMut, MessageInfo, StdError, Uint128, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal256, DepsMut, MessageInfo, StdError, Uint128, Uint256, WasmMsg, }; @@ -203,7 +203,7 @@ pub fn claim(deps: &mut DepsMut, info: &MessageInfo) -> Result, C AssetInfo::Token { contract_addr } => messages.push( WasmMsg::Execute { contract_addr: contract_addr.to_owned(), - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: address.clone().into_string(), amount: user_reward_at_epoch, })?, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/contract.rs b/contracts/liquidity_hub/pool-network/incentive/src/contract.rs index bd525433..9506d1e8 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, + to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, }; use cw2::{get_contract_version, set_contract_version}; use white_whale::pool_network::incentive::{ @@ -57,7 +57,7 @@ pub fn instantiate( ), ("lp_asset", config.lp_asset.to_string()), ]) - .set_data(to_binary( + .set_data(to_json_binary( &white_whale::pool_network::incentive::InstantiateReplyCallback { lp_asset: msg.lp_asset, }, @@ -65,7 +65,7 @@ pub fn instantiate( // takes a snapshot of the global weight at the current epoch from the start .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), - msg: to_binary(&ExecuteMsg::TakeGlobalWeightSnapshot {})?, + msg: to_json_binary(&ExecuteMsg::TakeGlobalWeightSnapshot {})?, funds: vec![], }))) } @@ -125,12 +125,12 @@ pub fn execute( #[entry_point] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Config {} => Ok(to_binary(&queries::get_config(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&queries::get_config(deps)?)?), QueryMsg::Flow { flow_identifier, start_epoch, end_epoch, - } => Ok(to_binary(&queries::get_flow( + } => Ok(to_json_binary(&queries::get_flow( deps, flow_identifier, start_epoch, @@ -139,19 +139,19 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result Ok(to_binary(&queries::get_flows( + } => Ok(to_json_binary(&queries::get_flows( deps, start_epoch, end_epoch, )?)?), - QueryMsg::Positions { address } => { - Ok(to_binary(&queries::get_positions(deps, env, address)?)?) - } - QueryMsg::Rewards { address } => Ok(to_binary(&queries::get_rewards(deps, address)?)?), - QueryMsg::GlobalWeight { epoch_id } => { - Ok(to_binary(&queries::get_global_weight(deps, epoch_id)?)?) - } - QueryMsg::CurrentEpochRewardsShare { address } => Ok(to_binary( + QueryMsg::Positions { address } => Ok(to_json_binary(&queries::get_positions( + deps, env, address, + )?)?), + QueryMsg::Rewards { address } => Ok(to_json_binary(&queries::get_rewards(deps, address)?)?), + QueryMsg::GlobalWeight { epoch_id } => Ok(to_json_binary(&queries::get_global_weight( + deps, epoch_id, + )?)?), + QueryMsg::CurrentEpochRewardsShare { address } => Ok(to_json_binary( &queries::get_rewards_share(deps, deps.api.addr_validate(&address)?)?, )?), } diff --git a/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs b/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs index 3ee09e3f..0645f6aa 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs @@ -1,5 +1,6 @@ use cosmwasm_std::{ - coins, to_binary, BankMsg, CosmosMsg, DepsMut, MessageInfo, Order, Response, StdResult, WasmMsg, + coins, to_json_binary, BankMsg, CosmosMsg, DepsMut, MessageInfo, Order, Response, StdResult, + WasmMsg, }; use white_whale::pool_network::asset::AssetInfo; @@ -52,7 +53,7 @@ pub fn close_flow( .into(), AssetInfo::Token { contract_addr } => WasmMsg::Execute { contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: flow.flow_creator.clone().into_string(), amount: amount_to_return, })?, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs b/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs index 1418fa83..1b0ec559 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Env, MessageInfo, Order, OverflowError, OverflowOperation, + to_json_binary, CosmosMsg, DepsMut, Env, MessageInfo, Order, OverflowError, OverflowOperation, Response, StdResult, Uint128, WasmMsg, }; @@ -72,7 +72,7 @@ pub fn expand_flow( messages.push( WasmMsg::Execute { contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs b/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs index b4d566f0..965e594f 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use std::collections::HashMap; use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, + to_json_binary, BankMsg, Coin, CosmosMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, WasmMsg, }; @@ -177,7 +177,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_fee_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: incentive_factory_config.fee_collector_addr.into_string(), amount: flow_fee.amount, @@ -259,7 +259,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_asset_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, @@ -288,7 +288,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_asset_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, @@ -307,7 +307,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_asset_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs b/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs index 2361e1a6..8c057268 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Deps, Env, MessageInfo, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Deps, Env, MessageInfo, Uint128, WasmMsg}; use cw_utils::PaymentError; use white_whale::pool_network::asset::AssetInfo; @@ -43,7 +43,7 @@ pub fn validate_funds_sent( // send the lp deposit to us Some(WasmMsg::Execute { contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.into_string(), recipient: env.contract.address.into_string(), amount, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs b/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs index 96bd70bd..3cc8e797 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ testing::{mock_dependencies, mock_env, MockApi, MockQuerier, MockStorage}, - to_binary, Addr, Env, OwnedDeps, Uint128, Uint64, WasmMsg, + to_json_binary, Addr, Env, OwnedDeps, Uint128, Uint64, WasmMsg, }; use cw20::Cw20Coin; use cw_multi_test::{App, Executor}; @@ -128,7 +128,7 @@ pub fn app_mock_instantiate(app: &mut App, lp_balance: Uint128) -> AppInstantiat mock_admin().sender, WasmMsg::Execute { contract_addr: incentive_factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::incentive_factory::ExecuteMsg::CreateIncentive { lp_asset: AssetInfo::Token { contract_addr: lp_addr.to_string(), diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs index e5f11bbd..3dd768ff 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, }; use cw2::{get_contract_version, set_contract_version}; use semver::Version; @@ -143,10 +143,12 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::get_config(deps)?), - QueryMsg::Incentive { lp_asset } => to_binary(&queries::get_incentive(deps, lp_asset)?), + QueryMsg::Config {} => to_json_binary(&queries::get_config(deps)?), + QueryMsg::Incentive { lp_asset } => { + to_json_binary(&queries::get_incentive(deps, lp_asset)?) + } QueryMsg::Incentives { start_after, limit } => { - to_binary(&queries::get_incentives(deps, start_after, limit)?) + to_json_binary(&queries::get_incentives(deps, start_after, limit)?) } } } diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs index 7aabbf44..4ca11e8b 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, DepsMut, Env, ReplyOn, Response, SubMsg, WasmMsg}; +use cosmwasm_std::{to_json_binary, DepsMut, Env, ReplyOn, Response, SubMsg, WasmMsg}; use white_whale::pool_network::asset::AssetInfo; use crate::{ @@ -39,7 +39,7 @@ pub fn create_incentive( msg: WasmMsg::Instantiate { admin: Some(env.contract.address.into_string()), code_id: config.incentive_code_id, - msg: to_binary(&white_whale::pool_network::incentive::InstantiateMsg { + msg: to_json_binary(&white_whale::pool_network::incentive::InstantiateMsg { lp_asset: lp_asset.clone(), fee_distributor_address: config.fee_distributor_addr.into_string(), })?, diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs index fcff7188..640681e4 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, CosmosMsg, DepsMut, Order, Response, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, DepsMut, Order, Response, StdResult, WasmMsg}; use crate::error::ContractError; use crate::state::INCENTIVE_MAPPINGS; @@ -48,7 +48,7 @@ fn migrate_incentive_msg(incentive_address: Addr, new_code_id: u64) -> StdResult Ok(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: incentive_address.to_string(), new_code_id, - msg: to_binary(&white_whale::pool_network::incentive::MigrateMsg {})?, + msg: to_json_binary(&white_whale::pool_network::incentive::MigrateMsg {})?, })) } diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs index 7ac209fa..1e6b6bd3 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs @@ -110,7 +110,7 @@ mod tests { use crate::contract::{execute, instantiate, query}; use crate::error::ContractError; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_binary, Addr, Uint128}; + use cosmwasm_std::{from_json, Addr, Uint128}; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::pool_network::incentive_factory::ExecuteMsg::UpdateConfig; use white_whale::pool_network::incentive_factory::{Config, InstantiateMsg, QueryMsg}; @@ -138,7 +138,7 @@ mod tests { instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!( config, @@ -181,7 +181,7 @@ mod tests { execute(deps.as_mut(), mock_env(), info, msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!( config, diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs index 3bac398d..bfe6f755 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs @@ -57,7 +57,7 @@ fn calc_range_start(start_after: Option) -> Option> { #[cfg(test)] mod tests { use cosmwasm_std::{ - testing::mock_dependencies, to_binary, Addr, Binary, DepsMut, Reply, SubMsgResponse, + testing::mock_dependencies, to_json_binary, Addr, Binary, DepsMut, Reply, SubMsgResponse, SubMsgResult, }; use protobuf::{Message, SpecialFields}; @@ -80,7 +80,7 @@ mod tests { data: Some(Binary::from( Message::write_to_bytes(&MsgInstantiateContractResponse { address: format!("incentive{id}"), - data: to_binary( + data: to_json_binary( &white_whale::pool_network::incentive::InstantiateReplyCallback { lp_asset: get_lp_asset(id), }, diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs index 7e34932a..1ce283a0 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{from_binary, DepsMut, Reply, Response}; +use cosmwasm_std::{from_json, DepsMut, Reply, Response}; use protobuf::Message; use crate::{ @@ -29,7 +29,7 @@ pub fn create_incentive_reply(deps: DepsMut, msg: Reply) -> Result StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Trio {} => Ok(to_binary(&queries::query_trio_info(deps)?)?), - QueryMsg::Pool {} => Ok(to_binary(&queries::query_pool(deps)?)?), + QueryMsg::Trio {} => Ok(to_json_binary(&queries::query_trio_info(deps)?)?), + QueryMsg::Pool {} => Ok(to_json_binary(&queries::query_pool(deps)?)?), QueryMsg::Simulation { offer_asset, ask_asset, - } => Ok(to_binary(&queries::query_simulation( + } => Ok(to_json_binary(&queries::query_simulation( deps, offer_asset, ask_asset, @@ -252,21 +252,21 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result Ok(to_binary(&queries::query_reverse_simulation( + } => Ok(to_json_binary(&queries::query_reverse_simulation( deps, ask_asset, offer_asset, env.block.height, )?)?), - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_binary(&queries::query_fees( + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, all_time, COLLECTED_PROTOCOL_FEES, Some(ALL_TIME_COLLECTED_PROTOCOL_FEES), )?)?), - QueryMsg::BurnedFees { asset_id } => Ok(to_binary(&queries::query_fees( + QueryMsg::BurnedFees { asset_id } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, None, diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs index 8afe24ce..162c9217 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, Decimal, Decimal256, Deps, DepsMut, Env, ReplyOn, Response, StdError, StdResult, - Storage, SubMsg, Uint128, Uint256, WasmMsg, + to_json_binary, Decimal, Decimal256, Deps, DepsMut, Env, ReplyOn, Response, StdError, + StdResult, Storage, SubMsg, Uint128, Uint256, WasmMsg, }; use cw20::MinterResponse; use cw_storage_plus::Item; @@ -288,7 +288,7 @@ pub fn create_lp_token( msg: WasmMsg::Instantiate { admin: None, code_id: msg.token_code_id, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: lp_token_name.to_owned(), symbol: "uLP".to_string(), decimals: 6, diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs index a7702104..674cc9c7 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs @@ -1,7 +1,7 @@ use crate::contract::{execute, instantiate}; use crate::error::ContractError; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; -use cosmwasm_std::{to_binary, Coin, Decimal, Uint128}; +use cosmwasm_std::{to_json_binary, Coin, Decimal, Uint128}; use cw20::Cw20ReceiveMsg; use white_whale::fee::Fee; use white_whale::pool_network::asset::{Asset, AssetInfo}; @@ -111,7 +111,7 @@ fn test_feature_toggle_swap_disabled() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::Token { contract_addr: "asset0000".to_string(), }, @@ -205,7 +205,7 @@ fn test_feature_toggle_withdrawals_disabled() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs index 1cc572d3..efdfb6d1 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs @@ -3,7 +3,7 @@ use crate::queries::query_fees; use crate::state::{ALL_TIME_COLLECTED_PROTOCOL_FEES, COLLECTED_PROTOCOL_FEES}; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -319,7 +319,7 @@ fn test_collect_protocol_fees_successful() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "asset0001".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::NativeToken { denom: "uusd".to_string(), }, @@ -369,7 +369,7 @@ fn test_collect_protocol_fees_successful() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "asset0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::Token { contract_addr: "asset0001".to_string(), }, @@ -426,7 +426,7 @@ fn test_collect_protocol_fees_successful() { transfer_asset0000_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees_for_asset0000.clone().first().unwrap().amount, }) @@ -438,7 +438,7 @@ fn test_collect_protocol_fees_successful() { transfer_asset0001_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0001".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees_for_asset0001.clone().first().unwrap().amount, }) @@ -642,7 +642,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() { transfer_cw20_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees[1].amount, }) diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs index f7a64d3c..3bacf2de 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs @@ -6,7 +6,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; #[cfg(feature = "token_factory")] use cosmwasm_std::{coin, BankMsg}; use cosmwasm_std::{ - to_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, + to_json_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -169,7 +169,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(2_000u128), @@ -182,7 +182,7 @@ fn provide_liquidity_cw20_lp() { mint_initial_lp_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "cosmos2contract".to_string(), amount: MINIMUM_LIQUIDITY_AMOUNT * Uint128::from(3u8), }) @@ -194,7 +194,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "addr0000".to_string(), amount: Uint128::from(3_000u128), }) @@ -274,7 +274,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(100u128), @@ -287,7 +287,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "staking0000".to_string(), // LP tokens sent to specified receiver amount: Uint128::from(57u128), }) diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs index d674f55d..bf4ffe66 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs @@ -8,8 +8,8 @@ use crate::state::{ }; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, coins, from_binary, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, SubMsg, - SubMsgResponse, SubMsgResult, Uint128, WasmMsg, + attr, coins, from_json, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, + SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use white_whale::fee::Fee; @@ -173,7 +173,7 @@ fn try_native_to_token() { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: expected_burn_fee_amount, }) .unwrap(), @@ -269,7 +269,7 @@ fn try_native_to_token() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -322,7 +322,7 @@ fn try_native_to_token() { ) .unwrap(); - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -397,7 +397,7 @@ fn try_native_to_token() { assert_eq!( &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_return_amount, }) @@ -626,7 +626,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::NativeToken { denom: "uusd".to_string(), }, @@ -735,7 +735,7 @@ fn try_token_to_native() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -789,7 +789,7 @@ fn try_token_to_native() { .unwrap(); // check reverse simulation res - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -876,7 +876,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::Token { contract_addr: "asset0000".to_string(), }, @@ -1029,7 +1029,7 @@ fn test_swap_to_third_party() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs index 6b718104..2c1be7b6 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs @@ -1,6 +1,6 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, to_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, + from_json, to_json_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::MinterResponse; @@ -78,7 +78,7 @@ fn proper_initialization_cw20_lp() { vec![SubMsg { msg: WasmMsg::Instantiate { code_id: 10u64, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: "uusd-mAAPL-mAAPL-LP".to_string(), symbol: "uLP".to_string(), decimals: 6, @@ -753,7 +753,7 @@ fn test_update_config_successful() { instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for original config assert_eq!(config.owner, Addr::unchecked("addr0000")); @@ -781,7 +781,7 @@ fn test_update_config_successful() { execute(deps.as_mut(), env, info, update_config_message).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for new config assert_eq!(config.owner, Addr::unchecked("new_admin")); diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs index 1dce1b4d..2d0d6d15 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs @@ -7,7 +7,7 @@ use crate::state::{get_fees_for_asset, store_fee, COLLECTED_PROTOCOL_FEES}; use cosmwasm_std::coin; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, SubMsg, SubMsgResponse, + attr, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -110,7 +110,7 @@ fn withdraw_liquidity_cw20_lp() { // withdraw liquidity let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -167,7 +167,7 @@ fn withdraw_liquidity_cw20_lp() { msg_refund_1, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_1_refund_amount, }) @@ -179,7 +179,7 @@ fn withdraw_liquidity_cw20_lp() { msg_refund_2, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0001".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_2_refund_amount, }) @@ -191,7 +191,7 @@ fn withdraw_liquidity_cw20_lp() { msg_burn_liquidity, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(100u128), }) .unwrap(), @@ -475,7 +475,7 @@ fn test_withdrawal_unauthorized() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -548,7 +548,7 @@ fn test_withdrawal_wrong_message() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&"invalid_message").unwrap(), + msg: to_json_binary(&"invalid_message").unwrap(), amount: Uint128::from(100u128), }); diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/schema/raw/execute.json b/contracts/liquidity_hub/pool-network/terraswap_factory/schema/raw/execute.json index 82556518..ead0b5fe 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/schema/raw/execute.json +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/schema/raw/execute.json @@ -134,7 +134,7 @@ "feature_toggle": { "anyOf": [ { - "$ref": "#/definitions/FeatureToggle" + "$ref": "#/definitions/FeatureToggle2" }, { "type": "null" @@ -156,7 +156,7 @@ "pool_fees": { "anyOf": [ { - "$ref": "#/definitions/PoolFee" + "$ref": "#/definitions/PoolFee2" }, { "type": "null" @@ -249,7 +249,7 @@ "minItems": 3 }, "pool_fees": { - "$ref": "#/definitions/PoolFee" + "$ref": "#/definitions/PoolFee2" }, "token_factory_lp": { "description": "If true, the pair will use the token factory to create the LP token. If false, it will use a cw20 token instead.", @@ -477,6 +477,27 @@ }, "additionalProperties": false }, + "FeatureToggle2": { + "description": "Pool feature toggle", + "type": "object", + "required": [ + "deposits_enabled", + "swaps_enabled", + "withdrawals_enabled" + ], + "properties": { + "deposits_enabled": { + "type": "boolean" + }, + "swaps_enabled": { + "type": "boolean" + }, + "withdrawals_enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, "Fee": { "type": "object", "required": [ @@ -544,6 +565,27 @@ }, "additionalProperties": false }, + "PoolFee2": { + "description": "Fees used by the pools on the pool network", + "type": "object", + "required": [ + "burn_fee", + "protocol_fee", + "swap_fee" + ], + "properties": { + "burn_fee": { + "$ref": "#/definitions/Fee" + }, + "protocol_fee": { + "$ref": "#/definitions/Fee" + }, + "swap_fee": { + "$ref": "#/definitions/Fee" + } + }, + "additionalProperties": false + }, "RampAmp": { "type": "object", "required": [ diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/schema/terraswap-factory.json b/contracts/liquidity_hub/pool-network/terraswap_factory/schema/terraswap-factory.json index 776947a3..96fc8c4e 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/schema/terraswap-factory.json +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/schema/terraswap-factory.json @@ -172,7 +172,7 @@ "feature_toggle": { "anyOf": [ { - "$ref": "#/definitions/FeatureToggle" + "$ref": "#/definitions/FeatureToggle2" }, { "type": "null" @@ -194,7 +194,7 @@ "pool_fees": { "anyOf": [ { - "$ref": "#/definitions/PoolFee" + "$ref": "#/definitions/PoolFee2" }, { "type": "null" @@ -287,7 +287,7 @@ "minItems": 3 }, "pool_fees": { - "$ref": "#/definitions/PoolFee" + "$ref": "#/definitions/PoolFee2" }, "token_factory_lp": { "description": "If true, the pair will use the token factory to create the LP token. If false, it will use a cw20 token instead.", @@ -515,6 +515,27 @@ }, "additionalProperties": false }, + "FeatureToggle2": { + "description": "Pool feature toggle", + "type": "object", + "required": [ + "deposits_enabled", + "swaps_enabled", + "withdrawals_enabled" + ], + "properties": { + "deposits_enabled": { + "type": "boolean" + }, + "swaps_enabled": { + "type": "boolean" + }, + "withdrawals_enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, "Fee": { "type": "object", "required": [ @@ -582,6 +603,27 @@ }, "additionalProperties": false }, + "PoolFee2": { + "description": "Fees used by the pools on the pool network", + "type": "object", + "required": [ + "burn_fee", + "protocol_fee", + "swap_fee" + ], + "properties": { + "burn_fee": { + "$ref": "#/definitions/Fee" + }, + "protocol_fee": { + "$ref": "#/definitions/Fee" + }, + "swap_fee": { + "$ref": "#/definitions/Fee" + } + }, + "additionalProperties": false + }, "RampAmp": { "type": "object", "required": [ diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs index 28c82951..1343baf6 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs @@ -1,7 +1,7 @@ use crate::contract::{CREATE_PAIR_RESPONSE, CREATE_TRIO_RESPONSE}; use cosmwasm_std::{ - to_binary, wasm_execute, CosmosMsg, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, + to_json_binary, wasm_execute, CosmosMsg, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, WasmMsg, }; @@ -163,7 +163,7 @@ pub fn create_pair( funds: info.funds, admin: Some(env.contract.address.to_string()), label: pair_label, - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos, token_code_id: config.token_code_id, asset_decimals, @@ -295,7 +295,7 @@ pub fn create_trio( funds: info.funds, admin: Some(env.contract.address.to_string()), label: trio_label, - msg: to_binary(&TrioInstantiateMsg { + msg: to_json_binary(&TrioInstantiateMsg { asset_infos, token_code_id: config.token_code_id, asset_decimals, @@ -408,7 +408,7 @@ pub fn execute_migrate_pair( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: contract, new_code_id: pair_code_id, - msg: to_binary(&PairMigrateMsg {})?, + msg: to_json_binary(&PairMigrateMsg {})?, })), ) } @@ -434,7 +434,7 @@ pub fn execute_migrate_trio( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: contract, new_code_id: trio_code_id, - msg: to_binary(&TrioMigrateMsg {})?, + msg: to_json_binary(&TrioMigrateMsg {})?, })), ) } diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs index 04c0aa8d..f4a9b2d8 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, }; use cw2::{get_contract_version, set_contract_version}; use protobuf::Message; @@ -224,17 +224,17 @@ fn create_trio_reply(deps: DepsMut, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::query_config(deps)?), - QueryMsg::Pair { asset_infos } => to_binary(&queries::query_pair(deps, asset_infos)?), + QueryMsg::Config {} => to_json_binary(&queries::query_config(deps)?), + QueryMsg::Pair { asset_infos } => to_json_binary(&queries::query_pair(deps, asset_infos)?), QueryMsg::Pairs { start_after, limit } => { - to_binary(&queries::query_pairs(deps, start_after, limit)?) + to_json_binary(&queries::query_pairs(deps, start_after, limit)?) } - QueryMsg::Trio { asset_infos } => to_binary(&queries::query_trio(deps, asset_infos)?), + QueryMsg::Trio { asset_infos } => to_json_binary(&queries::query_trio(deps, asset_infos)?), QueryMsg::Trios { start_after, limit } => { - to_binary(&queries::query_trios(deps, start_after, limit)?) + to_json_binary(&queries::query_trios(deps, start_after, limit)?) } QueryMsg::NativeTokenDecimals { denom } => { - to_binary(&queries::query_native_token_decimal(deps, denom)?) + to_json_binary(&queries::query_native_token_decimal(deps, denom)?) } } } diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs index 3aeeb81c..f9b32fc1 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs @@ -2,7 +2,7 @@ use cosmwasm_std::testing::{ mock_dependencies_with_balance, mock_env, mock_info, MockApi, MockStorage, MOCK_CONTRACT_ADDR, }; use cosmwasm_std::{ - attr, coin, from_binary, to_binary, Api, CanonicalAddr, Coin, CosmosMsg, Decimal, OwnedDeps, + attr, coin, from_json, to_json_binary, Api, CanonicalAddr, Coin, CosmosMsg, Decimal, OwnedDeps, Reply, ReplyOn, Response, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; @@ -45,7 +45,7 @@ fn proper_initialization() { let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: ConfigResponse = from_binary(&query_res).unwrap(); + let config_res: ConfigResponse = from_json(&query_res).unwrap(); assert_eq!(123u64, config_res.token_code_id); assert_eq!(321u64, config_res.pair_code_id); assert_eq!("addr0000".to_string(), config_res.owner); @@ -106,7 +106,7 @@ fn update_config() { // it worked, let's query the state let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: ConfigResponse = from_binary(&query_res).unwrap(); + let config_res: ConfigResponse = from_json(&query_res).unwrap(); assert_eq!(123u64, config_res.token_code_id); assert_eq!(321u64, config_res.pair_code_id); assert_eq!("addr0001".to_string(), config_res.owner); @@ -128,7 +128,7 @@ fn update_config() { // it worked, let's query the state let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: ConfigResponse = from_binary(&query_res).unwrap(); + let config_res: ConfigResponse = from_json(&query_res).unwrap(); assert_eq!(200u64, config_res.token_code_id); assert_eq!(100u64, config_res.pair_code_id); assert_eq!(300u64, config_res.trio_code_id); @@ -256,7 +256,7 @@ fn create_pair() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 8u8], @@ -356,7 +356,7 @@ fn create_stableswap_pair() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 8u8], @@ -468,7 +468,7 @@ fn create_pair_native_token_and_ibc_token() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 6u8], @@ -587,7 +587,7 @@ fn create_ibc_tokens_pair() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 6u8], @@ -706,7 +706,7 @@ fn create_pair_ethereum_asset_and_ibc_token() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 6u8], @@ -1172,7 +1172,7 @@ fn reply_test() { ) .unwrap(); - let pair_res: PairInfo = from_binary(&query_res).unwrap(); + let pair_res: PairInfo = from_json(&query_res).unwrap(); assert_eq!( pair_res, PairInfo { @@ -1216,7 +1216,7 @@ fn normal_add_allow_native_token() { }, ) .unwrap(); - let res: NativeTokenDecimalsResponse = from_binary(&res).unwrap(); + let res: NativeTokenDecimalsResponse = from_json(&res).unwrap(); assert_eq!(6u8, res.decimals) } @@ -1283,7 +1283,7 @@ fn append_add_allow_native_token_with_already_exist_token() { }, ) .unwrap(); - let res: NativeTokenDecimalsResponse = from_binary(&res).unwrap(); + let res: NativeTokenDecimalsResponse = from_json(&res).unwrap(); assert_eq!(6u8, res.decimals); let msg = ExecuteMsg::AddNativeTokenDecimals { @@ -1301,7 +1301,7 @@ fn append_add_allow_native_token_with_already_exist_token() { }, ) .unwrap(); - let res: NativeTokenDecimalsResponse = from_binary(&res).unwrap(); + let res: NativeTokenDecimalsResponse = from_json(&res).unwrap(); assert_eq!(7u8, res.decimals) } @@ -1397,7 +1397,7 @@ fn normal_migrate_pair() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 123u64, - msg: to_binary(&PairMigrateMsg {}).unwrap(), + msg: to_json_binary(&PairMigrateMsg {}).unwrap(), })), ); } @@ -1419,7 +1419,7 @@ fn normal_migrate_trio() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 123u64, - msg: to_binary(&TrioMigrateMsg {}).unwrap(), + msg: to_json_binary(&TrioMigrateMsg {}).unwrap(), })), ); } @@ -1441,7 +1441,7 @@ fn normal_migrate_pair_with_none_code_id_will_config_code_id() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 321u64, - msg: to_binary(&PairMigrateMsg {}).unwrap(), + msg: to_json_binary(&PairMigrateMsg {}).unwrap(), })), ); } @@ -1463,7 +1463,7 @@ fn normal_migrate_trio_with_none_code_id_will_config_code_id() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 456u64, - msg: to_binary(&TrioMigrateMsg {}).unwrap(), + msg: to_json_binary(&TrioMigrateMsg {}).unwrap(), })), ); } @@ -1629,7 +1629,7 @@ fn update_pair_config() { .add_message(WasmMsg::Execute { contract_addr: "pair_addr".to_string(), funds: vec![], - msg: to_binary(&pool_network::pair::ExecuteMsg::UpdateConfig { + msg: to_json_binary(&pool_network::pair::ExecuteMsg::UpdateConfig { owner: Some("new_owner".to_string()), fee_collector_addr: None, pool_fees: Some(PoolFee { @@ -1713,7 +1713,7 @@ fn create_trio_cw20_lp() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&TrioInstantiateMsg { + msg: to_json_binary(&TrioInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 8u8, 10u8], @@ -1842,7 +1842,7 @@ fn create_trio_with_native_tokens_token_factory_lp() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&TrioInstantiateMsg { + msg: to_json_binary(&TrioInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 6u8, 6u8], diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs index b6753f98..e05486f8 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - from_binary, to_binary, Addr, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, OverflowError, + from_json, to_json_binary, Addr, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, OverflowError, Response, StdError, StdResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -49,7 +49,7 @@ pub fn receive_cw20( let contract_addr = info.sender.clone(); let feature_toggle: FeatureToggle = CONFIG.load(deps.storage)?.feature_toggle; - match from_binary(&cw20_msg.msg) { + match from_json(&cw20_msg.msg) { Ok(Cw20HookMsg::Swap { belief_price, max_spread, @@ -171,7 +171,7 @@ pub fn provide_liquidity( if let AssetInfo::Token { contract_addr, .. } = &pool.info { messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: info.sender.to_string(), recipient: env.contract.address.to_string(), amount: deposits[i], @@ -613,7 +613,7 @@ fn mint_lp_token_msg( } else { Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -625,7 +625,7 @@ fn mint_lp_token_msg( ))] Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -653,7 +653,7 @@ fn burn_lp_token_msg( } else { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } @@ -664,7 +664,7 @@ fn burn_lp_token_msg( ))] Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs index 25145ae5..164553d6 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, + to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, }; use cw2::{get_contract_version, set_contract_version}; @@ -203,23 +203,24 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Pair {} => Ok(to_binary(&queries::query_pair_info(deps)?)?), - QueryMsg::Pool {} => Ok(to_binary(&queries::query_pool(deps)?)?), - QueryMsg::Simulation { offer_asset } => { - Ok(to_binary(&queries::query_simulation(deps, offer_asset)?)?) - } - QueryMsg::ReverseSimulation { ask_asset } => Ok(to_binary( + QueryMsg::Pair {} => Ok(to_json_binary(&queries::query_pair_info(deps)?)?), + QueryMsg::Pool {} => Ok(to_json_binary(&queries::query_pool(deps)?)?), + QueryMsg::Simulation { offer_asset } => Ok(to_json_binary(&queries::query_simulation( + deps, + offer_asset, + )?)?), + QueryMsg::ReverseSimulation { ask_asset } => Ok(to_json_binary( &queries::query_reverse_simulation(deps, ask_asset)?, )?), - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_binary(&queries::query_fees( + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, all_time, COLLECTED_PROTOCOL_FEES, Some(ALL_TIME_COLLECTED_PROTOCOL_FEES), )?)?), - QueryMsg::BurnedFees { asset_id } => Ok(to_binary(&queries::query_fees( + QueryMsg::BurnedFees { asset_id } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, None, diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/helpers.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/helpers.rs index ff915152..80003620 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/helpers.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/helpers.rs @@ -8,8 +8,8 @@ use cosmwasm_schema::cw_serde; ))] use cosmwasm_std::CosmosMsg; use cosmwasm_std::{ - to_binary, Decimal, Decimal256, DepsMut, Env, ReplyOn, Response, StdError, StdResult, Storage, - SubMsg, Uint128, Uint256, WasmMsg, + to_json_binary, Decimal, Decimal256, DepsMut, Env, ReplyOn, Response, StdError, StdResult, + Storage, SubMsg, Uint128, Uint256, WasmMsg, }; use cw20::MinterResponse; use cw_storage_plus::Item; @@ -454,7 +454,7 @@ pub fn create_lp_token( msg: WasmMsg::Instantiate { admin: None, code_id: msg.token_code_id, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: lp_token_name.to_owned(), symbol: LP_SYMBOL.to_string(), decimals: 6, diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs index 117b7352..78056481 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs @@ -1,7 +1,7 @@ use crate::contract::{execute, instantiate}; use crate::error::ContractError; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; -use cosmwasm_std::{to_binary, Coin, Decimal, Uint128}; +use cosmwasm_std::{to_json_binary, Coin, Decimal, Uint128}; use cw20::Cw20ReceiveMsg; use white_whale::fee::Fee; use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; @@ -103,7 +103,7 @@ fn test_feature_toggle_swap_disabled() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -183,7 +183,7 @@ fn test_feature_toggle_withdrawals_disabled() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs index a979de45..242c7711 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs @@ -3,7 +3,7 @@ use crate::queries::query_fees; use crate::state::{ALL_TIME_COLLECTED_PROTOCOL_FEES, COLLECTED_PROTOCOL_FEES}; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -299,7 +299,7 @@ fn test_collect_protocol_fees_successful() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -366,7 +366,7 @@ fn test_collect_protocol_fees_successful() { transfer_cw20_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees_for_token.first().unwrap().amount, }) @@ -548,7 +548,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() { transfer_cw20_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees[1].amount, }) diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs index 1d54b0f1..6102c0e8 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs @@ -2,7 +2,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; #[cfg(feature = "token_factory")] use cosmwasm_std::{coin, BankMsg}; use cosmwasm_std::{ - to_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, + to_json_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -166,7 +166,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(2_000u128), @@ -179,7 +179,7 @@ fn provide_liquidity_cw20_lp() { mint_initial_lp_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "cosmos2contract".to_string(), amount: MINIMUM_LIQUIDITY_AMOUNT, }) @@ -191,7 +191,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "addr0000".to_string(), amount: Uint128::from(1_000u128), }) @@ -261,7 +261,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(100u128), @@ -274,7 +274,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "staking0000".to_string(), // LP tokens sent to specified receiver amount: Uint128::from(50u128), }) diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs index 4fa0a0ef..c993e75d 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs @@ -7,8 +7,8 @@ use crate::state::{ }; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, coins, from_binary, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, SubMsg, - SubMsgResponse, SubMsgResult, Uint128, WasmMsg, + attr, coins, from_json, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, + SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use white_whale::fee::Fee; @@ -172,7 +172,7 @@ fn try_native_to_token() { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: expected_burn_fee_amount, }) .unwrap(), @@ -268,7 +268,7 @@ fn try_native_to_token() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -315,7 +315,7 @@ fn try_native_to_token() { ) .unwrap(); - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -385,7 +385,7 @@ fn try_native_to_token() { assert_eq!( &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_return_amount, }) @@ -595,7 +595,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(5u64)), to: Some("third_party".to_string()), @@ -700,7 +700,7 @@ fn try_token_to_native() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -748,7 +748,7 @@ fn try_token_to_native() { .unwrap(); // check reverse simulation res - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -830,7 +830,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -970,7 +970,7 @@ fn test_swap_to_third_party() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1048,7 +1048,7 @@ fn stableswap_reverse_simulation() { .unwrap(); // check reverse simulation res - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1242,7 +1242,7 @@ fn stableswap_with_different_precisions() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1289,7 +1289,7 @@ fn stableswap_with_different_precisions() { ) .unwrap(); - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1341,7 +1341,7 @@ fn stableswap_with_different_precisions() { assert_eq!( &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_return_amount, }) diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs index 4105cb3d..2a36bf22 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs @@ -2,7 +2,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; #[cfg(feature = "token_factory")] use cosmwasm_std::CosmosMsg; use cosmwasm_std::{ - from_binary, to_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, + from_json, to_json_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::MinterResponse; @@ -69,7 +69,7 @@ fn proper_initialization_cw20_lp() { vec![SubMsg { msg: WasmMsg::Instantiate { code_id: 10u64, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: "uusd-mAAPL-LP".to_string(), symbol: "uLP".to_string(), decimals: 6, @@ -614,7 +614,7 @@ fn test_update_config_successful() { instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for original config assert_eq!(config.owner, Addr::unchecked("addr0000")); @@ -641,7 +641,7 @@ fn test_update_config_successful() { execute(deps.as_mut(), env, info, update_config_message).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for new config assert_eq!(config.owner, Addr::unchecked("new_admin")); diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs index b6c785bd..e8b25c76 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs @@ -1,7 +1,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, Response, SubMsg, SubMsgResponse, - SubMsgResult, Uint128, WasmMsg, + attr, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, Response, SubMsg, + SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -107,7 +107,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { // withdraw liquidity let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -154,7 +154,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { msg_refund_1, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_refund_amount, }) @@ -166,7 +166,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { msg_burn_liquidity, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(100u128), }) .unwrap(), @@ -267,7 +267,7 @@ fn withdraw_stableswap_liquidity() { // withdraw liquidity let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -308,7 +308,7 @@ fn withdraw_stableswap_liquidity() { }), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_refund_amount, }) @@ -317,7 +317,7 @@ fn withdraw_stableswap_liquidity() { }), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(100u128), }) .unwrap(), @@ -385,7 +385,7 @@ fn test_withdrawal_unauthorized() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -451,7 +451,7 @@ fn test_withdrawal_wrong_message() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&"invalid_message").unwrap(), + msg: to_json_binary(&"invalid_message").unwrap(), amount: Uint128::from(100u128), }); diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs b/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs index 27724aaf..353a25c1 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, from_binary, to_binary, Addr, Api, Binary, CosmosMsg, Decimal, Deps, DepsMut, Env, + attr, from_json, to_json_binary, Addr, Api, Binary, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, WasmMsg, }; use cw2::{get_contract_version, set_contract_version}; @@ -125,7 +125,7 @@ pub fn receive_cw20( cw20_msg: Cw20ReceiveMsg, ) -> Result { let sender = deps.api.addr_validate(&cw20_msg.sender)?; - match from_binary(&cw20_msg.msg)? { + match from_json(&cw20_msg.msg)? { Cw20HookMsg::ExecuteSwapOperations { operations, minimum_receive, @@ -177,7 +177,7 @@ pub fn execute_swap_operations( Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: op, to: if operation_index == operations_len { Some(to.to_string()) @@ -192,12 +192,13 @@ pub fn execute_swap_operations( // Execute minimum amount assertion if let Some(minimum_receive) = minimum_receive { - let receiver_balance = target_asset_info.query_pool(&deps.querier, deps.api, to.clone())?; + let receiver_balance = + target_asset_info.query_balance(&deps.querier, deps.api, to.clone())?; messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AssertMinimumReceive { + msg: to_json_binary(&ExecuteMsg::AssertMinimumReceive { asset_info: target_asset_info, prev_balance: receiver_balance, minimum_receive, @@ -216,7 +217,7 @@ fn assert_minimum_receive( minimum_receive: Uint128, receiver: Addr, ) -> Result { - let receiver_balance = asset_info.query_pool(&deps.querier, deps.api, receiver)?; + let receiver_balance = asset_info.query_balance(&deps.querier, deps.api, receiver)?; let swap_amount = receiver_balance.checked_sub(prev_balance)?; if swap_amount < minimum_receive { @@ -279,11 +280,11 @@ fn add_swap_routes( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Config {} => Ok(to_binary(&query_config(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&query_config(deps)?)?), QueryMsg::SimulateSwapOperations { offer_amount, operations, - } => Ok(to_binary(&simulate_swap_operations( + } => Ok(to_json_binary(&simulate_swap_operations( deps, offer_amount, operations, @@ -291,18 +292,18 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Ok(to_binary(&reverse_simulate_swap_operations( + } => Ok(to_json_binary(&reverse_simulate_swap_operations( deps, ask_amount, operations, )?)?), QueryMsg::SwapRoute { offer_asset_info, ask_asset_info, - } => Ok(to_binary(&get_swap_route( + } => Ok(to_json_binary(&get_swap_route( deps, offer_asset_info, ask_asset_info, )?)?), - QueryMsg::SwapRoutes {} => Ok(to_binary(&get_swap_routes(deps)?)?), + QueryMsg::SwapRoutes {} => Ok(to_json_binary(&get_swap_routes(deps)?)?), } } diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs b/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs index 804b8df0..dd96e810 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs @@ -1,5 +1,6 @@ use cosmwasm_std::{ - to_binary, Addr, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Response, WasmMsg, + to_json_binary, Addr, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Response, + WasmMsg, }; use crate::state::{Config, CONFIG}; @@ -81,7 +82,7 @@ pub fn asset_into_swap_msg( denom, amount: offer_asset.amount, }], - msg: to_binary(&PairExecuteMsg::Swap { + msg: to_json_binary(&PairExecuteMsg::Swap { offer_asset, belief_price: None, max_spread, @@ -91,10 +92,10 @@ pub fn asset_into_swap_msg( AssetInfo::Token { contract_addr } => Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: pair_contract.to_string(), amount: offer_asset.amount, - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread, to, diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs b/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs index 8222d7eb..ab1e0986 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs @@ -1,6 +1,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, coin, from_binary, to_binary, Addr, Coin, CosmosMsg, StdError, SubMsg, Uint128, WasmMsg, + attr, coin, from_json, to_json_binary, Addr, Coin, CosmosMsg, StdError, SubMsg, Uint128, + WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use white_whale::pool_network; @@ -33,7 +34,7 @@ fn proper_initialization() { // it worked, let's query the state let config: ConfigResponse = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!("terraswapfactory", config.terraswap_factory.as_str()); } @@ -111,7 +112,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "ukrw".to_string(), @@ -128,7 +129,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0001".to_string(), @@ -145,7 +146,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -162,7 +163,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AssertMinimumReceive { + msg: to_json_binary(&ExecuteMsg::AssertMinimumReceive { asset_info: AssetInfo::Token { contract_addr: "asset0002".to_string(), }, @@ -178,7 +179,7 @@ fn execute_swap_operations() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: Uint128::from(1000000u128), - msg: to_binary(&Cw20HookMsg::ExecuteSwapOperations { + msg: to_json_binary(&Cw20HookMsg::ExecuteSwapOperations { operations: vec![ SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { @@ -220,7 +221,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "ukrw".to_string(), @@ -237,7 +238,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0001".to_string(), @@ -254,7 +255,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -436,10 +437,10 @@ fn execute_swap_operation() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: "pair0000".to_string(), amount: Uint128::from(1000000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: Some("addr0000".to_string()), @@ -544,7 +545,7 @@ fn query_buy_with_routes() { ); let res: SimulateSwapOperationsResponse = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!( res, SimulateSwapOperationsResponse { @@ -652,7 +653,7 @@ fn query_reverse_routes_with_from_native() { ); let res: SimulateSwapOperationsResponse = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!( res, @@ -690,7 +691,7 @@ fn query_reverse_routes_with_from_native() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "pair0000".to_string(), funds: vec![coin(target_amount, "ukrw")], - msg: to_binary(&PairExecuteMsg::Swap { + msg: to_json_binary(&PairExecuteMsg::Swap { offer_asset: Asset { info: AssetInfo::NativeToken { denom: "ukrw".to_string(), @@ -789,7 +790,7 @@ fn query_reverse_routes_with_to_native() { ); let res: SimulateSwapOperationsResponse = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!( res, @@ -803,7 +804,7 @@ fn query_reverse_routes_with_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::ExecuteSwapOperations { + msg: to_json_binary(&Cw20HookMsg::ExecuteSwapOperations { operations: vec![SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0000".to_string(), @@ -826,7 +827,7 @@ fn query_reverse_routes_with_to_native() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0000".to_string(), @@ -863,10 +864,10 @@ fn query_reverse_routes_with_to_native() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: "pair0000".to_string(), amount: Uint128::from(target_amount), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -1183,7 +1184,7 @@ fn add_swap_routes() { }; let res: Vec = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!(res, swap_route_1.swap_operations); } @@ -1569,7 +1570,7 @@ fn all_swap_routes() { let msg = QueryMsg::SwapRoutes {}; let res: Vec = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!(res.len(), 2usize); // Verify it has the correct swap routes assert_eq!(res[0].swap_route, swap_route_1.swap_operations); diff --git a/contracts/liquidity_hub/vault-manager/.cargo/config b/contracts/liquidity_hub/vault-manager/.cargo/config new file mode 100644 index 00000000..21608f3c --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin vault_manager_schema" diff --git a/contracts/liquidity_hub/vault-manager/.editorconfig b/contracts/liquidity_hub/vault-manager/.editorconfig new file mode 100644 index 00000000..3d36f20b --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.rs] +indent_size = 4 diff --git a/contracts/liquidity_hub/vault-manager/.gitignore b/contracts/liquidity_hub/vault-manager/.gitignore new file mode 100644 index 00000000..9095deaa --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/.gitignore @@ -0,0 +1,16 @@ +# Build results +/target +/schema + +# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) +.cargo-ok + +# Text file backups +**/*.rs.bk + +# macOS +.DS_Store + +# IDEs +*.iml +.idea diff --git a/contracts/liquidity_hub/vault-manager/Cargo.toml b/contracts/liquidity_hub/vault-manager/Cargo.toml new file mode 100644 index 00000000..e8f249fa --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "vault-manager" +version = "0.1.0" +authors = ["Kerber0x "] +edition.workspace = true +description = "The Vault Manager is a contract that allows to manage multiple vaults in a single contract, offerish flashloan capabilities with held assets." +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +publish.workspace = true + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +injective = ["white-whale/injective"] +token_factory = ["white-whale/token_factory"] +osmosis_token_factory = ["white-whale/osmosis_token_factory"] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] + +[dependencies] +cosmwasm-schema.workspace = true +cosmwasm-std.workspace = true +cw-storage-plus.workspace = true +cw2.workspace = true +cw20.workspace = true +cw20-base.workspace = true +schemars.workspace = true +semver.workspace = true +serde.workspace = true +thiserror.workspace = true +white-whale.workspace = true +cw-utils.workspace = true +cw-ownable.workspace = true +sha2.workspace = true + +[dev-dependencies] +cw-multi-test.workspace = true +whale-lair.workspace = true +terraswap-token.workspace = true +terraswap-pair.workspace = true +fee_collector.workspace = true +anyhow.workspace = true diff --git a/contracts/liquidity_hub/vault-manager/README.md b/contracts/liquidity_hub/vault-manager/README.md new file mode 100644 index 00000000..054ea481 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/README.md @@ -0,0 +1,99 @@ +# CosmWasm Starter Pack + +This is a template to build smart contracts in Rust to run inside a +[Cosmos SDK](https://github.com/cosmos/cosmos-sdk) module on all chains that enable it. +To understand the framework better, please read the overview in the +[cosmwasm repo](https://github.com/CosmWasm/cosmwasm/blob/master/README.md), +and dig into the [cosmwasm docs](https://www.cosmwasm.com). +This assumes you understand the theory and just want to get coding. + +## Creating a new repo from template + +Assuming you have a recent version of Rust and Cargo installed +(via [rustup](https://rustup.rs/)), +then the following should get you a new repo to start a contract: + +Install [cargo-generate](https://github.com/ashleygwilliams/cargo-generate) and cargo-run-script. +Unless you did that before, run this line now: + +```sh +cargo install cargo-generate --features vendored-openssl +cargo install cargo-run-script +``` + +Now, use it to create your new contract. +Go to the folder in which you want to place it and run: + +**Latest** + +```sh +cargo generate --git https://github.com/CosmWasm/cw-template.git --name PROJECT_NAME +``` + +For cloning minimal code repo: + +```sh +cargo generate --git https://github.com/CosmWasm/cw-template.git --name PROJECT_NAME -d minimal=true +``` + +**Older Version** + +Pass version as branch flag: + +```sh +cargo generate --git https://github.com/CosmWasm/cw-template.git --branch --name PROJECT_NAME +``` + +Example: + +```sh +cargo generate --git https://github.com/CosmWasm/cw-template.git --branch 0.16 --name PROJECT_NAME +``` + +You will now have a new folder called `PROJECT_NAME` (I hope you changed that to something else) +containing a simple working contract and build system that you can customize. + +## Create a Repo + +After generating, you have a initialized local git repo, but no commits, and no remote. +Go to a server (eg. github) and create a new upstream repo (called `YOUR-GIT-URL` below). +Then run the following: + +```sh +# this is needed to create a valid Cargo.lock file (see below) +cargo check +git branch -M main +git add . +git commit -m 'Initial Commit' +git remote add origin YOUR-GIT-URL +git push -u origin main +``` + +## CI Support + +We have template configurations for both [GitHub Actions](.github/workflows/Basic.yml) +and [Circle CI](.circleci/config.yml) in the generated project, so you can +get up and running with CI right away. + +One note is that the CI runs all `cargo` commands +with `--locked` to ensure it uses the exact same versions as you have locally. This also means +you must have an up-to-date `Cargo.lock` file, which is not auto-generated. +The first time you set up the project (or after adding any dep), you should ensure the +`Cargo.lock` file is updated, so the CI will test properly. This can be done simply by +running `cargo check` or `cargo unit-test`. + +## Using your project + +Once you have your custom repo, you should check out [Developing](./Developing.md) to explain +more on how to run tests and develop code. Or go through the +[online tutorial](https://docs.cosmwasm.com/) to get a better feel +of how to develop. + +[Publishing](./Publishing.md) contains useful information on how to publish your contract +to the world, once you are ready to deploy it on a running blockchain. And +[Importing](./Importing.md) contains information about pulling in other contracts or crates +that have been published. + +Please replace this README file with information about your specific project. You can keep +the `Developing.md` and `Publishing.md` files as useful referenced, but please set some +proper description in the README. diff --git a/contracts/liquidity_hub/vault-manager/src/bin/vault_manager_schema.rs b/contracts/liquidity_hub/vault-manager/src/bin/vault_manager_schema.rs new file mode 100644 index 00000000..f2f76b3b --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/bin/vault_manager_schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use white_whale::vault_manager::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/liquidity_hub/vault-manager/src/contract.rs b/contracts/liquidity_hub/vault-manager/src/contract.rs new file mode 100644 index 00000000..e642de83 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/contract.rs @@ -0,0 +1,194 @@ +use cosmwasm_std::{entry_point, from_json, to_json_binary}; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError}; +use cw2::{get_contract_version, set_contract_version}; +use cw_utils::one_coin; +use semver::Version; + +use white_whale::pool_network::asset::AssetInfo; +use white_whale::vault_manager::{ + Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, +}; + +use crate::error::ContractError; +use crate::helpers::assert_asset; +use crate::state::{get_vault_by_lp, CONFIG, ONGOING_FLASHLOAN, VAULT_COUNTER}; +use crate::{manager, queries, router, vault}; + +// version info for migration info +const CONTRACT_NAME: &str = "ww-vault-manager"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[entry_point] +pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + match msg.vault_creation_fee.info { + AssetInfo::Token { .. } => { + return Err(StdError::generic_err("Vault creation fee must be native token").into()); + } + AssetInfo::NativeToken { .. } => {} + } + + let config = Config { + lp_token_type: msg.lp_token_type, + whale_lair_addr: deps.api.addr_validate(&msg.whale_lair_addr)?, + vault_creation_fee: msg.vault_creation_fee.clone(), + flash_loan_enabled: true, + deposit_enabled: true, + withdraw_enabled: true, + }; + + CONFIG.save(deps.storage, &config)?; + + cw_ownable::initialize_owner(deps.storage, deps.api, Some(msg.owner.as_str()))?; + + // set flashloan counter to false + ONGOING_FLASHLOAN.save(deps.storage, &false)?; + // initialize vault counter + VAULT_COUNTER.save(deps.storage, &0u64)?; + + Ok(Response::default().add_attributes(vec![ + ("action", "instantiate".to_string()), + ("owner", msg.owner), + ("lp_token_type", config.lp_token_type.to_string()), + ("whale_lair_addr", config.whale_lair_addr.into_string()), + ("vault_creation_fee", config.vault_creation_fee.to_string()), + ])) +} + +#[entry_point] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::CreateVault { + asset_info, + fees, + vault_identifier, + } => manager::commands::create_vault(deps, env, info, asset_info, fees, vault_identifier), + ExecuteMsg::UpdateConfig { + whale_lair_addr, + vault_creation_fee, + cw20_lp_code_id, + flash_loan_enabled, + deposit_enabled, + withdraw_enabled, + } => manager::commands::update_config( + deps, + info, + whale_lair_addr, + vault_creation_fee, + cw20_lp_code_id, + flash_loan_enabled, + deposit_enabled, + withdraw_enabled, + ), + ExecuteMsg::Deposit { + asset, + vault_identifier, + } => vault::commands::deposit(deps, &env, &info, &asset, &vault_identifier), + ExecuteMsg::Withdraw => { + let lp_asset = AssetInfo::NativeToken { + denom: one_coin(&info)?.denom, + }; + + // check if the vault exists and the asset matches + let vault = get_vault_by_lp(&deps.as_ref(), &lp_asset)?; + assert_asset(&vault.lp_asset, &lp_asset)?; + + vault::commands::withdraw( + deps, + env, + info.sender.into_string(), + info.funds[0].amount, + vault, + ) + } + ExecuteMsg::Receive(msg) => { + // check if it's a cw20 lp asset executing this callback + let lp_asset = AssetInfo::Token { + contract_addr: info.sender.into_string(), + }; + + let vault = get_vault_by_lp(&deps.as_ref(), &lp_asset)?; + assert_asset(&vault.lp_asset, &lp_asset)?; + + match from_json(&msg.msg)? { + Cw20HookMsg::Withdraw => { + vault::commands::withdraw(deps, env, msg.sender, msg.amount, vault) + } + } + } + ExecuteMsg::FlashLoan { + asset, + vault_identifier, + payload, + } => router::commands::flash_loan(deps, env, info, asset, vault_identifier, payload), + ExecuteMsg::Callback(msg) => router::commands::callback(deps, env, info, msg), + ExecuteMsg::UpdateOwnership(action) => { + Ok( + cw_ownable::update_ownership(deps, &env.block, &info.sender, action).map( + |ownership| { + Response::default() + .add_attribute("action", "update_ownership") + .add_attributes(ownership.into_attributes()) + }, + )?, + ) + } + } +} + +#[entry_point] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_manager_config(deps)?)?), + QueryMsg::Vault { filter_by } => { + Ok(to_json_binary(&queries::query_vault(deps, filter_by)?)?) + } + QueryMsg::Vaults { start_after, limit } => Ok(to_json_binary(&queries::query_vaults( + deps, + start_after, + limit, + )?)?), + QueryMsg::Share { lp_share } => Ok(to_json_binary(&queries::get_share(deps, lp_share)?)?), + QueryMsg::PaybackAmount { + asset, + vault_identifier, + } => Ok(to_json_binary(&queries::get_payback_amount( + deps, + asset, + vault_identifier, + )?)?), + QueryMsg::Ownership {} => Ok(to_json_binary(&cw_ownable::get_ownership(deps.storage)?)?), + } +} + +#[cfg(not(tarpaulin_include))] +#[entry_point] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + use white_whale::migrate_guards::check_contract_name; + + check_contract_name(deps.storage, CONTRACT_NAME.to_string())?; + + let version: Version = CONTRACT_VERSION.parse()?; + let storage_version: Version = get_contract_version(deps.storage)?.version.parse()?; + + if storage_version >= version { + return Err(ContractError::MigrateInvalidVersion { + current_version: storage_version, + new_version: version, + }); + } + + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} diff --git a/contracts/liquidity_hub/vault-manager/src/error.rs b/contracts/liquidity_hub/vault-manager/src/error.rs new file mode 100644 index 00000000..a1d9f845 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/error.rs @@ -0,0 +1,94 @@ +use cosmwasm_std::{ConversionOverflowError, DivideByZeroError, OverflowError, StdError, Uint128}; +use cw_ownable::OwnershipError; +use cw_utils::PaymentError; +use semver::Version; +use thiserror::Error; + +use white_whale::pool_network::asset::AssetInfo; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Semver parsing error: {0}")] + SemVer(String), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("mismatch of sent {sent} but specified deposit amount of {wanted}")] + FundsMismatch { sent: Uint128, wanted: Uint128 }, + + #[error("The asset \"{asset_info}\" with the identifier \"{identifier}\" already has a vault")] + ExistingVault { + asset_info: AssetInfo, + identifier: String, + }, + + #[error("Attempt to migrate to version {new_version}, but contract is on a higher version {current_version}")] + MigrateInvalidVersion { + new_version: Version, + current_version: Version, + }, + + #[error("Vault doesn't exist")] + NonExistentVault {}, + + #[error("Invalid vault creation fee paid. Received {amount}, expected {expected}")] + InvalidVaultCreationFee { amount: Uint128, expected: Uint128 }, + + #[error("The token factory feature is not enabled")] + TokenFactoryNotEnabled {}, + + #[error("Invalid LpTokenType")] + InvalidLpTokenType {}, + + #[error("Initial liquidity amount must be over {0}")] + InvalidInitialLiquidityAmount(Uint128), + + #[error("{0}")] + OverflowError(#[from] OverflowError), + + #[error("{0}")] + ConversionOverflowError(#[from] ConversionOverflowError), + + #[error("{0}")] + DivideByZeroError(#[from] DivideByZeroError), + + #[error("{0}")] + PaymentError(#[from] PaymentError), + + #[error("{0}")] + OwnershipError(#[from] OwnershipError), + + #[error( + "Final desired amount of {required_amount} is less than current balance of {current_balance} (got {old_balance} -> {current_balance}, want {old_balance} -> {required_amount})" + )] + NegativeProfit { + /// The balance before the loan occurred + old_balance: Uint128, + /// The current balance of the vault manager + current_balance: Uint128, + /// The required return amount for the vault manager + required_amount: Uint128, + }, + + #[error("The balance of an asset in the vault has decreased after the flashloan.")] + FlashLoanLoss {}, + + #[error("The asset sent doesn't match the asset stored in contract. Expected {expected}, got {actual}")] + AssetMismatch { expected: String, actual: String }, + + #[error("The requested vault doesn't have enough balance to serve the demand. Asset balance: {asset_balance}, requested: {requested_amount}")] + InsufficientAssetBalance { + asset_balance: Uint128, + requested_amount: Uint128, + }, +} + +impl From for ContractError { + fn from(err: semver::Error) -> Self { + Self::SemVer(err.to_string()) + } +} diff --git a/contracts/liquidity_hub/vault-manager/src/helpers.rs b/contracts/liquidity_hub/vault-manager/src/helpers.rs new file mode 100644 index 00000000..e34bcad7 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/helpers.rs @@ -0,0 +1,63 @@ +use std::collections::{HashMap, HashSet}; + +use crate::ContractError; +use cosmwasm_std::{Addr, Deps, Uint128}; +use white_whale::pool_network::asset::AssetInfo; +use white_whale::pool_network::querier::query_all_balances; +use white_whale::traits::AssetReference; +use white_whale::vault_manager::Vault; + +/// Queries the balances of all assets in the vaults. +pub(crate) fn query_balances( + deps: Deps, + contract_address: Addr, + vaults: &[Vault], +) -> Result, Uint128>, ContractError> { + let mut balances = HashMap::new(); + + // get balances of all native assets in the contract, returns all non-zero balances + let coins = query_all_balances(&deps.querier, contract_address.clone())?; + for coin in coins { + let asset_info = AssetInfo::NativeToken { + denom: coin.denom.clone(), + }; + balances.insert(asset_info.get_reference().to_vec(), coin.amount); + } + + // Create a HashSet to track encountered AssetInfo variants + let mut encountered_assets: HashSet> = HashSet::new(); + + let filtered_vaults: Vec = vaults + .iter() + .filter(|vault| { + let is_duplicate = + !encountered_assets.insert(vault.asset.info.clone().get_reference().to_vec()); + !is_duplicate && !balances.contains_key(vault.asset.info.get_reference()) + }) + .cloned() + .collect(); + + // this should only query balances for unique cw20 tokens as native tokens are already accounted for + for vault in filtered_vaults { + let balance = + vault + .asset + .info + .query_balance(&deps.querier, deps.api, contract_address.clone())?; + + balances.insert(vault.asset.info.get_reference().to_vec(), balance); + } + + Ok(balances) +} + +/// Assets that the provided asset is held in the given vault. +pub(crate) fn assert_asset(expected: &AssetInfo, actual: &AssetInfo) -> Result<(), ContractError> { + if expected != actual { + return Err(ContractError::AssetMismatch { + expected: expected.to_string(), + actual: actual.to_string(), + }); + } + Ok(()) +} diff --git a/contracts/liquidity_hub/vault-manager/src/lib.rs b/contracts/liquidity_hub/vault-manager/src/lib.rs new file mode 100644 index 00000000..9a41fe9f --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/lib.rs @@ -0,0 +1,10 @@ +pub mod contract; +mod error; +pub mod helpers; +mod manager; +mod queries; +mod router; +pub mod state; +mod vault; + +pub use crate::error::ContractError; diff --git a/contracts/liquidity_hub/vault-manager/src/manager/commands.rs b/contracts/liquidity_hub/vault-manager/src/manager/commands.rs new file mode 100644 index 00000000..1b851c22 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/manager/commands.rs @@ -0,0 +1,259 @@ +use cosmwasm_std::{ + attr, instantiate2_address, to_json_binary, Attribute, Binary, CodeInfoResponse, CosmosMsg, + DepsMut, Env, MessageInfo, Response, StdError, Uint128, WasmMsg, +}; +use cw20::MinterResponse; +use sha2::{Digest, Sha256}; + +use white_whale::constants::LP_SYMBOL; +use white_whale::pool_network::asset::{Asset, AssetInfo}; +use white_whale::pool_network::token::InstantiateMsg as TokenInstantiateMsg; +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +use white_whale::tokenfactory; +use white_whale::vault_manager::{LpTokenType, Vault, VaultFee}; + +use crate::state::{get_vault_by_identifier, CONFIG, VAULTS, VAULT_COUNTER}; +use crate::ContractError; +use white_whale::whale_lair::fill_rewards_msg; + +/// Creates a new vault +pub fn create_vault( + deps: DepsMut, + env: Env, + info: MessageInfo, + asset_info: AssetInfo, + fees: VaultFee, + vault_identifier: Option, +) -> Result { + let config = CONFIG.load(deps.storage)?; + + let denom = match config.vault_creation_fee.info.clone() { + // this will never happen as the fee is always native, enforced when instantiating the contract + AssetInfo::Token { .. } => "".to_string(), + AssetInfo::NativeToken { denom } => denom, + }; + + // verify fee payment + let amount = cw_utils::must_pay(&info, denom.as_str())?; + if amount < config.vault_creation_fee.amount { + return Err(ContractError::InvalidVaultCreationFee { + amount, + expected: config.vault_creation_fee.amount, + }); + } + + let mut messages: Vec = vec![]; + + // send vault creation fee to whale lair + let creation_fee = vec![Asset { + info: config.vault_creation_fee.info, + amount: config.vault_creation_fee.amount, + }]; + + // send protocol fee to whale lair + messages.push(fill_rewards_msg( + config.whale_lair_addr.into_string(), + creation_fee, + )?); + + let vault_id = VAULT_COUNTER.load(deps.storage)?; + // if no identifier is provided, use the vault counter (id) as identifier + let identifier = vault_identifier.unwrap_or(vault_id.to_string()); + + // check if there is an existing vault with the given identifier + let vault = get_vault_by_identifier(&deps.as_ref(), identifier.clone()); + if vault.is_ok() { + return Err(ContractError::ExistingVault { + asset_info, + identifier, + }); + } + + // check the vault fees are valid + fees.is_valid()?; + + let asset_label = asset_info.clone().get_label(&deps.as_ref())?; + let mut attributes = Vec::::new(); + attributes.push(attr("vault_identifier", identifier.clone())); + + let message = if config.lp_token_type == LpTokenType::TokenFactory { + #[cfg(all( + not(feature = "token_factory"), + not(feature = "osmosis_token_factory"), + not(feature = "injective") + ))] + return Err(ContractError::TokenFactoryNotEnabled {}); + + let lp_symbol = format!("{asset_label}.vault.{identifier}.{LP_SYMBOL}"); + let denom = format!("{}/{}/{}", "factory", env.contract.address, lp_symbol); + let lp_asset = AssetInfo::NativeToken { denom }; + + VAULTS.save( + deps.storage, + identifier.clone(), + &Vault { + asset: Asset { + info: asset_info, + amount: Uint128::zero(), + }, + lp_asset: lp_asset.clone(), + fees, + identifier, + }, + )?; + + attributes.push(attr("lp_asset", lp_asset.to_string())); + + #[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" + ))] + Ok(tokenfactory::create_denom::create_denom( + env.contract.address, + lp_symbol, + )) + } else { + let creator = deps.api.addr_canonicalize(env.contract.address.as_str())?; + let code_id = config.lp_token_type.get_cw20_code_id()?; + let CodeInfoResponse { checksum, .. } = deps.querier.query_wasm_code_info(code_id)?; + let seed = format!( + "{}{}{}{}", + asset_label, + identifier, + info.sender.into_string(), + env.block.height + ); + let mut hasher = Sha256::new(); + hasher.update(seed.as_bytes()); + let salt: Binary = hasher.finalize().to_vec().into(); + + let vault_lp_address = deps.api.addr_humanize( + &instantiate2_address(&checksum, &creator, &salt) + .map_err(|e| StdError::generic_err(e.to_string()))?, + )?; + + let lp_asset = AssetInfo::Token { + contract_addr: vault_lp_address.into_string(), + }; + + VAULTS.save( + deps.storage, + identifier.clone(), + &Vault { + asset: Asset { + info: asset_info, + amount: Uint128::zero(), + }, + lp_asset: lp_asset.clone(), + fees, + identifier, + }, + )?; + + attributes.push(attr("lp_asset", lp_asset.to_string())); + + let lp_token_name = format!("{asset_label}-LP"); + + Ok::(CosmosMsg::Wasm(WasmMsg::Instantiate2 { + admin: None, + code_id, + label: lp_token_name.to_owned(), + msg: to_json_binary(&TokenInstantiateMsg { + name: lp_token_name, + symbol: LP_SYMBOL.to_string(), + decimals: 6, + initial_balances: vec![], + mint: Some(MinterResponse { + minter: env.contract.address.to_string(), + cap: None, + }), + })?, + funds: vec![], + salt, + })) + }?; + + // increase vault counter + VAULT_COUNTER.update(deps.storage, |mut counter| -> Result<_, ContractError> { + counter += 1; + Ok(counter) + })?; + + messages.push(message); + + Ok(Response::default() + .add_messages(messages) + .add_attribute("action", "create_vault".to_string()) + .add_attributes(attributes)) +} + +/// Updates the manager config +#[allow(clippy::too_many_arguments)] +pub fn update_config( + deps: DepsMut, + info: MessageInfo, + whale_lair_addr: Option, + vault_creation_fee: Option, + cw20_lp_code_id: Option, + flash_loan_enabled: Option, + deposit_enabled: Option, + withdraw_enabled: Option, +) -> Result { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + let new_config = CONFIG.update::<_, ContractError>(deps.storage, |mut config| { + if let Some(new_whale_lair_addr) = whale_lair_addr { + config.whale_lair_addr = deps.api.addr_validate(&new_whale_lair_addr)?; + } + + if let Some(vault_creation_fee) = vault_creation_fee { + config.vault_creation_fee = vault_creation_fee; + } + + if let Some(new_token_id) = cw20_lp_code_id { + match config.lp_token_type { + LpTokenType::Cw20(_) => { + config.lp_token_type = LpTokenType::Cw20(new_token_id); + } + LpTokenType::TokenFactory => { + return Err(ContractError::InvalidLpTokenType {}); + } + } + } + + if let Some(flash_loan_enabled) = flash_loan_enabled { + config.flash_loan_enabled = flash_loan_enabled; + } + + if let Some(deposit_enabled) = deposit_enabled { + config.deposit_enabled = deposit_enabled; + } + + if let Some(withdraw_enabled) = withdraw_enabled { + config.withdraw_enabled = withdraw_enabled; + } + + Ok(config) + })?; + + Ok(Response::default().add_attributes(vec![ + ("method", "update_manager_config"), + ("whale_lair_addr", &new_config.whale_lair_addr.into_string()), + ("lp_token_type", &new_config.lp_token_type.to_string()), + ( + "vault_creation_fee", + &new_config.vault_creation_fee.to_string(), + ), + ( + "flash_loan_enabled", + &new_config.flash_loan_enabled.to_string(), + ), + ("deposit_enabled", &new_config.deposit_enabled.to_string()), + ("withdraw_enabled", &new_config.withdraw_enabled.to_string()), + ])) +} diff --git a/contracts/liquidity_hub/vault-manager/src/manager/mod.rs b/contracts/liquidity_hub/vault-manager/src/manager/mod.rs new file mode 100644 index 00000000..82b6da3c --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/manager/mod.rs @@ -0,0 +1 @@ +pub mod commands; diff --git a/contracts/liquidity_hub/vault-manager/src/queries.rs b/contracts/liquidity_hub/vault-manager/src/queries.rs new file mode 100644 index 00000000..202767b9 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/queries.rs @@ -0,0 +1,104 @@ +use cosmwasm_std::{Decimal, Deps, Uint128, Uint256}; + +use white_whale::pool_network::asset::{get_total_share, Asset}; +use white_whale::vault_manager::{ + Config, FilterVaultBy, PaybackAssetResponse, ShareResponse, VaultsResponse, +}; + +use crate::state::{ + get_vault_by_identifier, get_vault_by_lp, get_vaults, get_vaults_by_asset_info, CONFIG, +}; +use crate::ContractError; + +/// Gets the [Config]. +pub(crate) fn query_manager_config(deps: Deps) -> Result { + Ok(CONFIG.load(deps.storage)?) +} + +/// Gets a vault given the params provided by the filter [FilterVaultBy]. +pub(crate) fn query_vault( + deps: Deps, + filter_by: FilterVaultBy, +) -> Result { + let vaults = match filter_by { + FilterVaultBy::Asset(params) => get_vaults_by_asset_info( + deps.storage, + params.asset_info, + params.start_after, + params.limit, + )?, + FilterVaultBy::Identifier(identifier) => { + vec![get_vault_by_identifier(&deps, identifier)?] + } + FilterVaultBy::LpAsset(lp_asset) => vec![get_vault_by_lp(&deps, &lp_asset)?], + }; + + Ok(VaultsResponse { vaults }) +} + +/// Gets all vaults in the contract. +pub(crate) fn query_vaults( + deps: Deps, + start_after: Option>, + limit: Option, +) -> Result { + let vaults = get_vaults(deps.storage, start_after, limit)?; + + Ok(VaultsResponse { vaults }) +} + +/// Gets the share of the assets stored in the vault that a given `lp_share` is entitled to. +pub(crate) fn get_share(deps: Deps, lp_asset: Asset) -> Result { + let vault = get_vault_by_lp(&deps, &lp_asset.info)?; + + let lp_amount = get_total_share(&deps, lp_asset.info.to_string())?; + + // lp_share = amount / lp_amount + // asset_share = lp_share * vault.asset.amount + let asset_share = Decimal::from_ratio(lp_asset.amount, lp_amount) * vault.asset.amount; + Ok(ShareResponse { + share: Asset { + info: vault.asset.info, + amount: asset_share, + }, + }) +} + +/// Gets payback amount for a given asset. +pub(crate) fn get_payback_amount( + deps: Deps, + asset: Asset, + vault_identifier: String, +) -> Result { + let vault = get_vault_by_identifier(&deps, vault_identifier)?; + + // sanity check + if vault.asset.amount < asset.amount { + return Err(ContractError::InsufficientAssetBalance { + asset_balance: vault.asset.amount, + requested_amount: asset.amount, + }); + } + + // check that balance is greater than expected + let protocol_fee = + Uint128::try_from(vault.fees.protocol_fee.compute(Uint256::from(asset.amount)))?; + let flash_loan_fee = Uint128::try_from( + vault + .fees + .flash_loan_fee + .compute(Uint256::from(asset.amount)), + )?; + + let required_amount = asset + .amount + .checked_add(protocol_fee)? + .checked_add(flash_loan_fee)?; + + Ok(PaybackAssetResponse { + asset_info: asset.info, + payback_amount: required_amount, + protocol_fee, + flash_loan_fee, + }) +} diff --git a/contracts/liquidity_hub/vault-manager/src/router/commands.rs b/contracts/liquidity_hub/vault-manager/src/router/commands.rs new file mode 100644 index 00000000..2000c040 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/router/commands.rs @@ -0,0 +1,240 @@ +use cosmwasm_std::{ + to_json_binary, Addr, CosmosMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, Uint128, + Uint256, WasmMsg, +}; + +use white_whale::pool_network::asset::Asset; +use white_whale::traits::AssetReference; +use white_whale::vault_manager::{CallbackMsg, ExecuteMsg}; +use white_whale::whale_lair::fill_rewards_msg; + +use crate::helpers::{assert_asset, query_balances}; + +use crate::queries::query_vaults; +use crate::state::{ + get_vault_by_identifier, CONFIG, MAX_LIMIT, ONGOING_FLASHLOAN, TEMP_BALANCES, VAULTS, +}; +use crate::ContractError; + +/// Takes a flashloan of the specified asset and executes the payload. +pub fn flash_loan( + deps: DepsMut, + env: Env, + info: MessageInfo, + asset: Asset, + vault_identifier: String, + payload: Vec, +) -> Result { + // check that flash loans are enabled + let config = CONFIG.load(deps.storage)?; + if !config.flash_loan_enabled || ONGOING_FLASHLOAN.load(deps.storage)? { + return Err(ContractError::Unauthorized {}); + } + + let vault = get_vault_by_identifier(&deps.as_ref(), vault_identifier.to_owned())?; + + // check that the asset sent matches the vault + assert_asset(&vault.asset.info, &asset.info)?; + + // check if the vault has enough funds + if vault.asset.amount < asset.amount { + return Err(ContractError::InsufficientAssetBalance { + asset_balance: vault.asset.amount, + requested_amount: asset.amount, + }); + } + + // toggle on the flashloan indicator + ONGOING_FLASHLOAN.update::<_, StdError>(deps.storage, |_| Ok(true))?; + + let vaults = query_vaults(deps.as_ref(), None, Some(MAX_LIMIT))?.vaults; + + // store balances of all assets in the contract, so that we can check that other assets were not touched during the fashloan + let balances = query_balances(deps.as_ref(), env.contract.address.clone(), &vaults)?; + for (asset_info_reference, balance) in &balances { + TEMP_BALANCES.save(deps.storage, asset_info_reference.as_slice(), balance)?; + } + + // store current balance for after trade profit check + let old_asset_balance = *balances + .get(asset.info.get_reference()) + .ok_or(ContractError::NonExistentVault {})?; + + let mut messages: Vec = vec![]; + + // call payload and add after flashloan callback afterwards + messages.extend(payload); + messages.push( + WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + msg: to_json_binary(&ExecuteMsg::Callback(CallbackMsg::AfterFlashloan { + old_asset_balance, + loan_asset: asset.clone(), + vault_identifier: vault_identifier.clone(), + sender: info.sender, + }))?, + funds: vec![], + } + .into(), + ); + + Ok(Response::default() + .add_messages(messages) + .add_attributes(vec![ + ("action", "flash_loan".to_string()), + ("asset", asset.to_string()), + ("vault_identifier", vault_identifier), + ])) +} + +/// Processes callback to this contract. Callbacks can only be done by the contract itself. +pub fn callback( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: CallbackMsg, +) -> Result { + // callback can only be called by contract + if info.sender != env.contract.address { + return Err(ContractError::Unauthorized {}); + } + + match msg { + CallbackMsg::AfterFlashloan { + old_asset_balance: old_balance, + loan_asset, + vault_identifier, + sender, + } => after_flashloan(deps, env, old_balance, loan_asset, vault_identifier, sender), + } +} + +/// Completes the flashloan by paying back the outstanding loan, fees and returning profits to the +/// original sender. +pub fn after_flashloan( + deps: DepsMut, + env: Env, + old_balance: Uint128, + loan_asset: Asset, + vault_identifier: String, + sender: Addr, +) -> Result { + // query asset balances + let vaults = query_vaults(deps.as_ref(), None, Some(MAX_LIMIT))?.vaults; + + // get balances of all assets in the vault + let new_balances = query_balances(deps.as_ref(), env.contract.address, &vaults)?; + + // check that no LP assets where taken during the flashloan. When a native asset is all sent, it + // disappears from the balance vector, thus we compare the length of the original balances + // vector with the new balances vector + let original_native_assets_count = TEMP_BALANCES + .keys(deps.storage, None, None, Order::Ascending) + .count(); + + if original_native_assets_count > new_balances.len() { + return Err(ContractError::FlashLoanLoss {}); + } + + // check that all assets balances are equal or greater than before flashloan + let any_balance_lower = new_balances + .iter() + .any(|(asset_info_reference, &new_balance)| { + // get old balance for the given asset. If not found (should only happen if a vault is + // created during the flashloan process), default to zero. + let old_balance = TEMP_BALANCES + .load(deps.storage, asset_info_reference) + .map_or(Uint128::zero(), |old_balance| old_balance); + + new_balance < old_balance + }); + + if any_balance_lower { + return Err(ContractError::FlashLoanLoss {}); + } + + TEMP_BALANCES.clear(deps.storage); + + let new_asset_balance = *new_balances + .get(loan_asset.info.get_reference()) + .ok_or(ContractError::NonExistentVault {})?; + + // calculate the fees for executing the flashloan + let mut vault = get_vault_by_identifier(&deps.as_ref(), vault_identifier.to_owned())?; + + // protocol fee goes to the bonders + let protocol_fee = Uint128::try_from( + vault + .fees + .protocol_fee + .compute(Uint256::from(loan_asset.amount)), + )?; + + // flashloan fee stays in the vault + let flash_loan_fee = Uint128::try_from( + vault + .fees + .flash_loan_fee + .compute(Uint256::from(loan_asset.amount)), + )?; + + // check that new balance is greater than expected + let required_amount = old_balance + .checked_add(protocol_fee)? + .checked_add(flash_loan_fee)?; + + if required_amount > new_asset_balance { + return Err(ContractError::NegativeProfit { + old_balance, + current_balance: new_asset_balance, + required_amount, + }); + } + + // add the flashloan fee to the vault + vault.asset.amount = vault.asset.amount.checked_add(flash_loan_fee)?; + VAULTS.save(deps.storage, vault_identifier, &vault)?; + + // calculate flashloan profit + let profit = new_asset_balance + .checked_sub(old_balance)? + .saturating_sub(protocol_fee) + .saturating_sub(flash_loan_fee); + + let mut messages: Vec = vec![]; + + if !profit.is_zero() { + let profit_asset = Asset { + info: loan_asset.info.clone(), + amount: profit, + }; + + // send profit to sender + messages.push(profit_asset.into_msg(sender)?); + } + + let config = CONFIG.load(deps.storage)?; + let protocol_fee_asset = vec![Asset { + info: loan_asset.info, + amount: protocol_fee, + }]; + + // send protocol fee to whale lair + messages.push(fill_rewards_msg( + config.whale_lair_addr.into_string(), + protocol_fee_asset, + )?); + + // toggle off ongoing flashloan flag + ONGOING_FLASHLOAN.update::<_, StdError>(deps.storage, |_| Ok(false))?; + + Ok(Response::default() + .add_messages(messages) + .add_attributes(vec![ + ("action", "after_flashloan".to_string()), + ("vault_identifier", vault.identifier), + ("profit", profit.to_string()), + ("protocol_fee", protocol_fee.to_string()), + ("flash_loan_fee", flash_loan_fee.to_string()), + ])) +} diff --git a/contracts/liquidity_hub/vault-manager/src/router/mod.rs b/contracts/liquidity_hub/vault-manager/src/router/mod.rs new file mode 100644 index 00000000..82b6da3c --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/router/mod.rs @@ -0,0 +1 @@ +pub mod commands; diff --git a/contracts/liquidity_hub/vault-manager/src/state.rs b/contracts/liquidity_hub/vault-manager/src/state.rs new file mode 100644 index 00000000..aaec2e05 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/state.rs @@ -0,0 +1,123 @@ +use std::string::ToString; + +use cosmwasm_std::{Deps, Order, StdResult, Storage, Uint128}; +use cw_storage_plus::{Bound, Index, IndexList, IndexedMap, Item, Map, MultiIndex, UniqueIndex}; + +use white_whale::pool_network::asset::AssetInfo; +use white_whale::vault_manager::{Config, Vault}; + +use crate::ContractError; + +// A bool representing if a flashloan is being performed or not +pub const ONGOING_FLASHLOAN: Item = Item::new("ongoing_flashloan"); + +// Stores the balances of all assets in the contract before a flashloan, to compare after the +// messages are executed +pub const TEMP_BALANCES: Map<&[u8], Uint128> = Map::new("temp_balances"); + +// Contract's config +pub const CONFIG: Item = Item::new("config"); +// Vault counter to keep track of the number of vaults. Used as identifier for vaults if no +// identifier is provided when creating a vault +pub const VAULT_COUNTER: Item = Item::new("vault_count"); + +pub const VAULTS: IndexedMap = IndexedMap::new( + "vaults", + VaultIndexes { + lp_asset: UniqueIndex::new(|v| v.lp_asset.to_string(), "vaults__lp_asset"), + asset_info: MultiIndex::new( + |_pk, v| v.asset.info.to_string(), + "vaults", + "vaults__asset_info", + ), + }, +); + +pub struct VaultIndexes<'a> { + pub lp_asset: UniqueIndex<'a, String, Vault, String>, + pub asset_info: MultiIndex<'a, String, Vault, String>, +} + +impl<'a> IndexList for VaultIndexes<'a> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.lp_asset, &self.asset_info]; + Box::new(v.into_iter()) + } +} + +// settings for pagination +pub(crate) const MAX_LIMIT: u32 = 1_000; +const DEFAULT_LIMIT: u32 = 10; + +/// Gets the vaults in the contract +pub fn get_vaults( + storage: &dyn Storage, + start_after: Option>, + limit: Option, +) -> StdResult> { + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = calc_range_start(start_after).map(Bound::ExclusiveRaw); + + VAULTS + .range(storage, start, None, Order::Ascending) + .take(limit) + .map(|item| { + let (_, vault) = item?; + + Ok(vault) + }) + .collect() +} + +/// Calculates the item at which to start the range +fn calc_range_start(start_after: Option>) -> Option> { + start_after.map(|asset_info| { + let mut v = asset_info; + v.push(1); + v + }) +} + +/// Gets vaults given an [AssetInfo] +pub fn get_vaults_by_asset_info( + storage: &dyn Storage, + asset_info: AssetInfo, + start_after: Option>, + limit: Option, +) -> StdResult> { + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = calc_range_start(start_after).map(Bound::ExclusiveRaw); + + VAULTS + .idx + .asset_info + .prefix(asset_info.to_string()) + .range(storage, start, None, Order::Ascending) + .take(limit) + .map(|item| { + let (_, vault) = item?; + + Ok(vault) + }) + .collect() +} + +/// Gets the vault given an lp asset as [AssetInfo] +pub fn get_vault_by_lp(deps: &Deps, lp_asset: &AssetInfo) -> Result { + Ok(VAULTS + .idx + .lp_asset + .item(deps.storage, lp_asset.to_string())? + .map_or_else(|| Err(ContractError::NonExistentVault {}), Ok)? + .1) +} + +/// Gets the vault given its identifier +pub fn get_vault_by_identifier( + deps: &Deps, + vault_identifier: String, +) -> Result { + VAULTS + .may_load(deps.storage, vault_identifier)? + .ok_or(ContractError::NonExistentVault {}) +} diff --git a/contracts/liquidity_hub/vault-manager/src/vault/commands.rs b/contracts/liquidity_hub/vault-manager/src/vault/commands.rs new file mode 100644 index 00000000..007b865d --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/vault/commands.rs @@ -0,0 +1,185 @@ +use cosmwasm_std::{ + to_json_binary, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, +}; +use cw_utils::must_pay; + +use white_whale::pool_network::asset::{ + get_total_share, Asset, AssetInfo, MINIMUM_LIQUIDITY_AMOUNT, +}; +use white_whale::vault_manager::Vault; + +use crate::helpers::assert_asset; +use crate::state::{get_vault_by_identifier, CONFIG, ONGOING_FLASHLOAN, VAULTS}; +use crate::ContractError; + +/// Deposits an asset into the vault +pub fn deposit( + deps: DepsMut, + env: &Env, + info: &MessageInfo, + asset: &Asset, + vault_identifier: &String, +) -> Result { + let config = CONFIG.load(deps.storage)?; + + // check that deposits are enabled and if that there's a flash-loan ongoing + if !config.deposit_enabled || ONGOING_FLASHLOAN.load(deps.storage)? { + return Err(ContractError::Unauthorized {}); + } + + let mut vault = get_vault_by_identifier(&deps.as_ref(), vault_identifier.to_owned())?; + + // check that the asset sent matches the vault + assert_asset(&vault.asset.info, &asset.info)?; + + // check that user sent the assets it claims to have sent + let sent_funds = match vault.asset.info.clone() { + AssetInfo::NativeToken { denom } => must_pay(info, denom.as_str())?, + AssetInfo::Token { contract_addr } => { + let allowance: cw20::AllowanceResponse = deps.querier.query_wasm_smart( + contract_addr, + &cw20::Cw20QueryMsg::Allowance { + owner: info.sender.clone().into_string(), + spender: env.contract.address.clone().into_string(), + }, + )?; + + allowance.allowance + } + }; + + if sent_funds != asset.amount { + return Err(ContractError::FundsMismatch { + sent: sent_funds, + wanted: asset.amount, + }); + } + + // Increase the amount of the asset in this vault + vault.asset.amount = vault.asset.amount.checked_add(sent_funds)?; + VAULTS.save(deps.storage, vault_identifier.to_owned(), &vault)?; + + let mut messages: Vec = vec![]; + // add cw20 transfer message if needed + if let AssetInfo::Token { contract_addr } = vault.asset.info.clone() { + messages.push( + WasmMsg::Execute { + contract_addr, + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + owner: info.sender.clone().into_string(), + recipient: env.contract.address.clone().into_string(), + amount: asset.amount, + })?, + funds: vec![], + } + .into(), + ) + } + + // mint LP token for the sender + let total_lp_share = get_total_share(&deps.as_ref(), vault.lp_asset.to_string())?; + + // todo revise this for cw20 tokens, duplicated vaults will not have total == 0 + let lp_amount = if total_lp_share.is_zero() { + // Make sure at least MINIMUM_LIQUIDITY_AMOUNT is deposited to mitigate the risk of the first + // depositor preventing small liquidity providers from joining the vault + let share = asset + .amount + .checked_sub(MINIMUM_LIQUIDITY_AMOUNT) + .map_err(|_| ContractError::InvalidInitialLiquidityAmount(MINIMUM_LIQUIDITY_AMOUNT))?; + + messages.append(&mut white_whale::lp_common::mint_lp_token_msg( + vault.lp_asset.to_string(), + &env.contract.address, + &env.contract.address, + MINIMUM_LIQUIDITY_AMOUNT, + )?); + + // share should be above zero after subtracting the MINIMUM_LIQUIDITY_AMOUNT + if share.is_zero() { + return Err(ContractError::InvalidInitialLiquidityAmount( + MINIMUM_LIQUIDITY_AMOUNT, + )); + } + + share + } else { + // return based on a share of the vault. We subtract the deposit amount from the vault since + // it was added previously to the vault in this function + let vault_total_deposits = vault.asset.amount.checked_sub(asset.amount)?; + + asset + .amount + .checked_mul(total_lp_share)? + .checked_div(vault_total_deposits)? + }; + + // mint LP token to sender + messages.append(&mut white_whale::lp_common::mint_lp_token_msg( + vault.lp_asset.to_string(), + &info.sender.clone(), + &env.contract.address, + lp_amount, + )?); + + Ok(Response::default() + .add_messages(messages) + .add_attributes(vec![("action", "deposit"), ("asset", &asset.to_string())])) +} + +/// Withdraws an asset from the given vault. +pub fn withdraw( + deps: DepsMut, + env: Env, + sender: String, + lp_amount: Uint128, + mut vault: Vault, +) -> Result { + let config = CONFIG.load(deps.storage)?; + + // check that withdrawals are enabled and if that there's a flash-loan ongoing + if !config.withdraw_enabled || ONGOING_FLASHLOAN.load(deps.storage)? { + return Err(ContractError::Unauthorized {}); + } + + let sender = deps.api.addr_validate(&sender)?; + + // calculate return amount based on the share of the given vault + let liquidity_asset = vault.lp_asset.to_string(); + let total_lp_share = get_total_share(&deps.as_ref(), liquidity_asset.clone())?; + let withdraw_amount = Decimal::from_ratio(lp_amount, total_lp_share) * vault.asset.amount; + + // sanity check + if withdraw_amount > vault.asset.amount { + return Err(ContractError::InsufficientAssetBalance { + asset_balance: vault.asset.amount, + requested_amount: withdraw_amount, + }); + } + + // asset to return + let return_asset = Asset { + info: vault.asset.info.clone(), + amount: withdraw_amount, + }; + let messages: Vec = vec![ + return_asset.clone().into_msg(sender)?, + white_whale::lp_common::burn_lp_asset_msg( + liquidity_asset, + env.contract.address, + lp_amount, + )?, + ]; + + // decrease the amount on the asset in this vault + vault.asset.amount = vault.asset.amount.checked_sub(withdraw_amount)?; + VAULTS.save(deps.storage, vault.identifier.clone(), &vault)?; + + Ok(Response::default() + .add_messages(messages) + .add_attributes(vec![ + ("action", "withdraw"), + ("lp_amount", &lp_amount.to_string()), + ("return_asset", &return_asset.to_string()), + ])) +} diff --git a/contracts/liquidity_hub/vault-manager/src/vault/mod.rs b/contracts/liquidity_hub/vault-manager/src/vault/mod.rs new file mode 100644 index 00000000..82b6da3c --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/src/vault/mod.rs @@ -0,0 +1 @@ +pub mod commands; diff --git a/contracts/liquidity_hub/vault-manager/tests/common/mod.rs b/contracts/liquidity_hub/vault-manager/tests/common/mod.rs new file mode 100644 index 00000000..9987f33e --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/tests/common/mod.rs @@ -0,0 +1,4 @@ +pub mod suite; +mod suite_contracts; + +pub(crate) const MOCK_CONTRACT_ADDR: &str = "migaloo1wrv0vap0sdpxt3xrdy0yg9ppsx3ppxrfhm6m3s"; diff --git a/contracts/liquidity_hub/vault-manager/tests/common/suite.rs b/contracts/liquidity_hub/vault-manager/tests/common/suite.rs new file mode 100644 index 00000000..b0eb7977 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/tests/common/suite.rs @@ -0,0 +1,728 @@ +use cosmwasm_std::{ + coin, to_json_binary, Addr, Coin, CosmosMsg, Decimal, StdResult, Timestamp, Uint128, Uint64, + WasmMsg, +}; +use cw20::{BalanceResponse, Cw20Coin, MinterResponse}; +use cw_multi_test::addons::{MockAddressGenerator, MockApiBech32}; +use cw_multi_test::{App, AppBuilder, AppResponse, BankKeeper, Executor, Wasm, WasmKeeper}; + +use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; +use white_whale::pool_network::pair::ExecuteMsg::{ProvideLiquidity, Swap}; +use white_whale::pool_network::pair::{PoolFee, SimulationResponse}; +use white_whale::vault_manager::{ + Config, Cw20HookMsg, FilterVaultBy, InstantiateMsg, LpTokenType, PaybackAssetResponse, + ShareResponse, VaultsResponse, +}; + +use crate::common::suite_contracts::{ + cw20_token_contract, fee_collector_contract, pair_contract, vault_manager_contract, + whale_lair_contract, +}; + +pub struct TestingSuite { + app: App, + pub senders: [Addr; 3], + pub whale_lair_addr: Addr, + pub vault_manager_addr: Addr, + pub cw20_tokens: Vec, + pub pools: Vec, +} + +/// TestingSuite helpers +impl TestingSuite { + pub(crate) fn creator(&mut self) -> Addr { + self.senders.first().unwrap().clone() + } + + pub(crate) fn set_time(&mut self, timestamp: Timestamp) -> &mut Self { + let mut block_info = self.app.block_info(); + block_info.time = timestamp; + self.app.set_block(block_info); + + self + } + + pub(crate) fn get_time(&mut self) -> Timestamp { + self.app.block_info().time + } + + #[track_caller] + pub(crate) fn increase_allowance( + &mut self, + sender: Addr, + cw20contract: Addr, + allowance: Uint128, + spender: Addr, + ) -> &mut Self { + let msg = cw20_base::msg::ExecuteMsg::IncreaseAllowance { + spender: spender.to_string(), + amount: allowance, + expires: None, + }; + + self.app + .execute_contract(sender, cw20contract, &msg, &vec![]) + .unwrap(); + + self + } + + #[track_caller] + pub(crate) fn create_pool( + &mut self, + asset_infos: [AssetInfo; 2], + asset_decimals: [u8; 2], + pool_fees: PoolFee, + pair_type: PairType, + token_factory_lp: bool, + ) -> &mut Self { + let pair_id = self.app.store_code(pair_contract()); + let token_code_id = self.app.store_code(cw20_token_contract()); + let fee_collector = self.create_fee_collector(); + + // create whale lair + let msg = white_whale::pool_network::pair::InstantiateMsg { + asset_infos, + token_code_id, + asset_decimals, + pool_fees, + fee_collector_addr: fee_collector.to_string(), + pair_type, + token_factory_lp, + }; + + let creator = self.creator().clone(); + + self.pools.append(&mut vec![self + .app + .instantiate_contract( + pair_id, + creator.clone(), + &msg, + &[], + "pool", + Some(creator.into_string()), + ) + .unwrap()]); + + self + } +} + +/// Instantiate +impl TestingSuite { + pub(crate) fn default_with_balances(initial_balance: Vec) -> Self { + let sender_1 = Addr::unchecked("migaloo1h3s5np57a8cxaca3rdjlgu8jzmr2d2zz55s5y3"); + let sender_2 = Addr::unchecked("migaloo193lk767456jhkzddnz7kf5jvuzfn67gyfvhc40"); + let sender_3 = Addr::unchecked("migaloo1ludaslnu24p5eftw499f7ngsc2jkzqdsrvxt75"); + + let bank = BankKeeper::new(); + + let balances = vec![ + (sender_1.clone(), initial_balance.clone()), + (sender_2.clone(), initial_balance.clone()), + (sender_3.clone(), initial_balance.clone()), + ]; + + let app = AppBuilder::new() + .with_api(MockApiBech32::new("migaloo")) + .with_wasm(WasmKeeper::default().with_address_generator(MockAddressGenerator)) + .with_bank(bank) + .build(|router, _api, storage| { + balances.into_iter().for_each(|(account, amount)| { + router.bank.init_balance(storage, &account, amount).unwrap() + }); + }); + + Self { + app, + senders: [sender_1, sender_2, sender_3], + whale_lair_addr: Addr::unchecked(""), + vault_manager_addr: Addr::unchecked(""), + cw20_tokens: vec![], + pools: vec![], + } + } + + #[track_caller] + pub(crate) fn instantiate_default(&mut self) -> &mut Self { + self.create_whale_lair(); + self.create_cw20_token(); + + // 17 May 2023 17:00:00 UTC + let timestamp = Timestamp::from_seconds(1684342800u64); + self.set_time(timestamp); + + self.instantiate( + self.whale_lair_addr.to_string(), + LpTokenType::TokenFactory, + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + ) + } + + #[track_caller] + pub(crate) fn instantiate_with_cw20_lp_token(&mut self) -> &mut Self { + self.create_whale_lair(); + let cw20_code_id = self.create_cw20_token(); + + // 17 May 2023 17:00:00 UTC + let timestamp = Timestamp::from_seconds(1684342800u64); + self.set_time(timestamp); + + self.instantiate( + self.whale_lair_addr.to_string(), + LpTokenType::Cw20(cw20_code_id), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + ) + } + + fn create_whale_lair(&mut self) { + let whale_lair_id = self.app.store_code(whale_lair_contract()); + + // create whale lair + let msg = white_whale::whale_lair::InstantiateMsg { + unbonding_period: Uint64::new(86400u64), + growth_rate: Decimal::one(), + bonding_assets: vec![ + AssetInfo::NativeToken { + denom: "bWHALE".to_string(), + }, + AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + ], + }; + + let creator = self.creator().clone(); + + self.whale_lair_addr = self + .app + .instantiate_contract( + whale_lair_id, + creator.clone(), + &msg, + &[], + "White Whale Lair".to_string(), + Some(creator.to_string()), + ) + .unwrap(); + } + + fn create_fee_collector(&mut self) -> Addr { + let fee_collector_contract = self.app.store_code(fee_collector_contract()); + + // create whale lair + let msg = white_whale::fee_collector::InstantiateMsg {}; + + let creator = self.creator().clone(); + + self.app + .instantiate_contract( + fee_collector_contract, + creator.clone(), + &msg, + &[], + "White Whale Lair".to_string(), + Some(creator.to_string()), + ) + .unwrap() + } + + #[track_caller] + pub fn create_cw20_token(&mut self) -> u64 { + let msg = white_whale::pool_network::token::InstantiateMsg { + name: "mocktoken".to_string(), + symbol: "MOCK".to_string(), + decimals: 6, + initial_balances: vec![ + Cw20Coin { + address: self.senders[0].to_string(), + amount: Uint128::new(1_000_000_000_000u128), + }, + Cw20Coin { + address: self.senders[1].to_string(), + amount: Uint128::new(1_000_000_000_000u128), + }, + Cw20Coin { + address: self.senders[2].to_string(), + amount: Uint128::new(1_000_000_000_000u128), + }, + ], + mint: Some(MinterResponse { + minter: self.senders[0].to_string(), + cap: None, + }), + }; + + let cw20_token_id = self.app.store_code(cw20_token_contract()); + + let creator = self.creator().clone(); + + self.cw20_tokens.append(&mut vec![self + .app + .instantiate_contract( + cw20_token_id, + creator.clone(), + &msg, + &[], + "mock cw20 token", + Some(creator.into_string()), + ) + .unwrap()]); + cw20_token_id + } + + #[track_caller] + pub(crate) fn instantiate( + &mut self, + whale_lair_addr: String, + lp_token_type: LpTokenType, + vault_creation_fee: Asset, + ) -> &mut Self { + let msg = InstantiateMsg { + owner: self.creator().to_string(), + lp_token_type, + whale_lair_addr, + vault_creation_fee, + }; + + let vault_manager_id = self.app.store_code(vault_manager_contract()); + + let creator = self.creator().clone(); + + self.vault_manager_addr = self + .app + .instantiate_contract( + vault_manager_id, + creator.clone(), + &msg, + &[], + "mock vault manager", + Some(creator.into_string()), + ) + .unwrap(); + self + } + + #[track_caller] + pub(crate) fn instantiate_err( + &mut self, + lp_token_type: LpTokenType, + vault_creation_fee: Asset, + error: impl Fn(anyhow::Error), + ) -> &mut Self { + let creator = self.creator().clone(); + + let msg = InstantiateMsg { + owner: creator.clone().to_string(), + lp_token_type, + whale_lair_addr: self.whale_lair_addr.to_string(), + vault_creation_fee, + }; + + let vault_manager_id = self.app.store_code(vault_manager_contract()); + + let err = self + .app + .instantiate_contract( + vault_manager_id, + creator.clone(), + &msg, + &[], + "mock vault manager", + Some(creator.into_string()), + ) + .unwrap_err(); + + error(err); + self + } +} + +/// execute messages +impl TestingSuite { + #[track_caller] + pub(crate) fn update_ownership( + &mut self, + sender: Addr, + action: cw_ownable::Action, + result: impl Fn(Result), + ) -> &mut Self { + let msg = white_whale::vault_manager::ExecuteMsg::UpdateOwnership(action); + + result( + self.app + .execute_contract(sender, self.vault_manager_addr.clone(), &msg, &[]), + ); + + self + } + + #[track_caller] + pub(crate) fn create_vault( + &mut self, + sender: Addr, + asset_info: AssetInfo, + vault_identifier: Option, + fees: white_whale::vault_manager::VaultFee, + funds: Vec, + result: impl Fn(Result), + ) -> &mut Self { + let msg = white_whale::vault_manager::ExecuteMsg::CreateVault { + asset_info, + fees, + vault_identifier, + }; + + result( + self.app + .execute_contract(sender, self.vault_manager_addr.clone(), &msg, &funds), + ); + + self + } + + #[track_caller] + pub(crate) fn deposit( + &mut self, + sender: Addr, + asset: Asset, + vault_identifier: String, + funds: Vec, + result: impl Fn(Result), + ) -> &mut Self { + let msg = white_whale::vault_manager::ExecuteMsg::Deposit { + asset, + vault_identifier, + }; + + result( + self.app + .execute_contract(sender, self.vault_manager_addr.clone(), &msg, &funds), + ); + + self + } + + #[track_caller] + pub(crate) fn withdraw( + &mut self, + sender: Addr, + asset: Asset, + funds: Vec, + result: impl Fn(Result), + ) -> &mut Self { + match asset.info { + AssetInfo::Token { contract_addr } => { + let msg = cw20::Cw20ExecuteMsg::Send { + contract: self.vault_manager_addr.to_string(), + amount: asset.amount, + msg: to_json_binary(&Cw20HookMsg::Withdraw).unwrap(), + }; + + result(self.app.execute_contract( + sender, + Addr::unchecked(contract_addr), + &msg, + &funds, + )); + } + AssetInfo::NativeToken { .. } => { + let msg = white_whale::vault_manager::ExecuteMsg::Withdraw {}; + + let vault_manager = self.vault_manager_addr.clone(); + + result( + self.app + .execute_contract(sender, vault_manager, &msg, &funds), + ); + } + } + + self + } + #[track_caller] + pub(crate) fn update_config( + &mut self, + sender: Addr, + whale_lair_addr: Option, + vault_creation_fee: Option, + cw20_lp_code_id: Option, + flash_loan_enabled: Option, + deposit_enabled: Option, + withdraw_enabled: Option, + funds: Vec, + result: impl Fn(Result), + ) -> &mut Self { + let msg = white_whale::vault_manager::ExecuteMsg::UpdateConfig { + whale_lair_addr, + vault_creation_fee, + cw20_lp_code_id, + flash_loan_enabled, + deposit_enabled, + withdraw_enabled, + }; + + result( + self.app + .execute_contract(sender, self.vault_manager_addr.clone(), &msg, &funds), + ); + + self + } + + #[track_caller] + pub(crate) fn flashloan( + &mut self, + sender: Addr, + asset: Asset, + vault_identifier: String, + payload: Vec, + result: impl Fn(Result), + ) -> &mut Self { + let msg = white_whale::vault_manager::ExecuteMsg::FlashLoan { + asset, + vault_identifier, + payload, + }; + + result( + self.app + .execute_contract(sender, self.vault_manager_addr.clone(), &msg, &[]), + ); + + self + } + + #[track_caller] + pub(crate) fn callback( + &mut self, + sender: Addr, + result: impl Fn(Result), + ) -> &mut Self { + // the values here don't matter as this is the test it would give an error, as only the + // contract itself can make callbacks + let msg = white_whale::vault_manager::ExecuteMsg::Callback( + white_whale::vault_manager::CallbackMsg::AfterFlashloan { + old_asset_balance: Uint128::zero(), + loan_asset: Asset { + info: AssetInfo::NativeToken { + denom: "".to_string(), + }, + amount: Default::default(), + }, + sender: sender.clone(), + vault_identifier: "".to_string(), + }, + ); + + result( + self.app + .execute_contract(sender, self.vault_manager_addr.clone(), &msg, &[]), + ); + + self + } +} + +/// queries +impl TestingSuite { + pub(crate) fn query_ownership( + &mut self, + result: impl Fn(StdResult>), + ) -> &mut Self { + let ownership_response: StdResult> = + self.app.wrap().query_wasm_smart( + &self.vault_manager_addr, + &white_whale::vault_manager::QueryMsg::Ownership {}, + ); + + result(ownership_response); + + self + } + + #[track_caller] + pub(crate) fn query_vault( + &mut self, + filter_by: FilterVaultBy, + result: impl Fn(StdResult), + ) -> &mut Self { + let vaults_response: StdResult = self.app.wrap().query_wasm_smart( + &self.vault_manager_addr, + &white_whale::vault_manager::QueryMsg::Vault { filter_by }, + ); + + result(vaults_response); + + self + } + + #[track_caller] + pub(crate) fn query_vaults( + &mut self, + start_after: Option>, + limit: Option, + result: impl Fn(StdResult), + ) -> &mut Self { + let vaults_response: StdResult = self.app.wrap().query_wasm_smart( + &self.vault_manager_addr, + &white_whale::vault_manager::QueryMsg::Vaults { start_after, limit }, + ); + + result(vaults_response); + + self + } + + #[track_caller] + pub(crate) fn query_balance( + &mut self, + asset_info: AssetInfo, + address: Addr, + result: impl Fn(Uint128), + ) -> &mut Self { + let balance: Uint128 = match asset_info { + AssetInfo::Token { contract_addr } => { + let balance_response: StdResult = + self.app.wrap().query_wasm_smart( + &contract_addr, + &cw20_base::msg::QueryMsg::Balance { + address: address.to_string(), + }, + ); + + if balance_response.is_err() { + Uint128::zero() + } else { + balance_response.unwrap().balance + } + } + AssetInfo::NativeToken { denom } => { + let balance_response = self.app.wrap().query_balance(address, denom.clone()); + + balance_response.unwrap_or(coin(0, denom)).amount + } + }; + + result(balance); + + self + } + #[track_caller] + pub(crate) fn query_config(&mut self, result: impl Fn(StdResult)) -> &mut Self { + let response: StdResult = self.app.wrap().query_wasm_smart( + &self.vault_manager_addr, + &white_whale::vault_manager::QueryMsg::Config {}, + ); + + result(response); + + self + } + #[track_caller] + pub(crate) fn query_share( + &mut self, + lp_share: Asset, + result: impl Fn(StdResult), + ) -> &mut Self { + let response: StdResult = self.app.wrap().query_wasm_smart( + &self.vault_manager_addr, + &white_whale::vault_manager::QueryMsg::Share { lp_share }, + ); + + result(response); + + self + } + + #[track_caller] + pub(crate) fn query_payback( + &mut self, + asset: Asset, + vault_identifier: String, + result: impl Fn(StdResult), + ) -> &mut Self { + let response: StdResult = self.app.wrap().query_wasm_smart( + &self.vault_manager_addr, + &white_whale::vault_manager::QueryMsg::PaybackAmount { + asset, + vault_identifier, + }, + ); + + result(response); + + self + } +} + +// pools interactions +impl TestingSuite { + #[track_caller] + pub(crate) fn provide_liquidity( + &mut self, + sender: Addr, + assets: [Asset; 2], + pool: Addr, + funds: &[Coin], + result: impl Fn(Result), + ) -> &mut Self { + let msg = ProvideLiquidity { + assets, + slippage_tolerance: None, + receiver: None, + }; + + result(self.app.execute_contract(sender, pool, &msg, funds)); + + self + } + #[track_caller] + pub(crate) fn swap( + &mut self, + sender: Addr, + offer_asset: Asset, + pool: Addr, + funds: &[Coin], + result: impl Fn(Result), + ) -> &mut Self { + let msg = Swap { + offer_asset, + belief_price: None, + max_spread: None, + to: None, + }; + + result(self.app.execute_contract(sender, pool, &msg, funds)); + + self + } + + #[track_caller] + pub(crate) fn simulate_swap( + &mut self, + offer_asset: Asset, + pool: Addr, + result: impl Fn(StdResult), + ) -> &mut Self { + let response: StdResult = self.app.wrap().query_wasm_smart( + pool, + &white_whale::pool_network::pair::QueryMsg::Simulation { offer_asset }, + ); + + result(response); + + self + } +} diff --git a/contracts/liquidity_hub/vault-manager/tests/common/suite_contracts.rs b/contracts/liquidity_hub/vault-manager/tests/common/suite_contracts.rs new file mode 100644 index 00000000..6604486d --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/tests/common/suite_contracts.rs @@ -0,0 +1,63 @@ +use cosmwasm_std::Empty; +use cw_multi_test::{Contract, ContractWrapper}; + +/// Creates the whale lair contract +pub fn whale_lair_contract() -> Box> { + let contract = ContractWrapper::new( + whale_lair::contract::execute, + whale_lair::contract::instantiate, + whale_lair::contract::query, + ) + .with_migrate(whale_lair::contract::migrate); + + Box::new(contract) +} + +/// Creates the fee collector contract +pub fn fee_collector_contract() -> Box> { + let contract = ContractWrapper::new( + fee_collector::contract::execute, + fee_collector::contract::instantiate, + fee_collector::contract::query, + ) + .with_reply(fee_collector::contract::reply) + .with_migrate(fee_collector::contract::migrate); + + Box::new(contract) +} + +/// Creates a cw20 token contract +pub fn cw20_token_contract() -> Box> { + let contract = ContractWrapper::new( + terraswap_token::contract::execute, + terraswap_token::contract::instantiate, + terraswap_token::contract::query, + ); + + Box::new(contract) +} + +/// Creates a vault manager contract +pub fn vault_manager_contract() -> Box> { + let contract = ContractWrapper::new( + vault_manager::contract::execute, + vault_manager::contract::instantiate, + vault_manager::contract::query, + ) + .with_migrate(vault_manager::contract::migrate); + + Box::new(contract) +} + +/// Creates a pair contract +pub fn pair_contract() -> Box> { + let contract = ContractWrapper::new( + terraswap_pair::contract::execute, + terraswap_pair::contract::instantiate, + terraswap_pair::contract::query, + ) + .with_reply(terraswap_pair::contract::reply) + .with_migrate(terraswap_pair::contract::migrate); + + Box::new(contract) +} diff --git a/contracts/liquidity_hub/vault-manager/tests/helpers.rs b/contracts/liquidity_hub/vault-manager/tests/helpers.rs new file mode 100644 index 00000000..f6646d5e --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/tests/helpers.rs @@ -0,0 +1,235 @@ +use cosmwasm_std::{coin, Uint128}; +use std::collections::{HashMap, HashSet}; +use white_whale::fee::Fee; +use white_whale::pool_network::asset::{Asset, AssetInfo}; +use white_whale::traits::AssetReference; +use white_whale::vault_manager::{Vault, VaultFee}; + +#[test] +pub fn query_balances() { + let mut balances = HashMap::new(); + + let coins = vec![ + coin(1_000u128, "uwhale".to_string()), + coin(1_000u128, "usdc".to_string()), + coin(1_000u128, "uluna".to_string()), + coin(1_000u128, "ibc/something".to_string()), + ]; + + for coin in coins { + let asset_info = AssetInfo::NativeToken { + denom: coin.denom.clone(), + }; + balances.insert(asset_info.get_reference().to_vec(), coin.amount); + } + + assert_eq!(balances.len(), 4); + + println!("balances::: {:?}", balances); + + let vaults = vec![ + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(500), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "0".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(500), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "2".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "usdc".to_string(), + }, + amount: Uint128::new(1000), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "3".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(1000), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "4".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ibc/something".to_string(), + }, + amount: Uint128::new(250), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "5".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ibc/something".to_string(), + }, + amount: Uint128::new(250), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "6".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ibc/something".to_string(), + }, + amount: Uint128::new(250), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "7".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ibc/something".to_string(), + }, + amount: Uint128::new(250), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "8".to_string(), + }, + Vault { + asset: Asset { + info: AssetInfo::Token { + contract_addr: "cw20_contract".to_string(), + }, + amount: Uint128::new(3333), + }, + lp_asset: AssetInfo::NativeToken { + denom: "factory/something".to_string(), + }, + fees: VaultFee { + protocol_fee: Fee { + share: Default::default(), + }, + flash_loan_fee: Fee { + share: Default::default(), + }, + }, + identifier: "9".to_string(), + }, + ]; + + let mut encountered_assets: HashSet> = HashSet::new(); + + let filtered_vaults: Vec = vaults + .into_iter() + .filter(|vault| { + let is_duplicate = + !encountered_assets.insert(vault.asset.info.clone().get_reference().to_vec()); + !is_duplicate && !balances.contains_key(vault.asset.info.get_reference()) + }) + .collect(); + + println!("filtered_vaults:::: {:?}", filtered_vaults); + assert_eq!(filtered_vaults.len(), 1); + + for vault in filtered_vaults { + let balance = vault.asset.amount; + balances.insert(vault.asset.info.get_reference().to_vec(), balance); + } + + println!("balances:::: {:?}", balances); + + assert_eq!(balances.len(), 5); +} diff --git a/contracts/liquidity_hub/vault-manager/tests/integration.rs b/contracts/liquidity_hub/vault-manager/tests/integration.rs new file mode 100644 index 00000000..ea550bd9 --- /dev/null +++ b/contracts/liquidity_hub/vault-manager/tests/integration.rs @@ -0,0 +1,1631 @@ +extern crate core; + +use std::cell::RefCell; + +use cosmwasm_std::{ + coin, coins, to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, Uint128, WasmMsg, +}; +use cw_ownable::OwnershipError; + +use vault_manager::ContractError; +use white_whale::fee::Fee; +use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; +use white_whale::pool_network::pair::PoolFee; +use white_whale::vault_manager::{ + AssetQueryParams, FilterVaultBy, LpTokenType, PaybackAssetResponse, VaultFee, +}; + +use crate::common::suite::TestingSuite; +use crate::common::MOCK_CONTRACT_ADDR; + +mod common; + +#[test] +fn instantiate_vault_manager_successful() { + let mut suite = TestingSuite::default_with_balances(vec![]); + + suite.create_cw20_token(); + + let cw20_token = suite.cw20_tokens[0].clone().into_string(); + + suite.instantiate_err( + LpTokenType::TokenFactory, + Asset { + info: AssetInfo::Token { + contract_addr: cw20_token.clone(), + }, + amount: Uint128::new(1_000u128), + }, + |error| { + assert!(error + .root_cause() + .to_string() + .contains("Vault creation fee must be native token")); + }, + ); + + suite.instantiate( + MOCK_CONTRACT_ADDR.to_string(), + LpTokenType::TokenFactory, + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + ); + + let cw20_code_id = suite.create_cw20_token(); + suite.instantiate( + MOCK_CONTRACT_ADDR.to_string(), + LpTokenType::Cw20(cw20_code_id), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + ); +} + +#[test] +fn verify_ownership() { + let mut suite = TestingSuite::default_with_balances(vec![]); + let creator = suite.creator(); + let other = suite.senders[1].clone(); + let unauthorized = suite.senders[2].clone(); + + suite + .instantiate_default() + .query_ownership(|result| { + let ownership = result.unwrap(); + assert_eq!(Addr::unchecked(ownership.owner.unwrap()), creator); + }) + .update_ownership( + unauthorized, + cw_ownable::Action::TransferOwnership { + new_owner: other.to_string(), + expiry: None, + }, + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::OwnershipError { .. } => {} + _ => panic!("Wrong error type, should return ContractError::OwnershipError"), + } + }, + ) + .update_ownership( + creator, + cw_ownable::Action::TransferOwnership { + new_owner: other.to_string(), + expiry: None, + }, + |result| { + result.unwrap(); + }, + ) + .update_ownership( + other.clone(), + cw_ownable::Action::AcceptOwnership, + |result| { + result.unwrap(); + }, + ) + .query_ownership(|result| { + let ownership = result.unwrap(); + assert_eq!(Addr::unchecked(ownership.owner.unwrap()), other); + }) + .update_ownership( + other.clone(), + cw_ownable::Action::RenounceOwnership, + |result| { + result.unwrap(); + }, + ) + .query_ownership(|result| { + let ownership = result.unwrap(); + assert!(ownership.owner.is_none()); + }); +} + +#[test] +fn create_vaults() { + let mut suite = TestingSuite::default_with_balances(vec![ + coin(1_000_000_000u128, "uwhale".to_string()), + coin(1_000_000_000u128, "factory/creator/uLP".to_string()), + coin(1_000_000_000u128, "factory/another_creator/uLP".to_string()), + ]); + + let creator = suite.creator(); + let other = suite.senders[1].clone(); + + suite + .instantiate_with_cw20_lp_token() + .create_vault( + creator.clone(), + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + None, + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 2000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }, + vec![coin(900u128, "uwhale".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::InvalidVaultCreationFee { .. } => {} + _ => panic!( + "Wrong error type, should return ContractError::InvalidVaultCreationFee" + ), + } + }, + ) + .create_vault( + creator, + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + None, + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 2000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .create_vault( + other.clone(), + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + Some("cheaper_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 20000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(1u128, 10000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .create_vault( + other, + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + Some("cheaper_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 20000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(1u128, 10000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::ExistingVault { .. } => {} + _ => panic!("Wrong error type, should return ContractError::ExistingVault"), + } + }, + ) + .query_vaults(None, None, |result| { + let vaults_response = result.unwrap(); + + assert_eq!(vaults_response.vaults.len(), 2); + assert_eq!(vaults_response.vaults[0].identifier, "0".to_string()); + assert_eq!( + vaults_response.vaults[1].identifier, + "cheaper_vault".to_string() + ); + }); +} + +#[test] +fn deposit_withdraw() { + let mut suite = TestingSuite::default_with_balances(vec![ + coin(1_000_000_000u128, "uwhale".to_string()), + coin(1_000_000_000u128, "uluna".to_string()), + coin(1_000_000_000u128, "factory/creator/uLP".to_string()), + coin(1_000_000_000u128, "factory/another_creator/uLP".to_string()), + ]); + + let creator = suite.creator(); + let other = suite.senders[1].clone(); + + let vault_lp_addr = RefCell::new(AssetInfo::Token { + contract_addr: "".to_string(), + }); + + suite + .instantiate_with_cw20_lp_token() + .create_vault( + creator.clone(), + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + None, + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 2000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .update_config( + creator.clone(), + None, + None, + None, + None, + Some(false), + Some(false), + vec![], + |result| { + result.unwrap(); + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "0".to_string(), + vec![coin(5_000u128, "uluna".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::Unauthorized { .. } => {} + _ => panic!("Wrong error type, should return ContractError::Unauthorized"), + } + }, + ) + .update_config( + creator.clone(), + None, + None, + None, + None, + Some(true), + None, + vec![], + |result| { + result.unwrap(); + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "unexisting_vault".to_string(), + vec![coin(5_000u128, "uluna".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::NonExistentVault { .. } => {} + _ => panic!("Wrong error type, should return ContractError::NonExistentVault"), + } + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "0".to_string(), + vec![coin(5_000u128, "uluna".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::AssetMismatch { .. } => {} + _ => panic!("Wrong error type, should return ContractError::AssetMismatch"), + } + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "0".to_string(), + vec![coin(3_000u128, "uwhale".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::FundsMismatch { .. } => {} + _ => panic!("Wrong error type, should return ContractError::FundsMismatch"), + } + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + "0".to_string(), + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::InvalidInitialLiquidityAmount { .. } => {} + _ => panic!("Wrong error type, should return ContractError::InvalidInitialLiquidityAmount"), + } + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "0".to_string(), + vec![coin(5_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .query_vault(FilterVaultBy::Identifier("0".to_string()), |result| { + let vault_response = result.unwrap(); + let vault = vault_response.vaults.get(0).unwrap(); + *vault_lp_addr.borrow_mut() = vault.lp_asset.clone(); + + assert_eq!( + vault.asset, + Asset { + amount: Uint128::new(5_000u128), + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }) + .query_vault(FilterVaultBy::Asset(AssetQueryParams { + asset_info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + start_after: None, + limit: None, + }), |result| { + let vault_response = result.unwrap(); + let vault = vault_response.vaults.get(0).unwrap(); + *vault_lp_addr.borrow_mut() = vault.lp_asset.clone(); + + assert_eq!( + vault.asset, + Asset { + amount: Uint128::new(5_000u128), + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }) + .query_vault(FilterVaultBy::LpAsset(vault_lp_addr.clone().into_inner()), |result| { + let vault_response = result.unwrap(); + let vault = vault_response.vaults.get(0).unwrap(); + *vault_lp_addr.borrow_mut() = vault.lp_asset.clone(); + + assert_eq!( + vault.asset, + Asset { + amount: Uint128::new(5_000u128), + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }) + .query_share(Asset { info: vault_lp_addr.clone().into_inner(), amount: Uint128::new(1_000u128) }, |result| { + let response = result.unwrap(); + assert_eq!( + response.share, + Asset { + amount: Uint128::new(1_000u128), + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }); + + let vault_manager = suite.vault_manager_addr.clone(); + let random_cw20_token = suite.cw20_tokens.get(0).unwrap().clone(); + + suite + .query_balance( + vault_lp_addr.clone().into_inner(), + creator.clone(), + |result| { + // 4k to the user + assert_eq!(result, Uint128::new(4_000u128)); + }, + ) + .query_balance( + vault_lp_addr.clone().into_inner(), + vault_manager.clone(), + |result| { + // 1k in vault + assert_eq!(result, Uint128::new(1_000u128)); + }, + ) + .deposit( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "0".to_string(), + vec![coin(5_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .query_balance( + vault_lp_addr.clone().into_inner(), + other.clone(), + |result| { + assert_eq!(result, Uint128::new(5_000u128)); + }, + ) + .withdraw( + other.clone(), + Asset { + info: vault_lp_addr.clone().into_inner(), + amount: Uint128::new(2_000u128), + }, + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::Unauthorized { .. } => {} + _ => panic!("Wrong error type, should return ContractError::Unauthorized"), + } + }, + ) + .withdraw( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "factory/another_creator/uLP".to_string(), + }, + amount: Uint128::new(2_000u128), + }, + vec![coin(2_000u128, "factory/another_creator/uLP".to_string())], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::NonExistentVault { .. } => {} + _ => panic!("Wrong error type, should return ContractError::NonExistentVault"), + } + }, + ) + .update_config( + creator.clone(), + None, + None, + None, + None, + None, + Some(true), + vec![], + |result| { + result.unwrap(); + }, + ) + .withdraw( + other.clone(), + Asset { + info: AssetInfo::Token { + contract_addr: random_cw20_token.to_string(), + }, + amount: Uint128::new(2_000u128), + }, + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::NonExistentVault { .. } => {} + _ => panic!("Wrong error type, should return ContractError::NonExistentVault"), + } + }, + ) + .withdraw( + other.clone(), + Asset { + info: vault_lp_addr.clone().into_inner(), + amount: Uint128::new(2_000u128), + }, + vec![], + |result| { + result.unwrap(); + }, + ) + .query_balance( + vault_lp_addr.clone().into_inner(), + other.clone(), + |result| { + assert_eq!(result, Uint128::new(3_000u128)); + }, + ) + .withdraw( + creator.clone(), + Asset { + info: vault_lp_addr.clone().into_inner(), + amount: Uint128::new(4_000u128), + }, + vec![], + |result| { + result.unwrap(); + }, + ) + .query_balance( + vault_lp_addr.clone().into_inner(), + creator.clone(), + |result| { + assert_eq!(result, Uint128::zero()); + }, + ); + + // create cw20 vault + suite + .create_vault( + creator.clone(), + AssetInfo::Token { + contract_addr: random_cw20_token.clone().to_string(), + }, + Some("cw_20_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 2000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .increase_allowance( + creator.clone(), + Addr::unchecked(random_cw20_token.clone()), + Uint128::new(5_000u128), + vault_manager.clone(), + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::Token { + contract_addr: random_cw20_token.clone().to_string(), + }, + amount: Uint128::new(5_000u128), + }, + "cw_20_vault".to_string(), + vec![], + |result| { + result.unwrap(); + }, + ); +} + +#[test] +pub fn update_config() { + let mut suite = TestingSuite::default_with_balances(vec![ + coin(1_000_000_000u128, "uwhale".to_string()), + coin(1_000_000_000u128, "uluna".to_string()), + coin(1_000_000_000u128, "factory/creator/uLP".to_string()), + coin(1_000_000_000u128, "factory/another_creator/uLP".to_string()), + ]); + + let creator = suite.creator(); + let unauthorized = suite.senders[2].clone(); + + let initial_config = RefCell::new(white_whale::vault_manager::Config { + lp_token_type: LpTokenType::TokenFactory, + whale_lair_addr: Addr::unchecked(""), + vault_creation_fee: Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Default::default(), + }, + flash_loan_enabled: true, + deposit_enabled: true, + withdraw_enabled: true, + }); + suite + .instantiate_with_cw20_lp_token() + .query_config(|response| { + let config = response.unwrap(); + *initial_config.borrow_mut() = config; + }) + .update_config( + unauthorized.clone(), + None, + None, + None, + None, + Some(false), + Some(false), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + if err != ContractError::OwnershipError(OwnershipError::NotOwner) { + panic!("Wrong error type, should return OwnershipError::NotOwner"); + } + }, + ) + .update_config( + creator.clone(), + Some(Addr::unchecked("migaloo1gqjwmexg70ajk439ckfjq0uw2k3u2qmqwy6axu").to_string()), + Some(Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000u128), + }), + Some(123), + Some(false), + Some(false), + Some(false), + vec![], + |result| { + result.unwrap(); + }, + ) + .query_config(|response| { + let new_config = response.unwrap(); + assert_ne!(new_config, initial_config.borrow().clone()); + assert_eq!( + new_config, + white_whale::vault_manager::Config { + lp_token_type: LpTokenType::Cw20(123), + whale_lair_addr: Addr::unchecked( + "migaloo1gqjwmexg70ajk439ckfjq0uw2k3u2qmqwy6axu" + ), + vault_creation_fee: Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000u128), + }, + flash_loan_enabled: false, + deposit_enabled: false, + withdraw_enabled: false, + } + ); + }); + + suite.instantiate_default().update_config( + creator.clone(), + Some(Addr::unchecked("migaloo1gqjwmexg70ajk439ckfjq0uw2k3u2qmqwy6axu").to_string()), + Some(Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000u128), + }), + Some(123), + Some(false), + Some(false), + Some(false), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::InvalidLpTokenType { .. } => {} + _ => panic!("Wrong error type, should return ContractError::InvalidLpTokenType"), + } + }, + ); +} + +#[test] +pub fn successful_flashloan() { + let mut suite = TestingSuite::default_with_balances(vec![ + coin(1_000_000_000u128, "uwhale".to_string()), + coin(1_000_000_000u128, "uluna".to_string()), + ]); + + let creator = suite.creator(); + let other = suite.senders[1].clone(); + + suite + .instantiate_with_cw20_lp_token() + .create_vault( + creator.clone(), + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + Some("whale_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(2u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + "whale_vault".to_string(), + vec![coin(100_000_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ); + + // create pools to arb + suite + .create_pool( + [ + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + ], + [6u8, 6u8], + PoolFee { + protocol_fee: Fee { + share: Default::default(), + }, + swap_fee: Fee { + share: Default::default(), + }, + burn_fee: Fee { + share: Default::default(), + }, + }, + PairType::ConstantProduct, + false, + ) + .create_pool( + [ + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + ], + [6u8, 6u8], + PoolFee { + protocol_fee: Fee { + share: Default::default(), + }, + swap_fee: Fee { + share: Default::default(), + }, + burn_fee: Fee { + share: Default::default(), + }, + }, + PairType::ConstantProduct, + false, + ); + + let balanced_pool = suite.pools[0].clone(); + let skewed_pool = suite.pools[1].clone(); + + let amount_balanced_pool = RefCell::new(Uint128::zero()); + let amount_skewed_pool = RefCell::new(Uint128::zero()); + + let other_balance = RefCell::new(Uint128::zero()); + + suite.query_balance( + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + other.clone(), + |result| { + *other_balance.borrow_mut() = result; + }, + ); + + // arb the pool with a flashloan + + // step 1 -> 50_000 whale for 95_238 luna on pool 1 + // step 2 -> 95_238 luna for 86_956 whale on pool 2 + // step 3 -> repay loan, pocket the difference which is 86_956 - 50_000 - 150 (fees) = 36_806 -> profit + + suite + .provide_liquidity( + creator.clone(), + [ + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(1_000_000), + }, + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000_000), + }, + ], + balanced_pool.clone(), + &vec![ + coin(1_000_000u128, "uluna".to_string()), + coin(1_000_000u128, "uwhale".to_string()), + ], + |result| { + result.unwrap(); + }, + ) + .provide_liquidity( + creator.clone(), + [ + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(2_000_000), + }, + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000_000), + }, + ], + skewed_pool.clone(), + &vec![ + coin(2_000_000u128, "uluna".to_string()), + coin(1_000_000u128, "uwhale".to_string()), + ], + |result| { + result.unwrap(); + }, + ) + .simulate_swap( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + balanced_pool.clone(), + |result| { + *amount_balanced_pool.borrow_mut() = result.unwrap().return_amount; + }, + ) + .simulate_swap( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + skewed_pool.clone(), + |result| { + *amount_skewed_pool.borrow_mut() = result.unwrap().return_amount; + }, + ) + .query_vault( + FilterVaultBy::Identifier("whale_vault".to_string()), + |result| { + let vault_response = result.unwrap(); + let vault = vault_response.vaults.get(0).unwrap(); + + assert_eq!( + vault.asset, + Asset { + amount: Uint128::new(100_000_000u128), + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }, + ) + .query_payback( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(500_000), + }, + "whale_vault".to_string(), + |result| { + let payback = result.unwrap(); + assert_eq!( + payback, + PaybackAssetResponse { + asset_info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + payback_amount: Uint128::new(501_500u128), + protocol_fee: Uint128::new(500u128), + flash_loan_fee: Uint128::new(1_000u128), + } + ); + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000u128), + }, + "whale_vault".to_string(), + vec![ + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: skewed_pool.to_string(), + msg: to_json_binary(&white_whale::pool_network::pair::ExecuteMsg::Swap { + offer_asset: Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + max_spread: Some(Decimal::percent(50u64)), + belief_price: None, + to: None, + }) + .unwrap(), + funds: vec![coin(50_000u128, "uwhale".to_string())], + }), + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: balanced_pool.to_string(), + msg: to_json_binary(&white_whale::pool_network::pair::ExecuteMsg::Swap { + offer_asset: Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: amount_skewed_pool.clone().into_inner(), + }, + max_spread: Some(Decimal::percent(50u64)), + belief_price: None, + to: None, + }) + .unwrap(), + funds: vec![coin( + amount_skewed_pool.clone().into_inner().u128(), + "uluna".to_string(), + )], + }), + ], + |result| { + result.unwrap(); + }, + ) + .query_vault( + FilterVaultBy::Identifier("whale_vault".to_string()), + |result| { + let vault_response = result.unwrap(); + let vault = vault_response.vaults.get(0).unwrap(); + + assert_eq!( + vault.asset, + Asset { + amount: Uint128::new(100_000_100u128), // the original amount + flashloan fees + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }, + ) + .query_balance( + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + other.clone(), + |result| { + assert_eq!( + result, + other_balance.clone().into_inner() + Uint128::new(36_806) + ); // original amount before flashloan + profits + }, + ); +} + +#[test] +pub fn unsuccessful_flashloan() { + let mut suite = TestingSuite::default_with_balances(vec![ + coin(1_000_000_000u128, "uwhale".to_string()), + coin(1_000_000_000u128, "uluna".to_string()), + ]); + + let creator = suite.creator(); + let other = suite.senders[1].clone(); + + suite.instantiate_with_cw20_lp_token().create_cw20_token(); + + let cw20_token = suite.cw20_tokens.get(0).unwrap().clone(); + let vault_manager = suite.vault_manager_addr.clone(); + // create some vaults + + suite + .create_vault( + creator.clone(), + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + Some("whale_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(2u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + "whale_vault".to_string(), + vec![coin(100_000_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .create_vault( + creator.clone(), + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + Some("luna_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(2u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + "luna_vault".to_string(), + vec![coin(100_000_000u128, "uluna".to_string())], + |result| { + result.unwrap(); + }, + ) + .create_vault( + creator.clone(), + AssetInfo::Token { + contract_addr: cw20_token.clone().to_string(), + }, + Some("cw20_vault".to_string()), + VaultFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + flash_loan_fee: Fee { + share: Decimal::from_ratio(2u128, 1000u128), + }, + }, + vec![coin(1_000u128, "uwhale".to_string())], + |result| { + result.unwrap(); + }, + ) + .increase_allowance( + creator.clone(), + cw20_token.clone(), + Uint128::new(100_000_000u128), + vault_manager.clone(), + ) + .deposit( + creator.clone(), + Asset { + info: AssetInfo::Token { + contract_addr: cw20_token.clone().to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + "cw20_vault".to_string(), + vec![], + |result| { + result.unwrap(); + }, + ); + + // create pools to arb + suite + .create_pool( + [ + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + ], + [6u8, 6u8], + PoolFee { + protocol_fee: Fee { + share: Default::default(), + }, + swap_fee: Fee { + share: Default::default(), + }, + burn_fee: Fee { + share: Default::default(), + }, + }, + PairType::ConstantProduct, + false, + ) + .create_pool( + [ + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + ], + [6u8, 6u8], + PoolFee { + protocol_fee: Fee { + share: Default::default(), + }, + swap_fee: Fee { + share: Default::default(), + }, + burn_fee: Fee { + share: Default::default(), + }, + }, + PairType::ConstantProduct, + false, + ); + + let balanced_pool = suite.pools[0].clone(); + let skewed_pool = suite.pools[1].clone(); + + let amount_balanced_pool = RefCell::new(Uint128::zero()); + let amount_skewed_pool = RefCell::new(Uint128::zero()); + + let other_balance = RefCell::new(Uint128::zero()); + + suite.query_balance( + AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + other.clone(), + |result| { + *other_balance.borrow_mut() = result; + }, + ); + + // arb the pool with a flashloan + + // step 1 -> 50_000 whale for 95_238 luna on pool 1 + // step 2 -> 95_238 luna for 86_956 whale on pool 2 + // step 3 -> repay loan, pocket the difference which is 86_956 - 50_000 - 1500 (fees) = 35_456 -> profit + + suite + .provide_liquidity( + creator.clone(), + [ + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(1_000_000), + }, + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000_000), + }, + ], + balanced_pool.clone(), + &vec![ + coin(1_000_000u128, "uluna".to_string()), + coin(1_000_000u128, "uwhale".to_string()), + ], + |result| { + result.unwrap(); + }, + ) + .provide_liquidity( + creator.clone(), + [ + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(2_000_000), + }, + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(1_000_000), + }, + ], + skewed_pool.clone(), + &vec![ + coin(2_000_000u128, "uluna".to_string()), + coin(1_000_000u128, "uwhale".to_string()), + ], + |result| { + result.unwrap(); + }, + ) + .simulate_swap( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + balanced_pool.clone(), + |result| { + *amount_balanced_pool.borrow_mut() = result.unwrap().return_amount; + }, + ) + .simulate_swap( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + skewed_pool.clone(), + |result| { + *amount_skewed_pool.borrow_mut() = result.unwrap().return_amount; + }, + ) + .query_vault( + FilterVaultBy::Identifier("whale_vault".to_string()), + |result| { + let vault_response = result.unwrap(); + let vault = vault_response.vaults.get(0).unwrap(); + + assert_eq!( + vault.asset, + Asset { + amount: Uint128::new(100_000_000u128), + info: AssetInfo::NativeToken { + denom: "uwhale".to_string() + }, + } + ); + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(500_000), + }, + "unexisting_vault".to_string(), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::NonExistentVault { .. } => {} + _ => panic!("Wrong error type, should return ContractError::NonExistentVault"), + } + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + amount: Uint128::new(500_000), + }, + "whale_vault".to_string(), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::AssetMismatch { .. } => {} + _ => panic!("Wrong error type, should return ContractError::AssetMismatch"), + } + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000_000_000_000), + }, + "whale_vault".to_string(), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::InsufficientAssetBalance { .. } => {} + _ => panic!( + "Wrong error type, should return ContractError::InsufficientAssetBalance" + ), + } + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + "whale_vault".to_string(), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::NegativeProfit { .. } => {} + _ => panic!("Wrong error type, should return ContractError::NegativeProfit"), + } + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + "whale_vault".to_string(), + vec![ + // try to drain a native token vault + CosmosMsg::Bank(BankMsg::Send { + to_address: other.clone().to_string(), + amount: coins(100_000_000u128, "uluna"), + }), + ], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + // This should be failing when doing + // `if original_native_assets_count > new_balances.len()` in the after_flashloan() function. + // However it does not because the BankKeeper mock returns 0 for denoms that are not + // in the balances map, which in the cosmos sdk doesn't happen as it only returns + // the non-zero values. + match err { + ContractError::FlashLoanLoss { .. } => {} + _ => panic!("Wrong error type, should return ContractError::FlashLoanLoss"), + } + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + "whale_vault".to_string(), + vec![ + // try to drain the cw20 token vault + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: cw20_token.clone().to_string(), + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { + recipient: other.clone().to_string(), + amount: Uint128::new(100_000_000u128), + }) + .unwrap(), + funds: vec![], + }), + ], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::FlashLoanLoss { .. } => {} + _ => panic!("Wrong error type, should return ContractError::FlashLoanLoss"), + } + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + "whale_vault".to_string(), + vec![ + // try to drain the cw20 token vault + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: vault_manager.clone().to_string(), + msg: to_json_binary(&white_whale::vault_manager::ExecuteMsg::Deposit { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + vault_identifier: "whale_vault".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::Unauthorized { .. } => {} + _ => panic!("Wrong error type, should return ContractError::Unauthorized"), + } + }, + ) + .update_config( + creator.clone(), + None, + None, + None, + Some(false), + None, + None, + vec![], + |result| { + result.unwrap(); + }, + ) + .flashloan( + other.clone(), + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(50_000), + }, + "whale_vault".to_string(), + vec![], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::Unauthorized { .. } => {} + _ => panic!("Wrong error type, should return ContractError::Unauthorized"), + } + }, + ) + .callback(other.clone(), |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::Unauthorized { .. } => {} + _ => panic!("Wrong error type, should return ContractError::Unauthorized"), + } + }); + + suite + .query_payback( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000_000_000_000), + }, + "whale_vault".to_string(), + |result| { + assert!(result.unwrap_err().to_string().contains( + "The requested vault doesn't have enough balance to serve the demand" + )); + }, + ) + .query_payback( + Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(5_000_000_000_000), + }, + "non_existent_vault".to_string(), + |result| { + assert!(result + .unwrap_err() + .to_string() + .contains("Vault doesn't exist")); + }, + ); +} diff --git a/contracts/liquidity_hub/vault-network/vault/src/contract.rs b/contracts/liquidity_hub/vault-network/vault/src/contract.rs index be453023..7f9e9682 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/contract.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/contract.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - attr, entry_point, to_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, ReplyOn, + attr, entry_point, to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, ReplyOn, Response, StdError, StdResult, SubMsg, WasmMsg, }; use cw2::{get_contract_version, set_contract_version}; @@ -153,7 +153,7 @@ pub fn instantiate( msg: WasmMsg::Instantiate { admin: None, code_id: msg.token_id, - msg: to_binary(&white_whale::pool_network::token::InstantiateMsg { + msg: to_json_binary(&white_whale::pool_network::token::InstantiateMsg { name: lp_label.clone(), symbol: lp_symbol, decimals: 6, diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs index b5a10477..3094f292 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs @@ -97,7 +97,8 @@ mod test { use cosmwasm_std::{ coins, testing::{mock_env, mock_info}, - to_binary, Addr, BankMsg, CosmosMsg, Decimal, ReplyOn, Response, SubMsg, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, ReplyOn, Response, SubMsg, Uint128, + WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -311,7 +312,7 @@ mod test { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "vault_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(1), }) .unwrap(), diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs index e2c61bb8..e9ec78cd 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs @@ -5,7 +5,7 @@ ))] use cosmwasm_std::coins; use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Env, MessageInfo, Response, Uint128, Uint256, WasmMsg, + to_json_binary, CosmosMsg, DepsMut, Env, MessageInfo, Response, Uint128, Uint256, WasmMsg, }; use cw20::{AllowanceResponse, Cw20ExecuteMsg}; @@ -81,7 +81,7 @@ pub fn deposit( messages.push( WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.clone().into_string(), amount, @@ -135,7 +135,7 @@ pub fn deposit( let collected_protocol_fees = COLLECTED_PROTOCOL_FEES.load(deps.storage)?; let total_deposits = config .asset_info - .query_pool(&deps.querier, deps.api, env.contract.address.clone())? + .query_balance(&deps.querier, deps.api, env.contract.address.clone())? .checked_sub(collected_protocol_fees.amount)? .checked_sub(deposit_amount)?; @@ -192,7 +192,7 @@ fn mint_lp_token_msg( } else { Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -204,7 +204,7 @@ fn mint_lp_token_msg( ))] Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -214,7 +214,7 @@ mod test { use cosmwasm_std::{ coins, testing::{mock_dependencies, mock_env, mock_info}, - to_binary, Addr, BankMsg, CosmosMsg, Response, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, CosmosMsg, Response, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; use cw_multi_test::Executor; @@ -285,7 +285,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: env.contract.address.to_string(), amount: Uint128::new(1_000), }) @@ -294,7 +294,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "creator".to_string(), amount: Uint128::new(4_000), }) @@ -361,7 +361,7 @@ mod test { WasmMsg::Execute { contract_addr: "vault_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "creator".to_string(), recipient: env.contract.address.clone().into_string(), amount: Uint128::new(5_000), @@ -371,7 +371,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: env.contract.address.into_string(), amount: Uint128::new(1_000), }) @@ -380,7 +380,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "creator".to_string(), amount: Uint128::new(4_000), }) diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs index 5d5b35ae..9ea8da16 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - coins, to_binary, Binary, CosmosMsg, DepsMut, Env, MessageInfo, OverflowError, Response, + coins, to_json_binary, Binary, CosmosMsg, DepsMut, Env, MessageInfo, OverflowError, Response, StdError, Uint128, WasmMsg, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; @@ -54,7 +54,7 @@ pub fn flash_loan( if let AssetInfo::Token { contract_addr } = config.asset_info.clone() { let loan_msg = WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: info.sender.clone().into_string(), amount, })?, @@ -84,7 +84,7 @@ pub fn flash_loan( messages.push( WasmMsg::Execute { contract_addr: env.contract.address.into_string(), - msg: to_binary(&ExecuteMsg::Callback(CallbackMsg::AfterTrade { + msg: to_json_binary(&ExecuteMsg::Callback(CallbackMsg::AfterTrade { old_balance, loan_amount: amount, }))?, @@ -104,7 +104,7 @@ mod test { use cosmwasm_std::{ coins, testing::{mock_dependencies, mock_dependencies_with_balance, mock_env}, - to_binary, Addr, BankMsg, Response, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, Response, Uint128, WasmMsg, }; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault::Config; @@ -147,7 +147,7 @@ mod test { mock_creator(), white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: Uint128::new(5_000), - msg: to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(), + msg: to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(), }, ); @@ -159,7 +159,7 @@ mod test { let mut deps = mock_dependencies_with_balance(&coins(10_000, "uluna")); let env = mock_env(); - let callback_msg = to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); + let callback_msg = to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); instantiate( deps.as_mut(), @@ -201,7 +201,7 @@ mod test { let mut deps = mock_dependencies_with_balance(&coins(10_000, "uluna")); let env = mock_env(); - let callback_msg = to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); + let callback_msg = to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); instantiate( deps.as_mut(), @@ -244,12 +244,14 @@ mod test { WasmMsg::Execute { contract_addr: env.contract.address.into_string(), funds: vec![], - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::Callback( - white_whale::vault_network::vault::CallbackMsg::AfterTrade { - old_balance: Uint128::new(10_000), - loan_amount: Uint128::new(5_000) - } - )) + msg: to_json_binary( + &white_whale::vault_network::vault::ExecuteMsg::Callback( + white_whale::vault_network::vault::CallbackMsg::AfterTrade { + old_balance: Uint128::new(10_000), + loan_amount: Uint128::new(5_000) + } + ) + ) .unwrap() } ]) @@ -268,7 +270,7 @@ mod test { vec![], ); - let callback_msg = to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); + let callback_msg = to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); // inject config CONFIG @@ -313,7 +315,7 @@ mod test { WasmMsg::Execute { contract_addr: "vault_token".to_string(), funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: mock_creator().sender.into_string(), amount: Uint128::new(5_000) }) @@ -327,12 +329,14 @@ mod test { WasmMsg::Execute { contract_addr: env.contract.address.into_string(), funds: vec![], - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::Callback( - white_whale::vault_network::vault::CallbackMsg::AfterTrade { - old_balance: Uint128::new(10_000), - loan_amount: Uint128::new(5_000) - } - )) + msg: to_json_binary( + &white_whale::vault_network::vault::ExecuteMsg::Callback( + white_whale::vault_network::vault::CallbackMsg::AfterTrade { + old_balance: Uint128::new(10_000), + loan_amount: Uint128::new(5_000) + } + ) + ) .unwrap() } ]) diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs index b08de1b0..b0b0d5b0 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{from_binary, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{from_json, DepsMut, Env, MessageInfo, Response}; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault::{Cw20HookMsg, Cw20ReceiveMsg}; @@ -27,14 +27,14 @@ pub fn receive( return Err(VaultError::ExternalCallback {}); } - match from_binary(&msg.msg)? { + match from_json(&msg.msg)? { Cw20HookMsg::Withdraw {} => withdraw(deps, env, msg.sender, msg.amount), } } #[cfg(test)] mod test { - use cosmwasm_std::{to_binary, Addr, Uint128}; + use cosmwasm_std::{to_json_binary, Addr, Uint128}; #[cfg(any( feature = "token_factory", @@ -89,7 +89,7 @@ mod test { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, ); @@ -136,7 +136,7 @@ mod test { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, ); diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs index fe5eacc9..82afb514 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - coins, to_binary, BankMsg, CosmosMsg, Decimal, DepsMut, Env, Response, Uint128, WasmMsg, + coins, to_json_binary, BankMsg, CosmosMsg, Decimal, DepsMut, Env, Response, Uint128, WasmMsg, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; @@ -75,7 +75,7 @@ pub fn withdraw( .into(), AssetInfo::Token { contract_addr } => WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: sender.into_string(), amount: withdraw_amount, })?, @@ -116,7 +116,7 @@ fn burn_lp_asset_msg( } else { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } @@ -127,7 +127,7 @@ fn burn_lp_asset_msg( ))] Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } @@ -137,7 +137,7 @@ mod tests { use cosmwasm_std::{ coins, testing::{mock_env, mock_info}, - to_binary, Addr, BankMsg, Response, SubMsg, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, Response, SubMsg, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; use cw_multi_test::Executor; @@ -171,8 +171,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ); @@ -191,8 +193,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ); @@ -248,8 +252,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { amount: Uint128::new(2_000), sender: mock_creator().sender.into_string(), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ); @@ -301,7 +307,7 @@ mod tests { &Cw20ExecuteMsg::Send { contract: vault_addr.to_string(), amount: Uint128::new(4_500), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, &[], @@ -409,7 +415,7 @@ mod tests { &Cw20ExecuteMsg::Send { contract: vault_addr.to_string(), amount: Uint128::new(4_500), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, &[], @@ -507,8 +513,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { amount: Uint128::new(5_000), sender: mock_creator().sender.into_string(), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ) @@ -539,7 +547,7 @@ mod tests { reply_on: cosmwasm_std::ReplyOn::Never, msg: WasmMsg::Execute { contract_addr: "lp_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(5000) }) .unwrap(), @@ -617,8 +625,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { amount: Uint128::new(5_000), sender: mock_creator().sender.into_string(), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ) @@ -639,7 +649,7 @@ mod tests { reply_on: cosmwasm_std::ReplyOn::Never, msg: WasmMsg::Execute { contract_addr: "vault_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { amount: Uint128::new(4_999), recipient: mock_creator().sender.into_string(), }) @@ -654,7 +664,7 @@ mod tests { reply_on: cosmwasm_std::ReplyOn::Never, msg: WasmMsg::Execute { contract_addr: "lp_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(5000) }) .unwrap(), diff --git a/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs b/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs index b3f2eacc..c1f4efbe 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs @@ -1,16 +1,16 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use crate::error::VaultError; use crate::state::CONFIG; pub fn get_config(deps: Deps) -> Result { - Ok(to_binary(&CONFIG.load(deps.storage)?)?) + Ok(to_json_binary(&CONFIG.load(deps.storage)?)?) } #[cfg(test)] mod test { use cosmwasm_std::{ - from_binary, + from_json, testing::{mock_dependencies, mock_env}, Addr, }; @@ -45,7 +45,7 @@ mod test { CONFIG.save(&mut deps.storage, &config).unwrap(); - let res: Config = from_binary( + let res: Config = from_json( &query( deps.as_ref(), env, diff --git a/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs b/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs index 9e2e2c1b..f695a04d 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps, Uint128, Uint256}; +use cosmwasm_std::{to_json_binary, Binary, Deps, Uint128, Uint256}; use white_whale::vault_network::vault::PaybackAmountResponse; use crate::error::VaultError; @@ -18,7 +18,7 @@ pub fn get_payback_amount(deps: Deps, amount: Uint128) -> Result Result { if all_time { let fees = all_time_fees_storage_item.load(deps.storage)?; - return Ok(to_binary(&ProtocolFeesResponse { fees })?); + return Ok(to_json_binary(&ProtocolFeesResponse { fees })?); } let fees = fees_storage_item .ok_or_else(|| StdError::generic_err("fees_storage_item was None"))? .load(deps.storage)?; - Ok(to_binary(&ProtocolFeesResponse { fees })?) + Ok(to_json_binary(&ProtocolFeesResponse { fees })?) } #[cfg(test)] mod test { use cosmwasm_std::{ - from_binary, + from_json, testing::{mock_dependencies, mock_env}, Uint128, }; @@ -68,7 +68,7 @@ mod test { ) .unwrap(); - let res: ProtocolFeesResponse = from_binary( + let res: ProtocolFeesResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -115,7 +115,7 @@ mod test { ) .unwrap(); - let res: ProtocolFeesResponse = from_binary( + let res: ProtocolFeesResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -154,8 +154,7 @@ mod test { .unwrap(); let res: ProtocolFeesResponse = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::BurnedFees {}).unwrap()) - .unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::BurnedFees {}).unwrap()).unwrap(); assert_eq!( res, ProtocolFeesResponse { diff --git a/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs b/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs index 17d2c970..504d898d 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Decimal, Deps, Env, Uint128}; +use cosmwasm_std::{to_json_binary, Binary, Decimal, Deps, Env, Uint128}; use cw20::{BalanceResponse, Cw20QueryMsg}; use white_whale::pool_network::asset::{get_total_share, AssetInfo}; @@ -40,12 +40,12 @@ pub fn get_share(deps: Deps, env: Env, amount: Uint128) -> Result { if contract_addr == "lp_token" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { decimals: 6, name: "lp_token".to_string(), symbol: "uLP".to_string(), @@ -120,7 +120,7 @@ impl WasmMockQuerier { } Cw20QueryMsg::Balance { address } => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&BalanceResponse { + to_json_binary(&BalanceResponse { balance: *self .token_querier .balances @@ -135,10 +135,10 @@ impl WasmMockQuerier { _ => panic!("DO NOT ENTER HERE"), } } else if contract_addr == "vault_token" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::Balance { address } => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&BalanceResponse { + to_json_binary(&BalanceResponse { balance: *self .token_querier .balances @@ -152,7 +152,7 @@ impl WasmMockQuerier { } Cw20QueryMsg::Allowance { owner, spender } => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&AllowanceResponse { + to_json_binary(&AllowanceResponse { allowance: *self .token_querier .allowances diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs index 9da0ac51..fd6cecad 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, WasmMsg}; +use cosmwasm_std::{to_json_binary, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, WasmMsg}; use white_whale::fee::VaultFee; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault::InstantiateMsg; @@ -37,7 +37,7 @@ pub fn create_vault( msg: WasmMsg::Instantiate { admin: Some(env.contract.address.clone().into_string()), code_id: config.vault_id, - msg: to_binary(&InstantiateMsg { + msg: to_json_binary(&InstantiateMsg { owner: env.contract.address.into_string(), asset_info: asset_info.clone(), token_id: config.token_id, @@ -70,7 +70,8 @@ pub fn create_vault( #[cfg(test)] mod tests { use cosmwasm_std::{ - testing::mock_info, to_binary, Addr, Decimal, ReplyOn, Response, StdError, SubMsg, WasmMsg, + testing::mock_info, to_json_binary, Addr, Decimal, ReplyOn, Response, StdError, SubMsg, + WasmMsg, }; use cw_multi_test::Executor; use white_whale::fee::{Fee, VaultFee}; @@ -114,7 +115,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, @@ -159,7 +160,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, @@ -354,7 +355,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, @@ -400,7 +401,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs index ddd62e14..bbd7770f 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, CosmosMsg, DepsMut, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, DepsMut, Response, WasmMsg}; use white_whale::vault_network::vault::MigrateMsg; @@ -42,7 +42,7 @@ fn migrate_vault_msg(vault_addr: Addr, code_id: u64) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: vault_addr.to_string(), new_code_id: code_id, - msg: to_binary(&MigrateMsg {})?, + msg: to_json_binary(&MigrateMsg {})?, })) } diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/remove_vault.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/remove_vault.rs index 9c8b4aca..f85e8026 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/remove_vault.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/remove_vault.rs @@ -72,7 +72,7 @@ mod tests { if event.ty == "wasm" { let expected_attributes = vec![ Attribute { - key: "_contract_addr".to_string(), + key: "_contract_address".to_string(), value: factory_addr.clone().to_string(), }, Attribute { diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs index a1aac9ef..2febb1cd 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs @@ -46,7 +46,7 @@ pub fn update_config( #[cfg(test)] mod tests { - use cosmwasm_std::{from_binary, testing::mock_info, Addr, Response}; + use cosmwasm_std::{from_json, testing::mock_info, Addr, Response}; use white_whale::vault_network::vault_factory::{Config, ExecuteMsg, QueryMsg}; use crate::{ @@ -83,7 +83,7 @@ mod tests { // check query let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config.owner, Addr::unchecked("other_acc")); // check storage @@ -118,7 +118,7 @@ mod tests { // check query let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config.fee_collector_addr, Addr::unchecked("other_acc")); // check storage @@ -160,7 +160,7 @@ mod tests { }; let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config, desired_config); // check storage @@ -202,7 +202,7 @@ mod tests { }; let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config, desired_config); // check storage diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs index 50cbfee5..13b229f1 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use crate::{err::StdResult, state::CONFIG}; @@ -6,7 +6,7 @@ use crate::{err::StdResult, state::CONFIG}; pub fn get_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; - Ok(to_binary(&config)?) + Ok(to_json_binary(&config)?) } #[cfg(test)] diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs index 38cc8e0f..f924b49c 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault_factory::{VaultInfo, VaultsResponse}; @@ -9,10 +9,10 @@ use crate::{asset::AssetReference, err::StdResult, state::VAULTS}; pub fn get_vault(deps: Deps, asset_info: AssetInfo) -> StdResult { let vault_option = VAULTS.may_load(deps.storage, asset_info.get_reference())?; if let Some((vault_addr, _)) = vault_option { - return Ok(to_binary(&vault_addr)?); + return Ok(to_json_binary(&vault_addr)?); } - Ok(to_binary(&vault_option)?) + Ok(to_json_binary(&vault_option)?) } pub fn get_vaults( @@ -21,7 +21,7 @@ pub fn get_vaults( limit: Option, ) -> StdResult { let vaults: Vec = read_vaults(deps.storage, deps.api, start_after, limit)?; - Ok(to_binary(&VaultsResponse { vaults })?) + Ok(to_json_binary(&VaultsResponse { vaults })?) } #[cfg(test)] diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs index d0b7b167..9c31f8d2 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - from_binary, + from_json, testing::{MockApi, MockQuerier, MockStorage}, Env, OwnedDeps, }; @@ -20,7 +20,7 @@ where { let (deps, env) = mock_instantiate(vault_id, token_id); - let res = from_binary(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); + let res = from_json(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); (res, deps, env) } diff --git a/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json b/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json index ad35024b..27712796 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json +++ b/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json @@ -451,6 +451,10 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, "DistributionMsg": { "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", "oneOf": [ @@ -538,6 +542,36 @@ } }, "additionalProperties": false + }, + { + "description": "This maps directly to [MsgVoteWeighted](https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/proto/cosmos/gov/v1beta1/tx.proto#L66-L78) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote_weighted" + ], + "properties": { + "vote_weighted": { + "type": "object", + "required": [ + "options", + "proposal_id" + ], + "properties": { + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/WeightedVoteOption" + } + }, + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false } ] }, @@ -569,7 +603,7 @@ ] }, "channel_id": { - "description": "exisiting channel to send the tokens over", + "description": "existing channel to send the tokens over", "type": "string" }, "timeout": { @@ -687,7 +721,7 @@ "minimum": 0.0 }, "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", "type": "integer", "format": "uint64", "minimum": 0.0 @@ -877,7 +911,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { @@ -893,6 +927,60 @@ }, "additionalProperties": false }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code using a predictable address derivation algorithm implemented in [`cosmwasm_std::instantiate2_address`].\n\nThis is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). `sender` is automatically filled with the current contract's address. `fix_msg` is automatically set to false.", + "type": "object", + "required": [ + "instantiate2" + ], + "properties": { + "instantiate2": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg", + "salt" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "salt": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, { "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", "type": "object", @@ -977,6 +1065,21 @@ "additionalProperties": false } ] + }, + "WeightedVoteOption": { + "type": "object", + "required": [ + "option", + "weight" + ], + "properties": { + "option": { + "$ref": "#/definitions/VoteOption" + }, + "weight": { + "$ref": "#/definitions/Decimal" + } + } } } } diff --git a/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json b/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json index e58a27be..b379d29e 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json +++ b/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json @@ -476,6 +476,10 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, "DistributionMsg": { "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", "oneOf": [ @@ -563,6 +567,36 @@ } }, "additionalProperties": false + }, + { + "description": "This maps directly to [MsgVoteWeighted](https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/proto/cosmos/gov/v1beta1/tx.proto#L66-L78) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote_weighted" + ], + "properties": { + "vote_weighted": { + "type": "object", + "required": [ + "options", + "proposal_id" + ], + "properties": { + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/WeightedVoteOption" + } + }, + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false } ] }, @@ -594,7 +628,7 @@ ] }, "channel_id": { - "description": "exisiting channel to send the tokens over", + "description": "existing channel to send the tokens over", "type": "string" }, "timeout": { @@ -712,7 +746,7 @@ "minimum": 0.0 }, "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", "type": "integer", "format": "uint64", "minimum": 0.0 @@ -902,7 +936,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { @@ -918,6 +952,60 @@ }, "additionalProperties": false }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code using a predictable address derivation algorithm implemented in [`cosmwasm_std::instantiate2_address`].\n\nThis is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). `sender` is automatically filled with the current contract's address. `fix_msg` is automatically set to false.", + "type": "object", + "required": [ + "instantiate2" + ], + "properties": { + "instantiate2": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg", + "salt" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "salt": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, { "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", "type": "object", @@ -1002,6 +1090,21 @@ "additionalProperties": false } ] + }, + "WeightedVoteOption": { + "type": "object", + "required": [ + "option", + "weight" + ], + "properties": { + "option": { + "$ref": "#/definitions/VoteOption" + }, + "weight": { + "$ref": "#/definitions/Decimal" + } + } } } }, diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs b/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs index 9f5586b6..33cf9ecd 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs @@ -1,5 +1,6 @@ use cosmwasm_std::{ - attr, coins, to_binary, Addr, BankMsg, CosmosMsg, DepsMut, Env, MessageInfo, Response, WasmMsg, + attr, coins, to_json_binary, Addr, BankMsg, CosmosMsg, DepsMut, Env, MessageInfo, Response, + WasmMsg, }; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::vault_network::vault::PaybackAmountResponse; @@ -76,7 +77,7 @@ pub fn complete_loan( AssetInfo::Token { contract_addr } => Ok(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: vault, amount: payback_amount.payback_amount, })?, @@ -97,7 +98,7 @@ pub fn complete_loan( AssetInfo::Token { contract_addr } => Ok(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: initiator.clone().into_string(), amount: profit_amount, })?, diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs b/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs index db3f84f5..eede9674 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, CosmosMsg, DepsMut, MessageInfo, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, CosmosMsg, DepsMut, MessageInfo, Response, WasmMsg}; use white_whale::pool_network::asset::Asset; use white_whale::vault_network::vault_router::ExecuteMsg; @@ -51,9 +51,9 @@ pub fn flash_loan( messages.push( WasmMsg::Execute { contract_addr: vault.to_string(), - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { + msg: to_json_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: asset.amount, - msg: to_binary(&ExecuteMsg::NextLoan { + msg: to_json_binary(&ExecuteMsg::NextLoan { initiator: info.sender, source_vault: vault.to_string(), source_vault_asset_info: asset.info.clone(), @@ -76,7 +76,7 @@ pub fn flash_loan( #[cfg(test)] mod tests { use cosmwasm_std::{ - coins, from_binary, to_binary, Attribute, BankMsg, CosmosMsg, Event, Response, Uint128, + coins, from_json, to_json_binary, Attribute, BankMsg, CosmosMsg, Event, Response, Uint128, WasmMsg, }; use cw_multi_test::Executor; @@ -110,7 +110,7 @@ mod tests { let payload = vec![WasmMsg::Execute { contract_addr: dummy_contract_addr.clone().into_string(), - msg: to_binary(&crate::tests::ExecuteMsg::Send { + msg: to_json_binary(&crate::tests::ExecuteMsg::Send { to_address: router_addr.clone(), amount: coins(transfer_amount, "uluna"), }) @@ -140,7 +140,7 @@ mod tests { // verify payload was executed let payload_amount = match payload.first().unwrap() { CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) => { - let msg: crate::tests::ExecuteMsg = from_binary(msg).unwrap(); + let msg: crate::tests::ExecuteMsg = from_json(msg).unwrap(); match msg { crate::tests::ExecuteMsg::Send { amount, .. } => amount, } @@ -296,7 +296,7 @@ mod tests { let payload = vec![WasmMsg::Execute { contract_addr: dummy_contract_addr.clone().into_string(), - msg: to_binary(&crate::tests::ExecuteMsg::Send { + msg: to_json_binary(&crate::tests::ExecuteMsg::Send { to_address: router_addr.clone(), amount: coins(transfer_amount, "uluna"), }) @@ -325,7 +325,7 @@ mod tests { let payload_amount = match payload.first().unwrap() { CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) => { - let msg: crate::tests::ExecuteMsg = from_binary(msg).unwrap(); + let msg: crate::tests::ExecuteMsg = from_json(msg).unwrap(); match msg { crate::tests::ExecuteMsg::Send { amount, .. } => amount, } @@ -336,10 +336,10 @@ mod tests { // verify messages where executed in the right order let events = res.events; let expected_events = vec![ - Event::new("execute").add_attribute("_contract_addr", router_addr.to_string()), + Event::new("execute").add_attribute("_contract_address", router_addr.to_string()), Event::new("wasm").add_attributes(vec![ Attribute { - key: "_contract_addr".to_string(), + key: "_contract_address".to_string(), value: router_addr.to_string(), }, Attribute { @@ -347,10 +347,10 @@ mod tests { value: "flash_loan".to_string(), }, ]), - Event::new("execute").add_attribute("_contract_addr", native_vault_addr.to_string()), + Event::new("execute").add_attribute("_contract_address", native_vault_addr.to_string()), Event::new("wasm").add_attributes(vec![ Attribute { - key: "_contract_addr".to_string(), + key: "_contract_address".to_string(), value: native_vault_addr.to_string(), }, Attribute { @@ -362,10 +362,10 @@ mod tests { value: flashloan_amount.to_string(), }, ]), - Event::new("execute").add_attribute("_contract_addr", router_addr.to_string()), + Event::new("execute").add_attribute("_contract_address", router_addr.to_string()), Event::new("wasm").add_attributes(vec![ Attribute { - key: "_contract_addr".to_string(), + key: "_contract_address".to_string(), value: router_addr.to_string(), }, Attribute { @@ -373,7 +373,8 @@ mod tests { value: "next_loan".to_string(), }, ]), - Event::new("execute").add_attribute("_contract_addr", dummy_contract_addr.to_string()), + Event::new("execute") + .add_attribute("_contract_address", dummy_contract_addr.to_string()), Event::new("transfer").add_attributes(vec![ Attribute { key: "recipient".to_string(), @@ -388,10 +389,10 @@ mod tests { value: payload_amount.first().unwrap().to_string(), }, ]), - Event::new("execute").add_attribute("_contract_addr", router_addr.to_string()), + Event::new("execute").add_attribute("_contract_address", router_addr.to_string()), Event::new("wasm").add_attributes(vec![ Attribute { - key: "_contract_addr".to_string(), + key: "_contract_address".to_string(), value: router_addr.to_string(), }, Attribute { @@ -424,10 +425,10 @@ mod tests { .to_string(), }, ]), - Event::new("execute").add_attribute("_contract_addr", native_vault_addr.to_string()), + Event::new("execute").add_attribute("_contract_address", native_vault_addr.to_string()), Event::new("wasm").add_attributes(vec![ Attribute { - key: "_contract_addr".to_string(), + key: "_contract_address".to_string(), value: native_vault_addr.to_string(), }, Attribute { diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs b/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs index ef9cf131..a24b72a5 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, CosmosMsg, DepsMut, Env, MessageInfo, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, DepsMut, Env, MessageInfo, Response, WasmMsg}; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::vault_network::vault_router::ExecuteMsg; @@ -44,9 +44,9 @@ pub fn next_loan( vec![WasmMsg::Execute { contract_addr: vault.clone(), funds: vec![], - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { + msg: to_json_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: asset.amount, - msg: to_binary(&ExecuteMsg::NextLoan { + msg: to_json_binary(&ExecuteMsg::NextLoan { initiator, source_vault: vault.to_string(), source_vault_asset_info: asset.info.clone(), @@ -64,7 +64,7 @@ pub fn next_loan( WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::CompleteLoan { + msg: to_json_binary(&ExecuteMsg::CompleteLoan { initiator, loaned_assets, })?, diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs b/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs index 1f080f4c..7941783d 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use crate::{err::StdResult, state::CONFIG}; @@ -6,7 +6,7 @@ use crate::{err::StdResult, state::CONFIG}; pub fn get_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; - Ok(to_binary(&config)?) + Ok(to_json_binary(&config)?) } #[cfg(test)] diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs b/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs index 0b6414d9..89349648 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - from_binary, + from_json, testing::{MockApi, MockQuerier, MockStorage}, Env, OwnedDeps, }; @@ -19,7 +19,7 @@ where { let (deps, env) = mock_instantiate(factory_addr); - let res = from_binary(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); + let res = from_json(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); (res, deps, env) } diff --git a/contracts/liquidity_hub/whale_lair/Cargo.toml b/contracts/liquidity_hub/whale_lair/Cargo.toml index e859e8ea..f96985fc 100644 --- a/contracts/liquidity_hub/whale_lair/Cargo.toml +++ b/contracts/liquidity_hub/whale_lair/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "whale-lair" -version = "0.9.1" +version = "0.9.2" authors = ["Kerber0x "] edition.workspace = true description = "The Whale Lair is a bonding contract used to bond WHALE LSDs." @@ -40,6 +40,6 @@ thiserror.workspace = true white-whale.workspace = true [dev-dependencies] -cw-multi-test = "0.16.2" -anyhow = { version = "1.0.68"} +cw-multi-test.workspace = true +anyhow.workspace = true white-whale-testing.workspace = true diff --git a/contracts/liquidity_hub/whale_lair/src/contract.rs b/contracts/liquidity_hub/whale_lair/src/contract.rs index 0470cfa9..0f36218e 100644 --- a/contracts/liquidity_hub/whale_lair/src/contract.rs +++ b/contracts/liquidity_hub/whale_lair/src/contract.rs @@ -1,9 +1,9 @@ use cosmwasm_std::{entry_point, Addr}; -use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::{get_contract_version, set_contract_version}; use semver::Version; -use white_whale::pool_network::asset::AssetInfo; +use white_whale::pool_network::asset::AssetInfo; use white_whale::whale_lair::{Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::error::ContractError; @@ -93,27 +93,32 @@ pub fn execute( growth_rate, fee_distributor_addr, ), + ExecuteMsg::FillRewards { .. } => { + //unimplemented!(); + //todo deposit in next epoch + Ok(Response::default().add_attributes(vec![("action", "fill_rewards".to_string())])) + } } } #[entry_point] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::query_config(deps)?), - QueryMsg::Bonded { address } => to_binary(&queries::query_bonded(deps, address)?), + QueryMsg::Config {} => to_json_binary(&queries::query_config(deps)?), + QueryMsg::Bonded { address } => to_json_binary(&queries::query_bonded(deps, address)?), QueryMsg::Unbonding { address, denom, start_after, limit, - } => to_binary(&queries::query_unbonding( + } => to_json_binary(&queries::query_unbonding( deps, address, denom, start_after, limit, )?), - QueryMsg::Withdrawable { address, denom } => to_binary(&queries::query_withdrawable( + QueryMsg::Withdrawable { address, denom } => to_json_binary(&queries::query_withdrawable( deps, env.block.time, address, @@ -128,15 +133,15 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { let timestamp = timestamp.unwrap_or(env.block.time); // TODO: Make better timestamp handling - to_binary(&queries::query_weight( + to_json_binary(&queries::query_weight( deps, timestamp, address, global_index, )?) } - QueryMsg::TotalBonded {} => to_binary(&queries::query_total_bonded(deps)?), - QueryMsg::GlobalIndex {} => to_binary(&queries::query_global_index(deps)?), + QueryMsg::TotalBonded {} => to_json_binary(&queries::query_total_bonded(deps)?), + QueryMsg::GlobalIndex {} => to_json_binary(&queries::query_global_index(deps)?), } } diff --git a/contracts/liquidity_hub/whale_lair/src/queries.rs b/contracts/liquidity_hub/whale_lair/src/queries.rs index e1cf9b0f..2fb39a5f 100644 --- a/contracts/liquidity_hub/whale_lair/src/queries.rs +++ b/contracts/liquidity_hub/whale_lair/src/queries.rs @@ -1,8 +1,8 @@ use std::collections::HashSet; use cosmwasm_std::{ - to_binary, Decimal, Deps, Order, QueryRequest, StdError, StdResult, Timestamp, Uint128, Uint64, - WasmQuery, + to_json_binary, Decimal, Deps, Order, QueryRequest, StdError, StdResult, Timestamp, Uint128, + Uint64, WasmQuery, }; use cw_storage_plus::Bound; @@ -64,7 +64,7 @@ pub(crate) fn query_bonded(deps: Deps, address: String) -> StdResult"] description = "Common White Whale types and utils" @@ -24,10 +24,13 @@ cosmwasm-std.workspace = true schemars.workspace = true serde.workspace = true cosmwasm-schema.workspace = true +cw-storage-plus.workspace = true cw20.workspace = true cw2.workspace = true protobuf.workspace = true uint.workspace = true osmosis-std-derive.workspace = true prost.workspace = true -prost-types.workspace = true \ No newline at end of file +prost-types.workspace = true +cw-ownable.workspace = true +anybuf.workspace = true \ No newline at end of file diff --git a/packages/white-whale/src/common.rs b/packages/white-whale/src/common.rs new file mode 100644 index 00000000..007347bd --- /dev/null +++ b/packages/white-whale/src/common.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::{Addr, StdError, StdResult, Storage}; +use cw_storage_plus::Item; + +/// Validates that the given address matches the address stored in the given owner_item. +pub fn validate_owner( + storage: &dyn Storage, + owner_item: Item, + address: Addr, +) -> StdResult<()> { + let owner = owner_item.load(storage)?; + + // verify owner + if owner != address { + return Err(StdError::generic_err("Unauthorized")); + } + + Ok(()) +} diff --git a/packages/white-whale/src/constants.rs b/packages/white-whale/src/constants.rs new file mode 100644 index 00000000..39820253 --- /dev/null +++ b/packages/white-whale/src/constants.rs @@ -0,0 +1 @@ +pub const LP_SYMBOL: &str = "uLP"; diff --git a/packages/white-whale/src/epoch_manager/hooks.rs b/packages/white-whale/src/epoch_manager/hooks.rs index 783bbdb8..74a6b66c 100644 --- a/packages/white-whale/src/epoch_manager/hooks.rs +++ b/packages/white-whale/src/epoch_manager/hooks.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Binary, CosmosMsg, StdResult, WasmMsg}; use crate::epoch_manager::epoch_manager::EpochV2; @@ -10,14 +10,14 @@ pub struct EpochChangedHookMsg { impl EpochChangedHookMsg { /// serializes the message - pub fn into_binary(self) -> StdResult { + pub fn into_json_binary(self) -> StdResult { let msg = EpochChangedExecuteMsg::EpochChangedHook(self); - to_binary(&msg) + to_json_binary(&msg) } /// creates a cosmos_msg sending this struct to the named contract pub fn into_cosmos_msg>(self, contract_addr: T) -> StdResult { - let msg = self.into_binary()?; + let msg = self.into_json_binary()?; let execute = WasmMsg::Execute { contract_addr: contract_addr.into(), msg, diff --git a/packages/white-whale/src/fee.rs b/packages/white-whale/src/fee.rs index c49dce66..b7ba8e7a 100644 --- a/packages/white-whale/src/fee.rs +++ b/packages/white-whale/src/fee.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Decimal, Decimal256, StdError, StdResult, Uint256}; +use std::fmt::{Display, Formatter}; #[cw_serde] pub struct Fee { @@ -26,6 +27,12 @@ impl Fee { } } +impl Display for Fee { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}%", self.share * Decimal::percent(100)) + } +} + /// Fees used by the flashloan vaults on the liquidity hub #[cw_serde] pub struct VaultFee { diff --git a/packages/white-whale/src/lib.rs b/packages/white-whale/src/lib.rs index 5b326434..1b97f22f 100644 --- a/packages/white-whale/src/lib.rs +++ b/packages/white-whale/src/lib.rs @@ -1,9 +1,15 @@ +pub mod common; +pub mod constants; pub mod epoch_manager; pub mod fee; pub mod fee_collector; pub mod fee_distributor; +pub mod lp_common; pub mod migrate_guards; pub mod pool_network; +pub mod token_factory; +pub mod tokenfactory; pub mod traits; +pub mod vault_manager; pub mod vault_network; pub mod whale_lair; diff --git a/packages/white-whale/src/lp_common.rs b/packages/white-whale/src/lp_common.rs new file mode 100644 index 00000000..da9d13d1 --- /dev/null +++ b/packages/white-whale/src/lp_common.rs @@ -0,0 +1,92 @@ +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +use cosmwasm_std::{coins, Coin}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, Uint128, WasmMsg}; + +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +use crate::pool_network::asset::is_factory_token; +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +use crate::tokenfactory; + +/// Creates the Mint LP message +#[allow(unused_variables)] +pub fn mint_lp_token_msg( + liquidity_asset: String, + recipient: &Addr, + sender: &Addr, + amount: Uint128, +) -> StdResult> { + #[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" + ))] + if is_factory_token(liquidity_asset.as_str()) { + let mut messages = vec![]; + messages.push(tokenfactory::mint::mint( + sender.clone(), + Coin { + denom: liquidity_asset.clone(), + amount, + }, + )); + + if sender != recipient { + messages.push(CosmosMsg::Bank(cosmwasm_std::BankMsg::Send { + to_address: recipient.clone().into_string(), + amount: coins(amount.u128(), liquidity_asset.as_str()), + })); + } + + return Ok(messages); + } + + Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: liquidity_asset, + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Mint { + recipient: recipient.clone().into_string(), + amount, + })?, + funds: vec![], + })]) +} + +/// Creates the Burn LP message +#[allow(unused_variables)] +pub fn burn_lp_asset_msg( + liquidity_asset: String, + sender: Addr, + amount: Uint128, +) -> StdResult { + #[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" + ))] + if is_factory_token(liquidity_asset.as_str()) { + return Ok(tokenfactory::burn::burn( + sender, + Coin { + denom: liquidity_asset, + amount, + }, + )); + } + + Ok(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: liquidity_asset, + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Burn { amount })?, + funds: vec![], + })) +} diff --git a/packages/white-whale/src/pool_network/asset.rs b/packages/white-whale/src/pool_network/asset.rs index e3823c93..68fae153 100644 --- a/packages/white-whale/src/pool_network/asset.rs +++ b/packages/white-whale/src/pool_network/asset.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - coins, to_binary, Addr, Api, BankMsg, CanonicalAddr, Coin, CosmosMsg, Deps, MessageInfo, + coins, to_json_binary, Addr, Api, BankMsg, CanonicalAddr, Coin, CosmosMsg, Deps, MessageInfo, QuerierWrapper, StdError, StdResult, SubMsg, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -50,7 +50,7 @@ impl Asset { match &self.info { AssetInfo::Token { contract_addr } => Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: recipient.to_string(), amount, })?, @@ -74,7 +74,7 @@ impl Asset { let burn_msg = match self.info { AssetInfo::Token { contract_addr } => CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: self.amount, })?, funds: vec![], @@ -170,21 +170,17 @@ impl AssetInfo { AssetInfo::Token { .. } => false, } } - pub fn query_pool( + pub fn query_balance( &self, querier: &QuerierWrapper, api: &dyn Api, - pool_addr: Addr, + addr: Addr, ) -> StdResult { match self { - AssetInfo::Token { contract_addr, .. } => query_token_balance( - querier, - api.addr_validate(contract_addr.as_str())?, - pool_addr, - ), - AssetInfo::NativeToken { denom, .. } => { - query_balance(querier, pool_addr, denom.to_string()) + AssetInfo::Token { contract_addr, .. } => { + query_token_balance(querier, api.addr_validate(contract_addr.as_str())?, addr) } + AssetInfo::NativeToken { denom, .. } => query_balance(querier, addr, denom.to_string()), } } @@ -231,7 +227,7 @@ impl AssetInfo { #[cfg(feature = "injective")] { if is_ethereum_bridged_asset(&denom) { - return get_ethereum_bridged_asset_label(denom.clone()); + return get_ethereum_bridged_asset_label(denom); } } if is_ibc_token(&denom) { @@ -471,11 +467,11 @@ impl PairInfoRaw { let info_1: AssetInfo = self.asset_infos[1].to_normal(api)?; Ok([ Asset { - amount: info_0.query_pool(querier, api, contract_addr.clone())?, + amount: info_0.query_balance(querier, api, contract_addr.clone())?, info: info_0, }, Asset { - amount: info_1.query_pool(querier, api, contract_addr)?, + amount: info_1.query_balance(querier, api, contract_addr)?, info: info_1, }, ]) @@ -603,15 +599,15 @@ impl TrioInfoRaw { let info_2: AssetInfo = self.asset_infos[2].to_normal(api)?; Ok([ Asset { - amount: info_0.query_pool(querier, api, contract_addr.clone())?, + amount: info_0.query_balance(querier, api, contract_addr.clone())?, info: info_0, }, Asset { - amount: info_1.query_pool(querier, api, contract_addr.clone())?, + amount: info_1.query_balance(querier, api, contract_addr.clone())?, info: info_1, }, Asset { - amount: info_2.query_pool(querier, api, contract_addr)?, + amount: info_2.query_balance(querier, api, contract_addr)?, info: info_2, }, ]) @@ -625,26 +621,14 @@ pub fn get_total_share(deps: &Deps, liquidity_asset: String) -> StdResult H impl Querier for WasmMockQuerier { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -141,7 +141,7 @@ impl Querier for WasmMockQuerier { impl Querier for WasmMockTrioQuerier { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -157,41 +157,41 @@ impl Querier for WasmMockTrioQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match from_binary(msg) { - Ok(FactoryQueryMsg::Pair { asset_infos }) => { - let key = [asset_infos[0].to_string(), asset_infos[1].to_string()].join(""); - let mut sort_key: Vec = key.chars().collect(); - sort_key.sort_by(|a, b| b.cmp(a)); - match self - .pool_factory_querier - .pairs - .get(&String::from_iter(sort_key.iter())) - { - Some(v) => SystemResult::Ok(ContractResult::Ok(to_binary(v).unwrap())), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No pair info exists".to_string(), - request: msg.as_slice().into(), - }), - } + QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => match from_json(msg) { + Ok(FactoryQueryMsg::Pair { asset_infos }) => { + let key = [asset_infos[0].to_string(), asset_infos[1].to_string()].join(""); + let mut sort_key: Vec = key.chars().collect(); + sort_key.sort_by(|a, b| b.cmp(a)); + match self + .pool_factory_querier + .pairs + .get(&String::from_iter(sort_key.iter())) + { + Some(v) => SystemResult::Ok(ContractResult::Ok(to_json_binary(v).unwrap())), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No pair info exists".to_string(), + request: msg.as_slice().into(), + }), } - Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { - match self.pool_factory_querier.native_token_decimals.get(&denom) { - Some(decimals) => SystemResult::Ok(ContractResult::Ok( - to_binary(&NativeTokenDecimalsResponse { - decimals: *decimals, - }) - .unwrap(), - )), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No decimal info exist".to_string(), - request: msg.as_slice().into(), - }), - } + } + Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { + match self.pool_factory_querier.native_token_decimals.get(&denom) { + Some(decimals) => SystemResult::Ok(ContractResult::Ok( + to_json_binary(&NativeTokenDecimalsResponse { + decimals: *decimals, + }) + .unwrap(), + )), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No decimal info exist".to_string(), + request: msg.as_slice().into(), + }), } - _ => match from_binary(msg) { - Ok(PairQueryMsg::Pool {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&PairPoolResponse { + } + _ => { + match from_json(msg) { + Ok(PairQueryMsg::Pool {}) => SystemResult::Ok(ContractResult::from( + to_json_binary(&PairPoolResponse { assets: vec![ Asset { info: AssetInfo::NativeToken { @@ -207,10 +207,10 @@ impl WasmMockQuerier { }, ], total_share: Uint128::new(2_000_000_000u128), - }))) - } + }), + )), Ok(PairQueryMsg::Pair {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&PairInfo { + SystemResult::Ok(ContractResult::from(to_json_binary(&PairInfo { asset_infos: [ AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -227,17 +227,17 @@ impl WasmMockQuerier { pair_type: PairType::ConstantProduct, }))) } - Ok(PairQueryMsg::Simulation { offer_asset }) => { - SystemResult::Ok(ContractResult::from(to_binary(&SimulationResponse { + Ok(PairQueryMsg::Simulation { offer_asset }) => SystemResult::Ok( + ContractResult::from(to_json_binary(&SimulationResponse { return_amount: offer_asset.amount, swap_fee_amount: Uint128::zero(), spread_amount: Uint128::zero(), protocol_fee_amount: Uint128::zero(), burn_fee_amount: Uint128::zero(), - }))) - } + })), + ), Ok(PairQueryMsg::ReverseSimulation { ask_asset }) => SystemResult::Ok( - ContractResult::from(to_binary(&ReverseSimulationResponse { + ContractResult::from(to_json_binary(&ReverseSimulationResponse { offer_amount: ask_asset.amount, swap_fee_amount: Uint128::zero(), spread_amount: Uint128::zero(), @@ -245,7 +245,7 @@ impl WasmMockQuerier { burn_fee_amount: Uint128::zero(), })), ), - _ => match from_binary(msg).unwrap() { + _ => match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { let balances: &HashMap = match self.token_querier.balances.get(contract_addr) { @@ -267,7 +267,7 @@ impl WasmMockQuerier { } SystemResult::Ok(ContractResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: "mAAPL".to_string(), symbol: "mAAPL".to_string(), decimals: 8, @@ -294,7 +294,7 @@ impl WasmMockQuerier { Some(v) => *v, None => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { + to_json_binary(&Cw20BalanceResponse { balance: Uint128::zero(), }) .unwrap(), @@ -303,15 +303,15 @@ impl WasmMockQuerier { }; SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { balance }).unwrap(), + to_json_binary(&Cw20BalanceResponse { balance }).unwrap(), )) } _ => panic!("DO NOT ENTER HERE"), }, - }, + } } - } + }, QueryRequest::Wasm(WasmQuery::ContractInfo { .. }) => { let mut contract_info_response = ContractInfoResponse::default(); contract_info_response.code_id = 0u64; @@ -319,7 +319,7 @@ impl WasmMockQuerier { contract_info_response.admin = Some("creator".to_string()); SystemResult::Ok(ContractResult::Ok( - to_binary(&contract_info_response).unwrap(), + to_json_binary(&contract_info_response).unwrap(), )) } _ => self.base.handle_query(request), @@ -330,108 +330,108 @@ impl WasmMockQuerier { impl WasmMockTrioQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match from_binary(msg) { - Ok(FactoryQueryMsg::Trio { asset_infos }) => { - let key = [ - asset_infos[0].to_string(), - asset_infos[1].to_string(), - asset_infos[2].to_string(), - ] - .join(""); - let mut sort_key: Vec = key.chars().collect(); - sort_key.sort_by(|a, b| b.cmp(a)); - match self - .pool_factory_querier - .pairs - .get(&String::from_iter(sort_key.iter())) - { - Some(v) => SystemResult::Ok(ContractResult::Ok(to_binary(v).unwrap())), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No trio info exists".to_string(), - request: msg.as_slice().into(), - }), - } + QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => match from_json(msg) { + Ok(FactoryQueryMsg::Trio { asset_infos }) => { + let key = [ + asset_infos[0].to_string(), + asset_infos[1].to_string(), + asset_infos[2].to_string(), + ] + .join(""); + let mut sort_key: Vec = key.chars().collect(); + sort_key.sort_by(|a, b| b.cmp(a)); + match self + .pool_factory_querier + .pairs + .get(&String::from_iter(sort_key.iter())) + { + Some(v) => SystemResult::Ok(ContractResult::Ok(to_json_binary(v).unwrap())), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No trio info exists".to_string(), + request: msg.as_slice().into(), + }), } - Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { - match self.pool_factory_querier.native_token_decimals.get(&denom) { - Some(decimals) => SystemResult::Ok(ContractResult::Ok( - to_binary(&NativeTokenDecimalsResponse { - decimals: *decimals, - }) - .unwrap(), - )), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No decimal info exist".to_string(), - request: msg.as_slice().into(), - }), - } + } + Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { + match self.pool_factory_querier.native_token_decimals.get(&denom) { + Some(decimals) => SystemResult::Ok(ContractResult::Ok( + to_json_binary(&NativeTokenDecimalsResponse { + decimals: *decimals, + }) + .unwrap(), + )), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No decimal info exist".to_string(), + request: msg.as_slice().into(), + }), } - _ => match from_binary(msg) { - Ok(TrioQueryMsg::Pool {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&TrioPoolResponse { - assets: vec![ - Asset { - info: AssetInfo::NativeToken { - denom: "uluna".to_string(), - }, - amount: Uint128::new(1_000_000_000u128), - }, - Asset { - info: AssetInfo::NativeToken { - denom: "ujuno".to_string(), - }, - amount: Uint128::new(1_000_000_000u128), - }, - Asset { - info: AssetInfo::NativeToken { - denom: "uatom".to_string(), - }, - amount: Uint128::new(1_000_000_000u128), - }, - ], - total_share: Uint128::new(3_000_000_000u128), - }))) - } - Ok(TrioQueryMsg::Trio {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&TrioInfo { - asset_infos: [ - AssetInfo::NativeToken { + } + _ => match from_json(msg) { + Ok(TrioQueryMsg::Pool {}) => { + SystemResult::Ok(ContractResult::from(to_json_binary(&TrioPoolResponse { + assets: vec![ + Asset { + info: AssetInfo::NativeToken { denom: "uluna".to_string(), }, - AssetInfo::NativeToken { - denom: "uluna".to_string(), + amount: Uint128::new(1_000_000_000u128), + }, + Asset { + info: AssetInfo::NativeToken { + denom: "ujuno".to_string(), }, - AssetInfo::NativeToken { + amount: Uint128::new(1_000_000_000u128), + }, + Asset { + info: AssetInfo::NativeToken { denom: "uatom".to_string(), }, - ], - asset_decimals: [6u8, 6u8, 10u8], - contract_addr: "trio0000".to_string(), - liquidity_token: AssetInfo::Token { - contract_addr: "liquidity0000".to_string(), + amount: Uint128::new(1_000_000_000u128), }, - }))) - } - Ok(TrioQueryMsg::Simulation { offer_asset, .. }) => SystemResult::Ok( - ContractResult::from(to_binary(&trio::SimulationResponse { - return_amount: offer_asset.amount, - swap_fee_amount: Uint128::zero(), - spread_amount: Uint128::zero(), - protocol_fee_amount: Uint128::zero(), - burn_fee_amount: Uint128::zero(), - })), - ), - Ok(TrioQueryMsg::ReverseSimulation { ask_asset, .. }) => SystemResult::Ok( - ContractResult::from(to_binary(&trio::ReverseSimulationResponse { - offer_amount: ask_asset.amount, - swap_fee_amount: Uint128::zero(), - spread_amount: Uint128::zero(), - protocol_fee_amount: Uint128::zero(), - burn_fee_amount: Uint128::zero(), - })), - ), - _ => match from_binary(msg).unwrap() { + ], + total_share: Uint128::new(3_000_000_000u128), + }))) + } + Ok(TrioQueryMsg::Trio {}) => { + SystemResult::Ok(ContractResult::from(to_json_binary(&TrioInfo { + asset_infos: [ + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + AssetInfo::NativeToken { + denom: "uluna".to_string(), + }, + AssetInfo::NativeToken { + denom: "uatom".to_string(), + }, + ], + asset_decimals: [6u8, 6u8, 10u8], + contract_addr: "trio0000".to_string(), + liquidity_token: AssetInfo::Token { + contract_addr: "liquidity0000".to_string(), + }, + }))) + } + Ok(TrioQueryMsg::Simulation { offer_asset, .. }) => SystemResult::Ok( + ContractResult::from(to_json_binary(&trio::SimulationResponse { + return_amount: offer_asset.amount, + swap_fee_amount: Uint128::zero(), + spread_amount: Uint128::zero(), + protocol_fee_amount: Uint128::zero(), + burn_fee_amount: Uint128::zero(), + })), + ), + Ok(TrioQueryMsg::ReverseSimulation { ask_asset, .. }) => SystemResult::Ok( + ContractResult::from(to_json_binary(&trio::ReverseSimulationResponse { + offer_amount: ask_asset.amount, + swap_fee_amount: Uint128::zero(), + spread_amount: Uint128::zero(), + protocol_fee_amount: Uint128::zero(), + burn_fee_amount: Uint128::zero(), + })), + ), + _ => { + match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { let balances: &HashMap = match self.token_querier.balances.get(contract_addr) { @@ -453,7 +453,7 @@ impl WasmMockTrioQuerier { } SystemResult::Ok(ContractResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: "mAAPL".to_string(), symbol: "mAAPL".to_string(), decimals: 8, @@ -480,7 +480,7 @@ impl WasmMockTrioQuerier { Some(v) => *v, None => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { + to_json_binary(&Cw20BalanceResponse { balance: Uint128::zero(), }) .unwrap(), @@ -489,15 +489,15 @@ impl WasmMockTrioQuerier { }; SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { balance }).unwrap(), + to_json_binary(&Cw20BalanceResponse { balance }).unwrap(), )) } _ => panic!("DO NOT ENTER HERE"), - }, - }, - } - } + } + } + }, + }, QueryRequest::Wasm(WasmQuery::ContractInfo { .. }) => { let mut contract_info_response = ContractInfoResponse::default(); contract_info_response.code_id = 0u64; @@ -505,7 +505,7 @@ impl WasmMockTrioQuerier { contract_info_response.admin = Some("creator".to_string()); SystemResult::Ok(ContractResult::Ok( - to_binary(&contract_info_response).unwrap(), + to_json_binary(&contract_info_response).unwrap(), )) } _ => self.base.handle_query(request), @@ -595,7 +595,7 @@ mod mock_exception { fn none_factory_pair_will_err() { let deps = mock_dependencies(&[]); - let msg = to_binary(&FactoryQueryMsg::Pair { + let msg = to_json_binary(&FactoryQueryMsg::Pair { asset_infos: [ AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -623,7 +623,7 @@ mod mock_exception { fn none_tokens_info_will_err() { let deps = mock_dependencies(&[]); - let msg = to_binary(&Cw20QueryMsg::TokenInfo {}).unwrap(); + let msg = to_json_binary(&Cw20QueryMsg::TokenInfo {}).unwrap(); assert_eq!( deps.querier @@ -642,7 +642,7 @@ mod mock_exception { fn none_tokens_balance_will_err() { let deps = mock_dependencies(&[]); - let msg = to_binary(&Cw20QueryMsg::Balance { + let msg = to_json_binary(&Cw20QueryMsg::Balance { address: "address0000".to_string(), }) .unwrap(); @@ -665,7 +665,7 @@ mod mock_exception { fn none_tokens_minter_will_panic() { let deps = mock_dependencies(&[]); - let msg = to_binary(&Cw20QueryMsg::Minter {}).unwrap(); + let msg = to_json_binary(&Cw20QueryMsg::Minter {}).unwrap(); deps.querier .handle_query(&QueryRequest::Wasm(WasmQuery::Smart { diff --git a/packages/white-whale/src/pool_network/querier.rs b/packages/white-whale/src/pool_network/querier.rs index 0ace1a5c..2326c6be 100644 --- a/packages/white-whale/src/pool_network/querier.rs +++ b/packages/white-whale/src/pool_network/querier.rs @@ -6,12 +6,13 @@ use crate::pool_network::pair::{ use crate::pool_network::trio::QueryMsg as TrioQueryMsg; use cosmwasm_std::{ - to_binary, Addr, AllBalanceResponse, BalanceResponse, BankQuery, Coin, QuerierWrapper, + to_json_binary, Addr, AllBalanceResponse, BalanceResponse, BankQuery, Coin, QuerierWrapper, QueryRequest, StdResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; +/// Queries the balance for a native denom for the given account. pub fn query_balance( querier: &QuerierWrapper, account_addr: Addr, @@ -25,6 +26,7 @@ pub fn query_balance( Ok(balance.amount.amount) } +/// Queries the balances of all native denom for the given account. pub fn query_all_balances(querier: &QuerierWrapper, account_addr: Addr) -> StdResult> { // load price form the oracle let all_balances: AllBalanceResponse = @@ -34,6 +36,7 @@ pub fn query_all_balances(querier: &QuerierWrapper, account_addr: Addr) -> StdRe Ok(all_balances.amount) } +/// Queries the balances of a cw20 token for the given account. pub fn query_token_balance( querier: &QuerierWrapper, contract_addr: Addr, @@ -41,7 +44,7 @@ pub fn query_token_balance( ) -> StdResult { let res: Cw20BalanceResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20QueryMsg::Balance { + msg: to_json_binary(&Cw20QueryMsg::Balance { address: account_addr.to_string(), })?, }))?; @@ -56,7 +59,7 @@ pub fn query_token_info( ) -> StdResult { let token_info: TokenInfoResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20QueryMsg::TokenInfo {})?, + msg: to_json_binary(&Cw20QueryMsg::TokenInfo {})?, }))?; Ok(token_info) @@ -70,7 +73,7 @@ pub fn query_native_decimals( let res: NativeTokenDecimalsResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_contract.to_string(), - msg: to_binary(&FactoryQueryMsg::NativeTokenDecimals { denom })?, + msg: to_json_binary(&FactoryQueryMsg::NativeTokenDecimals { denom })?, }))?; Ok(res.decimals) } @@ -82,7 +85,7 @@ pub fn query_pair_info( ) -> StdResult { querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_contract.to_string(), - msg: to_binary(&FactoryQueryMsg::Pair { + msg: to_json_binary(&FactoryQueryMsg::Pair { asset_infos: asset_infos.clone(), })?, })) @@ -95,7 +98,7 @@ pub fn simulate( ) -> StdResult { querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair_contract.to_string(), - msg: to_binary(&PairQueryMsg::Simulation { + msg: to_json_binary(&PairQueryMsg::Simulation { offer_asset: offer_asset.clone(), })?, })) @@ -108,7 +111,7 @@ pub fn reverse_simulate( ) -> StdResult { querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair_contract.to_string(), - msg: to_binary(&PairQueryMsg::ReverseSimulation { + msg: to_json_binary(&PairQueryMsg::ReverseSimulation { ask_asset: ask_asset.clone(), })?, })) @@ -120,7 +123,7 @@ pub fn query_pair_info_from_pair( ) -> StdResult { let pair_info: PairInfo = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair_contract.to_string(), - msg: to_binary(&PairQueryMsg::Pair {})?, + msg: to_json_binary(&PairQueryMsg::Pair {})?, }))?; Ok(pair_info) @@ -132,7 +135,7 @@ pub fn query_trio_info_from_trio( ) -> StdResult { let trio_info: TrioInfo = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: trio_contract.to_string(), - msg: to_binary(&TrioQueryMsg::Trio {})?, + msg: to_json_binary(&TrioQueryMsg::Trio {})?, }))?; Ok(trio_info) diff --git a/packages/white-whale/src/pool_network/testing.rs b/packages/white-whale/src/pool_network/testing.rs index b0936716..e0eaad3c 100644 --- a/packages/white-whale/src/pool_network/testing.rs +++ b/packages/white-whale/src/pool_network/testing.rs @@ -1,4 +1,6 @@ -use crate::pool_network::asset::{Asset, AssetInfo, AssetInfoRaw, AssetRaw, PairInfo, PairType}; +use crate::pool_network::asset::{ + is_factory_token, Asset, AssetInfo, AssetInfoRaw, AssetRaw, PairInfo, PairType, +}; use crate::pool_network::mock_querier::mock_dependencies; use crate::pool_network::querier::{ query_all_balances, query_balance, query_pair_info, query_token_balance, query_token_info, @@ -6,8 +8,8 @@ use crate::pool_network::querier::{ use cosmwasm_std::testing::MOCK_CONTRACT_ADDR; use cosmwasm_std::{ - coin, to_binary, Addr, Api, BankMsg, Coin, CosmosMsg, MessageInfo, StdError, SubMsg, Uint128, - WasmMsg, + coin, to_json_binary, Addr, Api, BankMsg, Coin, CosmosMsg, MessageInfo, StdError, SubMsg, + Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -137,7 +139,7 @@ fn test_asset_info() { assert_eq!( token_info - .query_pool( + .query_balance( &deps.as_ref().querier, deps.as_ref().api, Addr::unchecked(MOCK_CONTRACT_ADDR), @@ -147,7 +149,7 @@ fn test_asset_info() { ); assert_eq!( native_token_info - .query_pool( + .query_balance( &deps.as_ref().querier, deps.as_ref().api, Addr::unchecked(MOCK_CONTRACT_ADDR), @@ -195,7 +197,7 @@ fn test_asset() { .unwrap(), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: Uint128::from(123123u128), }) @@ -210,7 +212,7 @@ fn test_asset() { .unwrap(), SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: Uint128::from(123123u128), }) @@ -448,6 +450,7 @@ fn get_native_asset_label() { let asset_info = AssetInfo::NativeToken { denom: "factory/migaloo1wcg789e6vcd8vpq5smrjffjnn8hkep4nk7aa7frk0d7u022m63uqfrupkl/Qwertyuiopasdfghjkl/zxcvbnm/qwer.tyuiop.asdfghjklZXCVB".to_string(), }; + assert!(is_factory_token(&"factory/migaloo1wcg789e6vcd8vpq5smrjffjnn8hkep4nk7aa7frk0d7u022m63uqfrupkl/Qwertyuiopasdfghjkl/zxcvbnm/qwer.tyuiop.asdfghjklZXCVB")); let asset_label = asset_info.get_label(&deps.as_ref()).unwrap(); assert_eq!(asset_label, "factory/mig...pkl/Qwe...CVB"); } diff --git a/packages/white-whale/src/token_factory.rs b/packages/white-whale/src/token_factory.rs new file mode 100644 index 00000000..5ec68c7e --- /dev/null +++ b/packages/white-whale/src/token_factory.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::{CosmosMsg, StdResult}; + +/// A convenience function for processing the case where we use a token factory LP token or not. +pub fn is_token_factory_lp( + token_factory_lp: bool, + on_true: F, + on_false: G, +) -> StdResult +where + F: FnOnce() -> StdResult, + G: FnOnce() -> StdResult, +{ + if token_factory_lp { + on_true() + } else { + on_false() + } +} diff --git a/packages/white-whale/src/tokenfactory/burn.rs b/packages/white-whale/src/tokenfactory/burn.rs new file mode 100644 index 00000000..fb1acc0b --- /dev/null +++ b/packages/white-whale/src/tokenfactory/burn.rs @@ -0,0 +1,14 @@ +use crate::tokenfactory::common::{create_msg, MsgTypes}; +use crate::tokenfactory::mint::MsgMint; +use cosmwasm_std::{Addr, Coin, CosmosMsg}; + +/// Returns the MsgBurn Stargate message +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +pub fn burn(sender: Addr, coin: Coin) -> CosmosMsg { + let message_data = MsgMint { coin }; + create_msg(sender, message_data, MsgTypes::Burn.as_str()) +} diff --git a/packages/white-whale/src/tokenfactory/common.rs b/packages/white-whale/src/tokenfactory/common.rs new file mode 100644 index 00000000..edf6d7ac --- /dev/null +++ b/packages/white-whale/src/tokenfactory/common.rs @@ -0,0 +1,70 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, CosmosMsg}; +#[cw_serde] +enum Protocol { + Injective, + CosmWasm, + Osmosis, +} + +impl Protocol { + #![allow(unreachable_code)] + fn from_features() -> Self { + #[cfg(feature = "injective")] + { + return Self::Injective; + } + #[cfg(feature = "token_factory")] + { + return Self::CosmWasm; + } + #[cfg(feature = "osmosis_token_factory")] + { + return Self::Osmosis; + } + unreachable!() + } + + fn as_str(&self) -> &'static str { + match self { + Self::Injective => "injective", + Self::CosmWasm => "cosmwasm", + Self::Osmosis => "osmosis", + } + } +} + +pub(crate) enum MsgTypes { + CreateDenom, + Mint, + Burn, +} + +impl MsgTypes { + pub fn as_str(&self) -> &'static str { + match self { + Self::CreateDenom => "MsgCreateDenom", + Self::Mint => "MsgMint", + Self::Burn => "MsgBurn", + } + } +} + +pub(crate) trait EncodeMessage { + fn encode(sender: String, data: Self) -> Vec; +} + +pub(crate) fn create_msg( + sender: Addr, + message_data: M, + msg_type: &str, +) -> CosmosMsg { + CosmosMsg::Stargate { + type_url: format!( + "/{}.tokenfactory.v1beta1.{}", + Protocol::from_features().as_str(), + msg_type + ), + value: M::encode(sender.into(), message_data).into(), + } +} diff --git a/packages/white-whale/src/tokenfactory/create_denom.rs b/packages/white-whale/src/tokenfactory/create_denom.rs new file mode 100644 index 00000000..a8b41c3f --- /dev/null +++ b/packages/white-whale/src/tokenfactory/create_denom.rs @@ -0,0 +1,28 @@ +use anybuf::Anybuf; +use cosmwasm_std::{Addr, CosmosMsg}; + +use crate::tokenfactory::common::{create_msg, EncodeMessage, MsgTypes}; + +/// Returns the MsgCreateDenom Stargate message +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +pub fn create_denom(sender: Addr, subdenom: String) -> CosmosMsg { + let message_data = MsgCreateDenom { subdenom }; + create_msg(sender, message_data, MsgTypes::CreateDenom.as_str()) +} + +struct MsgCreateDenom { + pub subdenom: String, +} + +impl EncodeMessage for MsgCreateDenom { + fn encode(sender: String, data: Self) -> Vec { + Anybuf::new() + .append_string(1, sender) + .append_string(2, data.subdenom) + .into_vec() + } +} diff --git a/packages/white-whale/src/tokenfactory/mint.rs b/packages/white-whale/src/tokenfactory/mint.rs new file mode 100644 index 00000000..cac0dabc --- /dev/null +++ b/packages/white-whale/src/tokenfactory/mint.rs @@ -0,0 +1,31 @@ +use crate::tokenfactory::common::{create_msg, EncodeMessage, MsgTypes}; +use anybuf::Anybuf; +use cosmwasm_std::{Addr, Coin, CosmosMsg}; + +/// Returns the MsgMint Stargate message +#[cfg(any( + feature = "token_factory", + feature = "osmosis_token_factory", + feature = "injective" +))] +pub fn mint(sender: Addr, coin: Coin) -> CosmosMsg { + let message_data = MsgMint { coin }; + create_msg(sender, message_data, MsgTypes::Mint.as_str()) +} + +pub(crate) struct MsgMint { + pub coin: Coin, +} + +impl EncodeMessage for MsgMint { + fn encode(sender: String, data: Self) -> Vec { + let coin_buf = Anybuf::new() + .append_string(1, data.coin.denom) + .append_string(2, data.coin.amount.to_string()); + + Anybuf::new() + .append_string(1, sender) + .append_message(2, &coin_buf) + .into_vec() + } +} diff --git a/packages/white-whale/src/tokenfactory/mod.rs b/packages/white-whale/src/tokenfactory/mod.rs new file mode 100644 index 00000000..f4ac7963 --- /dev/null +++ b/packages/white-whale/src/tokenfactory/mod.rs @@ -0,0 +1,4 @@ +pub mod burn; +pub mod common; +pub mod create_denom; +pub mod mint; diff --git a/packages/white-whale/src/traits.rs b/packages/white-whale/src/traits.rs index aa6ad3f0..5a056c29 100644 --- a/packages/white-whale/src/traits.rs +++ b/packages/white-whale/src/traits.rs @@ -1,3 +1,4 @@ +use crate::pool_network::asset::AssetInfo; use cosmwasm_std::Decimal; /// A trait for converting an Option to a string. @@ -13,3 +14,17 @@ impl OptionDecimal for Option { } } } + +pub trait AssetReference { + fn get_reference(&self) -> &[u8]; +} + +impl AssetReference for AssetInfo { + fn get_reference(&self) -> &[u8] { + // convert AssetInfo into vec bytes + match self { + AssetInfo::Token { contract_addr } => contract_addr.as_bytes(), + AssetInfo::NativeToken { denom } => denom.as_bytes(), + } + } +} diff --git a/packages/white-whale/src/vault_manager.rs b/packages/white-whale/src/vault_manager.rs new file mode 100644 index 00000000..e5b4bf4a --- /dev/null +++ b/packages/white-whale/src/vault_manager.rs @@ -0,0 +1,247 @@ +use crate::fee::Fee; +use crate::pool_network::asset::{Asset, AssetInfo}; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{Addr, Binary, CosmosMsg, Decimal, StdError, StdResult, Uint128}; +use cw_ownable::{cw_ownable_execute, cw_ownable_query}; +use std::fmt::{Display, Formatter}; + +/// The instantiation message +#[cw_serde] +pub struct InstantiateMsg { + /// The owner of the contract + pub owner: String, + /// The type of LP token to use, whether a cw20 token or a token factory token + pub lp_token_type: LpTokenType, + /// The whale lair address, where protocol fees are distributed + pub whale_lair_addr: String, + /// The fee to create a vault + pub vault_creation_fee: Asset, +} + +/// Configuration for the contract (manager) +#[cw_serde] +pub struct Config { + /// The type of LP token to use, whether a cw20 token or a token factory token + pub lp_token_type: LpTokenType, + /// The whale lair contract address + pub whale_lair_addr: Addr, + /// The fee to create a new vault + pub vault_creation_fee: Asset, + /// If flash-loans are enabled + pub flash_loan_enabled: bool, + /// If deposits are enabled + pub deposit_enabled: bool, + /// If withdrawals are enabled + pub withdraw_enabled: bool, +} + +/// The type of LP token to use, whether a cw20 token or a token factory token +#[cw_serde] +pub enum LpTokenType { + Cw20(u64), + TokenFactory, +} + +impl LpTokenType { + pub fn get_cw20_code_id(&self) -> StdResult { + match self { + LpTokenType::TokenFactory => Err(StdError::generic_err("Not a cw20 token")), + LpTokenType::Cw20(code_id) => Ok(*code_id), + } + } +} +impl Display for LpTokenType { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + match self { + LpTokenType::Cw20(value) => write!(f, "cw20({})", value), + LpTokenType::TokenFactory => write!(f, "token_factory"), + } + } +} + +/// Vault representation +#[cw_serde] +pub struct Vault { + /// The asset the vault manages + pub asset: Asset, + /// The LP asset + pub lp_asset: AssetInfo, + /// The fees associated with the vault + pub fees: VaultFee, + /// Identifier associated with the vault + pub identifier: String, +} + +#[cw_serde] +pub struct VaultFee { + pub protocol_fee: Fee, + pub flash_loan_fee: Fee, +} + +impl VaultFee { + /// Checks that the given [VaultFee] is valid, i.e. the fees provided are valid, and they don't + /// exceed 100% together + pub fn is_valid(&self) -> StdResult<()> { + self.protocol_fee.is_valid()?; + self.flash_loan_fee.is_valid()?; + + if self + .protocol_fee + .share + .checked_add(self.flash_loan_fee.share)? + >= Decimal::percent(100) + { + return Err(StdError::generic_err("Invalid fees")); + } + Ok(()) + } +} + +impl Display for VaultFee { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "protocol_fee: {}, flash_loan_fee: {}", + self.protocol_fee, self.flash_loan_fee + ) + } +} + +/// The execution messages +#[cw_ownable_execute] +#[cw_serde] +pub enum ExecuteMsg { + /// Creates a new vault given the asset info the vault should manage deposits and withdrawals + /// for and the fees + CreateVault { + asset_info: AssetInfo, + fees: VaultFee, + vault_identifier: Option, + }, + /// Updates the configuration of the vault manager. + /// If a field is not specified, it will not be modified. + UpdateConfig { + whale_lair_addr: Option, + vault_creation_fee: Option, + cw20_lp_code_id: Option, + flash_loan_enabled: Option, + deposit_enabled: Option, + withdraw_enabled: Option, + }, + /// Deposits a given asset into the vault manager. + Deposit { + asset: Asset, + vault_identifier: String, + }, + /// Withdraws from the vault manager. Used when the LP token is a token manager token. + Withdraw, + Receive(Cw20ReceiveMsg), + /// Retrieves the desired `asset` and runs the `payload`, paying the required amount back to the vault + /// after running the messages in the payload, and returning the profit to the sender. + FlashLoan { + asset: Asset, + vault_identifier: String, + payload: Vec, + }, + /// Callback message for post-processing flash-loans. + Callback(CallbackMsg), +} + +/// The migrate message +#[cw_serde] +pub struct MigrateMsg {} + +/// The query messages +#[cw_ownable_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// Retrieves the configuration of the manager. + #[returns(Config)] + Config {}, + /// Retrieves a vault given the asset_info. + #[returns(VaultsResponse)] + Vault { filter_by: FilterVaultBy }, + /// Retrieves the addresses for all the vaults. + #[returns(VaultsResponse)] + Vaults { + start_after: Option>, + limit: Option, + }, + /// Retrieves the share of the assets stored in the vault that a given `lp_share` is entitled to. + #[returns(ShareResponse)] + Share { lp_share: Asset }, + /// Retrieves the [`Uint128`] amount that must be sent back to the contract to pay off a loan taken out. + #[returns(PaybackAssetResponse)] + PaybackAmount { + asset: Asset, + vault_identifier: String, + }, +} + +/// Response for the vaults query +#[cw_serde] +pub struct VaultsResponse { + pub vaults: Vec, +} + +/// Response for the vaults query +#[cw_serde] +pub enum FilterVaultBy { + Asset(AssetQueryParams), + Identifier(String), + LpAsset(AssetInfo), +} + +#[cw_serde] +pub struct AssetQueryParams { + pub asset_info: AssetInfo, + pub start_after: Option>, + pub limit: Option, +} + +/// The callback messages available. Only callable by the vault contract itself. +#[cw_serde] +pub enum CallbackMsg { + AfterFlashloan { + old_asset_balance: Uint128, + loan_asset: Asset, + vault_identifier: String, + sender: Addr, + }, +} + +/// Cw20 hook messages +#[cw_serde] +pub enum Cw20HookMsg { + /// Withdraws a given amount from the vault. + Withdraw, +} + +#[cw_serde] +pub struct Cw20ReceiveMsg { + pub sender: String, + pub amount: Uint128, + pub msg: Binary, +} + +/// Response for the PaybackAmount query. Contains the amount that must be paid back to the contract +/// if taken a flashloan. +#[cw_serde] +pub struct PaybackAssetResponse { + /// The asset info of the asset that must be paid back + pub asset_info: AssetInfo, + /// The total amount that must be returned. Equivalent to `amount` + `protocol_fee` + `flash_loan_fee`. + pub payback_amount: Uint128, + /// The amount of fee paid to the protocol + pub protocol_fee: Uint128, + /// The amount of fee paid to vault holders + pub flash_loan_fee: Uint128, +} + +/// Response for the Share query. Contains the amount of assets that the given `lp_share` is entitled to. +#[cw_serde] +pub struct ShareResponse { + /// The amount of assets that the given `lp_share` is entitled to. + pub share: Asset, +} diff --git a/packages/white-whale/src/whale_lair.rs b/packages/white-whale/src/whale_lair.rs index fa52328c..28ce83cb 100644 --- a/packages/white-whale/src/whale_lair.rs +++ b/packages/white-whale/src/whale_lair.rs @@ -1,6 +1,8 @@ -use crate::pool_network::asset::{Asset, AssetInfo}; +use crate::pool_network::asset::{Asset, AssetInfo, ToCoins}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Decimal, Timestamp, Uint128, Uint64}; +use cosmwasm_std::{ + to_json_binary, Addr, CosmosMsg, Decimal, StdResult, Timestamp, Uint128, Uint64, WasmMsg, +}; #[cw_serde] pub struct Config { @@ -80,6 +82,11 @@ pub enum ExecuteMsg { growth_rate: Option, fee_distributor_addr: Option, }, + + /// V2 MESSAGES + + /// Fills the whale lair with new rewards. + FillRewards { assets: Vec }, } #[cw_serde] @@ -158,3 +165,14 @@ pub struct BondingWeightResponse { pub share: Decimal, pub timestamp: Timestamp, } + +/// Creates a message to fill rewards on the whale lair contract. +pub fn fill_rewards_msg(contract_addr: String, assets: Vec) -> StdResult { + Ok(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr, + msg: to_json_binary(&ExecuteMsg::FillRewards { + assets: assets.clone(), + })?, + funds: assets.to_coins()?, + })) +} diff --git a/scripts/build_release.sh b/scripts/build_release.sh index ecc5dd62..b849068a 100755 --- a/scripts/build_release.sh +++ b/scripts/build_release.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e # Displays tool usage diff --git a/scripts/build_schemas.sh b/scripts/build_schemas.sh index 39dfa0b4..363a2252 100755 --- a/scripts/build_schemas.sh +++ b/scripts/build_schemas.sh @@ -1,12 +1,38 @@ -#!/bin/bash +#!/usr/bin/env bash set -e -# First argument, whether or not to run git diff and exit with an error on any json file diff, not used by default -if [[ -z $1 ]]; then - fail_diff_flag=false -else - fail_diff_flag=$1 + +# Displays tool usage +function display_usage() { + echo "Schema generator" + echo -e "\nUsage: $0 [flags].\n" + echo -e "Available flags:\n" + echo -e " -f \tSpecify the feature to use (token_factory|osmosis_token_factory|...)" + echo -e " -d \tEnable diff check (true|false)" +} + +if [ -z $1 ]; then + display_usage + exit 0 fi +feature_flag="" +fail_diff_flag=false + +while getopts ":f:d:" opt; do + case $opt in + f) + feature_flag="$OPTARG" + ;; + d) + fail_diff_flag="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + display_usage + exit 1 + ;; + esac +done projectRootPath=$(realpath "$0" | sed 's|\(.*\)/.*|\1|' | cd ../ | pwd) @@ -16,7 +42,7 @@ for component in "$projectRootPath"/contracts/liquidity_hub/*/; do if [[ -f "$component/Cargo.toml" ]]; then # it was a single contract (such as fee_collector) echo "generating for $component" - cd $component && cargo schema --locked + cd $component && cargo schema --locked --features "$feature_flag" else echo "folder $component" @@ -24,7 +50,7 @@ for component in "$projectRootPath"/contracts/liquidity_hub/*/; do for contract in "$component"*/; do echo "generating for $contract" - cd $contract && cargo schema --locked + cd $contract && cargo schema --locked --features "$feature_flag" # Optionally fail on any unaccounted changes in json schema files if [[ "$fail_diff_flag" == true ]]; then diff --git a/scripts/check_artifacts_size.sh b/scripts/check_artifacts_size.sh index 385f65f8..3d6d4018 100755 --- a/scripts/check_artifacts_size.sh +++ b/scripts/check_artifacts_size.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e # Maximum wasm file size diff --git a/scripts/deployment/deploy_liquidity_hub.sh b/scripts/deployment/deploy_liquidity_hub.sh index c2d96dee..dcd27109 100755 --- a/scripts/deployment/deploy_liquidity_hub.sh +++ b/scripts/deployment/deploy_liquidity_hub.sh @@ -31,6 +31,10 @@ function store_artifact_on_chain() { echo "Storing $(basename $artifact) on $CHAIN_ID..." + if [[ $artifact == *"-aarch64.wasm" ]]; then + artifact=$(echo "$artifact" | sed 's/-aarch64//') + fi + # Get contract version for storing purposes local contract_path=$(find "$project_root_path" -iname $(cut -d . -f 1 <<<$(basename $artifact)) -type d) local version=$(cat ''"$contract_path"'/Cargo.toml' | awk -F= '/^version/ { print $2 }')