From 93ec008bc7184af9c31fdb26d9242dce64702952 Mon Sep 17 00:00:00 2001 From: Jack Swenson Date: Tue, 19 Nov 2024 14:01:44 -0600 Subject: [PATCH] Basic staking fix (#394) * added basic_staking test * fixed bug & optimized send_msg on claim * added migrate fn * registering receive in migration * collapse reward sends working --- .gitignore | 2 +- Cargo.lock | 1640 +++++++++++++++++ contracts/basic_staking/src/contract.rs | 35 +- contracts/basic_staking/src/execute.rs | 243 +-- .../tests/single_staker_stake_no_compound.rs | 613 ++++++ .../contract_interfaces/basic_staking/mod.rs | 3 + 6 files changed, 2422 insertions(+), 114 deletions(-) create mode 100644 Cargo.lock create mode 100644 contracts/basic_staking/tests/single_staker_stake_no_compound.rs diff --git a/.gitignore b/.gitignore index c8dbb2c9b..b295f63cf 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,5 @@ node_modules/ *.pyc __pycache__/ compiled +artifacts logs -Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..6bf8ae29d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1640 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "admin" +version = "0.2.0" +dependencies = [ + "rstest", + "secret-cosmwasm-std", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "airdrop" +version = "0.1.0" +dependencies = [ + "rs_merkle", + "shade-protocol", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "basic_staking" +version = "0.1.0" +dependencies = [ + "secret-cosmwasm-std", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "bech32" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bincode2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49f6183038e081170ebbbadee6678966c7d54728938a3e7de7f4e780770318f" +dependencies = [ + "byteorder", + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[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.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "contract-derive" +version = "0.1.0" +dependencies = [ + "shade-protocol", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40abec852f3d4abec6d44ead9a58b78325021a1ead1e7229c3471414e57b2e49" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b166215fbfe93dc5575bae062aa57ae7bb41121cffe53bac33b033257949d2a9" +dependencies = [ + "cosmwasm-schema-derive 1.5.2", + "schemars 0.8.16", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema" +version = "2.0.0-beta.1" +source = "git+https://github.com/CosmWasm/cosmwasm#d619238d2733ee4b18f50ef6e0ae155986755a26" +dependencies = [ + "cosmwasm-schema-derive 2.0.0-beta.1", + "schemars 0.8.16", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf12f8e20bb29d1db66b7ca590bc2f670b548d21e9be92499bc0f9022a994a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "2.0.0-beta.1" +source = "git+https://github.com/CosmWasm/cosmwasm#d619238d2733ee4b18f50ef6e0ae155986755a26" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2 0.10.8", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "mock_adapter" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema 2.0.0-beta.1", + "schemars 0.8.16", + "serde", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "mock_sienna_pair" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema 1.5.2", + "shade-protocol", +] + +[[package]] +name = "mock_stkd_derivative" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema 1.5.2", + "mock_sienna_pair", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "multi-derive" +version = "0.1.0" + +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "query-authentication" +version = "0.1.0" +source = "git+https://github.com/securesecrets/query-authentication?branch=cosmwasm_v1_upgrade#473dae556a10a811a4a55563813df9107b18781a" +dependencies = [ + "bech32 0.8.1", + "cosmwasm-schema 1.5.2", + "remain", + "ripemd160", + "schemars 0.8.16", + "secp256k1 0.20.3", + "secret-cosmwasm-std", + "serde", + "sha2 0.9.9", + "thiserror", +] + +[[package]] +name = "query_auth" +version = "0.1.0" +dependencies = [ + "schemars 0.7.6", + "secret-cosmwasm-std", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "remain" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad5e011230cad274d0532460c5ab69828ea47ae75681b42a841663efffaf794" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "rs_merkle" +version = "1.1.0" +source = "git+https://github.com/FloppyDisck/rs-merkle?branch=node_export#b35c0aa203fdd7ba6c963ba84efb46906792c660" +dependencies = [ + "sha2 0.9.9", +] + +[[package]] +name = "rstest" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c9dc66cc29792b663ffb5269be669f1613664e69ad56441fdb895c2347b930" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5015e68a0685a95ade3eee617ff7101ab6a3fc689203101ca16ebc16f2b89c66" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "schemars" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be77ed66abed6954aabf6a3e31a84706bedbf93750d267e92ef4a6d90bbd6a61" +dependencies = [ + "schemars_derive 0.7.6", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive 0.8.16", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11af7a475c9ee266cfaa9e303a47c830ebe072bf3101ab907a7b7b9d816fa01d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals 0.25.0", + "syn 1.0.109", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals 0.26.0", + "syn 1.0.109", +] + +[[package]] +name = "scrt_staking" +version = "0.1.0" +dependencies = [ + "secret-cosmwasm-std", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "secp256k1-sys 0.4.2", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "secp256k1-sys 0.8.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "secret-cosmwasm-crypto" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8535d61c88d0a6c222df2cebb69859d8e9ba419a299a1bc84c904b0d9c00c7b2" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "secret-cosmwasm-std" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e4393b01aa6587007161a6bb193859deaa8165ab06c8a35f253d329ff99e4d" +dependencies = [ + "base64 0.13.1", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars 0.8.16", + "secret-cosmwasm-crypto", + "serde", + "serde-json-wasm", + "thiserror", + "uint", +] + +[[package]] +name = "secret-cosmwasm-storage" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb43da2cb72a53b16ea1555bca794fb828b48ab24ebeb45f8e26f1881c45a783" +dependencies = [ + "secret-cosmwasm-std", + "serde", +] + +[[package]] +name = "secret-multi-test" +version = "0.13.4" +source = "git+https://github.com/securesecrets/secret-plus-utils#96438a5bf7f1fb0acc540fe3a43e934f01e6711f" +dependencies = [ + "anyhow", + "derivative", + "itertools", + "nanoid", + "prost", + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-storage-plus 0.13.4 (git+https://github.com/securesecrets/secret-plus-utils)", + "secret-utils", + "serde", + "thiserror", +] + +[[package]] +name = "secret-storage-plus" +version = "0.13.4" +source = "git+https://github.com/securesecrets/secret-plus-utils?tag=v0.1.1#96438a5bf7f1fb0acc540fe3a43e934f01e6711f" +dependencies = [ + "bincode2", + "schemars 0.8.16", + "secret-cosmwasm-std", + "serde", +] + +[[package]] +name = "secret-storage-plus" +version = "0.13.4" +source = "git+https://github.com/securesecrets/secret-plus-utils#96438a5bf7f1fb0acc540fe3a43e934f01e6711f" +dependencies = [ + "bincode2", + "schemars 0.8.16", + "secret-cosmwasm-std", + "serde", +] + +[[package]] +name = "secret-toolkit" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338c972c0a98de51ccbb859312eb7672bc64b9050b086f058748ba26a509edbb" +dependencies = [ + "secret-toolkit-crypto", + "secret-toolkit-permit", + "secret-toolkit-serialization", + "secret-toolkit-snip20", + "secret-toolkit-snip721", + "secret-toolkit-storage", + "secret-toolkit-utils", + "secret-toolkit-viewing-key", +] + +[[package]] +name = "secret-toolkit-crypto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003d7d5772c67f2240b7f298f96eb73a8a501916fe18c1d730ebfd591bf7e519" +dependencies = [ + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "secp256k1 0.27.0", + "secret-cosmwasm-std", + "sha2 0.10.8", +] + +[[package]] +name = "secret-toolkit-permit" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4330571400b5959450fa37040609e6804a147d83f606783506bc2275f1527712" +dependencies = [ + "bech32 0.9.1", + "remain", + "ripemd", + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-toolkit-crypto", + "serde", +] + +[[package]] +name = "secret-toolkit-serialization" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "890adaeaa710f9f7068a807eb1553edc8c30ce9907290895c9097dd642fc613b" +dependencies = [ + "bincode2", + "schemars 0.8.16", + "secret-cosmwasm-std", + "serde", +] + +[[package]] +name = "secret-toolkit-snip20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8144a11df9a75adf42acd645f938eb2c1ab508d6672033eb84b1e672247d2f05" +dependencies = [ + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-toolkit-utils", + "serde", +] + +[[package]] +name = "secret-toolkit-snip721" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2ab35fd2a52306f87ab8dceab75254cc1b87c95c43acf9e30c09372f0ee971" +dependencies = [ + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-toolkit-utils", + "serde", +] + +[[package]] +name = "secret-toolkit-storage" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55e8c5418af3e7ae1d1331c383b32d56c74a340dbc3b972d53555a768698f2a3" +dependencies = [ + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "secret-toolkit-serialization", + "serde", +] + +[[package]] +name = "secret-toolkit-utils" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83f1cba2e70fd701e3dfc6072807c02eeeb9776bee49e346a9c7745d84ff40c8" +dependencies = [ + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "serde", +] + +[[package]] +name = "secret-toolkit-viewing-key" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d89a0b69fa9b12735a612fa30e6e7e48130943982f1783b7ddd5c46ed09e921" +dependencies = [ + "base64 0.21.7", + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "secret-toolkit-crypto", + "secret-toolkit-utils", + "serde", + "subtle", +] + +[[package]] +name = "secret-utils" +version = "0.13.4" +source = "git+https://github.com/securesecrets/secret-plus-utils#96438a5bf7f1fb0acc540fe3a43e934f01e6711f" +dependencies = [ + "schemars 0.8.16", + "secret-cosmwasm-std", + "serde", + "thiserror", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "shade-multi-test" +version = "0.1.0" +dependencies = [ + "admin", + "airdrop", + "basic_staking", + "mock_adapter", + "mock_sienna_pair", + "mock_stkd_derivative", + "multi-derive", + "query_auth", + "scrt_staking", + "shade-protocol", + "snip20", + "snip20_migration", + "stkd_scrt", + "treasury", + "treasury_manager", +] + +[[package]] +name = "shade-protocol" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64 0.12.3", + "chrono", + "const_format", + "contract-derive", + "cosmwasm-schema 1.5.2", + "query-authentication", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "remain", + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "secret-multi-test", + "secret-storage-plus 0.13.4 (git+https://github.com/securesecrets/secret-plus-utils?tag=v0.1.1)", + "serde", + "sha2 0.9.9", + "strum", + "strum_macros", + "subtle", + "thiserror", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "snip20" +version = "0.1.0" +dependencies = [ + "secret-cosmwasm-std", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "snip20_derivative" +version = "1.0.0" +dependencies = [ + "base64 0.13.1", + "cosmwasm-schema 1.5.2", + "schemars 0.8.16", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "secret-toolkit", + "secret-toolkit-crypto", + "serde", + "shade-protocol", +] + +[[package]] +name = "snip20_migration" +version = "0.1.0" +dependencies = [ + "rstest", + "schemars 0.7.6", + "serde_json", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stkd_scrt" +version = "0.1.0" +dependencies = [ + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "treasury" +version = "0.1.0" +dependencies = [ + "mock_adapter", + "serde_json", + "shade-multi-test", + "shade-protocol", + "treasury", +] + +[[package]] +name = "treasury_manager" +version = "0.1.0" +dependencies = [ + "chrono", + "cosmwasm-schema 2.0.0-beta.1", + "itertools", + "mock_adapter", + "schemars 0.7.6", + "shade-multi-test", + "shade-protocol", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/contracts/basic_staking/src/contract.rs b/contracts/basic_staking/src/contract.rs index 564969564..e447999ad 100644 --- a/contracts/basic_staking/src/contract.rs +++ b/contracts/basic_staking/src/contract.rs @@ -1,5 +1,7 @@ use shade_protocol::{ - basic_staking::{Auth, AuthPermit, Config, ExecuteMsg, InstantiateMsg, QueryAnswer, QueryMsg}, + basic_staking::{ + Auth, AuthPermit, Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryAnswer, QueryMsg, + }, c_std::{ shd_entry_point, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, @@ -210,3 +212,34 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { }), } } + +#[shd_entry_point] +pub fn migrate(deps: DepsMut, env: Env, _msg: MigrateMsg) -> StdResult { + let stake_token = STAKE_TOKEN.load(deps.storage)?; + let reward_tokens = REWARD_TOKENS.load(deps.storage)?; + + let mut msgs = vec![]; + let mut stake_is_reward = false; + + // Register receive on all reward tokens + for token in reward_tokens { + if token.address == stake_token.address { + stake_is_reward = true; + } + msgs.push(register_receive( + env.contract.code_hash.clone(), + None, + &token, + )?); + } + + // Register if not done with rewards + if !stake_is_reward { + msgs.push(register_receive( + env.contract.code_hash.clone(), + None, + &stake_token, + )?); + } + Ok(Response::default().add_messages(msgs)) +} diff --git a/contracts/basic_staking/src/execute.rs b/contracts/basic_staking/src/execute.rs index e637533c2..a61fb1bce 100644 --- a/contracts/basic_staking/src/execute.rs +++ b/contracts/basic_staking/src/execute.rs @@ -15,7 +15,10 @@ use shade_protocol::{ }; use crate::storage::*; -use std::cmp::{max, min}; +use std::{ + cmp::{max, min}, + collections::HashMap, +}; pub fn update_config( deps: DepsMut, @@ -151,11 +154,11 @@ pub fn receive( if compound && reward_pool.token == stake_token { // Compound stake_token rewards compound_amount += reward_claimed; - } else { + } else if !reward_claimed.is_zero() { // Claim if not compound or not stake token rewards response = response .add_message(send_msg( - info.sender.clone(), + from.clone(), reward_claimed, None, None, @@ -368,6 +371,85 @@ pub fn reward_pool_claim( Ok(user_reward) } +pub fn _do_claim( + storage: &mut dyn Storage, + mut response: Response, + mut reward_pools: Vec, + user_staked: Uint128, + user: Addr, +) -> StdResult<(Response, Vec)> { + let mut rewards: HashMap = HashMap::new(); + + for reward_pool in reward_pools.iter_mut() { + let reward_claimed = reward_pool_claim(storage, user.clone(), user_staked, &reward_pool)?; + + reward_pool.claimed += reward_claimed; + rewards + .entry(reward_pool.token.clone()) + .and_modify(|reward| *reward += reward_claimed) + .or_insert(reward_claimed); + } + + for (token, reward) in rewards.into_iter() { + if reward.is_zero() { + continue; + } + + response = response + .add_message(send_msg(user.clone(), reward, None, None, None, &token)?) + .add_attribute(token.address.to_string(), reward); + } + + Ok((response, reward_pools)) +} + +pub fn _do_compound( + storage: &mut dyn Storage, + mut response: Response, + mut reward_pools: Vec, + mut user_staked: Uint128, + mut total_staked: Uint128, + stake_token: Contract, + user: Addr, +) -> StdResult<(Response, Vec, Uint128, Uint128)> { + let mut claim_rewards: HashMap = HashMap::new(); + + let mut compound_amount = Uint128::zero(); + + for reward_pool in reward_pools.iter_mut() { + let reward_claimed = reward_pool_claim(storage, user.clone(), user_staked, &reward_pool)?; + reward_pool.claimed += reward_claimed; + + if reward_pool.token == stake_token { + // Compound stake_token rewards + compound_amount += reward_claimed; + } else { + // Claim non-stake_token rewards + claim_rewards + .entry(reward_pool.token.clone()) + .and_modify(|reward| *reward += reward_claimed) + .or_insert(reward_claimed); + } + } + + if compound_amount > Uint128::zero() { + response = response.add_attribute("compounded", compound_amount); + user_staked += compound_amount; + total_staked += compound_amount; + } + + for (token, reward) in claim_rewards.into_iter() { + if reward.is_zero() { + continue; + } + + response = response + .add_message(send_msg(user.clone(), reward, None, None, None, &token)?) + .add_attribute(token.address.to_string(), reward); + } + + Ok((response, reward_pools, user_staked, total_staked)) +} pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { let user_staked = USER_STAKED.load(deps.storage, info.sender.clone())?; @@ -387,54 +469,34 @@ pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult let mut response = Response::new(); - for reward_pool in reward_pools.iter_mut() { - let reward_claimed = - reward_pool_claim(deps.storage, info.sender.clone(), user_staked, &reward_pool)?; - - reward_pool.claimed += reward_claimed; - - response = response - .add_message(send_msg( - info.sender.clone(), - reward_claimed, - None, - None, - None, - &reward_pool.token, - )?) - .add_attribute(reward_pool.token.address.to_string(), reward_claimed); - } + (response, reward_pools) = _do_claim( + deps.storage, + response, + reward_pools, + user_staked, + info.sender, + )?; REWARD_POOLS.save(deps.storage, &reward_pools)?; Ok(response.set_data(to_binary(&ExecuteAnswer::Claim { - //claimed: status: ResponseStatus::Success, })?)) } pub fn unbond( - deps: DepsMut, + mut deps: DepsMut, env: Env, info: MessageInfo, amount: Uint128, compound: bool, ) -> StdResult { let config = CONFIG.load(deps.storage)?; - if amount.is_zero() { return Err(StdError::generic_err("Must unbond non-zero amount")); } if let Some(mut user_staked) = USER_STAKED.may_load(deps.storage, info.sender.clone())? { - // if not compounding, check staked >= unbond amount - if !compound && user_staked < amount { - return Err(StdError::generic_err(format!( - "Cannot unbond {}, only {} staked", - amount, user_staked - ))); - } - let now = env.block.time.seconds(); let mut total_staked = TOTAL_STAKED.load(deps.storage)?; @@ -443,48 +505,39 @@ pub fn unbond( update_rewards(env.clone(), &REWARD_POOLS.load(deps.storage)?, total_staked); let stake_token = STAKE_TOKEN.load(deps.storage)?; - let mut compound_amount = Uint128::zero(); let mut response = Response::new(); // Claim/Compound rewards - for reward_pool in reward_pools.iter_mut() { - let reward_claimed = - reward_pool_claim(deps.storage, info.sender.clone(), user_staked, &reward_pool)?; - reward_pool.claimed += reward_claimed; - - if compound && reward_pool.token == stake_token { - // Compound stake_token rewards - compound_amount += reward_claimed; - } else { - // Claim if not compound or not stake token rewards - response = response - .add_message(send_msg( - info.sender.clone(), - reward_claimed, - None, - None, - None, - &reward_pool.token, - )?) - .add_attribute(reward_pool.token.address.to_string(), reward_claimed); - } + if compound { + (response, reward_pools, user_staked, total_staked) = _do_compound( + deps.storage, + response, + reward_pools, + user_staked, + total_staked, + stake_token, + info.sender.clone(), + )?; + } else { + (response, reward_pools) = _do_claim( + deps.storage, + response, + reward_pools, + user_staked, + info.sender.clone(), + )?; } - // if compounding, check staked + compounded >= unbond amount - if user_staked + compound_amount < amount { + if user_staked < amount { return Err(StdError::generic_err(format!( - "Cannot unbond {}, only {} staked after compounding", - amount, - user_staked + compound_amount, + "Cannot unbond {}, only {} staked", + amount, user_staked, ))); } - if compound_amount > Uint128::zero() { - response = response.add_attribute("compounded", compound_amount); - } - user_staked = (user_staked + compound_amount) - amount; - total_staked = (total_staked + compound_amount) - amount; + // Reduce by unbonding + user_staked -= amount; TOTAL_STAKED.save(deps.storage, &total_staked)?; USER_STAKED.save(deps.storage, info.sender.clone(), &user_staked)?; @@ -601,58 +654,37 @@ pub fn withdraw( pub fn compound(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { let mut response = Response::new(); - let user_staked = USER_STAKED + let mut user_staked = USER_STAKED .may_load(deps.storage, info.sender.clone())? .unwrap_or(Uint128::zero()); if user_staked.is_zero() { return Err(StdError::generic_err("User has no stake")); } + let pre_compound_user_staked = user_staked; - let total_staked = TOTAL_STAKED.load(deps.storage)?; + let mut total_staked = TOTAL_STAKED.load(deps.storage)?; let mut reward_pools = update_rewards(env.clone(), &REWARD_POOLS.load(deps.storage)?, total_staked); let stake_token = STAKE_TOKEN.load(deps.storage)?; - let mut compound_amount = Uint128::zero(); - - for reward_pool in reward_pools.iter_mut() { - let reward_claimed = - reward_pool_claim(deps.storage, info.sender.clone(), user_staked, &reward_pool)?; - reward_pool.claimed += reward_claimed; - - if reward_pool.token == stake_token { - // Compound stake_token rewards - compound_amount += reward_claimed; - } else { - // Claim non-stake_token rewards - response = response - .add_message(send_msg( - info.sender.clone(), - reward_claimed, - None, - None, - None, - &reward_pool.token, - )?) - .add_attribute(reward_pool.token.address.to_string(), reward_claimed); - } - } - REWARD_POOLS.save(deps.storage, &reward_pools)?; - - if compound_amount > Uint128::zero() { - response = response.add_attribute("compounded", compound_amount); - } - - USER_STAKED.save( + (response, reward_pools, user_staked, total_staked) = _do_compound( deps.storage, + response, + reward_pools, + user_staked, + total_staked, + stake_token, info.sender.clone(), - &(user_staked + compound_amount), )?; - TOTAL_STAKED.save(deps.storage, &(total_staked + compound_amount))?; + + REWARD_POOLS.save(deps.storage, &reward_pools)?; + + USER_STAKED.save(deps.storage, info.sender, &user_staked)?; + TOTAL_STAKED.save(deps.storage, &(total_staked))?; Ok(response.set_data(to_binary(&ExecuteAnswer::Compound { - compounded: compound_amount, + compounded: user_staked - pre_compound_user_staked, status: ResponseStatus::Success, })?)) } @@ -694,7 +726,6 @@ pub fn end_reward_pool( // Delete reward pool if it hasn't started let deleted = if reward_pool.start > now { - println!("DELETING BEFORE START"); extract_amount = reward_pool.amount; true } @@ -702,7 +733,6 @@ pub fn end_reward_pool( else if reward_pool.end > now { // remove rewards from now -> end extract_amount = reward_pool.rate * (reward_pool.end - now) / Uint128::new(10u128.pow(18)); - println!("EXTRACTING {}", extract_amount); reward_pool.end = now; reward_pool.amount -= extract_amount; @@ -847,14 +877,12 @@ pub fn transfer_stake( // Claim/Compound rewards for Sender for reward_pool in reward_pools.iter_mut() { - println!("reward pool claim sender"); let reward_claimed = reward_pool_claim( deps.storage, info.sender.clone(), sender_staked, &reward_pool, )?; - println!("POST reward pool claim sender"); reward_pool.claimed += reward_claimed; if compound && reward_pool.token == stake_token { @@ -883,8 +911,6 @@ pub fn transfer_stake( ))); } - println!("sender compound amount {}", sender_compound_amount); - if sender_compound_amount > Uint128::zero() { response = response.add_attribute("compounded", sender_compound_amount); } @@ -903,7 +929,6 @@ pub fn transfer_stake( // Claim rewards for Receiver (no compound) for reward_pool in reward_pools.iter_mut() { - println!("reward pool claim recipient"); let reward_claimed = reward_pool_claim( deps.storage, recipient.clone(), @@ -912,12 +937,6 @@ pub fn transfer_stake( )?; reward_pool.claimed += reward_claimed; - // Claim if not compound or not stake token rewards - println!( - "SENDING RECIPIETN REWARD {} {}", - reward_claimed, - recipient.clone() - ); response = response.add_message(send_msg( recipient.clone(), reward_claimed, diff --git a/contracts/basic_staking/tests/single_staker_stake_no_compound.rs b/contracts/basic_staking/tests/single_staker_stake_no_compound.rs new file mode 100644 index 000000000..84430e7a7 --- /dev/null +++ b/contracts/basic_staking/tests/single_staker_stake_no_compound.rs @@ -0,0 +1,613 @@ +use shade_protocol::c_std::{to_binary, Addr, BlockInfo, Timestamp, Uint128}; + +use shade_protocol::{ + contract_interfaces::{basic_staking, query_auth, snip20}, + multi_test::App, + utils::{asset::RawContract, ExecuteCallback, InstantiateCallback, MultiTestable, Query}, +}; + +use shade_multi_test::multi::{ + admin::{init_admin_auth, Admin}, + basic_staking::BasicStaking, + query_auth::QueryAuth, + snip20::Snip20, +}; + +// Add other adapters here as they come +fn single_staker_stake_no_compound( + stake_amount: Uint128, + unbond_period: Uint128, + reward_amount: Uint128, + reward_start: Uint128, + reward_end: Uint128, +) { + let mut app = App::default(); + + // init block time for predictable behavior + app.set_block(BlockInfo { + height: 1, + time: Timestamp::from_seconds(0), + chain_id: "chain_id".to_string(), + }); + + let viewing_key = "unguessable".to_string(); + let admin_user = Addr::unchecked("admin"); + let staking_user = Addr::unchecked("staker"); + let reward_user = Addr::unchecked("reward_user"); + + let token = snip20::InstantiateMsg { + name: "stake_token".into(), + admin: Some(admin_user.to_string().clone()), + symbol: "STKN".into(), + decimals: 6, + initial_balances: Some(vec![ + snip20::InitialBalance { + amount: stake_amount, + address: staking_user.to_string(), + }, + snip20::InitialBalance { + amount: reward_amount, + address: reward_user.to_string(), + }, + ]), + query_auth: None, + prng_seed: to_binary("").ok().unwrap(), + config: Some(snip20::InitConfig { + public_total_supply: Some(true), + enable_deposit: Some(false), + enable_redeem: Some(false), + enable_mint: Some(false), + enable_burn: Some(false), + enable_transfer: Some(true), + }), + } + .test_init( + Snip20::default(), + &mut app, + admin_user.clone(), + "stake_token", + &[], + ) + .unwrap(); + + // set staking_user viewing key + snip20::ExecuteMsg::SetViewingKey { + key: viewing_key.clone(), + padding: None, + } + .test_exec(&token, &mut app, staking_user.clone(), &[]) + .unwrap(); + + let admin_contract = init_admin_auth(&mut app, &admin_user); + + let query_contract = query_auth::InstantiateMsg { + admin_auth: admin_contract.clone().into(), + prng_seed: to_binary("").ok().unwrap(), + } + .test_init( + QueryAuth::default(), + &mut app, + admin_user.clone(), + "query_auth", + &[], + ) + .unwrap(); + + // set staking user VK + query_auth::ExecuteMsg::SetViewingKey { + key: viewing_key.clone(), + padding: None, + } + .test_exec(&query_contract, &mut app, staking_user.clone(), &[]) + .unwrap(); + + // set reward user VK + query_auth::ExecuteMsg::SetViewingKey { + key: viewing_key.clone(), + padding: None, + } + .test_exec(&query_contract, &mut app, reward_user.clone(), &[]) + .unwrap(); + + let basic_staking = basic_staking::InstantiateMsg { + admin_auth: admin_contract.into(), + query_auth: query_contract.into(), + airdrop: None, + stake_token: token.clone().into(), + unbond_period, + max_user_pools: Uint128::one(), + viewing_key: viewing_key.clone(), + } + .test_init( + BasicStaking::default(), + &mut app, + admin_user.clone(), + "basic_staking", + &[], + ) + .unwrap(); + println!("BASIC STAKING {}", basic_staking.address); + + // Pre-staking user stake amount + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(staked, Uint128::zero(), "Pre-Stake Balance"); + } + _ => { + panic!("Staking balance query failed"); + } + }; + + // Stake funds + snip20::ExecuteMsg::Send { + recipient: basic_staking.address.to_string().clone(), + recipient_code_hash: None, + amount: stake_amount - Uint128::one(), + msg: Some( + to_binary(&basic_staking::Action::Stake { + compound: None, + airdrop_task: None, + }) + .unwrap(), + ), + memo: None, + padding: None, + } + .test_exec(&token, &mut app, staking_user.clone(), &[]) + .unwrap(); + + // Post-staking user balance + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(staked, stake_amount - Uint128::one(), "Post-Stake Balance"); + } + _ => { + panic!("Staking balance query failed"); + } + }; + + // Post staking total staked + match (basic_staking::QueryMsg::TotalStaked {}) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::TotalStaked { amount } => { + assert_eq!( + amount, + stake_amount - Uint128::one(), + "Post staking total staked" + ); + } + _ => { + panic!("Total Staked query failed"); + } + }; + + // Verify stake token + match (basic_staking::QueryMsg::StakeToken {}) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::StakeToken { token: stake_token } => { + assert_eq!(stake_token, token.address); + } + _ => { + panic!("Total Staked query failed"); + } + }; + + // Stake token should be registered + match (basic_staking::QueryMsg::RewardTokens {}) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::RewardTokens { tokens } => { + assert_eq!(tokens.len(), 1, "Only stake token registered"); + assert_eq!(tokens[0], token.address); + } + _ => { + panic!("Total Staked query failed"); + } + }; + + // Init Rewards + snip20::ExecuteMsg::Send { + recipient: basic_staking.address.to_string().clone(), + recipient_code_hash: None, + amount: reward_amount, + msg: Some( + to_binary(&basic_staking::Action::Rewards { + start: reward_start, + end: reward_end, + }) + .unwrap(), + ), + memo: None, + padding: None, + } + .test_exec(&token, &mut app, reward_user.clone(), &[]) + .unwrap(); + + // reward user has no stake + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: reward_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(staked, Uint128::zero(), "Reward User Stake Balance"); + } + _ => { + panic!("Staking balance query failed"); + } + }; + + // Check reward pool + match (basic_staking::QueryMsg::RewardPools {}) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::RewardPools { rewards } => { + assert_eq!(rewards[0].amount, reward_amount, "Reward Pool Amount"); + assert_eq!(rewards[0].start, reward_start, "Reward Pool Start"); + assert_eq!(rewards[0].end, reward_end, "Reward Pool End"); + } + _ => { + panic!("Staking balance query failed"); + } + }; + + // Move forward to reward start + app.set_block(BlockInfo { + height: 1, + time: Timestamp::from_seconds(reward_start.u128() as u64), + chain_id: "chain_id".to_string(), + }); + + // No rewards should be pending + match (basic_staking::QueryMsg::Rewards { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Rewards { rewards } => { + assert_eq!(rewards.len(), 1, "Rewards length at beginning"); + assert_eq!( + rewards[0].amount, + Uint128::zero(), + "Rewards claimable at beginning" + ); + } + _ => { + panic!("Staking rewards query failed"); + } + }; + + let reward_duration = reward_end - reward_start; + + // Move to middle of reward period + println!("Fast-forward to reward middle"); + app.set_block(BlockInfo { + height: 2, + time: Timestamp::from_seconds((reward_start.u128() + reward_duration.u128() / 2) as u64), + chain_id: "chain_id".to_string(), + }); + + // Half-ish rewards should be pending + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(rewards.len(), 1, "rewards length in the middle"); + let amount = rewards[0].amount; + let expected = reward_amount / Uint128::new(2); + assert!( + amount >= expected - Uint128::one() && amount <= expected, + "Rewards claimable in the middle within error of 1 unit token {} != {}", + amount, + expected + ); + } + _ => { + panic!("Staking rewards query failed"); + } + }; + + // Move to end of rewards + println!("Fast-forward to reward end"); + app.set_block(BlockInfo { + height: 3, + time: Timestamp::from_seconds(reward_end.u128() as u64), + chain_id: "chain_id".to_string(), + }); + + // All rewards should be pending + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(rewards.len(), 1, "rewards length at end"); + let amount = rewards[0].amount; + assert!( + amount >= reward_amount - Uint128::one() && amount <= reward_amount, + "Rewards claimable at the end within error of 1 unit token {} != {}", + amount, + reward_amount, + ); + } + _ => { + panic!("Staking rewards query failed"); + } + }; + + // Claim rewards + println!("Staking 1 utkn to test claim on stake"); + snip20::ExecuteMsg::Send { + recipient: basic_staking.address.to_string().clone(), + recipient_code_hash: None, + amount: Uint128::one(), + msg: Some( + to_binary(&basic_staking::Action::Stake { + compound: None, + airdrop_task: None, + }) + .unwrap(), + ), + memo: None, + padding: None, + } + .test_exec(&token, &mut app, staking_user.clone(), &[]) + .unwrap(); + + // Check rewards were received + match (snip20::QueryMsg::Balance { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }) + .test_query(&token, &app) + .unwrap() + { + snip20::QueryAnswer::Balance { amount } => { + assert!( + amount >= reward_amount - Uint128::one() && amount <= reward_amount, + "Rewards claimed at the end within error of 1 unit token {} != {}", + amount, + reward_amount, + ); + } + _ => { + panic!("Snip20 balance query failed"); + } + }; + + // Unbond + basic_staking::ExecuteMsg::Unbond { + amount: stake_amount, + compound: None, + padding: None, + } + .test_exec(&basic_staking, &mut app, staking_user.clone(), &[]) + .unwrap(); + + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(staked, Uint128::zero(), "0 staked after unbonding"); + assert_eq!(rewards, vec![], "0 rewards after unbonding"); + + assert_eq!(unbondings.len(), 1, "1 unbonding"); + assert_eq!(unbondings[0].amount, stake_amount, "Unbonding full amount"); + assert_eq!( + unbondings[0].complete, + reward_end + unbond_period, + "Unbonding complete expectedt" + ); + } + _ => { + panic!("Staking unbonding query failed"); + } + }; + println!("Fast-forward to end of unbonding period"); + app.set_block(BlockInfo { + height: 10, + time: Timestamp::from_seconds((reward_end + unbond_period).u128() as u64), + chain_id: "chain_id".to_string(), + }); + + basic_staking::ExecuteMsg::Withdraw { + ids: None, + padding: None, + } + .test_exec(&basic_staking, &mut app, staking_user.clone(), &[]) + .unwrap(); + + match (basic_staking::QueryMsg::Balance { + auth: basic_staking::Auth::ViewingKey { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }, + unbonding_ids: None, + }) + .test_query(&basic_staking, &app) + .unwrap() + { + basic_staking::QueryAnswer::Balance { + staked, + rewards, + unbondings, + } => { + assert_eq!(staked, Uint128::zero(), "Final Staked Balance"); + assert_eq!(rewards, vec![], "Final Rewards"); + assert_eq!(unbondings, vec![], "Final Unbondings"); + } + _ => { + panic!("Staking balance query failed"); + } + }; + + // Check snip20 received by user + match (snip20::QueryMsg::Balance { + key: viewing_key.clone(), + address: staking_user.clone().into(), + }) + .test_query(&token, &app) + .unwrap() + { + snip20::QueryAnswer::Balance { amount } => { + let expected = stake_amount + reward_amount; + assert!( + amount >= expected - Uint128::one() && amount <= expected, + "Final user balance within error of 1 unit token {} != {}", + amount, + expected, + ); + } + _ => { + panic!("Snip20 balance query failed"); + } + }; +} + +macro_rules! single_staker_stake_no_compound { + ($($name:ident: $value:expr,)*) => { + $( + #[test] + fn $name() { + let ( + stake_amount, + unbond_period, + reward_amount, + reward_start, + reward_end, + ) = $value; + single_staker_stake_no_compound( + stake_amount, + unbond_period, + reward_amount, + reward_start, + reward_end, + ) + } + )* + } +} + +single_staker_stake_no_compound! { + /* + single_staker_stake_no_compound_0: ( + Uint128::new(1), // stake_amount + Uint128::new(100), // unbond_period + Uint128::new(100), // reward_amount + Uint128::new(0), // reward_start (0-*) + Uint128::new(100), // reward_end + ), + */ + single_staker_stake_no_compound_1: ( + Uint128::new(100), + Uint128::new(100), + Uint128::new(1000), + Uint128::new(0), + Uint128::new(100), + ), + single_staker_stake_no_compound_2: ( + Uint128::new(1000), + Uint128::new(100), + Uint128::new(300), + Uint128::new(0), + Uint128::new(100), + ), + single_staker_stake_no_compound_3: ( + Uint128::new(10), + Uint128::new(100), + Uint128::new(50000), + Uint128::new(0), + Uint128::new(2500000), + ), + single_staker_stake_no_compound_4: ( + Uint128::new(1234567), + Uint128::new(10000), + Uint128::new(500), + Uint128::new(0), + Uint128::new(10000), + ), + single_staker_stake_no_compound_5: ( + Uint128::new(99999999999), + Uint128::new(100), + Uint128::new(8192), + Uint128::new(20), + Uint128::new(8000), + ), +} diff --git a/packages/shade_protocol/src/contract_interfaces/basic_staking/mod.rs b/packages/shade_protocol/src/contract_interfaces/basic_staking/mod.rs index 0a0b36368..9dffd91cd 100644 --- a/packages/shade_protocol/src/contract_interfaces/basic_staking/mod.rs +++ b/packages/shade_protocol/src/contract_interfaces/basic_staking/mod.rs @@ -297,3 +297,6 @@ pub enum QueryAnswer { whitelist: Vec, }, } + +#[cw_serde] +pub struct MigrateMsg {}