diff --git a/.github/workflows/cc.yml b/.github/workflows/cc.yml index e9e3aee0..65934fad 100644 --- a/.github/workflows/cc.yml +++ b/.github/workflows/cc.yml @@ -16,4 +16,4 @@ jobs: uses: actions/checkout@v3 - name: Check all commit messages for adherence - uses: bilalshaikh42/action-conventional-commits@v2.0.1 + uses: webiny/action-conventional-commits@v1.1.0 diff --git a/Cargo.lock b/Cargo.lock index e93095e0..d2b1e162 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,9 +108,9 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -119,9 +119,9 @@ version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -220,8 +220,8 @@ dependencies = [ "lazycell", "log", "peeking_take_while", - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", "regex", "rustc-hash", "shlex", @@ -558,7 +558,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5abeeb891e6d0098402e4d3d042f90451db52651d2fe14b170e69a1dd3e4115" dependencies = [ - "syn 1.0.109", + "syn", ] [[package]] @@ -580,9 +580,9 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78d6fc9854ac14e46cb69b0f396547893f93d2847aef975950ebbe73342324f3" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -681,7 +681,6 @@ dependencies = [ "cw20", "cw20-base", "osmosis-std", - "osmosis-test-tube", "proptest", "test-case", "thiserror", @@ -709,16 +708,12 @@ dependencies = [ "cw-it", "cw20", "cw20-base", - "osmosis-std", - "osmosis-test-tube", - "proptest", - "proptest-derive", ] [[package]] name = "cw-it" version = "0.1.0" -source = "git+https://github.com/apollodao/cw-it.git?rev=bbf4afe9153507efe13b035825396e62055ee3c3#bbf4afe9153507efe13b035825396e62055ee3c3" +source = "git+https://github.com/apollodao/cw-it.git?rev=59299395d74480f0a419ccafe4eeba95323fcb86#59299395d74480f0a419ccafe4eeba95323fcb86" dependencies = [ "anyhow", "astroport-types", @@ -730,7 +725,9 @@ dependencies = [ "cw20", "git2", "git2_credentials", + "osmosis-std", "osmosis-test-tube", + "proptest", "prost", "serde", "serde_json", @@ -831,10 +828,10 @@ dependencies = [ "cc", "codespan-reporting", "once_cell", - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", "scratch", - "syn 1.0.109", + "syn", ] [[package]] @@ -849,9 +846,9 @@ version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -872,10 +869,10 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", "strsim", - "syn 1.0.109", + "syn", ] [[package]] @@ -885,8 +882,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", - "quote 1.0.23", - "syn 1.0.109", + "quote", + "syn", ] [[package]] @@ -905,9 +902,9 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1202,9 +1199,9 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1805,9 +1802,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1919,9 +1916,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a455e262a6fdfd3914f3a4e11e6bc0ce491901cb9d507d7856d7ef6e129e90c6" dependencies = [ "itertools", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1940,7 +1937,7 @@ dependencies = [ [[package]] name = "osmosis-test-tube" version = "14.1.1" -source = "git+https://github.com/apollodao/test-tube.git?rev=d2245dfed56329d8c2e84d109a5a01f29d0db0e8#d2245dfed56329d8c2e84d109a5a01f29d0db0e8" +source = "git+https://github.com/apollodao/test-tube.git?rev=81e3cc2a360e9229449c3642e09eec656f7a83a7#81e3cc2a360e9229449c3642e09eec656f7a83a7" dependencies = [ "base64", "bindgen", @@ -1998,8 +1995,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" dependencies = [ "peg-runtime", - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", ] [[package]] @@ -2042,9 +2039,9 @@ checksum = "d06646e185566b5961b4058dd107e0a7f56e77c3f484549fb119867773c0f202" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2073,9 +2070,9 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2119,9 +2116,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", "version_check", ] @@ -2131,20 +2128,11 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", "version_check", ] -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - [[package]] name = "proc-macro2" version = "1.0.51" @@ -2175,17 +2163,6 @@ dependencies = [ "unarray", ] -[[package]] -name = "proptest-derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90b46295382dc76166cb7cf2bb4a97952464e4b7ed5a43e6cd34e1fec3349ddc" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - [[package]] name = "prost" version = "0.11.7" @@ -2204,9 +2181,9 @@ checksum = "8e9935362e8369bc3acd874caeeae814295c504c2bdbcde5c024089cf8b4dc12" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2230,22 +2207,13 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - [[package]] name = "quote" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ - "proc-macro2 1.0.51", + "proc-macro2", ] [[package]] @@ -2497,10 +2465,10 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", "serde_derive_internals", - "syn 1.0.109", + "syn", ] [[package]] @@ -2604,9 +2572,9 @@ version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2615,9 +2583,9 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2637,9 +2605,9 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2671,9 +2639,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2805,25 +2773,14 @@ dependencies = [ "zeroize", ] -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", + "proc-macro2", + "quote", "unicode-ident", ] @@ -2839,10 +2796,10 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", - "unicode-xid 0.2.4", + "proc-macro2", + "quote", + "syn", + "unicode-xid", ] [[package]] @@ -2999,9 +2956,9 @@ checksum = "72dc21b5887f4032c4656502d085dc28f2afbb686f25f216472bb0526f4b1b88" dependencies = [ "cfg-if", "proc-macro-error", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3011,16 +2968,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3786898e0be151a96f730fd529b0e8a10f5990fa2a7ea14e37ca27613c05190" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", "test-case-core", ] [[package]] name = "test-tube" version = "0.1.1" -source = "git+https://github.com/apollodao/test-tube.git?rev=d2245dfed56329d8c2e84d109a5a01f29d0db0e8#d2245dfed56329d8c2e84d109a5a01f29d0db0e8" +source = "git+https://github.com/apollodao/test-tube.git?rev=81e3cc2a360e9229449c3642e09eec656f7a83a7#81e3cc2a360e9229449c3642e09eec656f7a83a7" dependencies = [ "base64", "cosmrs", @@ -3073,9 +3030,9 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3155,9 +3112,9 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3321,9 +3278,9 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3408,12 +3365,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "unicode-xid" version = "0.2.4" @@ -3516,9 +3467,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-shared", ] @@ -3528,7 +3479,7 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ - "quote 1.0.23", + "quote", "wasm-bindgen-macro-support", ] @@ -3538,9 +3489,9 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3727,8 +3678,8 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ - "proc-macro2 1.0.51", - "quote 1.0.23", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 3d198da5..659b391b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,8 @@ schemars = "0.8.10" serde = { version = "1.0.145", default-features = false, features = ["derive"] } thiserror = { version = "1.0.31" } apollo-cw-asset = "0.1.0" -osmosis-test-tube = { git = "https://github.com/apollodao/test-tube.git", rev = "d2245dfed56329d8c2e84d109a5a01f29d0db0e8" } osmosis-std = "0.14.0" -cw-it = { git = "https://github.com/apollodao/cw-it.git", rev = "bbf4afe9153507efe13b035825396e62055ee3c3" } +cw-it = { git = "https://github.com/apollodao/cw-it.git", rev = "59299395d74480f0a419ccafe4eeba95323fcb86" } cw-dex = { path = "cw-dex" } cw-dex-test-contract = { path = "test-contracts/package" } cw-dex-test-helpers = { path = "test-helpers" } diff --git a/cw-dex/Cargo.toml b/cw-dex/Cargo.toml index 323b04ae..b04f66b9 100644 --- a/cw-dex/Cargo.toml +++ b/cw-dex/Cargo.toml @@ -35,8 +35,7 @@ astroport-types = { workspace = true, optional = true} uint = {version = "0.9.3", optional = true} [dev-dependencies] -osmosis-test-tube = { workspace = true } -cw-it = { workspace = true } +cw-it = { workspace = true, features = ["osmosis", "astroport"] } test-case = "3.0.0" cw-dex-test-contract = { workspace = true } cw-dex-test-helpers = { workspace = true } diff --git a/cw-dex/src/implementations/osmosis/staking.rs b/cw-dex/src/implementations/osmosis/staking.rs index 64f2498a..df6d5c99 100644 --- a/cw-dex/src/implementations/osmosis/staking.rs +++ b/cw-dex/src/implementations/osmosis/staking.rs @@ -9,7 +9,7 @@ use cosmwasm_std::{ use cw_utils::Duration as CwDuration; use osmosis_std::types::osmosis::lockup::{MsgBeginUnlocking, MsgForceUnlock, MsgLockTokens}; use osmosis_std::types::osmosis::superfluid::{ - MsgLockAndSuperfluidDelegate, MsgSuperfluidUnbondLock, + MsgLockAndSuperfluidDelegate, MsgSuperfluidUnbondLock, MsgSuperfluidUndelegate, }; use std::time::Duration; @@ -284,6 +284,10 @@ impl Unlock for OsmosisSuperfluidStaking { .lock_id .ok_or_else(|| StdError::generic_err("osmosis error: lock id not set"))?; + let undelegate_msg = MsgSuperfluidUndelegate { + sender: env.contract.address.to_string(), + lock_id, + }; let unstake_msg = MsgSuperfluidUnbondLock { sender: env.contract.address.to_string(), lock_id, @@ -294,7 +298,10 @@ impl Unlock for OsmosisSuperfluidStaking { .add_attribute("validator_address", self.validator_address.to_string()) .add_attribute("lock_id", lock_id.to_string()); - Ok(Response::new().add_message(unstake_msg).add_event(event)) + Ok(Response::new() + .add_message(undelegate_msg) + .add_message(unstake_msg) + .add_event(event)) } fn withdraw_unlocked( diff --git a/cw-dex/tests/astroport_tests.rs b/cw-dex/tests/astroport_tests.rs index 59091590..9e85ecdb 100644 --- a/cw-dex/tests/astroport_tests.rs +++ b/cw-dex/tests/astroport_tests.rs @@ -9,8 +9,8 @@ use cw_dex_test_helpers::astroport::setup_pool_and_test_contract; use cw_dex_test_helpers::{ cw20_balance_query, cw20_transfer, provide_liquidity, query_asset_balance, }; -use osmosis_test_tube::cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContractResponse; -use osmosis_test_tube::{ +use cw_it::osmosis_test_tube::cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContractResponse; +use cw_it::osmosis_test_tube::{ Account, ExecuteResponse, Module, OsmosisTestApp, Runner, RunnerResult, SigningAccount, Wasm, }; use test_case::test_case; diff --git a/cw-dex/tests/osmosis_proptests.proptest-regressions b/cw-dex/tests/osmosis_proptests.proptest-regressions new file mode 100644 index 00000000..4cd54f8e --- /dev/null +++ b/cw-dex/tests/osmosis_proptests.proptest-regressions @@ -0,0 +1,9 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc e22f8e171721ef28aa4455a55693db0d66d38dc34fcd13a29f99f241a297e9c5 # shrinks to (mut pool, added_liquidity) = (OsmosisTestPool { liquidity: [Coin { denom: "denom0", amount: Uint128(64398489025722006607121142527133757443) }, Coin { denom: "denom2", amount: Uint128(24749776827568749075501148375711454660) }, Coin { denom: "denom3", amount: Uint128(209232708431859127932131555418876463135) }], pool_type: StableSwap { scaling_factors: [6125911972980590975, 36836043941329637, 3741196375868371117] }, id: None }, [1, 2297327393948188247, 9649680553063585444]) +cc 491131784275305cbe74a1308b4f61bd9d1613991db75140ca4f14bc519568a8 # shrinks to (mut pool, offer_idx, ask_idx, offer_amount) = (OsmosisTestPool { liquidity: [Coin { denom: "denom0", amount: Uint128(69205465072514866847864745215393796241) }, Coin { denom: "denom1", amount: Uint128(217057400918852226210173550406390612888) }, Coin { denom: "denom2", amount: Uint128(257053008981358670749950541301584151482) }, Coin { denom: "denom3", amount: Uint128(248287397352331181831674854074148456157) }, Coin { denom: "denom5", amount: Uint128(267512863014068224646894171762879387107) }, Coin { denom: "denom7", amount: Uint128(136495380137982718741131105297167472666) }], pool_type: StableSwap { scaling_factors: [7379672990910284295, 3201606502839181030, 8143029735483265961, 7574665220120917016, 1011404902649139599, 1011259778286183074] }, id: None }, 0, 1, 3044241807239213473358838675772581010) +cc 754fd1e241aa59aed96b963714dbb23697a2f48c6968922fc5d41331deb3488b # shrinks to amount = 1 diff --git a/cw-dex/tests/osmosis_proptests.rs b/cw-dex/tests/osmosis_proptests.rs index 344105b5..53215a8e 100644 --- a/cw-dex/tests/osmosis_proptests.rs +++ b/cw-dex/tests/osmosis_proptests.rs @@ -1,10 +1,13 @@ use apollo_cw_asset::{Asset, AssetInfo}; -use cosmwasm_std::{Coin, Uint128}; -use cw_dex_test_contract::msg::ExecuteMsg; -use cw_dex_test_helpers::osmosis::{setup_pool_and_test_contract, test_pool, OsmosisTestPool}; +use cosmwasm_std::{Addr, Coin, Uint128}; +use cw_dex_test_contract::msg::{ExecuteMsg, OsmosisTestContractInstantiateMsg}; +use cw_dex_test_helpers::osmosis::setup_pool_and_test_contract; +use cw_dex_test_helpers::robot::CwDexTestRobot; use cw_it::helpers::bank_balance_query; +use cw_it::osmosis::{test_pool, OsmosisPoolType, OsmosisTestPool}; +use cw_it::osmosis_test_tube::Account; -use osmosis_test_tube::{Module, OsmosisTestApp, RunnerResult, SigningAccount, Wasm}; +use cw_it::osmosis_test_tube::{Module, OsmosisTestApp, RunnerResult, SigningAccount, Wasm}; use prop::collection::vec; use proptest::prelude::*; @@ -13,28 +16,39 @@ const TEST_CONTRACT_WASM_FILE_PATH: &str = const TWO_WEEKS_IN_SECONDS: u64 = 1_209_600; -pub fn setup_pool_and_contract( +fn setup_pool_and_contract( pool: &OsmosisTestPool, ) -> RunnerResult<(OsmosisTestApp, Vec, u64, String)> { setup_pool_and_test_contract( - &pool.pool_type, - &pool.pool_liquidity, - TWO_WEEKS_IN_SECONDS, + pool, 1, + Some(TWO_WEEKS_IN_SECONDS), + None, TEST_CONTRACT_WASM_FILE_PATH, ) } +fn init_account_with_max_balances(app: &OsmosisTestApp, pool: &OsmosisTestPool) -> SigningAccount { + let coins = pool + .liquidity + .iter() + .map(|c| Coin::new(u128::MAX, &c.denom)) + .collect::>(); + + app.init_account(&coins).unwrap() +} + proptest! { #![proptest_config(ProptestConfig { - cases: 64, + cases: 16, + max_global_rejects: 1, .. ProptestConfig::default() })] #[test] fn test_provide_liquidity( - (pool,added_liquidity) in test_pool().prop_flat_map(|x| { - (Just(x.clone()), vec(1..u64::MAX, x.pool_liquidity.len())) + (pool,added_liquidity) in test_pool(None).prop_flat_map(|x| { + (Just(x.clone()), vec(1..u64::MAX, x.liquidity.len())) })) { let (runner, accs, pool_id, contract_addr) = setup_pool_and_contract(&pool).unwrap(); @@ -43,7 +57,7 @@ proptest! { .into_iter() .enumerate() .map(|(i, amount)| Coin { - denom: format!("denom{}", i), + denom: pool.liquidity[i].denom.clone(), amount: amount.into(), }) .collect(); @@ -64,22 +78,23 @@ proptest! { #[test] fn test_pool_swap( - (pool,offer_idx,ask_idx, offer_amount) in test_pool().prop_flat_map(|x| { - let len = x.pool_liquidity.len(); + (pool,offer_denom,ask_denom, offer_amount) in test_pool(None).prop_flat_map(|x| { + let len = x.liquidity.len(); (Just(x), 0usize..len, 0usize..len) }) .prop_filter("Offer and ask can't be the same asset", |(_x, offer_idx, ask_idx)| { offer_idx != ask_idx }) .prop_flat_map(|(x, offer_idx, ask_idx)| { - (Just(x.clone()), Just(offer_idx), Just(ask_idx), 1..x.pool_liquidity[offer_idx]) + let denoms = x.liquidity.iter().map(|c| c.denom.clone()).collect::>(); + (Just(x.clone()), Just(denoms[offer_idx].clone()), Just(denoms[ask_idx].clone()), 1..x.liquidity[offer_idx].amount.u128()) }), ) { let offer = Asset { - info: AssetInfo::Native(format!("denom{}", offer_idx)), + info: AssetInfo::Native(offer_denom), amount: Uint128::from(offer_amount), }; - let ask = AssetInfo::Native(format!("denom{}", ask_idx)); + let ask = AssetInfo::Native(ask_denom); let (runner, accs, _pool_id, contract_addr) = setup_pool_and_contract(&pool).unwrap(); @@ -102,4 +117,52 @@ proptest! { assert_eq!(offer_balance, Uint128::zero()); assert_ne!(ask_balance, Uint128::zero()); } + + #[test] + fn superfluid_staking_stake_and_unstake(amount in 1..100_000_000_000_000_000_000u128) { + let app = OsmosisTestApp::new(); + let pool = OsmosisTestPool::new( + vec![ + Coin::new(1000000000u128, "uatom"), + Coin::new(1000000000u128, "uosmo"), + ], + OsmosisPoolType::Basic, + ); + let admin = init_account_with_max_balances(&app, &pool); + let pool_id = pool.create(&app, &admin); + + let validator = Addr::unchecked(app.get_first_validator_address()?); + + println!("validator_addr: {}", validator); + + let init_msg = OsmosisTestContractInstantiateMsg { + pool_id, + lock_duration: Some(TWO_WEEKS_IN_SECONDS), + lock_id: 1u64, + superfluid_validator: Some(validator), + }; + + // Whitelist LP token for superfluid staking + app.add_superfluid_lp_share(&format!("gamm/pool/{}", pool_id)); + + // Get LP token balance before + let lp_balance_before = bank_balance_query( + &app, + admin.address(), + format!("gamm/pool/{}", pool_id), + ).unwrap(); + println!("LP balance before: {}", lp_balance_before); + + println!("Superfluid staking amount: {}", amount); + let robot = CwDexTestRobot::osmosis(&app, &admin, &init_msg, TEST_CONTRACT_WASM_FILE_PATH); + let test_contract_addr = robot.test_contract_addr.clone(); + + robot + .superfluid_stake(&admin, amount.into()) + .assert_lp_balance(admin.address(), lp_balance_before.u128() - amount) + .superfluid_unlock(&admin, amount.into()) + .increase_time(TWO_WEEKS_IN_SECONDS) + .assert_lp_balance(test_contract_addr, amount); + } + } diff --git a/cw-dex/tests/osmosis_tests.rs b/cw-dex/tests/osmosis_tests.rs index bfe2847a..18d8121b 100644 --- a/cw-dex/tests/osmosis_tests.rs +++ b/cw-dex/tests/osmosis_tests.rs @@ -4,11 +4,12 @@ mod tests { use apollo_utils::submessages::{find_event, parse_attribute_value}; use cosmwasm_std::{Coin, SubMsgResponse, Uint128}; use cw_dex_test_contract::msg::{ExecuteMsg, QueryMsg}; - use cw_dex_test_helpers::osmosis::{setup_pool_and_test_contract, OsmosisPoolType}; + use cw_dex_test_helpers::osmosis::setup_pool_and_test_contract; use cw_dex_test_helpers::provide_liquidity; use cw_it::helpers::{bank_balance_query, bank_send}; - use osmosis_test_tube::cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContractResponse; - use osmosis_test_tube::{ + use cw_it::osmosis::{OsmosisPoolType, OsmosisTestPool}; + use cw_it::osmosis_test_tube::cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContractResponse; + use cw_it::osmosis_test_tube::{ Account, ExecuteResponse, Module, OsmosisTestApp, Runner, RunnerResult, SigningAccount, Wasm, }; @@ -36,11 +37,20 @@ mod tests { initial_liquidity: Vec, lock_duration: Option, ) -> RunnerResult<(OsmosisTestApp, Vec, u64, String)> { + let test_pool = OsmosisTestPool { + liquidity: initial_liquidity + .into_iter() + .enumerate() + .map(|(i, amount)| Coin::new(amount as u128, format!("denom{}", i))) + .collect(), + pool_type, + }; + setup_pool_and_test_contract( - &pool_type, - &initial_liquidity, - lock_duration.unwrap_or(TWO_WEEKS_IN_SECS), + &test_pool, 1, // Lock ID. Since it is the first lock it will be 1. + Some(lock_duration.unwrap_or(TWO_WEEKS_IN_SECS)), + None, TEST_CONTRACT_WASM_FILE_PATH, ) } @@ -67,9 +77,21 @@ mod tests { min_out: bool, expected_lps: Uint128, ) { - let initial_liquidity = added_liquidity.iter().map(|_| 1_000_000).collect(); - let (runner, accs, pool_id, contract_addr) = - setup_pool_and_contract(pool_type, initial_liquidity, None).unwrap(); + let initial_liquidity = added_liquidity + .iter() + .enumerate() + .map(|(i, _)| Coin::new(1_000_000, format!("denom{}", i))) + .collect(); + let pool = OsmosisTestPool::new(initial_liquidity, pool_type); + let (runner, accs, pool_id, contract_addr) = setup_pool_and_test_contract( + &pool, + 1, // First lock ID + Some(TWO_WEEKS_IN_SECS), + None, + TEST_CONTRACT_WASM_FILE_PATH, + ) + .unwrap(); + // setup_pool_and_contract(pool_type, initial_liquidity, None).unwrap(); let admin = &accs[0]; let coins = added_liquidity @@ -316,6 +338,7 @@ mod tests { } #[test_case(OsmosisPoolType::Basic, Uint128::new(1_000_000), false ; "basic pool")] + #[test_case(OsmosisPoolType::Basic, Uint128::new(1), false => panics ; "basic pool 1 unit amount")] #[test_case(OsmosisPoolType::Basic, Uint128::new(2), false ; "basic pool small amount")] #[test_case(OsmosisPoolType::Basic, Uint128::new(1000000), true ; "basic pool with min out")] #[test_case(OsmosisPoolType::Balancer { pool_weights: vec![2, 1] }, Uint128::new(1000000), false ; "2:1 balancer pool")] diff --git a/test-contracts/osmosis-test-contract/src/contract.rs b/test-contracts/osmosis-test-contract/src/contract.rs index 6d47af92..0d3b5370 100644 --- a/test-contracts/osmosis-test-contract/src/contract.rs +++ b/test-contracts/osmosis-test-contract/src/contract.rs @@ -2,14 +2,15 @@ use apollo_cw_asset::{Asset, AssetInfo, AssetList}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, Uint128, + to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, + Uint128, }; -use cw_dex::osmosis::{OsmosisPool, OsmosisStaking}; +use cw_dex::osmosis::{OsmosisPool, OsmosisStaking, OsmosisSuperfluidStaking}; use cw_dex::traits::{ForceUnlock, Pool, Stake, Unlock}; // use cw2::set_contract_version; use crate::error::ContractError; -use crate::state::{POOL, STAKING}; +use crate::state::{POOL, STAKING, SUPERFLUID}; use cw_dex_test_contract::msg::{ExecuteMsg, OsmosisTestContractInstantiateMsg, QueryMsg}; /* @@ -30,10 +31,26 @@ pub fn instantiate( let lp_token_denom = pool.lp_token().to_string(); - STAKING.save( - deps.storage, - &OsmosisStaking::new(msg.lock_duration, Some(msg.lock_id), lp_token_denom)?, - )?; + if msg.lock_duration.is_none() && msg.superfluid_validator.is_none() { + return Err(StdError::generic_err( + "Must provide either lock_duration or superfluid_validator_addr", + ) + .into()); + } + + if let Some(lock_duration) = msg.lock_duration { + STAKING.save( + deps.storage, + &OsmosisStaking::new(lock_duration, Some(msg.lock_id), lp_token_denom.clone())?, + )?; + } + + if let Some(validator) = msg.superfluid_validator { + SUPERFLUID.save( + deps.storage, + &OsmosisSuperfluidStaking::new(validator, Some(msg.lock_id), lp_token_denom)?, + )?; + } Ok(Response::default()) } @@ -65,6 +82,10 @@ pub fn execute( ask, min_out, } => execute_swap(deps, env, offer, ask, min_out), + ExecuteMsg::SuperfluidStake { amount } => execute_superfluid_stake(deps, env, info, amount), + ExecuteMsg::SuperfluidUnlock { amount } => { + execute_superfluid_unlock(deps, env, info, amount) + } } } @@ -117,6 +138,32 @@ pub fn execute_unlock( Ok(staking.unlock(deps.as_ref(), &env, amount)?) } +pub fn execute_superfluid_stake( + deps: DepsMut, + env: Env, + _info: MessageInfo, + amount: Uint128, +) -> Result { + let staking = SUPERFLUID + .may_load(deps.storage)? + .ok_or(StdError::generic_err("Superfluid staking not set"))?; + + Ok(staking.stake(deps.as_ref(), &env, amount)?) +} + +pub fn execute_superfluid_unlock( + deps: DepsMut, + env: Env, + _info: MessageInfo, + amount: Uint128, +) -> Result { + let staking = SUPERFLUID + .may_load(deps.storage)? + .ok_or(StdError::generic_err("Superfluid staking not set"))?; + + Ok(staking.unlock(deps.as_ref(), &env, amount)?) +} + pub fn execute_withdraw_unlocked( deps: DepsMut, env: Env, diff --git a/test-contracts/osmosis-test-contract/src/state.rs b/test-contracts/osmosis-test-contract/src/state.rs index 877358ff..fbbbff17 100644 --- a/test-contracts/osmosis-test-contract/src/state.rs +++ b/test-contracts/osmosis-test-contract/src/state.rs @@ -1,5 +1,6 @@ -use cw_dex::osmosis::{OsmosisPool, OsmosisStaking}; +use cw_dex::osmosis::{OsmosisPool, OsmosisStaking, OsmosisSuperfluidStaking}; use cw_storage_plus::Item; pub const POOL: Item = Item::new("pool"); pub const STAKING: Item = Item::new("staking"); +pub const SUPERFLUID: Item = Item::new("superfluid"); diff --git a/test-contracts/package/src/msg.rs b/test-contracts/package/src/msg.rs index f64ba6c9..d3e6a924 100644 --- a/test-contracts/package/src/msg.rs +++ b/test-contracts/package/src/msg.rs @@ -1,12 +1,13 @@ use apollo_cw_asset::{Asset, AssetInfo, AssetList}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_binary, Coin, CosmosMsg, Uint128, WasmMsg}; +use cosmwasm_std::{to_binary, Addr, Coin, CosmosMsg, Uint128, WasmMsg}; #[cw_serde] pub struct OsmosisTestContractInstantiateMsg { pub pool_id: u64, - pub lock_duration: u64, + pub lock_duration: Option, pub lock_id: u64, + pub superfluid_validator: Option, } #[cw_serde] @@ -32,6 +33,12 @@ pub enum ExecuteMsg { Unlock { amount: Uint128, }, + SuperfluidStake { + amount: Uint128, + }, + SuperfluidUnlock { + amount: Uint128, + }, WithdrawUnlocked { amount: Uint128, }, diff --git a/test-helpers/Cargo.toml b/test-helpers/Cargo.toml index e917b8ea..612a86c7 100644 --- a/test-helpers/Cargo.toml +++ b/test-helpers/Cargo.toml @@ -27,13 +27,9 @@ optimize = """docker run --rm -v "$(pwd)":/code \ [dependencies] cosmwasm-std = { workspace = true } apollo-cw-asset = { workspace = true } -osmosis-test-tube = { workspace = true } -osmosis-std = { workspace = true } apollo-utils = { workspace = true } cw-dex-test-contract = { workspace = true } -proptest = "1.0.0" -proptest-derive = "0.3.0" -cw-it = { workspace = true, features = ["astroport"] } +cw-it = { workspace = true, features = ["astroport", "osmosis"] } astroport-types = { workspace = true } cw20 = { workspace = true } cw20-base = { workspace = true } diff --git a/test-helpers/src/astroport.rs b/test-helpers/src/astroport.rs index ed191f55..38ba988a 100644 --- a/test-helpers/src/astroport.rs +++ b/test-helpers/src/astroport.rs @@ -10,7 +10,7 @@ use cw_dex_test_contract::msg::AstroportContractInstantiateMsg; use cw_it::astroport::{create_astroport_pair, instantiate_astroport, upload_astroport_contracts}; use cw_it::config::TestConfig; use cw_it::helpers::upload_wasm_file; -use osmosis_test_tube::{ +use cw_it::osmosis_test_tube::{ Account, Module, OsmosisTestApp, Runner, RunnerResult, SigningAccount, Wasm, }; use std::str::FromStr; diff --git a/test-helpers/src/helpers.rs b/test-helpers/src/helpers.rs index 7f3d503e..2b4d7fc2 100644 --- a/test-helpers/src/helpers.rs +++ b/test-helpers/src/helpers.rs @@ -5,8 +5,10 @@ use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use cw20_base::msg::InstantiateMsg as Cw20InstantiateMsg; use cw_dex_test_contract::msg::ExecuteMsg; use cw_it::helpers::bank_balance_query; -use osmosis_test_tube::cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContractResponse; -use osmosis_test_tube::{Account, Module, Runner, RunnerExecuteResult, SigningAccount, Wasm}; +use cw_it::osmosis_test_tube::cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContractResponse; +use cw_it::osmosis_test_tube::{ + Account, Module, Runner, RunnerExecuteResult, SigningAccount, Wasm, +}; pub fn provide_liquidity<'a, R: Runner<'a>>( runner: &'a R, diff --git a/test-helpers/src/lib.rs b/test-helpers/src/lib.rs index 71d4f61a..68026a38 100644 --- a/test-helpers/src/lib.rs +++ b/test-helpers/src/lib.rs @@ -2,3 +2,4 @@ pub mod astroport; mod helpers; pub mod osmosis; pub use helpers::*; +pub mod robot; diff --git a/test-helpers/src/osmosis.rs b/test-helpers/src/osmosis.rs index 70222928..27ebd186 100644 --- a/test-helpers/src/osmosis.rs +++ b/test-helpers/src/osmosis.rs @@ -1,183 +1,51 @@ -use apollo_cw_asset::{AssetInfo, AssetList}; -use cosmwasm_std::{Coin, Uint128}; +use apollo_cw_asset::AssetList; +use cosmwasm_std::{Addr, Coin, Uint128}; use cw_dex_test_contract::msg::OsmosisTestContractInstantiateMsg; use cw_it::helpers::upload_wasm_file; -use osmosis_std::types::osmosis::gamm::poolmodels::balancer::v1beta1::MsgCreateBalancerPool; -use osmosis_std::types::osmosis::gamm::poolmodels::stableswap::v1beta1::{ - MsgCreateStableswapPool, PoolParams as StableSwapPoolParams, +use cw_it::osmosis::OsmosisTestPool; +use cw_it::osmosis_test_tube::{ + Module, OsmosisTestApp, Runner, RunnerResult, SigningAccount, Wasm, }; -use osmosis_std::types::osmosis::gamm::v1beta1::{PoolAsset, PoolParams}; -use osmosis_test_tube::{ - Account, Gamm, Module, OsmosisTestApp, Runner, RunnerResult, SigningAccount, Wasm, -}; -use prop::collection::vec; -use proptest::prelude::{any_with, prop}; -use proptest::prop_compose; -use proptest::strategy::{Just, Strategy}; -use proptest_derive::Arbitrary; - -const MAX_SCALE_FACTOR: u64 = 0x7FFF_FFFF_FFFF_FFFF; // 2^63 - 1 -const MAX_POOL_WEIGHT: u64 = 1048575; //2^20 - 1 - -#[derive(Debug, Clone, PartialEq, Eq, Arbitrary)] -pub enum OsmosisPoolType { - Basic, - Balancer { - #[proptest(strategy = "vec(1..MAX_POOL_WEIGHT, param_0.len())")] - pool_weights: Vec, - }, - StableSwap { - #[proptest(params = "Vec")] - #[proptest(value = "params.clone()")] - scaling_factors: Vec, - }, -} - -#[derive(Debug, Clone)] -pub struct OsmosisTestPool { - pub assets: Vec, - pub pool_liquidity: Vec, - pub pool_type: OsmosisPoolType, -} - -prop_compose! { - /// Generates a touple of vectors with (pool_liquidity, scaling_factors) of size 2..8 - pub fn pool_params()(pool_params in vec((1..u64::MAX, 1..MAX_SCALE_FACTOR), 2..8).prop_filter("scaling factors must be smaller than liquidity",|v| v.iter().all(|(liq, scale)| scale < liq))) -> (Vec,Vec) { - let (pool_liquidity, scaling_factors): (Vec,Vec) = pool_params.into_iter().unzip(); - (pool_liquidity, scaling_factors) - } -} - -prop_compose! { - /// Generates a random OsmosisPoolType with the given scaling factors - pub fn pool_type(scaling_factors: Vec)(pool_type in any_with::(scaling_factors)) -> OsmosisPoolType { - pool_type - } -} - -prop_compose! { - /// Generates a random OsmosisTestPool with 2..8 assets - pub fn test_pool()(pool_params in pool_params())(pool_type in pool_type(pool_params.clone().1), pool_liquidity in Just(pool_params.0)) -> OsmosisTestPool { - let mut assets = vec![]; - for i in 0..pool_liquidity.len() { - assets.push(AssetInfo::Native(format!("denom{}", i))); - } - OsmosisTestPool { - assets, - pool_liquidity, - pool_type, - } - } -} - -/// Create an Osmosis pool with the given initial liquidity. -pub fn create_osmosis_pool<'a, R: Runner<'a>>( - runner: &'a R, - pool_type: &OsmosisPoolType, - initial_liquidity: &[Coin], - signer: &SigningAccount, -) -> u64 { - let gamm = Gamm::new(runner); - match pool_type { - OsmosisPoolType::Basic => { - gamm.create_basic_pool(initial_liquidity, signer) - .unwrap() - .data - .pool_id - } - OsmosisPoolType::Balancer { pool_weights } => { - gamm.create_balancer_pool( - MsgCreateBalancerPool { - sender: signer.address(), - pool_params: Some(PoolParams { - swap_fee: "10000000000000000".to_string(), - exit_fee: "10000000000000000".to_string(), - smooth_weight_change_params: None, - }), - pool_assets: initial_liquidity - .iter() - .zip(pool_weights.iter()) - .map(|(c, weight)| PoolAsset { - token: Some(c.clone().into()), - weight: weight.to_string(), - }) - .collect(), - future_pool_governor: "".to_string(), - }, - signer, - ) - .unwrap() - .data - .pool_id - } - OsmosisPoolType::StableSwap { scaling_factors } => { - gamm.create_stable_swap_pool( - MsgCreateStableswapPool { - sender: signer.address(), - pool_params: Some(StableSwapPoolParams { - swap_fee: "10000000000000000".to_string(), - exit_fee: "10000000000000000".to_string(), - }), - initial_pool_liquidity: initial_liquidity - .iter() - .map(|c| c.clone().into()) - .collect(), - scaling_factors: scaling_factors.clone(), - future_pool_governor: "".to_string(), - scaling_factor_controller: "".to_string(), - }, - signer, - ) - .unwrap() - .data - .pool_id - } - } -} /// Setup a pool and test contract for testing. pub fn setup_pool_and_test_contract( - pool_type: &OsmosisPoolType, - initial_liquidity: &[u64], - lock_duration: u64, + pool: &OsmosisTestPool, lock_id: u64, + lock_duration: Option, + superfluid_validator_addr: Option, wasm_file_path: &str, ) -> RunnerResult<(OsmosisTestApp, Vec, u64, String)> { let runner = OsmosisTestApp::new(); - let initial_liquidity = initial_liquidity - .iter() - .enumerate() - .map(|(i, amount)| Coin { - denom: format!("denom{}", i), - amount: (*amount).into(), - }) - .collect::>(); - - let mut initial_balances = initial_liquidity - .iter() - .map(|c| Coin { - denom: c.denom.clone(), - amount: Uint128::MAX, - }) - .collect::>(); - initial_balances.push(Coin { - denom: "uosmo".to_string(), - amount: Uint128::MAX, - }); - // Initialize 10 accounts with max balance of each token in the pool - let accs = runner.init_accounts(&initial_balances, 10).unwrap(); + let accs = runner + .init_accounts( + &pool + .liquidity + .iter() + .chain(vec![Coin::new(u128::MAX, "uosmo".to_string())].iter()) + .map(|c| Coin::new(u128::MAX, c.denom.clone())) + .collect::>(), + 10, + ) + .unwrap(); // Create pool - let pool_id = create_osmosis_pool(&runner, pool_type, &initial_liquidity, &accs[0]); + let pool_id = pool.create(&runner, &accs[0]); // Upload test contract wasm file let code_id = upload_wasm_file(&runner, &accs[0], wasm_file_path).unwrap(); // Instantiate the test contract - let contract_addr = - instantiate_test_contract(&runner, code_id, pool_id, lock_id, lock_duration, &accs[0])?; + let contract_addr = instantiate_test_contract( + &runner, + code_id, + pool_id, + lock_id, + lock_duration, + superfluid_validator_addr, + &accs[0], + )?; Ok((runner, accs, pool_id, contract_addr)) } @@ -200,13 +68,15 @@ pub fn instantiate_test_contract<'a, R: Runner<'a>>( code_id: u64, pool_id: u64, lock_id: u64, - lock_duration: u64, + lock_duration: Option, + superfluid_validator_addr: Option, signer: &SigningAccount, ) -> RunnerResult { let init_msg = OsmosisTestContractInstantiateMsg { pool_id, lock_duration, lock_id, + superfluid_validator: superfluid_validator_addr, }; let wasm = Wasm::new(runner); diff --git a/test-helpers/src/robot.rs b/test-helpers/src/robot.rs new file mode 100644 index 00000000..b9c5523a --- /dev/null +++ b/test-helpers/src/robot.rs @@ -0,0 +1,122 @@ +use cosmwasm_std::{Coin, Uint128}; +use cw_dex_test_contract::msg::{ExecuteMsg, OsmosisTestContractInstantiateMsg}; +use cw_it::helpers::{bank_balance_query, upload_wasm_file}; +use cw_it::osmosis_test_tube::{Module, OsmosisTestApp, SigningAccount, Wasm}; + +pub struct CwDexTestRobot<'a> { + pub app: &'a OsmosisTestApp, + pub test_contract_addr: String, + pub pool_id: u64, +} + +impl<'a> CwDexTestRobot<'a> { + pub fn osmosis( + app: &'a OsmosisTestApp, + signer: &SigningAccount, + init_msg: &OsmosisTestContractInstantiateMsg, + wasm_file_path: &str, + ) -> Self { + // Upload test contract wasm file + let code_id = upload_wasm_file(app, signer, wasm_file_path).unwrap(); + + let wasm = Wasm::new(app); + let test_contract_addr = wasm + .instantiate(code_id, &init_msg, None, None, &[], signer) + .unwrap() + .data + .address; + + Self { + app, + test_contract_addr, + pool_id: init_msg.pool_id, + } + } + + pub fn assert_native_balance( + &self, + address: String, + denom: String, + expected: impl Into, + ) -> &Self { + let balance = bank_balance_query(self.app, address, denom).unwrap(); + assert_eq!(balance, expected.into()); + self + } + + pub fn assert_lp_balance(&self, address: String, expected: impl Into) -> &Self { + self.assert_native_balance(address, format!("gamm/pool/{}", self.pool_id), expected); + self + } + + pub fn stake(&self, signer: &SigningAccount, amount: Uint128) -> &Self { + let wasm = Wasm::new(self.app); + wasm.execute( + &self.test_contract_addr, + &ExecuteMsg::Stake { amount }, + &[Coin { + amount, + denom: format!("gamm/pool/{}", self.pool_id), + }], + signer, + ) + .unwrap(); + self + } + + pub fn unlock(&self, signer: &SigningAccount, amount: Uint128) -> &Self { + let wasm = Wasm::new(self.app); + wasm.execute( + &self.test_contract_addr, + &ExecuteMsg::Unlock { amount }, + &[], + signer, + ) + .unwrap(); + self + } + + pub fn superfluid_stake(&self, signer: &SigningAccount, amount: Uint128) -> &Self { + let wasm = Wasm::new(self.app); + wasm.execute( + &self.test_contract_addr, + &ExecuteMsg::SuperfluidStake { amount }, + &[Coin { + amount, + denom: format!("gamm/pool/{}", self.pool_id), + }], + signer, + ) + .unwrap(); + self + } + + pub fn superfluid_unlock(&self, signer: &SigningAccount, amount: Uint128) -> &Self { + let wasm = Wasm::new(self.app); + wasm.execute( + &self.test_contract_addr, + &ExecuteMsg::SuperfluidUnlock { amount }, + &[], + signer, + ) + .unwrap(); + self + } + + pub fn increase_time(&self, seconds: u64) -> &Self { + self.app.increase_time(seconds); + self + } + + pub fn withdraw_unlocked(&self, signer: &SigningAccount, amount: Uint128) -> &Self { + let wasm = Wasm::new(self.app); + wasm.execute( + &self.test_contract_addr, + &ExecuteMsg::WithdrawUnlocked { amount }, + &[], + signer, + ) + .unwrap(); + self + } +}