diff --git a/Cargo.lock b/Cargo.lock index 42c63048..fc8fdf02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,11 +13,26 @@ dependencies = [ "version_check", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "astroport" @@ -250,6 +265,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytemuck" version = "1.14.0" @@ -268,12 +289,32 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "cc" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.5", +] + [[package]] name = "colored" version = "2.0.4" @@ -291,11 +332,17 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cosmwasm-crypto" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4c3f9c4616d6413d4b5fc4c270a4cc32a374b9be08671e80e1a019f805d8f" +checksum = "dd50718a2b6830ce9eb5d465de5a018a12e71729d66b70807ce97e6dd14f931d" dependencies = [ "digest 0.10.7", "ecdsa", @@ -307,18 +354,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c586ced10c3b00e809ee664a895025a024f60d65d34fe4c09daed4a4db68a3f3" +checksum = "242e98e7a231c122e08f300d9db3262d1007b51758a8732cd6210b3e9faa4f3a" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8467874827d384c131955ff6f4d47d02e72a956a08eb3c0ff24f8c903a5517b4" +checksum = "7879036156092ad1c22fe0d7316efc5a5eceec2bc3906462a2560215f2a2f929" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -329,9 +376,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6db85d98ac80922aef465e564d5b21fa9cfac5058cb62df7f116c3682337393" +checksum = "0bb57855fbfc83327f8445ae0d413b1a05ac0d68c396ab4d122b2abd7bb82cb6" dependencies = [ "proc-macro2", "quote", @@ -340,9 +387,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712fe58f39d55c812f7b2c84e097cdede3a39d520f89b6dc3153837e31741927" +checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" dependencies = [ "base64", "bech32 0.9.1", @@ -422,9 +469,9 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ffa9e3bae206540c084198e5be5aea2ecb1f2597f79dc09263b528ea0604788" +checksum = "91fc33b1d65c102d72f46548c64dca423c337e528d6747d0c595316aa65f887b" dependencies = [ "anyhow", "bech32 0.11.0", @@ -432,7 +479,7 @@ dependencies = [ "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "derivative", - "itertools 0.12.1", + "itertools 0.13.0", "prost", "schemars", "serde", @@ -793,6 +840,29 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "integer-sqrt" version = "0.1.5" @@ -831,12 +901,30 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "k256" version = "0.13.1" @@ -869,6 +957,12 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + [[package]] name = "num-traits" version = "0.2.18" @@ -935,9 +1029,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", "prost-derive", @@ -945,12 +1039,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.12.1", "proc-macro2", "quote", "syn 2.0.60", @@ -1070,9 +1164,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.16" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "schemars_derive", @@ -1082,14 +1176,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.16" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] @@ -1114,9 +1208,9 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.198" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -1132,9 +1226,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -1143,13 +1237,13 @@ dependencies = [ [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] @@ -1291,18 +1385,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -1389,6 +1483,7 @@ dependencies = [ "auction", "auction-package", "auctions-manager", + "chrono", "colored", "cosmwasm-schema", "cosmwasm-std", @@ -1418,13 +1513,76 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.60", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1433,13 +1591,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -1448,42 +1622,90 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index d3faaef5..878237ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,8 +51,8 @@ valence-macros = { path = "packages/valence-macros" } valence-package = { path = "packages/valence-package" } auction-package = { path = "packages/auction-package" } -cosmwasm-schema = "1.5.4" -cosmwasm-std = { version = "1.5.4", features = ["ibc3"] } +cosmwasm-schema = "1.5.5" +cosmwasm-std = { version = "1.5.5", features = ["ibc3"] } cw-storage-plus = "1.2.0" cw-utils = "1.0.3" cw2 = "1.1.2" @@ -61,5 +61,5 @@ thiserror = "1.0.31" schemars = "0.8.10" # dev-dependencies -cw-multi-test = "1.1.0" +cw-multi-test = "1.2.0" anyhow = { version = "1.0.51" } diff --git a/README.md b/README.md index afeebb5a..34ba0895 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ ## Code ids -- auctions manager = `1263` -- auction = `1262` -- oracle = `1261` -- rebalancer = `1260` -- services manager = `1259` -- account = `1258` +- auctions manager = `1404` +- auction = `1408` +- oracle = `1446` +- rebalancer = `1442` +- services manager = `1405` +- account = `1403` ## Owner / Admin diff --git a/contracts/auction/auction/src/contract.rs b/contracts/auction/auction/src/contract.rs index 6e068389..f7a7cc80 100644 --- a/contracts/auction/auction/src/contract.rs +++ b/contracts/auction/auction/src/contract.rs @@ -239,7 +239,7 @@ mod admin { // Verify the amount of funds we have to auction, is more then the start auction min amount let manager_addr = ADMIN.load(deps.storage)?; - let min_start_acution = MIN_AUCTION_AMOUNT + let min_start_auction = MIN_AUCTION_AMOUNT .query(&deps.querier, manager_addr, config.pair.0.clone())? .unwrap_or_default() .start_auction; @@ -251,12 +251,12 @@ mod admin { AUCTION_IDS.save(deps.storage, &auction_ids)?; // if its less, refund the funds to the users - if total_funds < min_start_acution { + if total_funds < min_start_auction { return do_refund( deps, auction_ids.curr, config.pair.0.clone(), - min_start_acution, + min_start_auction, total_funds, ); } diff --git a/contracts/auction/price_oracle/src/contract.rs b/contracts/auction/price_oracle/src/contract.rs index cd36a705..65db8c85 100644 --- a/contracts/auction/price_oracle/src/contract.rs +++ b/contracts/auction/price_oracle/src/contract.rs @@ -4,11 +4,14 @@ use auction_package::helpers::{ approve_admin_change, cancel_admin_change, start_admin_change, verify_admin, }; use auction_package::states::{ADMIN, PAIRS, PRICES, TWAP_PRICES}; -use auction_package::Price; +use auction_package::{Pair, Price}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{ + to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Response, StdResult, +}; use cw2::set_contract_version; +use cw_storage_plus::Bound; use valence_package::event_indexing::{ValenceEvent, ValenceGenericEvent}; use crate::error::ContractError; @@ -311,6 +314,15 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { + let from = from.map(Bound::::exclusive); + let prices = PRICES + .range(deps.storage, from, None, cosmwasm_std::Order::Ascending) + .take(limit.unwrap_or(10) as usize) + .collect::>>()?; + + Ok(to_json_binary(&prices)?) + } QueryMsg::GetConfig => { let config = CONFIG.load(deps.storage)?; Ok(to_json_binary(&config)?) diff --git a/contracts/auction/price_oracle/src/msg.rs b/contracts/auction/price_oracle/src/msg.rs index 4e15ef2c..cf9fe177 100644 --- a/contracts/auction/price_oracle/src/msg.rs +++ b/contracts/auction/price_oracle/src/msg.rs @@ -1,4 +1,4 @@ -use auction_package::{helpers::GetPriceResponse, Pair}; +use auction_package::{Pair, Price}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, Decimal}; use cw_utils::Expiration; @@ -46,8 +46,13 @@ pub enum ExecuteMsg { #[derive(QueryResponses)] pub enum QueryMsg { /// Get the minimum amount users can auction - #[returns(GetPriceResponse)] + #[returns(Price)] GetPrice { pair: Pair }, + #[returns(Vec<(Pair, Price)>)] + GetAllPrices { + from: Option, + limit: Option, + }, #[returns(Config)] GetConfig, #[returns(Addr)] diff --git a/contracts/services/rebalancer/src/contract.rs b/contracts/services/rebalancer/src/contract.rs index 6414b189..0ca4f3be 100644 --- a/contracts/services/rebalancer/src/contract.rs +++ b/contracts/services/rebalancer/src/contract.rs @@ -16,6 +16,7 @@ use valence_package::helpers::{approve_admin_change, verify_services_manager, Op use valence_package::services::rebalancer::{ PauseData, RebalancerExecuteMsg, SystemRebalanceStatus, }; +use valence_package::signed_decimal::SignedDecimal; use valence_package::states::{QueryFeeAction, ADMIN, SERVICES_MANAGER, SERVICE_FEE_CONFIG}; use crate::error::ContractError; @@ -302,6 +303,12 @@ pub fn execute( if let Some(pid) = data.pid { config.pid = pid.into_parsed()?; + + // If PID is updated, we reset the last calculation because they are no longer valid + config.targets.iter_mut().for_each(|t| { + t.last_input = None; + t.last_i = SignedDecimal::zero(); + }); } if let Some(max_limit_option) = data.max_limit_bps { diff --git a/contracts/services/rebalancer/src/helpers.rs b/contracts/services/rebalancer/src/helpers.rs index 0ad23220..fd579d95 100644 --- a/contracts/services/rebalancer/src/helpers.rs +++ b/contracts/services/rebalancer/src/helpers.rs @@ -27,7 +27,7 @@ pub struct TargetHelper { /// can either be to sell or to buy, depends on the calculation pub value_to_trade: Decimal, /// The minimum value we can send to the auction - pub auction_min_amount: Decimal, + pub auction_min_send_value: Decimal, } #[cw_serde] diff --git a/contracts/services/rebalancer/src/rebalance.rs b/contracts/services/rebalancer/src/rebalance.rs index 67991e48..50973e00 100644 --- a/contracts/services/rebalancer/src/rebalance.rs +++ b/contracts/services/rebalancer/src/rebalance.rs @@ -258,16 +258,22 @@ pub fn do_rebalance( env.block.time.seconds() - config.last_rebalance.seconds(), 0, )?; - (diff / Decimal::from_atomics(cycle_period, 0)?).min(Decimal::new(MAX_PID_DT_VALUE.into())) + (diff.checked_div(Decimal::from_atomics(cycle_period, 0)?))? + .min(Decimal::from_atomics(MAX_PID_DT_VALUE, 0)?) }; let (mut to_sell, to_buy) = do_pid(total_value, &mut target_helpers, config.pid.clone(), dt)?; - // Save targets to our config - config.targets = target_helpers - .iter_mut() - .map(|th| th.target.clone()) - .collect(); + // Update targets in config only the last data we need for the next rebalance calculation + for target in config.targets.iter_mut() { + if let Some(target_helper) = target_helpers + .iter() + .find(|th| th.target.denom == target.denom) + { + target.last_i = target_helper.target.last_i; + target.last_input = target_helper.target.last_input; + } + } // get minimum amount we can send to each auction set_auction_min_amounts(deps, auction_manager, &mut to_sell, min_amount_limits)?; @@ -326,8 +332,8 @@ pub(crate) fn set_auction_min_amounts( .find(|min_amount| min_amount.0 == sell_token.target.denom) { Some(min_amount) => { - sell_token.auction_min_amount = - Decimal::from_atomics(min_amount.1, 0)? / sell_token.price; + sell_token.auction_min_send_value = + Decimal::from_atomics(min_amount.1, 0)?.checked_div(sell_token.price)?; } None => { match MIN_AUCTION_AMOUNT.query( @@ -339,8 +345,9 @@ pub(crate) fn set_auction_min_amounts( send: min_send_amount, .. }) => { - sell_token.auction_min_amount = - Decimal::from_atomics(min_send_amount, 0)? / sell_token.price; + sell_token.auction_min_send_value = + Decimal::from_atomics(min_send_amount, 0)? + .checked_div(sell_token.price)?; min_amount_limits.push((sell_token.target.denom.clone(), min_send_amount)); Ok(()) } @@ -420,7 +427,8 @@ fn get_inputs( // Get current balance of the target, and calculate the value // safe if balance is 0, 0 / price = 0 let current_balance = deps.querier.query_balance(account, target.denom.clone())?; - let balance_value = Decimal::from_atomics(current_balance.amount, 0)? / price; + let balance_value = + Decimal::from_atomics(current_balance.amount, 0)?.checked_div(price)?; total_value += balance_value; targets_helpers.push(TargetHelper { @@ -429,7 +437,7 @@ fn get_inputs( price, balance_value, value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }); Ok((total_value, targets_helpers)) @@ -470,6 +478,7 @@ fn do_pid( Some(last_input) => signed_input - last_input.into(), None => SignedDecimal::zero(), }; + d = d * signed_d / signed_dt; let output = p + i - d; @@ -509,7 +518,7 @@ pub fn verify_targets( // Safe to unwrap here, because we only enter the function is there is a min_balance target // and we error out if we don't find the target above. let min_balance = Decimal::from_atomics(target.target.min_balance.unwrap(), 0)?; - let min_balance_target = min_balance * target.price; + let min_balance_target = min_balance / target.price; let real_target = total_value * target.target.percentage; // if the target is below the minimum balance target @@ -520,7 +529,7 @@ pub fn verify_targets( let (new_target_perc, mut leftover_perc) = if min_balance_target >= total_value { (Decimal::one(), Decimal::zero()) } else { - let perc = min_balance_target / total_value; + let perc = min_balance_target.checked_div(total_value)?; (perc, Decimal::one() - perc) }; @@ -529,23 +538,23 @@ pub fn verify_targets( let updated_targets = targets .into_iter() - .map(|mut t| { + .map(|mut t| -> Result { // If our target is the min_balance target, we update perc, and return t. if t.target.denom == target.target.denom { t.target.percentage = new_target_perc; - return t; + return Ok(t); }; // If leftover perc is 0, we set the perc as zero for this target if leftover_perc.is_zero() { t.target.percentage = Decimal::zero(); - return t; + return Ok(t); } // Calc new perc based on chosen strategy and new min_balance perc match config.target_override_strategy { TargetOverrideStrategy::Proportional => { - let old_perc = t.target.percentage / old_leftover_perc; + let old_perc = t.target.percentage.checked_div(old_leftover_perc)?; t.target.percentage = old_perc * leftover_perc; } TargetOverrideStrategy::Priority => { @@ -559,9 +568,9 @@ pub fn verify_targets( } new_total_perc += t.target.percentage; - t + Ok(t) }) - .collect(); + .collect::, ContractError>>()?; // If the new percentage is smaller then 0.9999 or higher then 1, we have something wrong in calculation if new_total_perc > Decimal::one() @@ -642,26 +651,26 @@ fn generate_trades_msgs( // check if the amount we intent to buy, is lower than min_amount of the sell token // if its not, it will be handled correctly by the main loop. // but if it is, it means we need to sell other token more then we intent to - if token_buy.value_to_trade < token_sell.auction_min_amount { + if token_buy.value_to_trade < token_sell.auction_min_send_value { // If the amount we try to sell, is below the auction_min_amount, we need to set it to zero // else we reduce the auction_min_amount value - if token_sell.value_to_trade < token_sell.auction_min_amount { + if token_sell.value_to_trade < token_sell.auction_min_send_value { token_sell.value_to_trade = Decimal::zero(); } else { - token_sell.value_to_trade -= token_sell.auction_min_amount; + token_sell.value_to_trade -= token_sell.auction_min_send_value; } let pair = Pair::from(( token_sell.target.denom.clone(), token_buy.target.denom.clone(), )); - let amount = (token_sell.auction_min_amount * token_sell.price).to_uint_ceil(); + let amount = (token_sell.auction_min_send_value * token_sell.price).to_uint_ceil(); let trade = RebalanceTrade::new(pair, amount); token_buy.value_to_trade = Decimal::zero(); if let Ok(msg) = construct_msg(deps, auction_manager.clone(), trade.clone()) { - max_sell -= token_sell.auction_min_amount; + max_sell -= token_sell.auction_min_send_value; msgs.push(msg); }; } @@ -697,6 +706,10 @@ fn generate_trades_msgs( // If our sell results in less then min_balance, we sell the difference to hit min_balance let diff = token_sell.balance_amount - min_balance; + if diff.is_zero() { + return; + } + // Unwrap should be safe here because diff should be a small number // and directly related to users balance token_sell.value_to_trade = @@ -705,18 +718,20 @@ fn generate_trades_msgs( } // If we intent to sell less then our minimum, we set to_trade to be 0 and continue - if token_sell.value_to_trade < token_sell.auction_min_amount { + if token_sell.value_to_trade < token_sell.auction_min_send_value { token_sell.value_to_trade = Decimal::zero(); return; } + // If our buy value is lower then our sell min_send value, we do nothing and continue. + if token_buy.value_to_trade < token_sell.auction_min_send_value { + return; + } + // If we hit our max sell limit, we only sell the limit left // otherwise, we keep track of how much we already sold if token_sell.value_to_trade > max_sell { token_sell.value_to_trade = max_sell; - max_sell = Decimal::zero(); - } else { - max_sell -= token_sell.value_to_trade; } let pair = Pair::from(( @@ -733,6 +748,7 @@ fn generate_trades_msgs( token_buy.value_to_trade = Decimal::zero(); let Ok(msg) = construct_msg(deps, auction_manager.clone(), trade.clone()) else { + max_sell -= token_buy.value_to_trade; return; }; @@ -747,6 +763,7 @@ fn generate_trades_msgs( token_sell.value_to_trade = Decimal::zero(); let Ok(msg) = construct_msg(deps, auction_manager.clone(), trade.clone()) else { + max_sell -= token_sell.value_to_trade; return; }; diff --git a/contracts/services/rebalancer/src/state.rs b/contracts/services/rebalancer/src/state.rs index 4a685391..16164ec3 100644 --- a/contracts/services/rebalancer/src/state.rs +++ b/contracts/services/rebalancer/src/state.rs @@ -11,7 +11,7 @@ pub(crate) const DENOM_WHITELIST: Item> = Item::new("token_white /// Base denom whitelist pub(crate) const BASE_DENOM_WHITELIST: Item> = Item::new("base_token_whitelist"); /// Storage to keep all configs of all registered accounts -pub(crate) const CONFIGS: Map = Map::new("configs"); +pub const CONFIGS: Map = Map::new("configs"); /// Storage to keep the current status of the system rebalance pub(crate) const SYSTEM_REBALANCE_STATUS: Item = Item::new("system_rebalance_status"); diff --git a/devtools/optimize.sh b/devtools/optimize.sh index b9860659..9505d790 100755 --- a/devtools/optimize.sh +++ b/devtools/optimize.sh @@ -5,11 +5,11 @@ if [[ $(uname -m) =~ "arm64" ]]; then \ docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/optimizer-arm64:0.15.0 + cosmwasm/optimizer-arm64:0.16.0 else docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/optimizer:0.15.1 + cosmwasm/optimizer:0.16.0 fi diff --git a/scripts/auction_funds.sh b/scripts/auction_funds.sh new file mode 100755 index 00000000..4cdf4c90 --- /dev/null +++ b/scripts/auction_funds.sh @@ -0,0 +1,95 @@ +BINARY="neutrond" +GAS_PRICES="0.075untrn" +EXECUTE_FLAGS="--gas-prices $GAS_PRICES --gas auto --gas-adjustment 1.4 --output json -y" + +ADMIN_ADDR="neutron1phx0sz708k3t6xdnyc98hgkyhra4tp44et5s68" +AUCTIONS_MANAGER_ADDR="neutron13exc5wdc7y5qpqazc34djnu934lqvfw2dru30j52ahhjep6jzx8ssjxcyz" + +NTRN_AMOUNT="1000001untrn" #1 NTRN +ATOM_AMOUNT="100001ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9" #0.1 ATOM +USDC_AMOUNT="1000001ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81" #1 USDC +NEWT_AMOUNT="13000001factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt" #13k NEWT + +declare -a NTRN_PAIRS=( + '["untrn","ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9"]' + '["untrn","ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81"]' + '["untrn","factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt"]' +) + +declare -a ATOM_PAIRS=( + '["ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9","untrn"]' + '["ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9","ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81"]' + '["ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9","factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt"]' +) + +declare -a USDC_PAIRS=( + '["ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81","ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9"]' + '["ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81","untrn"]' + '["ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81","factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt"]' +) + +declare -a NEWT_PAIRS=( + '["factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt","ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9"]' + '["factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt","untrn"]' + '["factory/neutron1p8d89wvxyjcnawmgw72klknr3lg9gwwl6ypxda/newt","ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81"]' +) + +for pair in "${NTRN_PAIRS[@]}"; do + echo "Auctioning $NTRN_AMOUNT for pair: $pair" + + EXECUTE_MSG=$( + jq -n \ + --argjson pair $pair \ + '{auction_funds:{ + pair: $pair, + }}' + ) + + $BINARY tx wasm execute $AUCTIONS_MANAGER_ADDR "$EXECUTE_MSG" --from $ADMIN_ADDR --amount $NTRN_AMOUNT $EXECUTE_FLAGS + sleep 9 +done + +for pair in "${ATOM_PAIRS[@]}"; do + echo "Auctioning $ATOM_AMOUNT for pair: $pair" + + EXECUTE_MSG=$( + jq -n \ + --argjson pair $pair \ + '{auction_funds:{ + pair: $pair, + }}' + ) + + $BINARY tx wasm execute $AUCTIONS_MANAGER_ADDR "$EXECUTE_MSG" --from $ADMIN_ADDR --amount $ATOM_AMOUNT $EXECUTE_FLAGS + sleep 9 +done + +for pair in "${USDC_PAIRS[@]}"; do + echo "Auctioning $USDC_AMOUNT for pair: $pair" + + EXECUTE_MSG=$( + jq -n \ + --argjson pair $pair \ + '{auction_funds:{ + pair: $pair, + }}' + ) + + $BINARY tx wasm execute $AUCTIONS_MANAGER_ADDR "$EXECUTE_MSG" --from $ADMIN_ADDR --amount $USDC_AMOUNT $EXECUTE_FLAGS + sleep 9 +done + +for pair in "${NEWT_PAIRS[@]}"; do + echo "Auctioning $NEWT_AMOUNT for pair: $pair" + + EXECUTE_MSG=$( + jq -n \ + --argjson pair $pair \ + '{auction_funds:{ + pair: $pair, + }}' + ) + + $BINARY tx wasm execute $AUCTIONS_MANAGER_ADDR "$EXECUTE_MSG" --from $ADMIN_ADDR --amount $NEWT_AMOUNT $EXECUTE_FLAGS + sleep 9 +done diff --git a/scripts/migrate.sh b/scripts/migrate.sh index e27f6566..665ec9b8 100755 --- a/scripts/migrate.sh +++ b/scripts/migrate.sh @@ -10,13 +10,13 @@ EXECUTE_FLAGS="--gas-prices $GAS_PRICES --gas auto --gas-adjustment 1.4 --output # addresses ADMIN_ADDR="neutron1phx0sz708k3t6xdnyc98hgkyhra4tp44et5s68" REBALANCER_ADDR="neutron1qs6mzpmcw3dvg5l8nyywetcj326scszdj7v4pfk55xwshd4prqnqfwc0z2" -ORACLE_ADDR="neutron1pkk88zqjd478x3maws3mv7qugylhsu0sjkejj3k2w02wwhp6fqgsl7m0js" +ORACLE_ADDR="neutron1s8uqyh0mmh8g66s2dectf56c08y6fvusp39undp8kf4v678ededsy6tstf" SERVICES_MANAGER_ADDR="neutron1gantvpnat0la8kkkzrnj48d5d8wxdjllh5r2w4r2hcrpwy00s69quypupa" AUCTIONS_MANAGER_ADDR="neutron13exc5wdc7y5qpqazc34djnu934lqvfw2dru30j52ahhjep6jzx8ssjxcyz" # Code ids -REBALANCER_CODE_ID=1260 -ORACLE_CODE_ID=1261 +REBALANCER_CODE_ID=1442 +ORACLE_CODE_ID=1446 SERVICES_MANAGER_CODE_ID=1259 AUCTIONS_MANAGER_CODE_ID=1263 AUCTION_CODE_ID=1262 diff --git a/tests/rust-tests/Cargo.toml b/tests/rust-tests/Cargo.toml index 030c923e..677855b5 100644 --- a/tests/rust-tests/Cargo.toml +++ b/tests/rust-tests/Cargo.toml @@ -30,6 +30,7 @@ auction-package = { workspace = true } auctions-manager = { workspace = true } auction = { workspace = true } price-oracle = { workspace = true } +chrono = "0.4.38" # Astro astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v2.9.5" } diff --git a/tests/rust-tests/src/lib.rs b/tests/rust-tests/src/lib.rs index 3c0f634f..b316c728 100644 --- a/tests/rust-tests/src/lib.rs +++ b/tests/rust-tests/src/lib.rs @@ -11,3 +11,6 @@ mod tests_auctions; #[cfg(test)] mod tests_account; + +#[cfg(test)] +mod live_debugging; diff --git a/tests/rust-tests/src/live_debugging/mod.rs b/tests/rust-tests/src/live_debugging/mod.rs new file mode 100644 index 00000000..751c75cc --- /dev/null +++ b/tests/rust-tests/src/live_debugging/mod.rs @@ -0,0 +1,16 @@ +#[cfg(test)] +mod test_specific_config; + +#[cfg(test)] +mod types; + +#[cfg(test)] +mod suite_builder; + +#[cfg(test)] +mod suite_helpers; + +const REBALANCER_ADDR: &str = "neutron1qs6mzpmcw3dvg5l8nyywetcj326scszdj7v4pfk55xwshd4prqnqfwc0z2"; +const ORACLE_ADDR: &str = "neutron1s8uqyh0mmh8g66s2dectf56c08y6fvusp39undp8kf4v678ededsy6tstf"; +const AUCTIONS_MANAGER_ADDR: &str = + "neutron13exc5wdc7y5qpqazc34djnu934lqvfw2dru30j52ahhjep6jzx8ssjxcyz"; diff --git a/tests/rust-tests/src/live_debugging/suite_builder.rs b/tests/rust-tests/src/live_debugging/suite_builder.rs new file mode 100644 index 00000000..41bc1916 --- /dev/null +++ b/tests/rust-tests/src/live_debugging/suite_builder.rs @@ -0,0 +1,74 @@ +use std::collections::HashMap; + +use auction_package::Pair; +use cosmwasm_std::{BlockInfo, Coin}; +use valence_package::services::rebalancer::RebalancerConfig; + +use crate::suite::{suite::Suite, suite_builder::SuiteBuilder}; + +use super::types::{Prices, WhitelistDenoms}; + +impl SuiteBuilder { + pub fn build_live_debug( + block_info: BlockInfo, + whitelists: WhitelistDenoms, + prices: Prices, + balances: Vec, + config: RebalancerConfig, + ) -> Suite { + let mut builder = SuiteBuilder::default(); + + // Get init app + let mut app = builder.set_app(); + + // Update our mocked block info with the correct info from mainnet + app.update_block(|b| *b = block_info.clone()); + + // Upload contracts + builder.upload_contracts(&mut app); + + // init oracle, auctions manager and auctions + let (auctions_manager_addr, oracle_addr, auction_addrs) = + builder.ld_init_auctions(&mut app, whitelists.denom_whitelist.clone(), prices); + + // init services manager + let manager_addr = builder.init_manager(&mut app); + + // init and register rebalancer + let rebalancer_addr = builder.ld_init_rebalancer( + &mut app, + auctions_manager_addr.clone(), + manager_addr.clone(), + whitelists.clone(), + ); + + let account_addr = builder.ld_init_accounts( + &mut app, + whitelists.denom_whitelist.clone(), + manager_addr.clone(), + rebalancer_addr.clone(), + balances, + config, + ); + + Suite { + app, + admin: builder.admin, + owner: builder.owner, + trustee: builder.trustee, + mm: builder.mm, + auctions_manager_addr, + oracle_addr, + manager_addr, + rebalancer_addr, + account_addrs: vec![account_addr], + auction_addrs, + pair: Pair::from(( + whitelists.denom_whitelist[0].clone(), + whitelists.denom_whitelist[1].clone(), + )), + account_code_id: builder.account_code_id, + astro_pools: HashMap::new(), + } + } +} diff --git a/tests/rust-tests/src/live_debugging/suite_helpers.rs b/tests/rust-tests/src/live_debugging/suite_helpers.rs new file mode 100644 index 00000000..5c1ca6bc --- /dev/null +++ b/tests/rust-tests/src/live_debugging/suite_helpers.rs @@ -0,0 +1,276 @@ +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + process::Command, +}; + +use auction_package::{ + states::{MinAmount, PRICES}, + AuctionStrategy, Pair, +}; +use cosmwasm_std::{from_json, to_json_binary, Addr, Coin}; +use cw_multi_test::{App, Executor}; +use rebalancer::state::CONFIGS; +use valence_package::services::{ + rebalancer::{RebalancerConfig, Target}, + ValenceServices, +}; + +use crate::suite::{ + instantiates::{ + AccountInstantiate, AuctionInstantiate, AuctionsManagerInstantiate, OracleInstantiate, + RebalancerInstantiate, + }, + suite_builder::SuiteBuilder, +}; + +use super::{ + types::{MinLimitsRes, Prices, WhitelistDenoms}, + AUCTIONS_MANAGER_ADDR, +}; + +impl SuiteBuilder { + pub fn ld_init_auctions( + &mut self, + app: &mut App, + whitelist_denoms: Vec, + prices: Prices, + ) -> (Addr, Addr, HashMap<(String, String), Addr>) { + // init auction manager + let auctions_manager_addr = self.init_auctions_manager( + app, + AuctionsManagerInstantiate::new(self.auction_code_id, self.mm.to_string()).into(), + ); + + // init the oracle + let price_oracle_addr = self.init_oracle( + app, + OracleInstantiate::default(auctions_manager_addr.clone()) + .change_seconds_allow_manual_change(1) + .into(), + ); + + // add oracle addr to the manager + app.execute_contract( + self.admin.clone(), + auctions_manager_addr.clone(), + &auctions_manager::msg::ExecuteMsg::Admin(Box::new( + auctions_manager::msg::AdminMsgs::UpdateOracle { + oracle_addr: price_oracle_addr.to_string(), + }, + )), + &[], + ) + .unwrap(); + + // get min limits of each denom + let min_limits = SuiteBuilder::get_auction_min_amounts(&whitelist_denoms); + + let mut auctions_addrs: HashMap<(String, String), Addr> = HashMap::new(); + // create auction for each whitelisted pair of denoms + whitelist_denoms.iter().for_each(|denom_1| { + whitelist_denoms.iter().for_each(|denom_2| { + if denom_1 == denom_2 { + return; + } + + let pair = Pair::from((denom_1.clone(), denom_2.clone())); + let auction_init_msg = AuctionInstantiate::new( + pair.clone(), + AuctionStrategy { + start_price_perc: 5000, + end_price_perc: 5000, + }, + ); + let min_amount = min_limits.get(denom_1).unwrap().clone(); + app.execute_contract( + self.admin.clone(), + auctions_manager_addr.clone(), + &auctions_manager::msg::ExecuteMsg::Admin(Box::new( + auctions_manager::msg::AdminMsgs::NewAuction { + msg: auction_init_msg.into(), + label: "auction".to_string(), + min_amount: Some(min_amount), + }, + )), + &[], + ) + .unwrap(); + + // Get the addr of the auction + let auction_addr: Addr = app + .wrap() + .query_wasm_smart( + auctions_manager_addr.clone(), + &auction_package::msgs::AuctionsManagerQueryMsg::GetPairAddr { + pair: pair.clone(), + }, + ) + .unwrap(); + + auctions_addrs.insert(pair.clone().into(), auction_addr); + + // Update the price of the auction + let price = prices.iter().find(|(p, _)| p == &pair).unwrap().1.clone(); + let mut oracle_storage = app.contract_storage_mut(&price_oracle_addr); + PRICES.save(oracle_storage.as_mut(), pair, &price).unwrap(); + }) + }); + + (auctions_manager_addr, price_oracle_addr, auctions_addrs) + } + + pub fn ld_init_rebalancer( + &mut self, + app: &mut App, + auctions_manager_addr: Addr, + manager_addr: Addr, + whitelists: WhitelistDenoms, + ) -> Addr { + // init rebalancer + let rebalancer_instantiate_msg: rebalancer::msg::InstantiateMsg = + RebalancerInstantiate::default(manager_addr.as_str(), auctions_manager_addr.as_str()) + .change_denom_whitelist(whitelists.denom_whitelist) + .change_base_denom_whitelist(whitelists.base_denom_whitelist) + .into(); + + let rebalancer_addr = app + .instantiate_contract( + self.rebalancer_code_id, + self.admin.clone(), + &rebalancer_instantiate_msg, + &[], + "rebalancer", + Some(self.admin.to_string()), + ) + .unwrap(); + + app.execute_contract( + self.admin.clone(), + manager_addr, + &valence_package::msgs::core_execute::ServicesManagerExecuteMsg::Admin( + valence_package::msgs::core_execute::ServicesManagerAdminMsg::AddService { + name: ValenceServices::Rebalancer, + addr: rebalancer_addr.to_string(), + }, + ), + &[], + ) + .unwrap(); + + rebalancer_addr + } + + /// Init an account and register it to the rebalancer + pub fn ld_init_accounts( + &mut self, + app: &mut App, + whitelist_denoms: Vec, + manager_addr: Addr, + rebalancer_addr: Addr, + account_balances: Vec, + account_config: RebalancerConfig, + ) -> Addr { + let account_init_msg: valence_account::msg::InstantiateMsg = + AccountInstantiate::new(manager_addr.as_str()).into(); + + // Instantiate the account contract + let account_addr = app + .instantiate_contract( + self.account_code_id, + self.owner.clone(), + &account_init_msg, + &[], + "account".to_string(), + Some(self.owner.to_string()), + ) + .unwrap(); + + // update account balance based on mainnet balance + app.init_modules(|router, _api, storage| { + router + .bank + .init_balance(storage, &account_addr, account_balances) + .unwrap(); + }); + + // register to the rebalancer with some mock data first + let targets: HashSet = HashSet::from_iter([ + Target { + denom: whitelist_denoms[0].to_string(), + bps: 7500, + min_balance: None, + }, + Target { + denom: whitelist_denoms[1].to_string(), + bps: 2500, + min_balance: None, + }, + ]); + + let mut mock_rebalancer_data = SuiteBuilder::get_default_rebalancer_register_data(); + mock_rebalancer_data.base_denom = "untrn".to_string(); + mock_rebalancer_data.targets = targets; + + app.execute_contract( + self.owner.clone(), + account_addr.clone(), + &valence_package::msgs::core_execute::AccountBaseExecuteMsg::RegisterToService { + service_name: ValenceServices::Rebalancer, + data: Some(to_json_binary(&mock_rebalancer_data).unwrap()), + }, + &[], + ) + .unwrap(); + + // Update config in place with mainnet config + let mut contract_storage = app.contract_storage_mut(&rebalancer_addr); + CONFIGS + .save( + contract_storage.as_mut(), + account_addr.clone(), + &account_config, + ) + .unwrap(); + + // app.init_modules(|_router, _api, storage| { + // let namespace = concat(NAMESPACE_WASM, b"contract_data/"); + // let namespace = concat(&namespace, REBALANCER_ADDR.as_bytes()); + // let storage_key = concat(&namespace, b"configs"); + // let account_key = concat(&storage_key, account_addr.as_bytes()); + // storage.set(&account_key, &to_json_vec(&account_config).unwrap()); + // }); + + account_addr + } +} + +impl SuiteBuilder { + pub fn get_auction_min_amounts(denoms: &[String]) -> BTreeMap { + BTreeMap::from_iter(denoms.iter().map(|denom| { + let q_string = format!("{{\"get_min_limit\": {{\"denom\": \"{}\"}}}}", denom); + let min_limits_output = Command::new("neutrond") + .args([ + "q", + "wasm", + "contract-state", + "smart", + AUCTIONS_MANAGER_ADDR, + ]) + .arg(q_string) + .args(["--node", "https://neutron-tw-rpc.polkachu.com:443"]) + .args(["--chain-id", "neutron-1"]) + .args(["--output", "json"]) + .output() + .expect("Failed getting auctions min limits"); + + ( + denom.clone(), + from_json::( + String::from_utf8_lossy(&min_limits_output.stdout).to_string(), + ) + .unwrap() + .data, + ) + })) + } +} diff --git a/tests/rust-tests/src/live_debugging/test_specific_config.rs b/tests/rust-tests/src/live_debugging/test_specific_config.rs new file mode 100644 index 00000000..b2ebb2b7 --- /dev/null +++ b/tests/rust-tests/src/live_debugging/test_specific_config.rs @@ -0,0 +1,167 @@ +// Test a specific config of an account with the state of the system +// This test should give us an idea of how the next rebalance would work, and give us +// a manualy way to check what trades the rebalancer is calculating +// best for debuging live data without without for a cycle + +// The state of the system includes: +// - the specific account config +// - the account balances +// - all prices from oracle + +// To get the data we want, we want to do those queries: +// - account config = neutrond query wasm contract-state smart neutron1qs6mzpmcw3dvg5l8nyywetcj326scszdj7v4pfk55xwshd4prqnqfwc0z2 '{"get_config": {"addr": "[ACCOUNT_ADDR]"}}' +// - account balances = neutrond q bank balances [ACCOUNT_ADDR] +// - prices = neutrond query wasm contract-state smart neutron1s8uqyh0mmh8g66s2dectf56c08y6fvusp39undp8kf4v678ededsy6tstf '"get_all_prices"' + +// NOTE - we are taking the data live, so make sure to have the neutrond set up correctly with the correct version +use std::process::Command; + +use cosmwasm_std::{from_json, BlockInfo}; +use valence_package::services::rebalancer::RebalancerConfig; + +use crate::{ + live_debugging::{ + types::{AllPricesRes, BlockRes, ConfigRes, Prices, WhitelistDenoms, WhitelistDenomsRes}, + ORACLE_ADDR, REBALANCER_ADDR, + }, + suite::suite_builder::SuiteBuilder, +}; + +use super::types::Balances; + +const ACCOUNT_ADDR: &str = "neutron1yd27kgnsjkeddwtuy29q9yzrnd247v6hcml6swl54dfkcwuuytqs8ha94x"; +const HEIGHT: &str = ""; + +#[ignore = "For debugging mainnet data"] +#[test] +fn live_debugging() { + // If we have specifig height, query by that height + let mut height_arg = vec![]; + let mut block_height = vec![]; + if !HEIGHT.is_empty() { + height_arg = vec!["--height", HEIGHT]; + block_height = vec![HEIGHT]; + } + + // query mainnet for the balances of the account + let block_output = Command::new("neutrond") + .args(["q", "block"]) + // .args(["--node", ""]) + .args(["--chain-id", "neutron-1"]) + .args(block_height.to_vec()) + .output() + .expect("Failed getting balances"); + + let block_info: BlockInfo = + from_json::(String::from_utf8_lossy(&block_output.stdout).to_string()) + .unwrap() + .block + .header + .into(); + + // query mainnet for the balances of the account + let balances_output = Command::new("neutrond") + .args(["q", "bank", "balances", ACCOUNT_ADDR]) + // .args(["--node", ""]) + .args(["--chain-id", "neutron-1"]) + .args(["--output", "json"]) + .args(height_arg.to_vec()) + .output() + .expect("Failed getting balances"); + + let balances: Balances = + from_json(String::from_utf8_lossy(&balances_output.stdout).to_string()).unwrap(); + + // Query mainnet for the config of the account + let q_string = format!("{{\"get_config\": {{\"addr\": \"{}\"}}}}", ACCOUNT_ADDR); + let config_output = Command::new("neutrond") + .args(["q", "wasm", "contract-state", "smart", REBALANCER_ADDR]) + .arg(q_string) + // .args(["--node", ""]) + .args(["--chain-id", "neutron-1"]) + .args(["--output", "json"]) + .args(height_arg.to_vec()) + .output() + .expect("Failed getting config"); + + let config: RebalancerConfig = + from_json::(String::from_utf8_lossy(&config_output.stdout).to_string()) + .unwrap() + .data; + + // Query mainnet for all prices from oracle + let q_string: &str = "\"get_all_prices\""; + let prices_output = Command::new("neutrond") + .args(["q", "wasm", "contract-state", "smart", ORACLE_ADDR]) + .arg(q_string) + // .args(["--node", ]) + .args(["--chain-id", "neutron-1"]) + .args(["--output", "json"]) + .args(height_arg.to_vec()) + .output() + .expect("Failed getting all prices"); + + let prices: Prices = + from_json::(String::from_utf8_lossy(&prices_output.stdout).to_string()) + .unwrap() + .data; + + // Query mainnet for the whitelist denoms + let q_string: &str = "\"get_white_lists\""; + let whitelists_output = Command::new("neutrond") + .args(["q", "wasm", "contract-state", "smart", REBALANCER_ADDR]) + .arg(q_string) + // .args(["--node", ""]) + .args(["--chain-id", "neutron-1"]) + .args(["--output", "json"]) + .args(height_arg.to_vec()) + .output() + .expect("Failed getting whitelists"); + + let whitelists: WhitelistDenoms = from_json::( + String::from_utf8_lossy(&whitelists_output.stdout).to_string(), + ) + .unwrap() + .data; + + // print the data we get from mainnet for debugging + // println!("1. Balances: {:?}", balances); + // println!("2. Config: {:?}", config); + // println!("3. Prices: {:?}", prices); + // println!("whitelists: {:?}", whitelists); + + //---------------------- + // Start mocking + //---------------------- + + let mut suite = SuiteBuilder::build_live_debug( + block_info, + whitelists, + prices.clone(), + balances.balances, + config.clone(), + ); + let account_config = suite + .query_rebalancer_config(suite.account_addrs[0].clone()) + .unwrap(); + let all_prices = suite.query_oracle_all_prices(None, None); + + // make sure the config is set in our mock rebalancer + assert_eq!(account_config, config); + // make sure prices in oracle are matching mainnet prices + assert_eq!(all_prices, prices); + + // After we confirmed everything is in place, we can do rebalance, and read the response (events should tell us the info we need) + let res = suite.rebalance(None).unwrap(); + // println!("Rebalance response: {:?}", res); + + // print our events for debugging + res.events.iter().for_each(|event| { + if event.ty.contains("valence") { + println!( + "Type: {} | Data: {}", + event.attributes[1].value, event.attributes[2].value + ); + } + }); +} diff --git a/tests/rust-tests/src/live_debugging/types.rs b/tests/rust-tests/src/live_debugging/types.rs new file mode 100644 index 00000000..327ceb09 --- /dev/null +++ b/tests/rust-tests/src/live_debugging/types.rs @@ -0,0 +1,112 @@ +use auction_package::{states::MinAmount, Pair, Price}; +use chrono::NaiveDateTime; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{BlockInfo, Coin, Timestamp}; +use valence_package::services::rebalancer::{BaseDenom, RebalancerConfig}; + +#[derive( + cosmwasm_schema::serde::Serialize, + cosmwasm_schema::serde::Deserialize, + std::clone::Clone, + std::fmt::Debug, + std::cmp::PartialEq, + cosmwasm_schema::schemars::JsonSchema, +)] +#[allow(clippy::derive_partial_eq_without_eq)] // Allow users of `#[cw_serde]` to not implement Eq without clippy complaining +#[serde(crate = "::cosmwasm_schema::serde")] +#[schemars(crate = "::cosmwasm_schema::schemars")] +pub struct Balances { + pub balances: Vec, +} + +#[derive( + cosmwasm_schema::serde::Serialize, + cosmwasm_schema::serde::Deserialize, + std::clone::Clone, + std::fmt::Debug, + std::cmp::PartialEq, + cosmwasm_schema::schemars::JsonSchema, +)] +#[allow(clippy::derive_partial_eq_without_eq)] // Allow users of `#[cw_serde]` to not implement Eq without clippy complaining +#[serde(crate = "::cosmwasm_schema::serde")] +#[schemars(crate = "::cosmwasm_schema::schemars")] +pub struct BlockRes { + pub block: Block, +} + +#[derive( + cosmwasm_schema::serde::Serialize, + cosmwasm_schema::serde::Deserialize, + std::clone::Clone, + std::fmt::Debug, + std::cmp::PartialEq, + cosmwasm_schema::schemars::JsonSchema, +)] +#[allow(clippy::derive_partial_eq_without_eq)] // Allow users of `#[cw_serde]` to not implement Eq without clippy complaining +#[serde(crate = "::cosmwasm_schema::serde")] +#[schemars(crate = "::cosmwasm_schema::schemars")] +pub struct Block { + pub header: BlockInfoTemp, +} + +#[derive( + cosmwasm_schema::serde::Serialize, + cosmwasm_schema::serde::Deserialize, + std::clone::Clone, + std::fmt::Debug, + std::cmp::PartialEq, + cosmwasm_schema::schemars::JsonSchema, +)] +#[allow(clippy::derive_partial_eq_without_eq)] // Allow users of `#[cw_serde]` to not implement Eq without clippy complaining +#[serde(crate = "::cosmwasm_schema::serde")] +#[schemars(crate = "::cosmwasm_schema::schemars")] +pub struct BlockInfoTemp { + pub height: String, + pub time: String, + pub chain_id: String, +} + +impl From for BlockInfo { + fn from(block_info_temp: BlockInfoTemp) -> Self { + let seconds = + NaiveDateTime::parse_from_str(&block_info_temp.time, "%Y-%m-%dT%H:%M:%S%.9fZ") + .unwrap() + .and_utc() + .timestamp_nanos_opt() + .unwrap(); + + BlockInfo { + height: block_info_temp.height.parse().unwrap(), + time: Timestamp::from_nanos(seconds as u64), + chain_id: block_info_temp.chain_id, + } + } +} + +#[cw_serde] +pub struct ConfigRes { + pub data: RebalancerConfig, +} + +#[cw_serde] +pub struct AllPricesRes { + pub data: Prices, +} + +pub type Prices = Vec<(Pair, Price)>; + +#[cw_serde] +pub struct WhitelistDenomsRes { + pub data: WhitelistDenoms, +} + +#[cw_serde] +pub struct WhitelistDenoms { + pub denom_whitelist: Vec, + pub base_denom_whitelist: Vec, +} + +#[cw_serde] +pub struct MinLimitsRes { + pub data: MinAmount, +} diff --git a/tests/rust-tests/src/suite/instantiates/oracle.rs b/tests/rust-tests/src/suite/instantiates/oracle.rs index 6d6349d5..828a47de 100644 --- a/tests/rust-tests/src/suite/instantiates/oracle.rs +++ b/tests/rust-tests/src/suite/instantiates/oracle.rs @@ -10,6 +10,12 @@ impl From for price_oracle::msg::InstantiateMsg { } } +impl From<&mut OracleInstantiate> for price_oracle::msg::InstantiateMsg { + fn from(value: &mut OracleInstantiate) -> Self { + value.msg.clone() + } +} + impl OracleInstantiate { pub fn default(auctions_manager_addr: Addr) -> Self { Self::new(auctions_manager_addr) @@ -30,4 +36,13 @@ impl OracleInstantiate { self.msg.auctions_manager_addr = auctions_manager_addr.to_string(); self } + + /* Change functions */ + pub fn change_seconds_allow_manual_change( + &mut self, + seconds_allow_manual_change: u64, + ) -> &mut Self { + self.msg.seconds_allow_manual_change = seconds_allow_manual_change; + self + } } diff --git a/tests/rust-tests/src/suite/instantiates/rebalancer.rs b/tests/rust-tests/src/suite/instantiates/rebalancer.rs index 97b24e9f..1506ef7f 100644 --- a/tests/rust-tests/src/suite/instantiates/rebalancer.rs +++ b/tests/rust-tests/src/suite/instantiates/rebalancer.rs @@ -14,6 +14,12 @@ impl From for rebalancer::msg::InstantiateMsg { } } +impl From<&mut RebalancerInstantiate> for rebalancer::msg::InstantiateMsg { + fn from(value: &mut RebalancerInstantiate) -> Self { + value.msg.clone() + } +} + impl RebalancerInstantiate { pub fn default(services_manager: &str, auctions_manager: &str) -> Self { Self { diff --git a/tests/rust-tests/src/suite/suite_auction.rs b/tests/rust-tests/src/suite/suite_auction.rs index 27038ac3..29d9aafb 100644 --- a/tests/rust-tests/src/suite/suite_auction.rs +++ b/tests/rust-tests/src/suite/suite_auction.rs @@ -6,7 +6,7 @@ use auction_package::{ helpers::{ChainHaltConfig, GetPriceResponse}, msgs::AuctionsManagerQueryMsg, states::MinAmount, - AuctionStrategy, Pair, PriceFreshnessStrategy, + AuctionStrategy, Pair, Price, PriceFreshnessStrategy, }; use cosmwasm_std::{coin, coins, Addr, Coin, Decimal, Uint128}; use cw_multi_test::{AppResponse, Executor}; @@ -695,6 +695,20 @@ impl Suite { .unwrap() } + pub fn query_oracle_all_prices( + &self, + from: Option, + limit: Option, + ) -> Vec<(Pair, Price)> { + self.app + .wrap() + .query_wasm_smart( + self.oracle_addr.clone(), + &price_oracle::msg::QueryMsg::GetAllPrices { from, limit }, + ) + .unwrap() + } + pub fn query_auction_price(&self, auction_addr: Addr) -> GetPriceResponse { self.app .wrap() diff --git a/tests/rust-tests/src/tests_rebalancer/test_limits.rs b/tests/rust-tests/src/tests_rebalancer/test_limits.rs index 7ccf8cd6..baf734f3 100644 --- a/tests/rust-tests/src/tests_rebalancer/test_limits.rs +++ b/tests/rust-tests/src/tests_rebalancer/test_limits.rs @@ -72,6 +72,10 @@ fn test_min_balance() { .with_rebalancer_data(vec![config]) .build_default(); + let old_config = suite + .query_rebalancer_config(suite.get_account_addr(0)) + .unwrap(); + for _ in 0..10 { suite.resolve_cycle(); } @@ -80,6 +84,20 @@ fn test_min_balance() { // Balance should be equal or greater then our set minimum assert!(balance_atom.amount < Uint128::new(1000)); assert!(balance_atom.amount >= Uint128::new(950)); + + let new_config = suite + .query_rebalancer_config(suite.get_account_addr(0)) + .unwrap(); + + new_config.targets.iter().for_each(|new_target| { + let target = old_config + .targets + .iter() + .find(|t| t.denom == new_target.denom) + .unwrap(); + + assert!(new_target.percentage == target.percentage); + }); } #[test] diff --git a/tests/rust-tests/src/tests_rebalancer/tests_unit.rs b/tests/rust-tests/src/tests_rebalancer/tests_unit.rs index a8dcff19..7bc84380 100644 --- a/tests/rust-tests/src/tests_rebalancer/tests_unit.rs +++ b/tests/rust-tests/src/tests_rebalancer/tests_unit.rs @@ -31,7 +31,7 @@ fn test_verify_target_2_denoms() { balance_amount: Uint128::from_str("100").unwrap(), balance_value: Decimal::from_str("100").unwrap(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -45,7 +45,7 @@ fn test_verify_target_2_denoms() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, ]; @@ -114,7 +114,7 @@ fn test_verify_target_3_denoms() { balance_amount: Uint128::new(100), balance_value: Decimal::from_str("100").unwrap(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -128,7 +128,7 @@ fn test_verify_target_3_denoms() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -142,7 +142,7 @@ fn test_verify_target_3_denoms() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, ]; @@ -227,7 +227,7 @@ fn test_verify_target_leftover_strategy() { balance_amount: Uint128::new(100), balance_value: Decimal::from_str("100").unwrap(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -241,7 +241,7 @@ fn test_verify_target_leftover_strategy() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -255,7 +255,7 @@ fn test_verify_target_leftover_strategy() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, ]; @@ -337,7 +337,7 @@ fn test_verify_target_min_balance_over_balance() { balance_amount: Uint128::new(100), balance_value: Decimal::from_str("100").unwrap(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -351,7 +351,7 @@ fn test_verify_target_min_balance_over_balance() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -365,7 +365,7 @@ fn test_verify_target_min_balance_over_balance() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, ]; @@ -375,6 +375,8 @@ fn test_verify_target_min_balance_over_balance() { assert_eq!(res[2].target.percentage, Decimal::bps(0)); } +// We have 100 ATOM so our total value is 100 +// we #[test] fn test_verify_target_priority() { let deps = mock_dependencies(); @@ -394,13 +396,13 @@ fn test_verify_target_priority() { balance_amount: Uint128::new(100), balance_value: Decimal::from_str("100").unwrap(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { denom: NTRN.to_string(), percentage: Decimal::bps(2500), - min_balance: Some(160_u128.into()), + min_balance: Some(25_u128.into()), last_input: None, last_i: SignedDecimal::zero(), }, @@ -408,7 +410,7 @@ fn test_verify_target_priority() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, TargetHelper { target: ParsedTarget { @@ -422,7 +424,7 @@ fn test_verify_target_priority() { balance_amount: Uint128::zero(), balance_value: Decimal::zero(), value_to_trade: Decimal::zero(), - auction_min_amount: Decimal::zero(), + auction_min_send_value: Decimal::zero(), }, ]; @@ -433,31 +435,37 @@ fn test_verify_target_priority() { target_helpers.clone(), ) .unwrap(); + assert_eq!( res[0].target.percentage, - Decimal::from_str("0.133333333333333333").unwrap() + Decimal::from_str("0.333333333333333333").unwrap() ); - assert_eq!(res[1].target.percentage, Decimal::bps(8000)); + assert_eq!(res[1].target.percentage, Decimal::bps(5000)); assert_eq!( res[2].target.percentage, - Decimal::from_str("0.066666666666666666").unwrap() + Decimal::from_str("0.166666666666666666").unwrap() ); // Priority config.target_override_strategy = TargetOverrideStrategy::Priority; + // our total value is 100 + // min_balance is 25 (price is 0.5, which means 25 / 0.5 = 50 value) + // so we expect the result to be 50% of target 1 and 50% target 2 (target 3 is 0) let res = verify_targets( &config, Decimal::from_str("100").unwrap(), target_helpers.clone(), ) .unwrap(); - assert_eq!(res[0].target.percentage, Decimal::bps(2000)); - assert_eq!(res[1].target.percentage, Decimal::bps(8000)); + + assert_eq!(res[0].target.percentage, Decimal::bps(5000)); + assert_eq!(res[1].target.percentage, Decimal::bps(5000)); assert_eq!(res[2].target.percentage, Decimal::bps(0)); - target_helpers[2].target.min_balance = Some(500_u128.into()); - target_helpers[1].target.min_balance = None; + // total value is still 100 + // we set min_balance to be 20 meaning (price is 0.5, which means 25 / 0.5 = 50 value) + target_helpers[1].target.min_balance = Some(20_u128.into()); let res = verify_targets( &config, @@ -465,11 +473,12 @@ fn test_verify_target_priority() { target_helpers.clone(), ) .unwrap(); + assert_eq!(res[0].target.percentage, Decimal::bps(5000)); - assert_eq!(res[1].target.percentage, Decimal::bps(0)); - assert_eq!(res[2].target.percentage, Decimal::bps(5000)); + assert_eq!(res[1].target.percentage, Decimal::bps(4000)); // 40% is the min_balance we set (20 / 0.5) + assert_eq!(res[2].target.percentage, Decimal::bps(1000)); - target_helpers[2].target.min_balance = Some(400_u128.into()); + target_helpers[1].target.min_balance = Some(40_u128.into()); let res = verify_targets( &config, @@ -477,7 +486,10 @@ fn test_verify_target_priority() { target_helpers.clone(), ) .unwrap(); - assert_eq!(res[0].target.percentage, Decimal::bps(5000)); - assert_eq!(res[1].target.percentage, Decimal::bps(1000)); - assert_eq!(res[2].target.percentage, Decimal::bps(4000)); + + println!("{:?}", res); + + assert_eq!(res[0].target.percentage, Decimal::bps(2000)); + assert_eq!(res[1].target.percentage, Decimal::bps(8000)); // 80% is the min_balance we set (40 / 0.5) + assert_eq!(res[2].target.percentage, Decimal::bps(0)); }