diff --git a/Cargo.lock b/Cargo.lock index 5c16c79d..c2ed3f62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anybuf" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a03eb4d55fa21466cac727930be07f82581223ee04bcaf61f934e98b7ecb859" + [[package]] name = "anyhow" version = "1.0.71" @@ -20,11 +26,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" -version = "0.13.0" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -32,6 +44,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "bit-set" version = "0.5.3" @@ -71,6 +89,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" + [[package]] name = "byteorder" version = "1.4.3" @@ -97,37 +121,38 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.0" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cosmwasm-crypto" -version = "1.2.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" +checksum = "ad24bc9dae9aac5dc124b4560e3f7678729d701f1bf3cb11140703d91f247d31" dependencies = [ - "digest 0.10.5", + "digest 0.10.7", + "ecdsa 0.16.9", "ed25519-zebra", - "k256", - "rand_core 0.6.3", + "k256 0.13.3", + "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "ca65635b768406eabdd28ba015cc3f2f863ca5a2677a7dc4c237b8ee1298efb3" dependencies = [ "syn 1.0.99", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "77e2a6ce6dbcad572495fd9d9c1072793fe682aebfcc09752c3b0de3fa1814d7" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -138,9 +163,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "904408dc6d73fd1d535c764a55370803cccf6b9be5af7423c4db8967058673f0" dependencies = [ "proc-macro2", "quote", @@ -149,11 +174,13 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "1ed4564772e5d779235f2d7353e3d66e37793065c3a5155a2978256bf4c5b7d5" dependencies = [ "base64", + "bech32", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -163,8 +190,8 @@ dependencies = [ "serde", "serde-json-wasm", "sha2 0.10.6", + "static_assertions", "thiserror", - "uint", ] [[package]] @@ -199,7 +226,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -254,7 +293,7 @@ dependencies = [ "cw-utils", "derivative", "itertools", - "k256", + "k256 0.11.6", "prost 0.9.0", "schemars", "serde", @@ -354,6 +393,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -376,11 +425,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] @@ -397,10 +447,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.0", + "elliptic-curve 0.12.3", + "rfc6979 0.3.0", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.8", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -411,7 +475,7 @@ checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" dependencies = [ "curve25519-dalek", "hex", - "rand_core 0.6.3", + "rand_core 0.6.4", "serde", "sha2 0.9.9", "thiserror", @@ -430,16 +494,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest 0.10.5", - "ff", + "base16ct 0.1.1", + "crypto-bigint 0.4.8", + "der 0.6.0", + "digest 0.10.7", + "ff 0.12.0", "generic-array", - "group", - "pkcs8", - "rand_core 0.6.3", - "sec1", + "group 0.12.0", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.1", "subtle", "zeroize", ] @@ -557,7 +640,17 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", "subtle", ] @@ -603,6 +696,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -633,8 +727,19 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ - "ff", - "rand_core 0.6.3", + "ff 0.12.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", "subtle", ] @@ -656,7 +761,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -759,11 +864,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", ] +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.6", + "signature 2.2.0", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -819,9 +938,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -870,8 +989,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.0", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.3", ] [[package]] @@ -1075,7 +1204,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1085,7 +1214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1099,9 +1228,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom 0.2.7", ] @@ -1112,7 +1241,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1145,11 +1274,21 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88c86280f057430a52f4861551b092a01b419b8eacefc7c995eacb9dc132fe32" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.8", "hmac", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rustix" version = "0.37.19" @@ -1218,10 +1357,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.0", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -1304,7 +1457,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -1313,8 +1466,18 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.5", - "rand_core 0.6.3", + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", ] [[package]] @@ -1330,7 +1493,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.0", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.8", ] [[package]] @@ -1436,6 +1609,7 @@ dependencies = [ name = "terraswap-pair" version = "1.3.3" dependencies = [ + "anybuf", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", @@ -1816,6 +1990,6 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "zeroize" -version = "1.5.7" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index 5388a2c5..cebc164b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "packages/*", @@ -35,13 +36,14 @@ thiserror = "1.0.43" osmosis-std-derive = "0.15.3" prost = {version = "0.11.9", default-features = false, features = ["prost-derive"]} prost-types = {version = "0.11.9", default-features = false} -white-whale = { path = "./packages/white-whale" } +white-whale = { path = "./packages/white-whale", features = [] } white-whale-testing = { path = "./packages/white-whale-testing" } cw-multi-test = { version = "0.16.5" } uint = "0.9.5" integer-sqrt = "0.1.5" anyhow = { version = "1.0.71"} cw-controllers = "1.1.0" +anybuf = { version = "0.3.0"} # contracts whale-lair = { path = "./contracts/liquidity_hub/whale_lair" } diff --git a/contracts/liquidity_hub/epoch-manager/Cargo.toml b/contracts/liquidity_hub/epoch-manager/Cargo.toml index d355c2cc..44262838 100644 --- a/contracts/liquidity_hub/epoch-manager/Cargo.toml +++ b/contracts/liquidity_hub/epoch-manager/Cargo.toml @@ -19,6 +19,7 @@ crate-type = ["cdylib", "rlib"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/liquidity_hub/epoch-manager/src/contract.rs b/contracts/liquidity_hub/epoch-manager/src/contract.rs index 0f2fc474..8421f12b 100644 --- a/contracts/liquidity_hub/epoch-manager/src/contract.rs +++ b/contracts/liquidity_hub/epoch-manager/src/contract.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{entry_point, to_binary, StdError}; +use cosmwasm_std::{entry_point, to_json_binary, StdError}; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::{get_contract_version, set_contract_version}; use semver::Version; @@ -79,9 +79,9 @@ pub fn execute( #[entry_point] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::CurrentEpoch {} => Ok(to_binary(&queries::query_current_epoch(deps)?)?), - QueryMsg::Epoch { id } => Ok(to_binary(&queries::query_epoch(deps, id)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::CurrentEpoch {} => Ok(to_json_binary(&queries::query_current_epoch(deps)?)?), + QueryMsg::Epoch { id } => Ok(to_json_binary(&queries::query_epoch(deps, id)?)?), } } diff --git a/contracts/liquidity_hub/fee-distributor-mock/Cargo.toml b/contracts/liquidity_hub/fee-distributor-mock/Cargo.toml index 45a3e244..7563c292 100644 --- a/contracts/liquidity_hub/fee-distributor-mock/Cargo.toml +++ b/contracts/liquidity_hub/fee-distributor-mock/Cargo.toml @@ -28,6 +28,7 @@ overflow-checks = true [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs b/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs index b3e2964c..d2486011 100644 --- a/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs +++ b/contracts/liquidity_hub/fee-distributor-mock/src/contract.rs @@ -1,6 +1,6 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint64, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint64, }; use white_whale::fee_distributor::EpochResponse; @@ -71,7 +71,7 @@ pub fn query( match msg { white_whale::fee_distributor::QueryMsg::Config {} => {} white_whale::fee_distributor::QueryMsg::CurrentEpoch {} => { - return to_binary(&EpochResponse { + return to_json_binary(&EpochResponse { epoch: CURRENT_EPOCH.load(deps.storage)?, }); } @@ -80,5 +80,5 @@ pub fn query( white_whale::fee_distributor::QueryMsg::Claimable { .. } => {} } - to_binary(&"") + to_json_binary(&"") } diff --git a/contracts/liquidity_hub/fee_collector/Cargo.toml b/contracts/liquidity_hub/fee_collector/Cargo.toml index 14d253d3..7eca1ba5 100644 --- a/contracts/liquidity_hub/fee_collector/Cargo.toml +++ b/contracts/liquidity_hub/fee_collector/Cargo.toml @@ -27,6 +27,7 @@ backtraces = ["cosmwasm-std/backtraces"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] [dependencies] cosmwasm-std.workspace = true diff --git a/contracts/liquidity_hub/fee_collector/src/commands.rs b/contracts/liquidity_hub/fee_collector/src/commands.rs index 44047ff3..3a3f082b 100644 --- a/contracts/liquidity_hub/fee_collector/src/commands.rs +++ b/contracts/liquidity_hub/fee_collector/src/commands.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, Addr, BalanceResponse, BankQuery, Coin, CosmosMsg, Decimal, DepsMut, Env, + to_json_binary, Addr, BalanceResponse, BankQuery, Coin, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, QueryRequest, ReplyOn, Response, StdResult, SubMsg, Uint128, WasmMsg, WasmQuery, }; use cw20::{Cw20ExecuteMsg, Cw20QueryMsg}; @@ -49,10 +49,10 @@ pub fn collect_fees(deps: DepsMut, collect_fees_for: FeesFor) -> Result StdResult { let collect_protocol_fees_msg = match contract_type { ContractType::Vault {} => { - to_binary(&white_whale::vault_network::vault::ExecuteMsg::CollectProtocolFees {})? + to_json_binary(&white_whale::vault_network::vault::ExecuteMsg::CollectProtocolFees {})? } ContractType::Pool {} => { - to_binary(&white_whale::pool_network::pair::ExecuteMsg::CollectProtocolFees {})? + to_json_binary(&white_whale::pool_network::pair::ExecuteMsg::CollectProtocolFees {})? } }; @@ -76,7 +76,7 @@ fn collect_fees_for_factory( let response: VaultsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::vault_network::vault_factory::QueryMsg::Vaults { start_after, limit, @@ -95,7 +95,7 @@ fn collect_fees_for_factory( let response: PairsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary(&QueryMsg::Pairs { start_after, limit })?, + msg: to_json_binary(&QueryMsg::Pairs { start_after, limit })?, }))?; for pair in response.pairs { @@ -182,7 +182,7 @@ pub fn aggregate_fees( let response: VaultsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::vault_network::vault_factory::QueryMsg::Vaults { start_after, limit, @@ -198,7 +198,7 @@ pub fn aggregate_fees( let response: PairsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary(&QueryMsg::Pairs { start_after, limit })?, + msg: to_json_binary(&QueryMsg::Pairs { start_after, limit })?, }))?; for pair in response.pairs { @@ -224,7 +224,7 @@ pub fn aggregate_fees( let balance_response: cw20::BalanceResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20QueryMsg::Balance { + msg: to_json_binary(&Cw20QueryMsg::Balance { address: env.contract.address.to_string(), })?, }))?; @@ -234,7 +234,7 @@ pub fn aggregate_fees( // Increase the allowance for the cw20 token so the router can perform the swap aggregate_fees_messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&Cw20ExecuteMsg::IncreaseAllowance { spender: config.pool_router.to_string(), amount: balance_response.balance, expires: None, @@ -261,7 +261,7 @@ pub fn aggregate_fees( let operations_res: StdResult> = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.pool_router.to_string(), - msg: to_binary(&router::QueryMsg::SwapRoute { + msg: to_json_binary(&router::QueryMsg::SwapRoute { offer_asset_info: offer_asset_info.clone(), ask_asset_info: ask_asset_info.clone(), })?, @@ -270,7 +270,7 @@ pub fn aggregate_fees( match operations_res { Ok(operations) => { let execute_swap_operations_msg = - to_binary(&router::ExecuteMsg::ExecuteSwapOperations { + to_json_binary(&router::ExecuteMsg::ExecuteSwapOperations { operations, minimum_receive: None, to: None, @@ -282,7 +282,7 @@ pub fn aggregate_fees( aggregate_fees_messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: config.pool_router.to_string(), amount: balance, msg: execute_swap_operations_msg, @@ -336,7 +336,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::CollectFees { + msg: to_json_binary(&ExecuteMsg::CollectFees { collect_fees_for: FeesFor::Factory { factory_addr: config.vault_factory.to_string(), factory_type: FactoryType::Vault { @@ -355,7 +355,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::CollectFees { + msg: to_json_binary(&ExecuteMsg::CollectFees { collect_fees_for: FeesFor::Factory { factory_addr: config.pool_factory.to_string(), factory_type: FactoryType::Pool { @@ -375,7 +375,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AggregateFees { + msg: to_json_binary(&ExecuteMsg::AggregateFees { aggregate_fees_for: FeesFor::Factory { factory_addr: config.vault_factory.to_string(), factory_type: FactoryType::Vault { @@ -394,7 +394,7 @@ pub fn forward_fees( msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AggregateFees { + msg: to_json_binary(&ExecuteMsg::AggregateFees { aggregate_fees_for: FeesFor::Factory { factory_addr: config.pool_factory.to_string(), factory_type: FactoryType::Pool { diff --git a/contracts/liquidity_hub/fee_collector/src/contract.rs b/contracts/liquidity_hub/fee_collector/src/contract.rs index f6e0dfd4..c7e8a1c0 100644 --- a/contracts/liquidity_hub/fee_collector/src/contract.rs +++ b/contracts/liquidity_hub/fee_collector/src/contract.rs @@ -1,8 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Addr, BalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, Deps, DepsMut, Env, - MessageInfo, QueryRequest, Reply, Response, StdResult, Uint128, + to_json_binary, Addr, BalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, Deps, DepsMut, + Env, MessageInfo, QueryRequest, Reply, Response, StdResult, Uint128, }; use cw2::{get_contract_version, set_contract_version}; use semver::Version; @@ -96,7 +96,7 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::query_config(deps)?), + QueryMsg::Config {} => to_json_binary(&queries::query_config(deps)?), QueryMsg::Fees { query_fees_for, all_time, - } => to_binary(&queries::query_fees( + } => to_json_binary(&queries::query_fees( deps, query_fees_for, all_time.unwrap_or(false), diff --git a/contracts/liquidity_hub/fee_collector/src/queries.rs b/contracts/liquidity_hub/fee_collector/src/queries.rs index fb436ee3..050539ed 100644 --- a/contracts/liquidity_hub/fee_collector/src/queries.rs +++ b/contracts/liquidity_hub/fee_collector/src/queries.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, Deps, QueryRequest, StdResult, WasmQuery}; +use cosmwasm_std::{to_json_binary, Addr, Deps, QueryRequest, StdResult, WasmQuery}; use white_whale::fee_collector::{Config, ContractType, FactoryType, FeesFor}; use white_whale::pool_network; @@ -75,7 +75,7 @@ fn query_fees_for_vault(deps: &Deps, vault: String, all_time: bool) -> StdResult .querier .query::(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: vault, - msg: to_binary(&white_whale::vault_network::vault::QueryMsg::ProtocolFees { + msg: to_json_binary(&white_whale::vault_network::vault::QueryMsg::ProtocolFees { all_time, })?, }))? @@ -90,7 +90,7 @@ fn query_fees_for_pair(deps: &Deps, pair: String, all_time: bool) -> StdResult(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair, - msg: to_binary(&pool_network::pair::QueryMsg::ProtocolFees { + msg: to_json_binary(&pool_network::pair::QueryMsg::ProtocolFees { all_time: Some(all_time), asset_id: None, })?, @@ -114,7 +114,7 @@ fn query_fees_for_factory( let response: VaultsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::vault_network::vault_factory::QueryMsg::Vaults { start_after, limit, @@ -131,7 +131,10 @@ fn query_fees_for_factory( let response: PairsResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory.to_string(), - msg: to_binary(&pool_network::factory::QueryMsg::Pairs { start_after, limit })?, + msg: to_json_binary(&pool_network::factory::QueryMsg::Pairs { + start_after, + limit, + })?, }))?; for pair in response.pairs { @@ -151,7 +154,7 @@ pub(crate) fn query_distribution_asset(deps: Deps) -> StdResult { let fee_distributor_config: white_whale::fee_distributor::Config = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.fee_distributor.to_string(), - msg: to_binary(&white_whale::fee_distributor::QueryMsg::Config {})?, + msg: to_json_binary(&white_whale::fee_distributor::QueryMsg::Config {})?, }))?; Ok(fee_distributor_config.distribution_asset) diff --git a/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs b/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs index 5dbd012a..db210ec5 100644 --- a/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs +++ b/contracts/liquidity_hub/fee_collector/src/tests/dummy_contract.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, BankMsg, Coin, Response}; +use cosmwasm_std::{to_json_binary, Addr, BankMsg, Coin, Response}; use cw_multi_test::ContractWrapper; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -28,6 +28,6 @@ pub fn create_dummy_flash_loan_contract( } }, |_deps, _env, _info, _msg| Ok(Response::new()), - |_deps, _env, _query| Ok(to_binary::>(&vec![]).unwrap()), + |_deps, _env, _query| Ok(to_json_binary::>(&vec![]).unwrap()), ) } diff --git a/contracts/liquidity_hub/fee_collector/src/tests/integration.rs b/contracts/liquidity_hub/fee_collector/src/tests/integration.rs index a953f8f1..11de53d9 100644 --- a/contracts/liquidity_hub/fee_collector/src/tests/integration.rs +++ b/contracts/liquidity_hub/fee_collector/src/tests/integration.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use cosmwasm_std::{ - coin, coins, to_binary, Addr, BankMsg, BlockInfo, Coin, Decimal, Timestamp, Uint128, Uint256, - Uint64, + coin, coins, to_json_binary, Addr, BankMsg, BlockInfo, Coin, Decimal, Timestamp, Uint128, + Uint256, Uint64, }; use cw20::{BalanceResponse, Cw20Coin, Cw20ExecuteMsg, MinterResponse}; use cw_multi_test::Executor; @@ -61,16 +61,18 @@ fn collect_all_factories_cw20_fees_successfully() { ) .unwrap(); + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -135,6 +137,35 @@ fn collect_all_factories_cw20_fees_successfully() { cw20_tokens.push(token_address.clone()); } + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(5u64), + }, + swap_fee: Fee { + share: Decimal::percent(7u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(5u64), + }, + swap_fee: Fee { + share: Decimal::percent(7u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::zero(), + }, + }; + // Create few pools let mut pair_tokens: Vec = Vec::new(); for i in 0..TOKEN_AMOUNT - 1 { @@ -151,17 +182,7 @@ fn collect_all_factories_cw20_fees_successfully() { contract_addr: cw20_tokens[i as usize + 1].to_string(), }, ], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(5u64), - }, - swap_fee: Fee { - share: Decimal::percent(7u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, + pool_fees: pool_fees.clone(), pair_type: PairType::ConstantProduct, token_factory_lp: false, }, @@ -256,7 +277,7 @@ fn collect_all_factories_cw20_fees_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i as usize - 1].to_string(), amount: Uint128::new(100_000_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -273,7 +294,7 @@ fn collect_all_factories_cw20_fees_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i as usize].to_string(), amount: Uint128::new(200_000_000_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(20u64)), to: None, @@ -538,6 +559,7 @@ fn collect_all_factories_cw20_fees_successfully() { assert!(balance_res.balance > ask_asset_original_balance); } +#[cfg(not(feature = "osmosis"))] #[test] fn collect_cw20_fees_for_specific_contracts_successfully() { const TOKEN_AMOUNT: usize = 10; @@ -563,16 +585,40 @@ fn collect_cw20_fees_for_specific_contracts_successfully() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -749,7 +795,7 @@ fn collect_cw20_fees_for_specific_contracts_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i - 1].to_string(), amount: Uint128::new(100_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(30u64)), to: None, @@ -766,7 +812,7 @@ fn collect_cw20_fees_for_specific_contracts_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i].to_string(), amount: Uint128::new(200_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(30u64)), to: None, @@ -964,7 +1010,7 @@ fn collect_cw20_fees_for_specific_contracts_successfully() { assert_eq!(asset.amount, Uint128::zero()); } } - +#[cfg(not(feature = "osmosis"))] #[test] fn collect_pools_native_fees_successfully() { const TOKEN_AMOUNT: u8 = 3; @@ -996,16 +1042,40 @@ fn collect_pools_native_fees_successfully() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -1229,7 +1299,7 @@ fn collect_pools_native_fees_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i].to_string(), amount: Uint128::new(200_000_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -1558,7 +1628,7 @@ fn collect_pools_native_fees_successfully() { .unwrap(); assert!(balance_res.balance > ask_asset_original_balance); } - +#[cfg(not(feature = "osmosis"))] #[test] fn collect_fees_with_pagination_successfully() { const TOKEN_AMOUNT: usize = 10; @@ -1588,16 +1658,40 @@ fn collect_fees_with_pagination_successfully() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -1768,7 +1862,7 @@ fn collect_fees_with_pagination_successfully() { &Cw20ExecuteMsg::Send { contract: pair_tokens[i].to_string(), amount: Uint128::new(200_000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(40u64)), to: None, @@ -2088,7 +2182,7 @@ fn collect_fees_for_vault() { vaults[i].clone(), &white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: Uint128::new(flash_loan_value), - msg: to_binary(&BankMsg::Send { + msg: to_json_binary(&BankMsg::Send { to_address: vaults[i].to_string(), // return a higher amount than the flashloan + fees amount: coins(return_flash_loan_value, coin.denom.clone()), @@ -2207,7 +2301,7 @@ fn collect_fees_for_vault() { }; assert_eq!(fee_collector_fees_query[0], expected_asset); } - +#[cfg(not(feature = "osmosis"))] #[test] fn aggregate_fees_for_vault() { let creator = mock_creator(); @@ -2310,16 +2404,40 @@ fn aggregate_fees_for_vault() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -2492,7 +2610,7 @@ fn aggregate_fees_for_vault() { vaults[i].clone(), &white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: Uint128::new(flash_loan_value), - msg: to_binary(&BankMsg::Send { + msg: to_json_binary(&BankMsg::Send { to_address: vaults[i].to_string(), // return a higher amount than the flashloan + fees amount: coins(return_flash_loan_value, coin.denom.clone()), @@ -2844,7 +2962,7 @@ fn accumulate_fee_works() { } } } - +#[cfg(not(feature = "osmosis"))] #[test] fn collect_and_distribute_fees_successfully() { let creator = mock_creator(); @@ -2882,16 +3000,40 @@ fn collect_and_distribute_fees_successfully() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -3226,7 +3368,7 @@ fn collect_and_distribute_fees_successfully() { assert_eq!(fee_distributor_current_epoch_query.epoch.id, Uint64::one()); assert!(!fee_distributor_current_epoch_query.epoch.total.is_empty()); } - +#[cfg(not(feature = "osmosis"))] #[test] fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_end() { let creator = mock_creator(); @@ -3275,16 +3417,40 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -4169,7 +4335,7 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e user_1_claims.iter().sum::() + user_2_claims.iter().sum::() ); } - +#[cfg(not(feature = "osmosis"))] #[test] fn collect_and_distribute_fees_with_expiring_epoch_successfully() { let creator = mock_creator(); @@ -4218,16 +4384,40 @@ fn collect_and_distribute_fees_with_expiring_epoch_successfully() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -4730,30 +4920,19 @@ fn collect_and_distribute_fees_with_expiring_epoch_successfully() { <= Uint128::one() ); } - +#[cfg(not(feature = "osmosis"))] #[test] -fn collect_distribute_with_unbonders() { +fn create_epoch_unsuccessfully() { let creator = mock_creator(); - let balances = vec![ - ( - creator.clone().sender, - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), - coin(1_000_000_000, "ampWHALE"), - coin(1_000_000_000, "bWHALE"), - ], - ), - ( - Addr::unchecked("other"), - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), - coin(1_000_000_000, "ampWHALE"), - coin(1_000_000_000, "bWHALE"), - ], - ), - ]; + let balances = vec![( + creator.clone().sender, + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), + coin(1_000_000_000, "ampWHALE"), + coin(1_000_000_000, "bWHALE"), + ], + )]; let mut app = mock_app_with_balance(balances); @@ -4779,16 +4958,40 @@ fn collect_distribute_with_unbonders() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -4829,7 +5032,7 @@ fn collect_distribute_with_unbonders() { whale_lair_id, creator.clone().sender, &white_whale::whale_lair::InstantiateMsg { - unbonding_period: Uint64::new(1u64), + unbonding_period: Uint64::new(1_000_000_000_000u64), growth_rate: Decimal::one(), bonding_assets: vec![ AssetInfo::NativeToken { @@ -4868,20 +5071,6 @@ fn collect_distribute_with_unbonders() { ) .unwrap(); - // add the fee distributor address to the whale lair contract so we can use it as a clock - app.execute_contract( - creator.sender.clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::UpdateConfig { - fee_distributor_addr: Some(fee_distributor_address.to_string()), - owner: None, - unbonding_period: None, - growth_rate: None, - }, - &[], - ) - .unwrap(); - // add pool router address to the fee collector to be able to aggregate fees app.execute_contract( creator.sender.clone(), @@ -5040,46 +5229,8 @@ fn collect_distribute_with_unbonders() { .unwrap(); } - // bond some tokens - app.execute_contract( - creator.sender.clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(1_000u128), - }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(1_000u128), - }], - ) - .unwrap(); - - app.execute_contract( - Addr::unchecked("other").clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(1_000u128), - }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(1_000u128), - }], - ) - .unwrap(); - - // Create some epochs, for the first one all good but for the second we will have an unbonding + // add epochs to the fee distributor. - // Create EPOCH 1 with 100 whale // whale -> native app.execute_contract( creator.sender.clone(), @@ -5089,28 +5240,26 @@ fn collect_distribute_with_unbonders() { info: AssetInfo::NativeToken { denom: "usdc".to_string(), }, - amount: Uint128::new(2_010u128), + amount: Uint128::new(200_000u128), }, belief_price: None, - max_spread: None, + max_spread: Some(Decimal::percent(40u64)), to: None, }, &[Coin { denom: "usdc".to_string(), - amount: Uint128::new(2_010u128), + amount: Uint128::new(200_000u128), }], ) .unwrap(); - // advance the time to one day after the first epoch was created app.set_block(BlockInfo { height: 123456789u64, - time: Timestamp::from_nanos(1678888800_000000000u64), + time: Timestamp::from_nanos(1678802400_000000000u64), chain_id: "".to_string(), }); // Create new epoch, which triggers fee collection, aggregation and distribution - // Verify epoch 1 app.execute_contract( creator.sender.clone(), fee_distributor_address.clone(), @@ -5119,50 +5268,13 @@ fn collect_distribute_with_unbonders() { ) .unwrap(); - // check that a new epoch was created - let expiring_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, - ) - .unwrap(); - assert_eq!(expiring_epoch_res.epoch.id, Uint64::one()); - assert_eq!( - expiring_epoch_res.epoch.available, - expiring_epoch_res.epoch.total - ); - assert!(expiring_epoch_res.epoch.claimed.is_empty()); - // Verify expiring_epoch_res.epoch.available, has 100 whale as an Asset - assert_eq!( - expiring_epoch_res.epoch.available, - vec![Asset { - info: AssetInfo::NativeToken { - denom: "uwhale".to_string(), - }, - amount: Uint128::new(100u128), - }] - ); - - // for user in vec![creator.sender.clone(), Addr::unchecked("other")] { - // let weight: BondingWeightResponse = app - // .wrap() - // .query_wasm_smart( - // whale_lair_address.clone(), - // &white_whale::whale_lair::QueryMsg::Weight { - // address: user.to_string(), - // // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), - // global_weight: None, - // timestamp: None, - // }, - // ) - // .unwrap(); - // weights.push(weight.weight); - // } - // println!(" -> weights after each bonding 1000 whale: {:?}", weights); + // advance some time, but not enough to create a new epoch + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1678802500_000000000u64), //less than a day + chain_id: "".to_string(), + }); - // When creating the second epoch, the first one will be expiring since the grace_period was set to 1. - // Make sure the available tokens on the expiring epoch are transferred to the second one. app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -5171,331 +5283,163 @@ fn collect_distribute_with_unbonders() { info: AssetInfo::NativeToken { denom: "usdc".to_string(), }, - amount: Uint128::new(2_050u128), + amount: Uint128::new(200_000u128), }, belief_price: None, - max_spread: None, + max_spread: Some(Decimal::percent(40u64)), to: None, }, &[Coin { denom: "usdc".to_string(), - amount: Uint128::new(2_050u128), + amount: Uint128::new(200_000u128), }], ) .unwrap(); - // Get the weight of create.sender before bonding - // Get the weight after bonding ensure its different - let _weight_before: BondingWeightResponse = app - .wrap() - .query_wasm_smart( - whale_lair_address.clone(), - &white_whale::whale_lair::QueryMsg::Weight { - address: creator.sender.to_string(), - // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), - global_index: None, - timestamp: None, - }, + let err = app + .execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &NewEpoch {}, + &[], + ) + .unwrap_err(); + + assert_eq!( + err.downcast::().unwrap(), + fee_distributor::ContractError::CurrentEpochNotExpired {} + ); +} + +#[test] +fn aggregate_fees_unsuccessfully() { + let creator = mock_creator(); + + let mut app = mock_app(); + + let fee_collector_id = store_fee_collector_code(&mut app); + let fee_distributor_id = store_fee_distributor_code(&mut app); + + let fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "fee_collector", + None, ) .unwrap(); - // advance the time to one day after the first epoch was created - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(1678888800_000000000u64), - chain_id: "".to_string(), - }); + let fee_distributor_address = app + .instantiate_contract( + fee_distributor_id, + creator.clone().sender, + &white_whale::fee_distributor::InstantiateMsg { + bonding_contract_addr: "whale_lair".to_string(), + fee_collector_addr: fee_collector_address.to_string(), + grace_period: Uint64::new(5), + epoch_config: EpochConfig { + duration: Uint64::new(86400000000000), + genesis_epoch: Default::default(), + }, + distribution_asset: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + }, + &[], + "fee_distributor", + None, + ) + .unwrap(); - // Create new epoch, which triggers fee collection, aggregation and distribution - // Create EPOCH 2 + // update the fee_distributor_address on fee collector app.execute_contract( creator.sender.clone(), - fee_distributor_address.clone(), - &NewEpoch {}, + fee_collector_address.clone(), + &UpdateConfig { + owner: None, + pool_router: None, + fee_distributor: Some(fee_distributor_address.to_string()), + pool_factory: None, + vault_factory: None, + }, &[], ) .unwrap(); - // check that the second epoch was created - let new_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, + let err = app + .execute_contract( + Addr::unchecked("anyone"), + fee_collector_address.clone(), + &AggregateFees { + aggregate_fees_for: FeesFor::Contracts { contracts: vec![] }, + }, + &[], ) - .unwrap(); + .unwrap_err(); - assert_eq!(new_epoch_res.epoch.id, Uint64::new(2u64)); - assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); - assert!(new_epoch_res.epoch.claimed.is_empty()); + assert_eq!( + err.downcast::().unwrap(), + ContractError::InvalidContractsFeeAggregation {} + ); +} - // check that the available assets for the expired epoch are zero/empty - let expired_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { id: Uint64::one() }, +#[test] +fn forward_fees_unsuccessfully() { + let creator = mock_creator(); + + let mut app = mock_app(); + + let fee_collector_id = store_fee_collector_code(&mut app); + + let fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "fee_collector", + None, ) .unwrap(); - assert!(expired_epoch_res.epoch.available.is_empty()); - - // let weight_after: BondingWeightResponse = app - // .wrap() - // .query_wasm_smart( - // whale_lair_address.clone(), - // &white_whale::whale_lair::QueryMsg::Weight { - // address: creator.sender.to_string(), - // // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), - // global_weight: None, - // timestamp: None, - // }, - // ) - // .unwrap(); - // Get weight of other user and ensure its lower than the first - // let user_two_weight: BondingWeightResponse = app - // .wrap() - // .query_wasm_smart( - // whale_lair_address.clone(), - // &white_whale::whale_lair::QueryMsg::Weight { - // address: Addr::unchecked("other").to_string(), - // // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), - // global_weight: None, - // timestamp: None, - // }, - // ) - // .unwrap(); + // try to forward fees from an unauthorized address + let err = app + .execute_contract( + Addr::unchecked("unauthorized"), + fee_collector_address.clone(), + &ForwardFees { + epoch: Default::default(), + forward_fees_as: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + }, + &[], + ) + .unwrap_err(); - // since the fees collected for the second epoch were the same for the first, the available - // assets for the second epoch should be twice the amount of the first + assert_eq!( + err.downcast::().unwrap(), + ContractError::Unauthorized {} + ); +} - // iterate the new_epoch_res.epoch.available and add up the amounts for each asset - let mut total_amount_new_epoch = Uint128::zero(); - for asset in new_epoch_res.epoch.available { - total_amount_new_epoch += asset.amount; - } - println!("total_amount_new_epoch: {}", total_amount_new_epoch); - let mut total_amount_expired = Uint128::zero(); - //checking against total since total and available where the same, but available is empty now - for asset in expired_epoch_res.epoch.total { - total_amount_expired += asset.amount; - } - println!("total_amount_expired: {}", total_amount_expired); - assert!(total_amount_new_epoch - total_amount_expired > Uint128::zero()); +#[cfg(not(feature = "osmosis"))] +#[test] +fn decrease_grace_period_fee_distributor() { + let creator = mock_creator(); + let balances = vec![( + creator.clone().sender, + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), + coin(1_000_000_000, "ampWHALE"), + coin(1_000_000_000, "bWHALE"), + ], + )]; - let mut user_1_claims: Vec = vec![]; - // let mut user_2_claims: Vec = vec![]; - - // Get the balance of the sender before claiming - let uwhale_balance_before_claiming = app - .wrap() - .query_balance(creator.sender.clone(), "uwhale") - .unwrap() - .amount; - // claim some rewards - app.execute_contract( - creator.sender.clone(), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - - // Get balance after claiming - let uwhale_balance_after_claiming = app - .wrap() - .query_balance(creator.sender.clone(), "uwhale") - .unwrap() - .amount; - // // Verify amount - // assert_eq!( - // uwhale_balance_after_claiming - - // uwhale_balance_before_claiming, Uint128::new(100) - // ); - user_1_claims.push(uwhale_balance_after_claiming - uwhale_balance_before_claiming); - - // Time to unbond with user 1 - app.execute_contract( - creator.sender.clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Unbond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(500u128), - }, - }, - &[], - ) - .unwrap(); - - // NOTE: Here is where we could check weights if we wanted too - // Make sure the available tokens on the expiring epoch are transferred to the second one. - app.execute_contract( - creator.sender.clone(), - pair_tokens[0].clone(), - &pool_network::pair::ExecuteMsg::Swap { - offer_asset: Asset { - info: AssetInfo::NativeToken { - denom: "usdc".to_string(), - }, - amount: Uint128::new(2_050u128), - }, - belief_price: None, - max_spread: None, - to: None, - }, - &[Coin { - denom: "usdc".to_string(), - amount: Uint128::new(2_050u128), - }], - ) - .unwrap(); - - // Now we can advance time, create a third epoch and check that the fees collected are - // distributed to the users - // advance the time to one day after the second epoch was created - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(3357777600_000000000u64), - chain_id: "".to_string(), - }); - - // Create new epoch, which triggers fee collection, aggregation and distribution - // Create EPOCH 3 - - app.execute_contract( - creator.sender.clone(), - fee_distributor_address.clone(), - &NewEpoch {}, - &[], - ) - .unwrap(); - - // check that the third epoch was created - let new_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, - ) - .unwrap(); - - assert_eq!(new_epoch_res.epoch.id, Uint64::new(3u64)); - assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); - assert!(new_epoch_res.epoch.claimed.is_empty()); - - // check that the available assets for the expired epoch are zero/empty - let expired_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { - id: Uint64::from(2u64), - }, - ) - .unwrap(); - assert!(expired_epoch_res.epoch.available.is_empty()); - - // Advance time one more time - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(503666400_000000000u64), - chain_id: "".to_string(), - }); - - // We should have about triple the amount of fees collected in the third epoch - // compared to the first - // iterate the new_epoch_res.epoch.available and add up the amounts for each asset - let mut total_amount_new_epoch = Uint128::zero(); - - for asset in new_epoch_res.epoch.available { - total_amount_new_epoch += asset.amount; - } - let mut total_amount_expired = Uint128::zero(); - //checking against total since total and available where the same, but available is empty now - for asset in expired_epoch_res.epoch.total { - total_amount_expired += asset.amount; - } - // assert!(total_amount_new_epoch - total_amount_expired > Uint128::zero()); - - // // Query and verify what is due to user 1 - // let claimable: ClaimableEpochsResponse = app.wrap().query_wasm_smart(fee_distributor_address.clone(), &white_whale::fee_distributor::QueryMsg::Claimable { address: creator.sender.to_string() }).unwrap(); - // println!(" -> claimable: {:?}", claimable); - // claim some rewards - let uwhale_balance_before_claiming = app - .wrap() - .query_balance(Addr::unchecked("other"), "uwhale") - .unwrap() - .amount; - // Claim for user 2 - app.execute_contract( - Addr::unchecked("other"), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - - let uwhale_balance_after_claiming = app - .wrap() - .query_balance(Addr::unchecked("other"), "uwhale") - .unwrap() - .amount; - - let user_2_whale_received = uwhale_balance_after_claiming - uwhale_balance_before_claiming; - println!("-> User 2 whale_received: {}", user_2_whale_received); - - // Claim 2 - // claim some rewards - let uwhale_balance_before_claiming = app - .wrap() - .query_balance(creator.sender.clone(), "uwhale") - .unwrap() - .amount; - - app.execute_contract( - creator.sender.clone(), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - - let uwhale_balance_after_claiming = app - .wrap() - .query_balance(creator.sender.clone(), "uwhale") - .unwrap() - .amount; - - let user_1_whale_received = uwhale_balance_after_claiming - uwhale_balance_before_claiming; - println!("whale_received: {}", user_1_whale_received); - - // For these claims, the bonds and weights started the same - // No claims happened - // User 2 should have received more than user 1 as user 1 halfed their bond and thus their weight - // User 1 should not get an even share anymore considering all else stays the same - assert_eq!(user_2_whale_received, Uint128::new(133u128)); - assert_eq!(user_1_whale_received, Uint128::new(66u128)); - - assert_ne!(user_2_whale_received, user_1_whale_received); -} - -#[test] -fn create_epoch_unsuccessfully() { - let creator = mock_creator(); - let balances = vec![( - creator.clone().sender, - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), - coin(1_000_000_000, "ampWHALE"), - coin(1_000_000_000, "bWHALE"), - ], - )]; - - let mut app = mock_app_with_balance(balances); + let mut app = mock_app_with_balance(balances); let fee_collector_id = store_fee_collector_code(&mut app); let fee_distributor_id = store_fee_distributor_code(&mut app); @@ -5519,16 +5463,40 @@ fn create_epoch_unsuccessfully() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -5593,7 +5561,7 @@ fn create_epoch_unsuccessfully() { &white_whale::fee_distributor::InstantiateMsg { bonding_contract_addr: whale_lair_address.clone().to_string(), fee_collector_addr: fee_collector_address.clone().to_string(), - grace_period: Uint64::new(1), + grace_period: Uint64::new(2), epoch_config: EpochConfig { duration: Uint64::new(86_400_000_000_000u64), // a day genesis_epoch: Uint64::new(1678802400_000000000u64), // March 14, 2023 2:00:00 PM @@ -5790,9 +5758,10 @@ fn create_epoch_unsuccessfully() { ) .unwrap(); + // advance the time to one day after the first epoch was created app.set_block(BlockInfo { height: 123456789u64, - time: Timestamp::from_nanos(1678802400_000000000u64), + time: Timestamp::from_nanos(1678888800_000000000u64), chain_id: "".to_string(), }); @@ -5805,13 +5774,8 @@ fn create_epoch_unsuccessfully() { ) .unwrap(); - // advance some time, but not enough to create a new epoch - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(1678802500_000000000u64), //less than a day - chain_id: "".to_string(), - }); - + // When creating the second epoch, the first one will be expiring since the grace_period was set to 1/. + // Make sure the available tokens on the expiring epoch are transferred to the second one. app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -5833,29 +5797,82 @@ fn create_epoch_unsuccessfully() { ) .unwrap(); + // advance the time to one day after the first epoch was created + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1678888800_000000000u64), + chain_id: "".to_string(), + }); + + // Create new epoch, which triggers fee collection, aggregation and distribution + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &NewEpoch {}, + &[], + ) + .unwrap(); + + // try updating the grace_period on the config to 1, cannot be decreased let err = app .execute_contract( creator.sender.clone(), fee_distributor_address.clone(), - &NewEpoch {}, + &white_whale::fee_distributor::ExecuteMsg::UpdateConfig { + owner: None, + bonding_contract_addr: None, + fee_collector_addr: None, + grace_period: Some(Uint64::one()), + distribution_asset: None, + epoch_config: None, + }, &[], ) .unwrap_err(); assert_eq!( err.downcast::().unwrap(), - fee_distributor::ContractError::CurrentEpochNotExpired {} + fee_distributor::ContractError::GracePeriodDecrease {} ); } +#[cfg(not(feature = "osmosis"))] #[test] -fn aggregate_fees_unsuccessfully() { +fn users_cannot_claim_rewards_from_past_epochs() { let creator = mock_creator(); + let balances = vec![ + ( + creator.clone().sender, + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), + coin(1_000_000_000, "ampWHALE"), + coin(1_000_000_000, "bWHALE"), + ], + ), + ( + Addr::unchecked("other"), + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), + coin(1_000_000_000, "ampWHALE"), + coin(1_000_000_000, "bWHALE"), + ], + ), + ]; - let mut app = mock_app(); + let mut app = mock_app_with_balance(balances); let fee_collector_id = store_fee_collector_code(&mut app); let fee_distributor_id = store_fee_distributor_code(&mut app); + let whale_lair_id = store_whale_lair_code(&mut app); + let pool_factory_id = store_pool_factory_code(&mut app); + let pool_router_id = store_pool_router_code(&mut app); + let pair_id = store_pair_code(&mut app); + let trio_id = store_trio_code(&mut app); + let token_id = store_token_code(&mut app); + let vault_factory_id = store_vault_factory_code(&mut app); + let vault_id = store_vault_code(&mut app); let fee_collector_address = app .instantiate_contract( @@ -5868,147 +5885,40 @@ fn aggregate_fees_unsuccessfully() { ) .unwrap(); - let fee_distributor_address = app - .instantiate_contract( - fee_distributor_id, - creator.clone().sender, - &white_whale::fee_distributor::InstantiateMsg { - bonding_contract_addr: "whale_lair".to_string(), - fee_collector_addr: fee_collector_address.to_string(), - grace_period: Uint64::new(5), - epoch_config: EpochConfig { - duration: Uint64::new(86400000000000), - genesis_epoch: Default::default(), - }, - distribution_asset: AssetInfo::NativeToken { - denom: "uwhale".to_string(), - }, - }, - &[], - "fee_distributor", - None, - ) - .unwrap(); - - // update the fee_distributor_address on fee collector - app.execute_contract( - creator.sender.clone(), - fee_collector_address.clone(), - &UpdateConfig { - owner: None, - pool_router: None, - fee_distributor: Some(fee_distributor_address.to_string()), - pool_factory: None, - vault_factory: None, - }, - &[], - ) - .unwrap(); - - let err = app - .execute_contract( - Addr::unchecked("anyone"), - fee_collector_address.clone(), - &AggregateFees { - aggregate_fees_for: FeesFor::Contracts { contracts: vec![] }, - }, - &[], - ) - .unwrap_err(); - - assert_eq!( - err.downcast::().unwrap(), - ContractError::InvalidContractsFeeAggregation {} - ); -} - -#[test] -fn forward_fees_unsuccessfully() { - let creator = mock_creator(); - - let mut app = mock_app(); - - let fee_collector_id = store_fee_collector_code(&mut app); - - let fee_collector_address = app + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app .instantiate_contract( fee_collector_id, creator.clone().sender, &InstantiateMsg {}, &[], - "fee_collector", + "osmosis_fee_collector", None, ) .unwrap(); - // try to forward fees from an unauthorized address - let err = app - .execute_contract( - Addr::unchecked("unauthorized"), - fee_collector_address.clone(), - &ForwardFees { - epoch: Default::default(), - forward_fees_as: AssetInfo::NativeToken { - denom: "uwhale".to_string(), - }, - }, - &[], - ) - .unwrap_err(); - - assert_eq!( - err.downcast::().unwrap(), - ContractError::Unauthorized {} - ); -} - -#[test] -fn decrease_grace_period_fee_distributor() { - let creator = mock_creator(); - let balances = vec![( - creator.clone().sender, - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), - coin(1_000_000_000, "ampWHALE"), - coin(1_000_000_000, "bWHALE"), - ], - )]; - - let mut app = mock_app_with_balance(balances); - - let fee_collector_id = store_fee_collector_code(&mut app); - let fee_distributor_id = store_fee_distributor_code(&mut app); - let whale_lair_id = store_whale_lair_code(&mut app); - let pool_factory_id = store_pool_factory_code(&mut app); - let pool_router_id = store_pool_router_code(&mut app); - let pair_id = store_pair_code(&mut app); - let trio_id = store_trio_code(&mut app); - let token_id = store_token_code(&mut app); - let vault_factory_id = store_vault_factory_code(&mut app); - let vault_id = store_vault_code(&mut app); + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; - let fee_collector_address = app - .instantiate_contract( - fee_collector_id, - creator.clone().sender, - &InstantiateMsg {}, - &[], - "fee_collector", - None, - ) - .unwrap(); + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -6073,7 +5983,7 @@ fn decrease_grace_period_fee_distributor() { &white_whale::fee_distributor::InstantiateMsg { bonding_contract_addr: whale_lair_address.clone().to_string(), fee_collector_addr: fee_collector_address.clone().to_string(), - grace_period: Uint64::new(2), + grace_period: Uint64::new(3u64), epoch_config: EpochConfig { duration: Uint64::new(86_400_000_000_000u64), // a day genesis_epoch: Uint64::new(1678802400_000000000u64), // March 14, 2023 2:00:00 PM @@ -6088,6 +5998,19 @@ fn decrease_grace_period_fee_distributor() { ) .unwrap(); + // add the fee distributor address to the whale lair contract so we can use it as a clock + app.execute_contract( + creator.sender.clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::UpdateConfig { + fee_distributor_addr: Some(fee_distributor_address.to_string()), + owner: None, + unbonding_period: None, + growth_rate: None, + }, + &[], + ) + .unwrap(); // add pool router address to the fee collector to be able to aggregate fees app.execute_contract( creator.sender.clone(), @@ -6246,6 +6169,25 @@ fn decrease_grace_period_fee_distributor() { .unwrap(); } + // bond some tokens + app.execute_contract( + creator.sender.clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "bWHALE".to_string(), + }, + amount: Uint128::new(300_000_000u128), + }, + }, + &[Coin { + denom: "bWHALE".to_string(), + amount: Uint128::new(300_000_000u128), + }], + ) + .unwrap(); + // add epochs to the fee distributor. // whale -> native @@ -6286,8 +6228,22 @@ fn decrease_grace_period_fee_distributor() { ) .unwrap(); - // When creating the second epoch, the first one will be expiring since the grace_period was set to 1/. - // Make sure the available tokens on the expiring epoch are transferred to the second one. + // check that a new epoch was created + let expiring_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, + ) + .unwrap(); + assert_eq!(expiring_epoch_res.epoch.id, Uint64::one()); + assert_eq!( + expiring_epoch_res.epoch.available, + expiring_epoch_res.epoch.total + ); + assert!(expiring_epoch_res.epoch.claimed.is_empty()); + + // Create second epoch app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -6325,38 +6281,138 @@ fn decrease_grace_period_fee_distributor() { ) .unwrap(); - // try updating the grace_period on the config to 1, cannot be decreased - let err = app - .execute_contract( - creator.sender.clone(), + // check that the second epoch was created + let new_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::UpdateConfig { - owner: None, - bonding_contract_addr: None, - fee_collector_addr: None, - grace_period: Some(Uint64::one()), - distribution_asset: None, - epoch_config: None, - }, - &[], + &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, ) - .unwrap_err(); + .unwrap(); - assert_eq!( - err.downcast::().unwrap(), - fee_distributor::ContractError::GracePeriodDecrease {} - ); -} + assert_eq!(new_epoch_res.epoch.id, Uint64::new(2u64)); + assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); + assert!(new_epoch_res.epoch.claimed.is_empty()); -#[test] -fn users_cannot_claim_rewards_from_past_epochs() { - let creator = mock_creator(); - let balances = vec![ - ( - creator.clone().sender, - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), + // bond with the other account at epoch 2. He shouldn't have anything claimable + app.execute_contract( + Addr::unchecked("other").clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(100_000_000u128), + }], + ) + .unwrap(); + + // make sure the other account cannot claim anything for epoch 1 + let claimable_epochs_res: ClaimableEpochsResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Claimable { + address: "other".to_string(), + }, + ) + .unwrap(); + assert_eq!(claimable_epochs_res.epochs.len(), 0); + + // Create second epoch + app.execute_contract( + creator.sender.clone(), + pair_tokens[0].clone(), + &pool_network::pair::ExecuteMsg::Swap { + offer_asset: Asset { + info: AssetInfo::NativeToken { + denom: "usdc".to_string(), + }, + amount: Uint128::new(200_000u128), + }, + belief_price: None, + max_spread: Some(Decimal::percent(40u64)), + to: None, + }, + &[Coin { + denom: "usdc".to_string(), + amount: Uint128::new(200_000u128), + }], + ) + .unwrap(); + + // advance the time to one day after the first epoch was created + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1678978800_000000000u64), + chain_id: "".to_string(), + }); + + // Create new epoch + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &NewEpoch {}, + &[], + ) + .unwrap(); + + // check that the second epoch was created + let new_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, + ) + .unwrap(); + + assert_eq!(new_epoch_res.epoch.id, Uint64::new(3u64)); + assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); + assert!(new_epoch_res.epoch.claimed.is_empty()); + + let claimable_epochs_res: ClaimableEpochsResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Claimable { + address: "other".to_string(), + }, + ) + .unwrap(); + + assert_eq!(claimable_epochs_res.epochs.len(), 1); + // only epoch 3 should be claimable to the other account + assert_eq!(claimable_epochs_res.epochs[0].id, Uint64::new(3u64)); + + let claimable_epochs_res: ClaimableEpochsResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Claimable { + address: creator.sender.clone().to_string(), + }, + ) + .unwrap(); + // creator bonded before the genesis epoch was created, it means he has right to claim from epoch 1 + assert_eq!(claimable_epochs_res.epochs.len(), 3); +} + +#[cfg(not(feature = "osmosis"))] +#[test] +fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { + let creator = mock_creator(); + let balances = vec![ + ( + creator.clone().sender, + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), coin(1_000_000_000, "ampWHALE"), coin(1_000_000_000, "bWHALE"), ], @@ -6396,16 +6452,40 @@ fn users_cannot_claim_rewards_from_past_epochs() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -6656,7 +6736,7 @@ fn users_cannot_claim_rewards_from_past_epochs() { .unwrap(); } - // bond some tokens + // bond some tokens with both users app.execute_contract( creator.sender.clone(), whale_lair_address.clone(), @@ -6675,6 +6755,24 @@ fn users_cannot_claim_rewards_from_past_epochs() { ) .unwrap(); + app.execute_contract( + Addr::unchecked("other").clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(100_000_000u128), + }], + ) + .unwrap(); + // add epochs to the fee distributor. // whale -> native @@ -6781,27 +6879,78 @@ fn users_cannot_claim_rewards_from_past_epochs() { assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); assert!(new_epoch_res.epoch.claimed.is_empty()); - // bond with the other account at epoch 2. He shouldn't have anything claimable - app.execute_contract( - Addr::unchecked("other").clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(100_000_000u128), + // check what's claimable for both users + let claimable_epochs_res: ClaimableEpochsResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Claimable { + address: "creator".to_string(), }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(100_000_000u128), - }], + ) + .unwrap(); + // should be able to claim 2 epochs + assert_eq!(claimable_epochs_res.epochs.len(), 2); + + let claimable_epochs_res: ClaimableEpochsResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Claimable { + address: "other".to_string(), + }, + ) + .unwrap(); + // should be able to claim 2 epochs + assert_eq!(claimable_epochs_res.epochs.len(), 2); + + // claim with creator + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], ) .unwrap(); - // make sure the other account cannot claim anything for epoch 1 let claimable_epochs_res: ClaimableEpochsResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Claimable { + address: "creator".to_string(), + }, + ) + .unwrap(); + // shouldn't be able to claim any more epochs + assert!(claimable_epochs_res.epochs.is_empty()); + + //query the epochs to check that something has been claimed + let epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { + id: Uint64::new(2u64), + }, + ) + .unwrap(); + assert_eq!(epoch_res.epoch.id, Uint64::new(2u64)); + assert_eq!(epoch_res.epoch.claimed.len(), 1usize); + + let epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { + id: Uint64::new(1u64), + }, + ) + .unwrap(); + assert_eq!(epoch_res.epoch.id, Uint64::new(1u64)); + assert_eq!(epoch_res.epoch.claimed.len(), 1usize); + + let _claimable_epochs_res: ClaimableEpochsResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), @@ -6810,9 +6959,24 @@ fn users_cannot_claim_rewards_from_past_epochs() { }, ) .unwrap(); - assert_eq!(claimable_epochs_res.epochs.len(), 0); - // Create second epoch + // let's unbond everything with creator" + app.execute_contract( + creator.sender.clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Unbond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "bWHALE".to_string(), + }, + amount: Uint128::new(300_000_000u128), + }, + }, + &[], + ) + .unwrap(); + + // advance the time app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -6834,14 +6998,13 @@ fn users_cannot_claim_rewards_from_past_epochs() { ) .unwrap(); - // advance the time to one day after the first epoch was created app.set_block(BlockInfo { height: 123456789u64, time: Timestamp::from_nanos(1678978800_000000000u64), chain_id: "".to_string(), }); - // Create new epoch + // Create new epoch, which triggers fee collection, aggregation and distribution app.execute_contract( creator.sender.clone(), fee_distributor_address.clone(), @@ -6863,7 +7026,7 @@ fn users_cannot_claim_rewards_from_past_epochs() { assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); assert!(new_epoch_res.epoch.claimed.is_empty()); - let claimable_epochs_res: ClaimableEpochsResponse = app + let _claimable_epochs_res: ClaimableEpochsResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), @@ -6872,26 +7035,36 @@ fn users_cannot_claim_rewards_from_past_epochs() { }, ) .unwrap(); + // try to claim now with other + app.execute_contract( + Addr::unchecked("other"), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], + ) + .unwrap(); - assert_eq!(claimable_epochs_res.epochs.len(), 1); - // only epoch 3 should be claimable to the other account - assert_eq!(claimable_epochs_res.epochs[0].id, Uint64::new(3u64)); - - let claimable_epochs_res: ClaimableEpochsResponse = app + let _claimable_epochs_res: ClaimableEpochsResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), &white_whale::fee_distributor::QueryMsg::Claimable { - address: creator.sender.clone().to_string(), + address: "creator".to_string(), }, ) .unwrap(); - // creator bonded before the genesis epoch was created, it means he has right to claim from epoch 1 - assert_eq!(claimable_epochs_res.epochs.len(), 3); + app.execute_contract( + Addr::unchecked("creator"), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], + ) + .unwrap(); } +#[cfg(not(feature = "osmosis"))] #[test] -fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { +fn user_weight_accounts_for_unbondings() { let creator = mock_creator(); let balances = vec![ ( @@ -6938,16 +7111,40 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -7198,6 +7395,8 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { .unwrap(); } + // creator has 75% while other 25% + // bond some tokens with both users app.execute_contract( creator.sender.clone(), @@ -7207,12 +7406,30 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { info: AssetInfo::NativeToken { denom: "bWHALE".to_string(), }, - amount: Uint128::new(300_000_000u128), + amount: Uint128::new(100_000_000u128), }, }, &[Coin { denom: "bWHALE".to_string(), - amount: Uint128::new(300_000_000u128), + amount: Uint128::new(100_000_000u128), + }], + ) + .unwrap(); + + app.execute_contract( + creator.sender.clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(200_000_000u128), + }, + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(200_000_000u128), }], ) .unwrap(); @@ -7422,23 +7639,23 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { ) .unwrap(); - // let's unbond everything with creator" + // let's unbond just ampWHALE with creator, so it has bWHALE left. That would leave creator and other with 50% of the rewards each app.execute_contract( creator.sender.clone(), whale_lair_address.clone(), &white_whale::whale_lair::ExecuteMsg::Unbond { asset: Asset { info: AssetInfo::NativeToken { - denom: "bWHALE".to_string(), + denom: "ampWHALE".to_string(), }, - amount: Uint128::new(300_000_000u128), + amount: Uint128::new(200_000_000u128), }, }, &[], ) .unwrap(); - // advance the time + // prepare to create a new epoch app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -7460,6 +7677,7 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { ) .unwrap(); + // advance the time app.set_block(BlockInfo { height: 123456789u64, time: Timestamp::from_nanos(1678978800_000000000u64), @@ -7483,12 +7701,11 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, ) .unwrap(); - assert_eq!(new_epoch_res.epoch.id, Uint64::new(3u64)); assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); assert!(new_epoch_res.epoch.claimed.is_empty()); - let _claimable_epochs_res: ClaimableEpochsResponse = app + let claimable_epochs_res: ClaimableEpochsResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), @@ -7497,16 +7714,9 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { }, ) .unwrap(); - // try to claim now with other - app.execute_contract( - Addr::unchecked("other"), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); + assert_eq!(claimable_epochs_res.epochs.len(), 3usize); - let _claimable_epochs_res: ClaimableEpochsResponse = app + let claimable_epochs_res: ClaimableEpochsResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), @@ -7515,6 +7725,8 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { }, ) .unwrap(); + assert_eq!(claimable_epochs_res.epochs.len(), 1usize); + app.execute_contract( Addr::unchecked("creator"), fee_distributor_address.clone(), @@ -7522,103 +7734,310 @@ fn user_can_claim_even_when_his_weight_increases_for_past_epochs() { &[], ) .unwrap(); -} - -#[test] -fn user_weight_accounts_for_unbondings() { - let creator = mock_creator(); - let balances = vec![ - ( - creator.clone().sender, - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), - coin(1_000_000_000, "ampWHALE"), - coin(1_000_000_000, "bWHALE"), - ], - ), - ( - Addr::unchecked("other"), - vec![ - coin(1_000_000_000, "usdc"), - coin(1_000_000_000, "uwhale"), - coin(1_000_000_000, "ampWHALE"), - coin(1_000_000_000, "bWHALE"), - ], - ), - ]; - - let mut app = mock_app_with_balance(balances); - - let fee_collector_id = store_fee_collector_code(&mut app); - let fee_distributor_id = store_fee_distributor_code(&mut app); - let whale_lair_id = store_whale_lair_code(&mut app); - let pool_factory_id = store_pool_factory_code(&mut app); - let pool_router_id = store_pool_router_code(&mut app); - let pair_id = store_pair_code(&mut app); - let trio_id = store_trio_code(&mut app); - let token_id = store_token_code(&mut app); - let vault_factory_id = store_vault_factory_code(&mut app); - let vault_id = store_vault_code(&mut app); - let fee_collector_address = app - .instantiate_contract( - fee_collector_id, - creator.clone().sender, - &InstantiateMsg {}, - &[], - "fee_collector", - None, + let epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { + id: Uint64::new(3u64), + }, ) .unwrap(); + assert_eq!(epoch_res.epoch.id, Uint64::new(3u64)); + // creator claimed 50% of the rewards + assert_eq!( + epoch_res.epoch.available, + vec![Asset { + info: NativeToken { + denom: "uwhale".to_string() + }, + amount: Uint128::new(1324u128) + }] + ); + assert_eq!( + epoch_res.epoch.claimed, + vec![Asset { + info: NativeToken { + denom: "uwhale".to_string() + }, + amount: Uint128::new(1323u128) + }] + ); - let pool_factory_address = app - .instantiate_contract( - pool_factory_id, - creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), + //let's claim the rewards for other + app.execute_contract( + Addr::unchecked("other"), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], + ) + .unwrap(); + + let epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { + id: Uint64::new(3u64), }, - &[], - "fee_collector", - None, ) .unwrap(); + assert_eq!(epoch_res.epoch.id, Uint64::new(3u64)); - let pool_router_address = app - .instantiate_contract( - pool_router_id, - creator.clone().sender, - &pool_network::router::InstantiateMsg { - terraswap_factory: pool_factory_address.to_string(), + assert_eq!( + epoch_res.epoch.available, + vec![Asset { + info: NativeToken { + denom: "uwhale".to_string() }, - &[], - "pool_router", - None, - ) - .unwrap(); + amount: Uint128::one() + }] + ); + assert_eq!( + epoch_res.epoch.claimed, + vec![Asset { + info: NativeToken { + denom: "uwhale".to_string() + }, + amount: Uint128::new(2646u128) + }] + ); + assert!( + (epoch_res.epoch.claimed.first().unwrap().amount.u128() as i128 + - epoch_res.epoch.total.first().unwrap().amount.u128() as i128) + .abs() + < 2i128 + ); - let vault_factory_address = app - .instantiate_contract( - vault_factory_id, - creator.clone().sender, - &vault_network::vault_factory::InstantiateMsg { - owner: creator.clone().sender.to_string(), - vault_id, - token_id, - fee_collector_addr: fee_collector_address.to_string(), + //now unbond partially, check if weight is computed correctly + app.execute_contract( + creator.sender.clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Unbond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "bWHALE".to_string(), + }, + amount: Uint128::new(50_000_000u128), }, - &[], - "pool_router", - None, - ) - .unwrap(); + }, + &[], + ) + .unwrap(); - let whale_lair_address = app - .instantiate_contract( + // cretor -> 50bwhale -> 33% + // other -> 100bwhale -> 66% + + // prepare to create a new epoch + app.execute_contract( + creator.sender.clone(), + pair_tokens[0].clone(), + &pool_network::pair::ExecuteMsg::Swap { + offer_asset: Asset { + info: AssetInfo::NativeToken { + denom: "usdc".to_string(), + }, + amount: Uint128::new(200_000u128), + }, + belief_price: None, + max_spread: Some(Decimal::percent(40u64)), + to: None, + }, + &[Coin { + denom: "usdc".to_string(), + amount: Uint128::new(200_000u128), + }], + ) + .unwrap(); + + // advance the time + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1679065200_000000000u64), + chain_id: "".to_string(), + }); + + // Create new epoch, which triggers fee collection, aggregation and distribution + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &NewEpoch {}, + &[], + ) + .unwrap(); + + // check that the second epoch was created + let new_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, + ) + .unwrap(); + assert_eq!(new_epoch_res.epoch.id, Uint64::new(4u64)); + assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); + assert!(new_epoch_res.epoch.claimed.is_empty()); + + // now the creator has 33% of the total weight, and other has 66% + app.execute_contract( + Addr::unchecked("creator"), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], + ) + .unwrap(); + + let epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { + id: Uint64::new(4u64), + }, + ) + .unwrap(); + assert_eq!(epoch_res.epoch.id, Uint64::new(4u64)); + // creator claimed 33 % of the rewards + assert_eq!( + epoch_res.epoch.available, + vec![Asset { + info: NativeToken { + denom: "uwhale".to_string() + }, + amount: Uint128::new(1242u128) + }] + ); + assert_eq!( + epoch_res.epoch.claimed, + vec![Asset { + info: NativeToken { + denom: "uwhale".to_string() + }, + amount: Uint128::new(620u128) + }] + ); +} + +#[cfg(not(feature = "osmosis"))] +#[test] +fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { + let creator = mock_creator(); + let balances = vec![ + ( + creator.clone().sender, + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), + coin(1_000_000_000, "ampWHALE"), + coin(1_000_000_000, "bWHALE"), + ], + ), + ( + Addr::unchecked("other"), + vec![ + coin(1_000_000_000, "usdc"), + coin(1_000_000_000, "uwhale"), + coin(1_000_000_000, "ampWHALE"), + coin(1_000_000_000, "bWHALE"), + ], + ), + ]; + + let mut app = mock_app_with_balance(balances); + + let fee_collector_id = store_fee_collector_code(&mut app); + let fee_distributor_id = store_fee_distributor_code(&mut app); + let whale_lair_id = store_whale_lair_code(&mut app); + let pool_factory_id = store_pool_factory_code(&mut app); + let pool_router_id = store_pool_router_code(&mut app); + let pair_id = store_pair_code(&mut app); + let trio_id = store_trio_code(&mut app); + let token_id = store_token_code(&mut app); + let vault_factory_id = store_vault_factory_code(&mut app); + let vault_id = store_vault_code(&mut app); + + let fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "fee_collector", + None, + ) + .unwrap(); + + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + + let pool_factory_address = app + .instantiate_contract( + pool_factory_id, + creator.clone().sender, + &instantiate_msg, + &[], + "fee_collector", + None, + ) + .unwrap(); + let pool_router_address = app + .instantiate_contract( + pool_router_id, + creator.clone().sender, + &pool_network::router::InstantiateMsg { + terraswap_factory: pool_factory_address.to_string(), + }, + &[], + "pool_router", + None, + ) + .unwrap(); + + let vault_factory_address = app + .instantiate_contract( + vault_factory_id, + creator.clone().sender, + &vault_network::vault_factory::InstantiateMsg { + owner: creator.clone().sender.to_string(), + vault_id, + token_id, + fee_collector_addr: fee_collector_address.to_string(), + }, + &[], + "pool_router", + None, + ) + .unwrap(); + + let whale_lair_address = app + .instantiate_contract( whale_lair_id, creator.clone().sender, &white_whale::whale_lair::InstantiateMsg { @@ -7814,285 +8233,53 @@ fn user_weight_accounts_for_unbondings() { }, amount: Uint128::new(500_000u128), }, - ], - slippage_tolerance: None, - receiver: None, - }, - &[ - Coin { - denom: "uwhale".to_string(), - amount: Uint128::new(500_000u128), - }, - Coin { - denom: native_token.clone().to_string(), - amount: Uint128::new(500_000u128), - }, - ], - ) - .unwrap(); - } - - // creator has 75% while other 25% - - // bond some tokens with both users - app.execute_contract( - creator.sender.clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "bWHALE".to_string(), - }, - amount: Uint128::new(100_000_000u128), - }, - }, - &[Coin { - denom: "bWHALE".to_string(), - amount: Uint128::new(100_000_000u128), - }], - ) - .unwrap(); - - app.execute_contract( - creator.sender.clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(200_000_000u128), - }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(200_000_000u128), - }], - ) - .unwrap(); - - app.execute_contract( - Addr::unchecked("other").clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(100_000_000u128), - }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(100_000_000u128), - }], - ) - .unwrap(); - - // add epochs to the fee distributor. - - // whale -> native - app.execute_contract( - creator.sender.clone(), - pair_tokens[0].clone(), - &pool_network::pair::ExecuteMsg::Swap { - offer_asset: Asset { - info: AssetInfo::NativeToken { - denom: "usdc".to_string(), - }, - amount: Uint128::new(200_000u128), - }, - belief_price: None, - max_spread: Some(Decimal::percent(40u64)), - to: None, - }, - &[Coin { - denom: "usdc".to_string(), - amount: Uint128::new(200_000u128), - }], - ) - .unwrap(); - - // advance the time to one day after the first epoch was created - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(1678888800_000000000u64), - chain_id: "".to_string(), - }); - - // Create new epoch, which triggers fee collection, aggregation and distribution - app.execute_contract( - creator.sender.clone(), - fee_distributor_address.clone(), - &NewEpoch {}, - &[], - ) - .unwrap(); - - // check that a new epoch was created - let expiring_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, - ) - .unwrap(); - assert_eq!(expiring_epoch_res.epoch.id, Uint64::one()); - assert_eq!( - expiring_epoch_res.epoch.available, - expiring_epoch_res.epoch.total - ); - assert!(expiring_epoch_res.epoch.claimed.is_empty()); - - // Create second epoch - app.execute_contract( - creator.sender.clone(), - pair_tokens[0].clone(), - &pool_network::pair::ExecuteMsg::Swap { - offer_asset: Asset { - info: AssetInfo::NativeToken { - denom: "usdc".to_string(), - }, - amount: Uint128::new(200_000u128), - }, - belief_price: None, - max_spread: Some(Decimal::percent(40u64)), - to: None, - }, - &[Coin { - denom: "usdc".to_string(), - amount: Uint128::new(200_000u128), - }], - ) - .unwrap(); - - // advance the time to one day after the first epoch was created - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(1678888800_000000000u64), - chain_id: "".to_string(), - }); - - // Create new epoch, which triggers fee collection, aggregation and distribution - app.execute_contract( - creator.sender.clone(), - fee_distributor_address.clone(), - &NewEpoch {}, - &[], - ) - .unwrap(); - - // check that the second epoch was created - let new_epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, - ) - .unwrap(); - - assert_eq!(new_epoch_res.epoch.id, Uint64::new(2u64)); - assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); - assert!(new_epoch_res.epoch.claimed.is_empty()); - - // check what's claimable for both users - let claimable_epochs_res: ClaimableEpochsResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Claimable { - address: "creator".to_string(), - }, - ) - .unwrap(); - // should be able to claim 2 epochs - assert_eq!(claimable_epochs_res.epochs.len(), 2); - - let claimable_epochs_res: ClaimableEpochsResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Claimable { - address: "other".to_string(), - }, - ) - .unwrap(); - // should be able to claim 2 epochs - assert_eq!(claimable_epochs_res.epochs.len(), 2); - - // claim with creator - app.execute_contract( - creator.sender.clone(), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - - let claimable_epochs_res: ClaimableEpochsResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Claimable { - address: "creator".to_string(), - }, - ) - .unwrap(); - // shouldn't be able to claim any more epochs - assert!(claimable_epochs_res.epochs.is_empty()); - - //query the epochs to check that something has been claimed - let epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { - id: Uint64::new(2u64), - }, - ) - .unwrap(); - assert_eq!(epoch_res.epoch.id, Uint64::new(2u64)); - assert_eq!(epoch_res.epoch.claimed.len(), 1usize); - - let epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { - id: Uint64::new(1u64), - }, - ) - .unwrap(); - assert_eq!(epoch_res.epoch.id, Uint64::new(1u64)); - assert_eq!(epoch_res.epoch.claimed.len(), 1usize); - - let _claimable_epochs_res: ClaimableEpochsResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Claimable { - address: "other".to_string(), + ], + slippage_tolerance: None, + receiver: None, }, + &[ + Coin { + denom: "uwhale".to_string(), + amount: Uint128::new(500_000u128), + }, + Coin { + denom: native_token.clone().to_string(), + amount: Uint128::new(500_000u128), + }, + ], ) .unwrap(); + } - // let's unbond just ampWHALE with creator, so it has bWHALE left. That would leave creator and other with 50% of the rewards each + // // "enable" bonding on 10 March 2023 15:00:00 + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1678460400_000000000u64), + chain_id: "".to_string(), + }); + + // bond some tokens app.execute_contract( creator.sender.clone(), whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Unbond { + &white_whale::whale_lair::ExecuteMsg::Bond { asset: Asset { info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), + denom: "bWHALE".to_string(), }, - amount: Uint128::new(200_000_000u128), + amount: Uint128::new(300_000_000u128), }, }, - &[], + &[Coin { + denom: "bWHALE".to_string(), + amount: Uint128::new(300_000_000u128), + }], ) .unwrap(); - // prepare to create a new epoch + // add epochs to the fee distributor. + + // whale -> native app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -8114,10 +8301,10 @@ fn user_weight_accounts_for_unbondings() { ) .unwrap(); - // advance the time + // advance the time until the point when the first epoch was created app.set_block(BlockInfo { height: 123456789u64, - time: Timestamp::from_nanos(1678978800_000000000u64), + time: Timestamp::from_nanos(1678888800_000000000u64), chain_id: "".to_string(), }); @@ -8130,143 +8317,28 @@ fn user_weight_accounts_for_unbondings() { ) .unwrap(); - // check that the second epoch was created - let new_epoch_res: EpochResponse = app + // check that a new epoch was created + let expiring_epoch_res: EpochResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, ) .unwrap(); - assert_eq!(new_epoch_res.epoch.id, Uint64::new(3u64)); - assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); - assert!(new_epoch_res.epoch.claimed.is_empty()); - - let claimable_epochs_res: ClaimableEpochsResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Claimable { - address: "other".to_string(), - }, - ) - .unwrap(); - assert_eq!(claimable_epochs_res.epochs.len(), 3usize); - - let claimable_epochs_res: ClaimableEpochsResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Claimable { - address: "creator".to_string(), - }, - ) - .unwrap(); - assert_eq!(claimable_epochs_res.epochs.len(), 1usize); - - app.execute_contract( - Addr::unchecked("creator"), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - let epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { - id: Uint64::new(3u64), - }, - ) - .unwrap(); - assert_eq!(epoch_res.epoch.id, Uint64::new(3u64)); - // creator claimed 50% of the rewards - assert_eq!( - epoch_res.epoch.available, - vec![Asset { - info: NativeToken { - denom: "uwhale".to_string() - }, - amount: Uint128::new(1324u128) - }] - ); - assert_eq!( - epoch_res.epoch.claimed, - vec![Asset { - info: NativeToken { - denom: "uwhale".to_string() - }, - amount: Uint128::new(1323u128) - }] + println!( + "new epoch with good global_index:: {:?}", + expiring_epoch_res.epoch ); - //let's claim the rewards for other - app.execute_contract( - Addr::unchecked("other"), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - - let epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { - id: Uint64::new(3u64), - }, - ) - .unwrap(); - assert_eq!(epoch_res.epoch.id, Uint64::new(3u64)); - - assert_eq!( - epoch_res.epoch.available, - vec![Asset { - info: NativeToken { - denom: "uwhale".to_string() - }, - amount: Uint128::one() - }] - ); + assert_eq!(expiring_epoch_res.epoch.id, Uint64::one()); assert_eq!( - epoch_res.epoch.claimed, - vec![Asset { - info: NativeToken { - denom: "uwhale".to_string() - }, - amount: Uint128::new(2646u128) - }] - ); - assert!( - (epoch_res.epoch.claimed.first().unwrap().amount.u128() as i128 - - epoch_res.epoch.total.first().unwrap().amount.u128() as i128) - .abs() - < 2i128 + expiring_epoch_res.epoch.available, + expiring_epoch_res.epoch.total ); + assert!(expiring_epoch_res.epoch.claimed.is_empty()); - //now unbond partially, check if weight is computed correctly - app.execute_contract( - creator.sender.clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Unbond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "bWHALE".to_string(), - }, - amount: Uint128::new(50_000_000u128), - }, - }, - &[], - ) - .unwrap(); - - // cretor -> 50bwhale -> 33% - // other -> 100bwhale -> 66% - - // prepare to create a new epoch + // Create second epoch app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -8288,13 +8360,39 @@ fn user_weight_accounts_for_unbondings() { ) .unwrap(); - // advance the time + // advance just a bit more after the new epoch can be created app.set_block(BlockInfo { height: 123456789u64, - time: Timestamp::from_nanos(1679065200_000000000u64), + time: Timestamp::from_nanos(1678888900_000000000u64), chain_id: "".to_string(), }); + // bond right after the next epoch start_time passed, but before the new epoch was created. + // should error because of the restriction we added on bonding/unbonding + let err = app + .execute_contract( + Addr::unchecked("other").clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(100_000_000u128), + }, + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(100_000_000u128), + }], + ) + .unwrap_err(); + + assert_eq!( + err.downcast::().unwrap(), + whale_lair::ContractError::NewEpochNotCreatedYet {} + ); + // Create new epoch, which triggers fee collection, aggregation and distribution app.execute_contract( creator.sender.clone(), @@ -8312,52 +8410,39 @@ fn user_weight_accounts_for_unbondings() { &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, ) .unwrap(); - assert_eq!(new_epoch_res.epoch.id, Uint64::new(4u64)); + + println!( + "new epoch with broken global_index:: {:?}", + new_epoch_res.epoch + ); + + assert_eq!(new_epoch_res.epoch.id, Uint64::new(2u64)); assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); assert!(new_epoch_res.epoch.claimed.is_empty()); - // now the creator has 33% of the total weight, and other has 66% + // bond now with other app.execute_contract( - Addr::unchecked("creator"), - fee_distributor_address.clone(), - &white_whale::fee_distributor::ExecuteMsg::Claim {}, - &[], - ) - .unwrap(); - - let epoch_res: EpochResponse = app - .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::Epoch { - id: Uint64::new(4u64), - }, - ) - .unwrap(); - assert_eq!(epoch_res.epoch.id, Uint64::new(4u64)); - // creator claimed 33 % of the rewards - assert_eq!( - epoch_res.epoch.available, - vec![Asset { - info: NativeToken { - denom: "uwhale".to_string() - }, - amount: Uint128::new(1242u128) - }] - ); - assert_eq!( - epoch_res.epoch.claimed, - vec![Asset { - info: NativeToken { - denom: "uwhale".to_string() + Addr::unchecked("other").clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(100_000_000u128), }, - amount: Uint128::new(620u128) - }] - ); + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(100_000_000u128), + }], + ) + .unwrap(); } +#[cfg(not(feature = "osmosis"))] #[test] -fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { +fn collect_distribute_with_unbonders() { let creator = mock_creator(); let balances = vec![ ( @@ -8404,16 +8489,40 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { ) .unwrap(); + #[cfg(feature = "osmosis")] + let osmosis_fee_collector_address = app + .instantiate_contract( + fee_collector_id, + creator.clone().sender, + &InstantiateMsg {}, + &[], + "osmosis_fee_collector", + None, + ) + .unwrap(); + + #[cfg(not(feature = "osmosis"))] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + }; + + #[cfg(feature = "osmosis")] + let instantiate_msg = pool_network::factory::InstantiateMsg { + pair_code_id: pair_id, + trio_code_id: trio_id, + token_code_id: token_id, + fee_collector_addr: fee_collector_address.to_string(), + osmosis_fee_collector_addr: osmosis_fee_collector_address.to_string(), + }; + let pool_factory_address = app .instantiate_contract( pool_factory_id, creator.clone().sender, - &pool_network::factory::InstantiateMsg { - pair_code_id: pair_id, - trio_code_id: trio_id, - token_code_id: token_id, - fee_collector_addr: fee_collector_address.to_string(), - }, + &instantiate_msg, &[], "fee_collector", None, @@ -8454,7 +8563,7 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { whale_lair_id, creator.clone().sender, &white_whale::whale_lair::InstantiateMsg { - unbonding_period: Uint64::new(1_000_000_000_000u64), + unbonding_period: Uint64::new(1u64), growth_rate: Decimal::one(), bonding_assets: vec![ AssetInfo::NativeToken { @@ -8478,7 +8587,7 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { &white_whale::fee_distributor::InstantiateMsg { bonding_contract_addr: whale_lair_address.clone().to_string(), fee_collector_addr: fee_collector_address.clone().to_string(), - grace_period: Uint64::new(3u64), + grace_period: Uint64::new(1), epoch_config: EpochConfig { duration: Uint64::new(86_400_000_000_000u64), // a day genesis_epoch: Uint64::new(1678802400_000000000u64), // March 14, 2023 2:00:00 PM @@ -8506,6 +8615,7 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { &[], ) .unwrap(); + // add pool router address to the fee collector to be able to aggregate fees app.execute_contract( creator.sender.clone(), @@ -8664,35 +8774,298 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { .unwrap(); } - // // "enable" bonding on 10 March 2023 15:00:00 - app.set_block(BlockInfo { - height: 123456789u64, - time: Timestamp::from_nanos(1678460400_000000000u64), - chain_id: "".to_string(), - }); + // bond some tokens + app.execute_contract( + creator.sender.clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(1_000u128), + }], + ) + .unwrap(); + + app.execute_contract( + Addr::unchecked("other").clone(), + whale_lair_address.clone(), + &white_whale::whale_lair::ExecuteMsg::Bond { + asset: Asset { + info: AssetInfo::NativeToken { + denom: "ampWHALE".to_string(), + }, + amount: Uint128::new(1_000u128), + }, + }, + &[Coin { + denom: "ampWHALE".to_string(), + amount: Uint128::new(1_000u128), + }], + ) + .unwrap(); + + // Create some epochs, for the first one all good but for the second we will have an unbonding + + // Create EPOCH 1 with 100 whale + // whale -> native + app.execute_contract( + creator.sender.clone(), + pair_tokens[0].clone(), + &pool_network::pair::ExecuteMsg::Swap { + offer_asset: Asset { + info: AssetInfo::NativeToken { + denom: "usdc".to_string(), + }, + amount: Uint128::new(2_010u128), + }, + belief_price: None, + max_spread: None, + to: None, + }, + &[Coin { + denom: "usdc".to_string(), + amount: Uint128::new(2_010u128), + }], + ) + .unwrap(); + + // advance the time to one day after the first epoch was created + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1678888800_000000000u64), + chain_id: "".to_string(), + }); + + // Create new epoch, which triggers fee collection, aggregation and distribution + // Verify epoch 1 + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &NewEpoch {}, + &[], + ) + .unwrap(); + + // check that a new epoch was created + let expiring_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, + ) + .unwrap(); + assert_eq!(expiring_epoch_res.epoch.id, Uint64::one()); + assert_eq!( + expiring_epoch_res.epoch.available, + expiring_epoch_res.epoch.total + ); + assert!(expiring_epoch_res.epoch.claimed.is_empty()); + // Verify expiring_epoch_res.epoch.available, has 100 whale as an Asset + assert_eq!( + expiring_epoch_res.epoch.available, + vec![Asset { + info: AssetInfo::NativeToken { + denom: "uwhale".to_string(), + }, + amount: Uint128::new(100u128), + }] + ); + + // for user in vec![creator.sender.clone(), Addr::unchecked("other")] { + // let weight: BondingWeightResponse = app + // .wrap() + // .query_wasm_smart( + // whale_lair_address.clone(), + // &white_whale::whale_lair::QueryMsg::Weight { + // address: user.to_string(), + // // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), + // global_weight: None, + // timestamp: None, + // }, + // ) + // .unwrap(); + // weights.push(weight.weight); + // } + // println!(" -> weights after each bonding 1000 whale: {:?}", weights); + + // When creating the second epoch, the first one will be expiring since the grace_period was set to 1. + // Make sure the available tokens on the expiring epoch are transferred to the second one. + app.execute_contract( + creator.sender.clone(), + pair_tokens[0].clone(), + &pool_network::pair::ExecuteMsg::Swap { + offer_asset: Asset { + info: AssetInfo::NativeToken { + denom: "usdc".to_string(), + }, + amount: Uint128::new(2_050u128), + }, + belief_price: None, + max_spread: None, + to: None, + }, + &[Coin { + denom: "usdc".to_string(), + amount: Uint128::new(2_050u128), + }], + ) + .unwrap(); + + // Get the weight of create.sender before bonding + // Get the weight after bonding ensure its different + let _weight_before: BondingWeightResponse = app + .wrap() + .query_wasm_smart( + whale_lair_address.clone(), + &white_whale::whale_lair::QueryMsg::Weight { + address: creator.sender.to_string(), + // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), + global_index: None, + timestamp: None, + }, + ) + .unwrap(); + + // advance the time to one day after the first epoch was created + app.set_block(BlockInfo { + height: 123456789u64, + time: Timestamp::from_nanos(1678888800_000000000u64), + chain_id: "".to_string(), + }); + + // Create new epoch, which triggers fee collection, aggregation and distribution + // Create EPOCH 2 + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &NewEpoch {}, + &[], + ) + .unwrap(); + + // check that the second epoch was created + let new_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, + ) + .unwrap(); + + assert_eq!(new_epoch_res.epoch.id, Uint64::new(2u64)); + assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); + assert!(new_epoch_res.epoch.claimed.is_empty()); + + // check that the available assets for the expired epoch are zero/empty + let expired_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { id: Uint64::one() }, + ) + .unwrap(); + assert!(expired_epoch_res.epoch.available.is_empty()); + + // let weight_after: BondingWeightResponse = app + // .wrap() + // .query_wasm_smart( + // whale_lair_address.clone(), + // &white_whale::whale_lair::QueryMsg::Weight { + // address: creator.sender.to_string(), + // // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), + // global_weight: None, + // timestamp: None, + // }, + // ) + // .unwrap(); + + // Get weight of other user and ensure its lower than the first + // let user_two_weight: BondingWeightResponse = app + // .wrap() + // .query_wasm_smart( + // whale_lair_address.clone(), + // &white_whale::whale_lair::QueryMsg::Weight { + // address: Addr::unchecked("other").to_string(), + // // timestamp: Some(Timestamp::from_nanos(1678888800_000000000u64-1)), + // global_weight: None, + // timestamp: None, + // }, + // ) + // .unwrap(); + + // since the fees collected for the second epoch were the same for the first, the available + // assets for the second epoch should be twice the amount of the first + + // iterate the new_epoch_res.epoch.available and add up the amounts for each asset + let mut total_amount_new_epoch = Uint128::zero(); + for asset in new_epoch_res.epoch.available { + total_amount_new_epoch += asset.amount; + } + println!("total_amount_new_epoch: {}", total_amount_new_epoch); + let mut total_amount_expired = Uint128::zero(); + //checking against total since total and available where the same, but available is empty now + for asset in expired_epoch_res.epoch.total { + total_amount_expired += asset.amount; + } + println!("total_amount_expired: {}", total_amount_expired); + assert!(total_amount_new_epoch - total_amount_expired > Uint128::zero()); + + let mut user_1_claims: Vec = vec![]; + // let mut user_2_claims: Vec = vec![]; - // bond some tokens + // Get the balance of the sender before claiming + let uwhale_balance_before_claiming = app + .wrap() + .query_balance(creator.sender.clone(), "uwhale") + .unwrap() + .amount; + // claim some rewards + app.execute_contract( + creator.sender.clone(), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], + ) + .unwrap(); + + // Get balance after claiming + let uwhale_balance_after_claiming = app + .wrap() + .query_balance(creator.sender.clone(), "uwhale") + .unwrap() + .amount; + // // Verify amount + // assert_eq!( + // uwhale_balance_after_claiming - + // uwhale_balance_before_claiming, Uint128::new(100) + // ); + user_1_claims.push(uwhale_balance_after_claiming - uwhale_balance_before_claiming); + + // Time to unbond with user 1 app.execute_contract( creator.sender.clone(), whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { + &white_whale::whale_lair::ExecuteMsg::Unbond { asset: Asset { info: AssetInfo::NativeToken { - denom: "bWHALE".to_string(), + denom: "ampWHALE".to_string(), }, - amount: Uint128::new(300_000_000u128), + amount: Uint128::new(500u128), }, }, - &[Coin { - denom: "bWHALE".to_string(), - amount: Uint128::new(300_000_000u128), - }], + &[], ) .unwrap(); - // add epochs to the fee distributor. - - // whale -> native + // NOTE: Here is where we could check weights if we wanted too + // Make sure the available tokens on the expiring epoch are transferred to the second one. app.execute_contract( creator.sender.clone(), pair_tokens[0].clone(), @@ -8701,27 +9074,31 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { info: AssetInfo::NativeToken { denom: "usdc".to_string(), }, - amount: Uint128::new(200_000u128), + amount: Uint128::new(2_050u128), }, belief_price: None, - max_spread: Some(Decimal::percent(40u64)), + max_spread: None, to: None, }, &[Coin { denom: "usdc".to_string(), - amount: Uint128::new(200_000u128), + amount: Uint128::new(2_050u128), }], ) .unwrap(); - // advance the time until the point when the first epoch was created + // Now we can advance time, create a third epoch and check that the fees collected are + // distributed to the users + // advance the time to one day after the second epoch was created app.set_block(BlockInfo { height: 123456789u64, - time: Timestamp::from_nanos(1678888800_000000000u64), + time: Timestamp::from_nanos(3357777600_000000000u64), chain_id: "".to_string(), }); // Create new epoch, which triggers fee collection, aggregation and distribution + // Create EPOCH 3 + app.execute_contract( creator.sender.clone(), fee_distributor_address.clone(), @@ -8730,8 +9107,8 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { ) .unwrap(); - // check that a new epoch was created - let expiring_epoch_res: EpochResponse = app + // check that the third epoch was created + let new_epoch_res: EpochResponse = app .wrap() .query_wasm_smart( fee_distributor_address.clone(), @@ -8739,116 +9116,102 @@ fn users_can_claim_even_when_global_index_was_taken_after_epoch_was_created() { ) .unwrap(); - println!( - "new epoch with good global_index:: {:?}", - expiring_epoch_res.epoch - ); - - assert_eq!(expiring_epoch_res.epoch.id, Uint64::one()); - assert_eq!( - expiring_epoch_res.epoch.available, - expiring_epoch_res.epoch.total - ); - assert!(expiring_epoch_res.epoch.claimed.is_empty()); + assert_eq!(new_epoch_res.epoch.id, Uint64::new(3u64)); + assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); + assert!(new_epoch_res.epoch.claimed.is_empty()); - // Create second epoch - app.execute_contract( - creator.sender.clone(), - pair_tokens[0].clone(), - &pool_network::pair::ExecuteMsg::Swap { - offer_asset: Asset { - info: AssetInfo::NativeToken { - denom: "usdc".to_string(), - }, - amount: Uint128::new(200_000u128), + // check that the available assets for the expired epoch are zero/empty + let expired_epoch_res: EpochResponse = app + .wrap() + .query_wasm_smart( + fee_distributor_address.clone(), + &white_whale::fee_distributor::QueryMsg::Epoch { + id: Uint64::from(2u64), }, - belief_price: None, - max_spread: Some(Decimal::percent(40u64)), - to: None, - }, - &[Coin { - denom: "usdc".to_string(), - amount: Uint128::new(200_000u128), - }], - ) - .unwrap(); + ) + .unwrap(); + assert!(expired_epoch_res.epoch.available.is_empty()); - // advance just a bit more after the new epoch can be created + // Advance time one more time app.set_block(BlockInfo { height: 123456789u64, - time: Timestamp::from_nanos(1678888900_000000000u64), + time: Timestamp::from_nanos(503666400_000000000u64), chain_id: "".to_string(), }); - // bond right after the next epoch start_time passed, but before the new epoch was created. - // should error because of the restriction we added on bonding/unbonding - let err = app - .execute_contract( - Addr::unchecked("other").clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(100_000_000u128), - }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(100_000_000u128), - }], - ) - .unwrap_err(); + // We should have about triple the amount of fees collected in the third epoch + // compared to the first + // iterate the new_epoch_res.epoch.available and add up the amounts for each asset + let mut total_amount_new_epoch = Uint128::zero(); - assert_eq!( - err.downcast::().unwrap(), - whale_lair::ContractError::NewEpochNotCreatedYet {} - ); + for asset in new_epoch_res.epoch.available { + total_amount_new_epoch += asset.amount; + } + let mut total_amount_expired = Uint128::zero(); + //checking against total since total and available where the same, but available is empty now + for asset in expired_epoch_res.epoch.total { + total_amount_expired += asset.amount; + } + // assert!(total_amount_new_epoch - total_amount_expired > Uint128::zero()); - // Create new epoch, which triggers fee collection, aggregation and distribution + // // Query and verify what is due to user 1 + // let claimable: ClaimableEpochsResponse = app.wrap().query_wasm_smart(fee_distributor_address.clone(), &white_whale::fee_distributor::QueryMsg::Claimable { address: creator.sender.to_string() }).unwrap(); + // println!(" -> claimable: {:?}", claimable); + // claim some rewards + let uwhale_balance_before_claiming = app + .wrap() + .query_balance(Addr::unchecked("other"), "uwhale") + .unwrap() + .amount; + // Claim for user 2 app.execute_contract( - creator.sender.clone(), + Addr::unchecked("other"), fee_distributor_address.clone(), - &NewEpoch {}, + &white_whale::fee_distributor::ExecuteMsg::Claim {}, &[], ) .unwrap(); - // check that the second epoch was created - let new_epoch_res: EpochResponse = app + let uwhale_balance_after_claiming = app .wrap() - .query_wasm_smart( - fee_distributor_address.clone(), - &white_whale::fee_distributor::QueryMsg::CurrentEpoch {}, - ) - .unwrap(); + .query_balance(Addr::unchecked("other"), "uwhale") + .unwrap() + .amount; - println!( - "new epoch with broken global_index:: {:?}", - new_epoch_res.epoch - ); + let user_2_whale_received = uwhale_balance_after_claiming - uwhale_balance_before_claiming; + println!("-> User 2 whale_received: {}", user_2_whale_received); - assert_eq!(new_epoch_res.epoch.id, Uint64::new(2u64)); - assert_eq!(new_epoch_res.epoch.available, new_epoch_res.epoch.total); - assert!(new_epoch_res.epoch.claimed.is_empty()); + // Claim 2 + // claim some rewards + let uwhale_balance_before_claiming = app + .wrap() + .query_balance(creator.sender.clone(), "uwhale") + .unwrap() + .amount; - // bond now with other app.execute_contract( - Addr::unchecked("other").clone(), - whale_lair_address.clone(), - &white_whale::whale_lair::ExecuteMsg::Bond { - asset: Asset { - info: AssetInfo::NativeToken { - denom: "ampWHALE".to_string(), - }, - amount: Uint128::new(100_000_000u128), - }, - }, - &[Coin { - denom: "ampWHALE".to_string(), - amount: Uint128::new(100_000_000u128), - }], + creator.sender.clone(), + fee_distributor_address.clone(), + &white_whale::fee_distributor::ExecuteMsg::Claim {}, + &[], ) .unwrap(); + + let uwhale_balance_after_claiming = app + .wrap() + .query_balance(creator.sender.clone(), "uwhale") + .unwrap() + .amount; + + let user_1_whale_received = uwhale_balance_after_claiming - uwhale_balance_before_claiming; + println!("whale_received: {}", user_1_whale_received); + + // For these claims, the bonds and weights started the same + // No claims happened + // User 2 should have received more than user 1 as user 1 halfed their bond and thus their weight + // User 1 should not get an even share anymore considering all else stays the same + assert_eq!(user_2_whale_received, Uint128::new(133u128)); + assert_eq!(user_1_whale_received, Uint128::new(66u128)); + + assert_ne!(user_2_whale_received, user_1_whale_received); } diff --git a/contracts/liquidity_hub/fee_collector/src/tests/testing.rs b/contracts/liquidity_hub/fee_collector/src/tests/testing.rs index e1e6f204..dcfbd99d 100644 --- a/contracts/liquidity_hub/fee_collector/src/tests/testing.rs +++ b/contracts/liquidity_hub/fee_collector/src/tests/testing.rs @@ -1,5 +1,5 @@ use cosmwasm_std::testing::{mock_env, mock_info}; -use cosmwasm_std::{from_binary, Addr, DepsMut, MessageInfo, Response}; +use cosmwasm_std::{from_json, Addr, DepsMut, MessageInfo, Response}; use cw2::{get_contract_version, set_contract_version, ContractVersion}; use std::env; @@ -24,7 +24,7 @@ fn proper_initialization() { instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!("owner".to_string(), config_res.owner); } @@ -35,7 +35,7 @@ fn test_update_config_successfully() { mock_instantiation(deps.as_mut(), info.clone()).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!(config_res.owner, Addr::unchecked("owner")); let msg = ExecuteMsg::UpdateConfig { @@ -49,7 +49,7 @@ fn test_update_config_successfully() { execute(deps.as_mut(), mock_env(), info, msg).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!(config_res.owner, Addr::unchecked("new_owner")); assert_eq!(config_res.pool_router, Addr::unchecked("new_router")); } @@ -61,7 +61,7 @@ fn test_update_config_unsuccessfully_unauthorized() { mock_instantiation(deps.as_mut(), info).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: Config = from_binary(&query_res).unwrap(); + let config_res: Config = from_json(&query_res).unwrap(); assert_eq!(config_res.owner, Addr::unchecked("owner")); let info = mock_info("unauthorized", &[]); diff --git a/contracts/liquidity_hub/fee_distributor/Cargo.toml b/contracts/liquidity_hub/fee_distributor/Cargo.toml index a181d929..c32358b4 100644 --- a/contracts/liquidity_hub/fee_distributor/Cargo.toml +++ b/contracts/liquidity_hub/fee_distributor/Cargo.toml @@ -27,6 +27,7 @@ backtraces = ["cosmwasm-std/backtraces"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] [dependencies] cosmwasm-schema.workspace = true diff --git a/contracts/liquidity_hub/fee_distributor/src/commands.rs b/contracts/liquidity_hub/fee_distributor/src/commands.rs index 760e37e6..8169abdc 100644 --- a/contracts/liquidity_hub/fee_distributor/src/commands.rs +++ b/contracts/liquidity_hub/fee_distributor/src/commands.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Env, MessageInfo, QueryRequest, ReplyOn, Response, StdError, - SubMsg, Timestamp, Uint64, WasmMsg, WasmQuery, + to_json_binary, CosmosMsg, DepsMut, Env, MessageInfo, QueryRequest, ReplyOn, Response, + StdError, SubMsg, Timestamp, Uint64, WasmMsg, WasmQuery, }; use white_whale::epoch_manager::epoch_manager::EpochConfig; @@ -59,7 +59,7 @@ pub fn create_new_epoch(deps: DepsMut, env: Env) -> Result Result Result Result StdResult { match msg { - QueryMsg::CurrentEpoch {} => Ok(to_binary(&state::get_current_epoch(deps)?)?), - QueryMsg::Epoch { id } => Ok(to_binary(&state::get_epoch(deps, id)?)?), - QueryMsg::ClaimableEpochs {} => Ok(to_binary(&state::get_claimable_epochs(deps)?)?), - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::Claimable { address } => Ok(to_binary(&state::query_claimable( + QueryMsg::CurrentEpoch {} => Ok(to_json_binary(&state::get_current_epoch(deps)?)?), + QueryMsg::Epoch { id } => Ok(to_json_binary(&state::get_epoch(deps, id)?)?), + QueryMsg::ClaimableEpochs {} => Ok(to_json_binary(&state::get_claimable_epochs(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::Claimable { address } => Ok(to_json_binary(&state::query_claimable( deps, &deps.api.addr_validate(&address)?, )?)?), diff --git a/contracts/liquidity_hub/fee_distributor/src/migrations.rs b/contracts/liquidity_hub/fee_distributor/src/migrations.rs index d5f12859..326b6c31 100644 --- a/contracts/liquidity_hub/fee_distributor/src/migrations.rs +++ b/contracts/liquidity_hub/fee_distributor/src/migrations.rs @@ -2,8 +2,8 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Order, QueryRequest, StdError, StdResult, Timestamp, Uint64, - WasmQuery, + to_json_binary, CosmosMsg, DepsMut, Order, QueryRequest, StdError, StdResult, Timestamp, + Uint64, WasmQuery, }; use cw_storage_plus::Map; @@ -47,7 +47,7 @@ pub fn migrate_to_v090(deps: DepsMut) -> Result<(), StdError> { // Query the current global index let global_index: GlobalIndex = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: bonding_contract_addr.to_string(), - msg: to_binary(&LairQueryMsg::GlobalIndex {})?, + msg: to_json_binary(&LairQueryMsg::GlobalIndex {})?, }))?; for epoch in epochs_v08 { diff --git a/contracts/liquidity_hub/fee_distributor/src/state.rs b/contracts/liquidity_hub/fee_distributor/src/state.rs index 930b0eee..782cff7c 100644 --- a/contracts/liquidity_hub/fee_distributor/src/state.rs +++ b/contracts/liquidity_hub/fee_distributor/src/state.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, Deps, Order, QueryRequest, StdResult, Uint64, WasmQuery}; +use cosmwasm_std::{to_json_binary, Addr, Deps, Order, QueryRequest, StdResult, Uint64, WasmQuery}; use cw_storage_plus::{Item, Map}; use white_whale::fee_distributor::{ClaimableEpochsResponse, Config, Epoch, EpochResponse}; @@ -93,7 +93,7 @@ pub fn query_claimable(deps: Deps, address: &Addr) -> StdResult(vec![ WasmMsg::Execute { contract_addr: token_contract_addr.clone(), - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.clone().into_string(), amount: token_amount, @@ -104,7 +105,7 @@ pub fn execute( }, WasmMsg::Execute { contract_addr: token_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { spender: pair_address.clone(), amount: token_amount, expires: None, @@ -131,7 +132,7 @@ pub fn execute( gas_limit: None, msg: WasmMsg::Execute { contract_addr: pair_address, - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::pair::ExecuteMsg::ProvideLiquidity { assets, slippage_tolerance, @@ -186,7 +187,7 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => Ok(to_binary(&CONFIG.load(deps.storage)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&CONFIG.load(deps.storage)?)?), } } diff --git a/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs b/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs index dc5a5cc2..77e7412f 100644 --- a/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs +++ b/contracts/liquidity_hub/pool-network/frontend_helper/src/reply/deposit_pair.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, DepsMut, Env, Reply, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, DepsMut, Env, Reply, Response, WasmMsg}; use white_whale::pool_network::{ asset::AssetInfo, frontend_helper::TempState, incentive::QueryPosition, }; @@ -75,7 +75,7 @@ pub fn deposit_pair(deps: DepsMut, env: Env, msg: Reply) -> Result Result white_whale::pool_network::incentive::ExecuteMsg::ExpandPosition { amount: lp_amount, unbonding_duration, diff --git a/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs b/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs index 2234b0a4..d9cfb155 100644 --- a/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs +++ b/contracts/liquidity_hub/pool-network/frontend_helper/src/testing.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod tests { use crate::error::ContractError; - use cosmwasm_std::{coin, coins, to_binary, Addr, Uint128, WasmMsg}; + use cosmwasm_std::{coin, coins, to_json_binary, Addr, Uint128, WasmMsg}; use cw_multi_test::Executor; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::pool_network::frontend_helper::ConfigResponse; @@ -129,7 +129,7 @@ mod tests { vec![ WasmMsg::Execute { contract_addr: pool_assets[1].to_string(), - msg: to_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::IncreaseAllowance { spender: frontend_helper.clone().into_string(), amount: Uint128::new(5_000), expires: None, @@ -140,7 +140,7 @@ mod tests { .into(), WasmMsg::Execute { contract_addr: frontend_helper.into_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::frontend_helper::ExecuteMsg::Deposit { pair_address: pair_address.into_string(), assets: [ diff --git a/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs b/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs index c0622a54..f3976c01 100644 --- a/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs +++ b/contracts/liquidity_hub/pool-network/frontend_helper/src/tests/mock_instantiate.rs @@ -1,13 +1,15 @@ -use crate::tests::mock_info::mock_creator; -use crate::tests::store_code::fee_distributor_mock_contract; -use cosmwasm_std::{to_binary, Addr, Decimal, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, Decimal, Uint128, WasmMsg}; use cw20::Cw20Coin; use cw_multi_test::{App, Executor}; + use white_whale::{ fee::Fee, pool_network::asset::{Asset, AssetInfo, PairType}, }; +use crate::tests::mock_info::mock_creator; +use crate::tests::store_code::fee_distributor_mock_contract; + use super::{ mock_info::mock_admin, store_code::{ @@ -69,30 +71,51 @@ pub fn app_mock_instantiate(app: &mut App, pool_assets: [AssetInfo; 2]) -> AppIn .try_into() .unwrap(); + #[cfg(not(feature = "osmosis"))] + let pool_fee = white_whale::pool_network::pair::PoolFee { + burn_fee: Fee { + share: Decimal::zero(), + }, + protocol_fee: Fee { + share: Decimal::zero(), + }, + swap_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fee = white_whale::pool_network::pair::PoolFee { + burn_fee: Fee { + share: Decimal::zero(), + }, + protocol_fee: Fee { + share: Decimal::zero(), + }, + swap_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::zero(), + }, + }; + + let instantiate_msg = white_whale::pool_network::pair::InstantiateMsg { + token_factory_lp: false, + token_code_id: token_id, + pool_fees: pool_fee.clone(), + pair_type: PairType::ConstantProduct, + fee_collector_addr: "fee_collector_addr".to_string(), + asset_decimals: [6, 6], + asset_infos: pool_assets.clone(), + }; + // create the pair let pair = app .instantiate_contract( pair_id, mock_admin().sender, - &white_whale::pool_network::pair::InstantiateMsg { - token_factory_lp: false, - token_code_id: token_id, - pool_fees: white_whale::pool_network::pair::PoolFee { - burn_fee: Fee { - share: Decimal::zero(), - }, - protocol_fee: Fee { - share: Decimal::zero(), - }, - swap_fee: Fee { - share: Decimal::zero(), - }, - }, - pair_type: PairType::ConstantProduct, - fee_collector_addr: "fee_collector_addr".to_string(), - asset_decimals: [6, 6], - asset_infos: pool_assets.clone(), - }, + &instantiate_msg, &[], "mock pair", None, @@ -150,7 +173,7 @@ pub fn app_mock_instantiate(app: &mut App, pool_assets: [AssetInfo; 2]) -> AppIn mock_admin().sender, WasmMsg::Execute { contract_addr: incentive_factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::incentive_factory::ExecuteMsg::CreateIncentive { lp_asset: lp_token.clone(), }, diff --git a/contracts/liquidity_hub/pool-network/incentive/Cargo.toml b/contracts/liquidity_hub/pool-network/incentive/Cargo.toml index 37b7d9b9..600860f6 100644 --- a/contracts/liquidity_hub/pool-network/incentive/Cargo.toml +++ b/contracts/liquidity_hub/pool-network/incentive/Cargo.toml @@ -20,6 +20,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] # for quicker tests, cargo test --lib diff --git a/contracts/liquidity_hub/pool-network/incentive/src/claim.rs b/contracts/liquidity_hub/pool-network/incentive/src/claim.rs index 9ba23587..6a510954 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/claim.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/claim.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, Decimal256, DepsMut, MessageInfo, StdError, Uint128, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal256, DepsMut, MessageInfo, StdError, Uint128, Uint256, WasmMsg, }; @@ -203,7 +203,7 @@ pub fn claim(deps: &mut DepsMut, info: &MessageInfo) -> Result, C AssetInfo::Token { contract_addr } => messages.push( WasmMsg::Execute { contract_addr: contract_addr.to_owned(), - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: address.clone().into_string(), amount: user_reward_at_epoch, })?, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/contract.rs b/contracts/liquidity_hub/pool-network/incentive/src/contract.rs index bd525433..9506d1e8 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, + to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, }; use cw2::{get_contract_version, set_contract_version}; use white_whale::pool_network::incentive::{ @@ -57,7 +57,7 @@ pub fn instantiate( ), ("lp_asset", config.lp_asset.to_string()), ]) - .set_data(to_binary( + .set_data(to_json_binary( &white_whale::pool_network::incentive::InstantiateReplyCallback { lp_asset: msg.lp_asset, }, @@ -65,7 +65,7 @@ pub fn instantiate( // takes a snapshot of the global weight at the current epoch from the start .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), - msg: to_binary(&ExecuteMsg::TakeGlobalWeightSnapshot {})?, + msg: to_json_binary(&ExecuteMsg::TakeGlobalWeightSnapshot {})?, funds: vec![], }))) } @@ -125,12 +125,12 @@ pub fn execute( #[entry_point] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Config {} => Ok(to_binary(&queries::get_config(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&queries::get_config(deps)?)?), QueryMsg::Flow { flow_identifier, start_epoch, end_epoch, - } => Ok(to_binary(&queries::get_flow( + } => Ok(to_json_binary(&queries::get_flow( deps, flow_identifier, start_epoch, @@ -139,19 +139,19 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result Ok(to_binary(&queries::get_flows( + } => Ok(to_json_binary(&queries::get_flows( deps, start_epoch, end_epoch, )?)?), - QueryMsg::Positions { address } => { - Ok(to_binary(&queries::get_positions(deps, env, address)?)?) - } - QueryMsg::Rewards { address } => Ok(to_binary(&queries::get_rewards(deps, address)?)?), - QueryMsg::GlobalWeight { epoch_id } => { - Ok(to_binary(&queries::get_global_weight(deps, epoch_id)?)?) - } - QueryMsg::CurrentEpochRewardsShare { address } => Ok(to_binary( + QueryMsg::Positions { address } => Ok(to_json_binary(&queries::get_positions( + deps, env, address, + )?)?), + QueryMsg::Rewards { address } => Ok(to_json_binary(&queries::get_rewards(deps, address)?)?), + QueryMsg::GlobalWeight { epoch_id } => Ok(to_json_binary(&queries::get_global_weight( + deps, epoch_id, + )?)?), + QueryMsg::CurrentEpochRewardsShare { address } => Ok(to_json_binary( &queries::get_rewards_share(deps, deps.api.addr_validate(&address)?)?, )?), } diff --git a/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs b/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs index 3ee09e3f..0645f6aa 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/execute/close_flow.rs @@ -1,5 +1,6 @@ use cosmwasm_std::{ - coins, to_binary, BankMsg, CosmosMsg, DepsMut, MessageInfo, Order, Response, StdResult, WasmMsg, + coins, to_json_binary, BankMsg, CosmosMsg, DepsMut, MessageInfo, Order, Response, StdResult, + WasmMsg, }; use white_whale::pool_network::asset::AssetInfo; @@ -52,7 +53,7 @@ pub fn close_flow( .into(), AssetInfo::Token { contract_addr } => WasmMsg::Execute { contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: flow.flow_creator.clone().into_string(), amount: amount_to_return, })?, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs b/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs index 1418fa83..1b0ec559 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/execute/expand_flow.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Env, MessageInfo, Order, OverflowError, OverflowOperation, + to_json_binary, CosmosMsg, DepsMut, Env, MessageInfo, Order, OverflowError, OverflowOperation, Response, StdResult, Uint128, WasmMsg, }; @@ -72,7 +72,7 @@ pub fn expand_flow( messages.push( WasmMsg::Execute { contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs b/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs index b4d566f0..965e594f 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/execute/open_flow.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use std::collections::HashMap; use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, + to_json_binary, BankMsg, Coin, CosmosMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, WasmMsg, }; @@ -177,7 +177,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_fee_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: incentive_factory_config.fee_collector_addr.into_string(), amount: flow_fee.amount, @@ -259,7 +259,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_asset_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, @@ -288,7 +288,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_asset_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, @@ -307,7 +307,7 @@ pub fn open_flow( messages.push( WasmMsg::Execute { contract_addr: flow_asset_contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.into_string(), amount: flow_asset.amount, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs b/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs index 2361e1a6..8c057268 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/funds_validation.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Deps, Env, MessageInfo, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Deps, Env, MessageInfo, Uint128, WasmMsg}; use cw_utils::PaymentError; use white_whale::pool_network::asset::AssetInfo; @@ -43,7 +43,7 @@ pub fn validate_funds_sent( // send the lp deposit to us Some(WasmMsg::Execute { contract_addr, - msg: to_binary(&cw20::Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::TransferFrom { owner: info.sender.into_string(), recipient: env.contract.address.into_string(), amount, diff --git a/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs b/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs index 96bd70bd..3cc8e797 100644 --- a/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs +++ b/contracts/liquidity_hub/pool-network/incentive/src/tests/mock_instantiate.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ testing::{mock_dependencies, mock_env, MockApi, MockQuerier, MockStorage}, - to_binary, Addr, Env, OwnedDeps, Uint128, Uint64, WasmMsg, + to_json_binary, Addr, Env, OwnedDeps, Uint128, Uint64, WasmMsg, }; use cw20::Cw20Coin; use cw_multi_test::{App, Executor}; @@ -128,7 +128,7 @@ pub fn app_mock_instantiate(app: &mut App, lp_balance: Uint128) -> AppInstantiat mock_admin().sender, WasmMsg::Execute { contract_addr: incentive_factory.to_string(), - msg: to_binary( + msg: to_json_binary( &white_whale::pool_network::incentive_factory::ExecuteMsg::CreateIncentive { lp_asset: AssetInfo::Token { contract_addr: lp_addr.to_string(), diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/Cargo.toml b/contracts/liquidity_hub/pool-network/incentive_factory/Cargo.toml index 7de62865..284f4d0c 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/Cargo.toml +++ b/contracts/liquidity_hub/pool-network/incentive_factory/Cargo.toml @@ -20,6 +20,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] # for quicker tests, cargo test --lib diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs index e5f11bbd..3dd768ff 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, }; use cw2::{get_contract_version, set_contract_version}; use semver::Version; @@ -143,10 +143,12 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::get_config(deps)?), - QueryMsg::Incentive { lp_asset } => to_binary(&queries::get_incentive(deps, lp_asset)?), + QueryMsg::Config {} => to_json_binary(&queries::get_config(deps)?), + QueryMsg::Incentive { lp_asset } => { + to_json_binary(&queries::get_incentive(deps, lp_asset)?) + } QueryMsg::Incentives { start_after, limit } => { - to_binary(&queries::get_incentives(deps, start_after, limit)?) + to_json_binary(&queries::get_incentives(deps, start_after, limit)?) } } } diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs index 7aabbf44..4ca11e8b 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/create_incentive.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, DepsMut, Env, ReplyOn, Response, SubMsg, WasmMsg}; +use cosmwasm_std::{to_json_binary, DepsMut, Env, ReplyOn, Response, SubMsg, WasmMsg}; use white_whale::pool_network::asset::AssetInfo; use crate::{ @@ -39,7 +39,7 @@ pub fn create_incentive( msg: WasmMsg::Instantiate { admin: Some(env.contract.address.into_string()), code_id: config.incentive_code_id, - msg: to_binary(&white_whale::pool_network::incentive::InstantiateMsg { + msg: to_json_binary(&white_whale::pool_network::incentive::InstantiateMsg { lp_asset: lp_asset.clone(), fee_distributor_address: config.fee_distributor_addr.into_string(), })?, diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs index fcff7188..640681e4 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/migrate_incentive.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, CosmosMsg, DepsMut, Order, Response, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, DepsMut, Order, Response, StdResult, WasmMsg}; use crate::error::ContractError; use crate::state::INCENTIVE_MAPPINGS; @@ -48,7 +48,7 @@ fn migrate_incentive_msg(incentive_address: Addr, new_code_id: u64) -> StdResult Ok(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: incentive_address.to_string(), new_code_id, - msg: to_binary(&white_whale::pool_network::incentive::MigrateMsg {})?, + msg: to_json_binary(&white_whale::pool_network::incentive::MigrateMsg {})?, })) } diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs index 7ac209fa..1e6b6bd3 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/execute/update_config.rs @@ -110,7 +110,7 @@ mod tests { use crate::contract::{execute, instantiate, query}; use crate::error::ContractError; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_binary, Addr, Uint128}; + use cosmwasm_std::{from_json, Addr, Uint128}; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::pool_network::incentive_factory::ExecuteMsg::UpdateConfig; use white_whale::pool_network::incentive_factory::{Config, InstantiateMsg, QueryMsg}; @@ -138,7 +138,7 @@ mod tests { instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!( config, @@ -181,7 +181,7 @@ mod tests { execute(deps.as_mut(), mock_env(), info, msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!( config, diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs index 3bac398d..bfe6f755 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/queries/get_incentives.rs @@ -57,7 +57,7 @@ fn calc_range_start(start_after: Option) -> Option> { #[cfg(test)] mod tests { use cosmwasm_std::{ - testing::mock_dependencies, to_binary, Addr, Binary, DepsMut, Reply, SubMsgResponse, + testing::mock_dependencies, to_json_binary, Addr, Binary, DepsMut, Reply, SubMsgResponse, SubMsgResult, }; use protobuf::{Message, SpecialFields}; @@ -80,7 +80,7 @@ mod tests { data: Some(Binary::from( Message::write_to_bytes(&MsgInstantiateContractResponse { address: format!("incentive{id}"), - data: to_binary( + data: to_json_binary( &white_whale::pool_network::incentive::InstantiateReplyCallback { lp_asset: get_lp_asset(id), }, diff --git a/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs b/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs index 7e34932a..1ce283a0 100644 --- a/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs +++ b/contracts/liquidity_hub/pool-network/incentive_factory/src/reply/create_incentive_reply.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{from_binary, DepsMut, Reply, Response}; +use cosmwasm_std::{from_json, DepsMut, Reply, Response}; use protobuf::Message; use crate::{ @@ -29,7 +29,7 @@ pub fn create_incentive_reply(deps: DepsMut, msg: Reply) -> Result commands::collect_protocol_fees(deps), } } @@ -238,12 +240,12 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Trio {} => Ok(to_binary(&queries::query_trio_info(deps)?)?), - QueryMsg::Pool {} => Ok(to_binary(&queries::query_pool(deps)?)?), + QueryMsg::Trio {} => Ok(to_json_binary(&queries::query_trio_info(deps)?)?), + QueryMsg::Pool {} => Ok(to_json_binary(&queries::query_pool(deps)?)?), QueryMsg::Simulation { offer_asset, ask_asset, - } => Ok(to_binary(&queries::query_simulation( + } => Ok(to_json_binary(&queries::query_simulation( deps, offer_asset, ask_asset, @@ -252,21 +254,21 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result Ok(to_binary(&queries::query_reverse_simulation( + } => Ok(to_json_binary(&queries::query_reverse_simulation( deps, ask_asset, offer_asset, env.block.height, )?)?), - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_binary(&queries::query_fees( + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, all_time, COLLECTED_PROTOCOL_FEES, Some(ALL_TIME_COLLECTED_PROTOCOL_FEES), )?)?), - QueryMsg::BurnedFees { asset_id } => Ok(to_binary(&queries::query_fees( + QueryMsg::BurnedFees { asset_id } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, None, diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs index 8afe24ce..8fe0dcf3 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/helpers.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, Decimal, Decimal256, Deps, DepsMut, Env, ReplyOn, Response, StdError, StdResult, - Storage, SubMsg, Uint128, Uint256, WasmMsg, + to_json_binary, Decimal, Decimal256, Deps, DepsMut, Env, ReplyOn, Response, StdError, + StdResult, Storage, SubMsg, Uint128, Uint256, WasmMsg, }; use cw20::MinterResponse; use cw_storage_plus::Item; @@ -50,17 +50,38 @@ pub fn compute_swap( let protocol_fee_amount: Uint256 = pool_fees.protocol_fee.compute(return_amount); let burn_fee_amount: Uint256 = pool_fees.burn_fee.compute(return_amount); - // swap and protocol fee will be absorbed by the pool. Burn fee amount will be burned on a subsequent msg. - let return_amount: Uint256 = - return_amount - swap_fee_amount - protocol_fee_amount - burn_fee_amount; + #[cfg(not(feature = "osmosis"))] + { + // swap and protocol fee will be absorbed by the pool. Burn fee amount will be burned on a subsequent msg. + let return_amount: Uint256 = + return_amount - swap_fee_amount - protocol_fee_amount - burn_fee_amount; - Ok(SwapComputation { - return_amount: return_amount.try_into()?, - spread_amount: spread_amount.try_into()?, - swap_fee_amount: swap_fee_amount.try_into()?, - protocol_fee_amount: protocol_fee_amount.try_into()?, - burn_fee_amount: burn_fee_amount.try_into()?, - }) + Ok(SwapComputation { + return_amount: return_amount.try_into()?, + spread_amount: spread_amount.try_into()?, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + }) + } + + #[cfg(feature = "osmosis")] + { + let osmosis_fee_amount: Uint256 = pool_fees.osmosis_fee.compute(return_amount); + + // swap and protocol fee will be absorbed by the pool. Burn fee amount will be burned on a subsequent msg. + let return_amount: Uint256 = + return_amount - swap_fee_amount - protocol_fee_amount - osmosis_fee_amount; + + Ok(SwapComputation { + return_amount: return_amount.try_into()?, + spread_amount: spread_amount.try_into()?, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + osmosis_fee_amount: osmosis_fee_amount.try_into()?, + }) + } } /// Represents the swap computation values @@ -71,6 +92,8 @@ pub struct SwapComputation { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } pub fn compute_offer_amount( @@ -81,11 +104,25 @@ pub fn compute_offer_amount( pool_fees: PoolFee, invariant: StableSwap, ) -> StdResult { - let fees = pool_fees.swap_fee.share + pool_fees.protocol_fee.share + pool_fees.burn_fee.share; + let fees = { + let base_fees = + pool_fees.swap_fee.share + pool_fees.protocol_fee.share + pool_fees.burn_fee.share; + + #[cfg(feature = "osmosis")] + { + base_fees + pool_fees.osmosis_fee.share + } + + #[cfg(not(feature = "osmosis"))] + { + base_fees + } + }; + let one_minus_commission = Decimal::one() - fees; let inv_one_minus_commission = Decimal::one() / one_minus_commission; - let before_commission_deduction: Uint128 = ask_amount * inv_one_minus_commission; + let before_commission_deduction = ask_amount * inv_one_minus_commission; let offer_amount = invariant .reverse_sim( @@ -112,13 +149,32 @@ pub fn compute_offer_amount( .burn_fee .compute(before_commission_deduction.into()); - Ok(OfferAmountComputation { - offer_amount, - spread_amount, - swap_fee_amount: swap_fee_amount.try_into()?, - protocol_fee_amount: protocol_fee_amount.try_into()?, - burn_fee_amount: burn_fee_amount.try_into()?, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(OfferAmountComputation { + offer_amount, + spread_amount, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + }) + } + + #[cfg(feature = "osmosis")] + { + let osmosis_fee_amount = pool_fees + .osmosis_fee + .compute(before_commission_deduction.into()); + + Ok(OfferAmountComputation { + offer_amount, + spread_amount, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + osmosis_fee_amount: osmosis_fee_amount.try_into()?, + }) + } } /// Represents the offer amount computation values @@ -129,6 +185,8 @@ pub struct OfferAmountComputation { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } pub fn assert_slippage_tolerance( slippage_tolerance: &Option, @@ -288,7 +346,7 @@ pub fn create_lp_token( msg: WasmMsg::Instantiate { admin: None, code_id: msg.token_code_id, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: lp_token_name.to_owned(), symbol: "uLP".to_string(), decimals: 6, diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/queries.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/queries.rs index b204121f..67388422 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/queries.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/queries.rs @@ -148,13 +148,28 @@ pub fn query_simulation( invariant, )?; - Ok(SimulationResponse { - return_amount: swap_computation.return_amount, - spread_amount: swap_computation.spread_amount, - swap_fee_amount: swap_computation.swap_fee_amount, - protocol_fee_amount: swap_computation.protocol_fee_amount, - burn_fee_amount: swap_computation.burn_fee_amount, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(SimulationResponse { + return_amount: swap_computation.return_amount, + spread_amount: swap_computation.spread_amount, + swap_fee_amount: swap_computation.swap_fee_amount, + protocol_fee_amount: swap_computation.protocol_fee_amount, + burn_fee_amount: swap_computation.burn_fee_amount, + }) + } + + #[cfg(feature = "osmosis")] + { + Ok(SimulationResponse { + return_amount: swap_computation.return_amount, + spread_amount: swap_computation.spread_amount, + swap_fee_amount: swap_computation.swap_fee_amount, + protocol_fee_amount: swap_computation.protocol_fee_amount, + burn_fee_amount: swap_computation.burn_fee_amount, + osmosis_fee_amount: swap_computation.osmosis_fee_amount, + }) + } } /// Queries a swap reverse simulation. Used to derive the number of source tokens returned for @@ -247,13 +262,28 @@ pub fn query_reverse_simulation( invariant, )?; - Ok(ReverseSimulationResponse { - offer_amount: offer_amount_computation.offer_amount, - spread_amount: offer_amount_computation.spread_amount, - swap_fee_amount: offer_amount_computation.swap_fee_amount, - protocol_fee_amount: offer_amount_computation.protocol_fee_amount, - burn_fee_amount: offer_amount_computation.burn_fee_amount, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(ReverseSimulationResponse { + offer_amount: offer_amount_computation.offer_amount, + spread_amount: offer_amount_computation.spread_amount, + swap_fee_amount: offer_amount_computation.swap_fee_amount, + protocol_fee_amount: offer_amount_computation.protocol_fee_amount, + burn_fee_amount: offer_amount_computation.burn_fee_amount, + }) + } + + #[cfg(feature = "osmosis")] + { + Ok(ReverseSimulationResponse { + offer_amount: offer_amount_computation.offer_amount, + spread_amount: offer_amount_computation.spread_amount, + swap_fee_amount: offer_amount_computation.swap_fee_amount, + protocol_fee_amount: offer_amount_computation.protocol_fee_amount, + burn_fee_amount: offer_amount_computation.burn_fee_amount, + osmosis_fee_amount: offer_amount_computation.osmosis_fee_amount, + }) + } } /// Queries the [Config], which contains the owner, pool_fees and feature_toggle diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs index a7702104..a69fc22d 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/feature_toggle.rs @@ -1,7 +1,7 @@ use crate::contract::{execute, instantiate}; use crate::error::ContractError; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; -use cosmwasm_std::{to_binary, Coin, Decimal, Uint128}; +use cosmwasm_std::{to_json_binary, Coin, Decimal, Uint128}; use cw20::Cw20ReceiveMsg; use white_whale::fee::Fee; use white_whale::pool_network::asset::{Asset, AssetInfo}; @@ -11,6 +11,7 @@ use white_whale::pool_network::trio::{ Cw20HookMsg, ExecuteMsg, FeatureToggle, InstantiateMsg, PoolFee, }; +#[cfg(not(feature = "osmosis"))] #[test] fn test_feature_toggle_swap_disabled() { let mut deps = mock_dependencies(&[Coin { @@ -111,7 +112,7 @@ fn test_feature_toggle_swap_disabled() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::Token { contract_addr: "asset0000".to_string(), }, @@ -129,6 +130,7 @@ fn test_feature_toggle_swap_disabled() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_feature_toggle_withdrawals_disabled() { let mut deps = mock_dependencies(&[Coin { @@ -205,7 +207,7 @@ fn test_feature_toggle_withdrawals_disabled() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -219,6 +221,7 @@ fn test_feature_toggle_withdrawals_disabled() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_feature_toggle_deposits_disabled() { let mut deps = mock_dependencies(&[Coin { diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs index 1cc572d3..cf550a96 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/protocol_fees.rs @@ -3,7 +3,7 @@ use crate::queries::query_fees; use crate::state::{ALL_TIME_COLLECTED_PROTOCOL_FEES, COLLECTED_PROTOCOL_FEES}; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -12,6 +12,7 @@ use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::pool_network::mock_querier::mock_dependencies; use white_whale::pool_network::trio::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, PoolFee}; +#[cfg(not(feature = "osmosis"))] #[test] fn test_protocol_fees() { let total_share = Uint128::from(60_000_000_000u128); @@ -207,6 +208,7 @@ fn test_protocol_fees() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_collect_protocol_fees_successful() { let total_share = Uint128::from(30_000_000_000u128); @@ -319,7 +321,7 @@ fn test_collect_protocol_fees_successful() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "asset0001".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::NativeToken { denom: "uusd".to_string(), }, @@ -369,7 +371,7 @@ fn test_collect_protocol_fees_successful() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "asset0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::Token { contract_addr: "asset0001".to_string(), }, @@ -426,7 +428,7 @@ fn test_collect_protocol_fees_successful() { transfer_asset0000_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees_for_asset0000.clone().first().unwrap().amount, }) @@ -438,7 +440,7 @@ fn test_collect_protocol_fees_successful() { transfer_asset0001_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0001".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees_for_asset0001.clone().first().unwrap().amount, }) @@ -509,6 +511,7 @@ fn test_collect_protocol_fees_successful() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_collect_protocol_fees_successful_1_fee_only() { let total_share = Uint128::from(30_000_000_000u128); @@ -642,7 +645,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() { transfer_cw20_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees[1].amount, }) @@ -697,6 +700,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn protocol_fees() { let protocol_fee = PoolFee { diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs index f7a64d3c..00c9a222 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/provide_liquidity.rs @@ -6,7 +6,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; #[cfg(feature = "token_factory")] use cosmwasm_std::{coin, BankMsg}; use cosmwasm_std::{ - to_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, + to_json_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -17,6 +17,7 @@ use white_whale::pool_network::denom::MsgMint; use white_whale::pool_network::mock_querier::mock_dependencies; use white_whale::pool_network::trio::{ExecuteMsg, InstantiateMsg, PoolFee}; +#[cfg(not(feature = "osmosis"))] #[test] fn provide_liquidity_cw20_lp() { let mut deps = mock_dependencies(&[Coin { @@ -169,7 +170,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(2_000u128), @@ -182,7 +183,7 @@ fn provide_liquidity_cw20_lp() { mint_initial_lp_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "cosmos2contract".to_string(), amount: MINIMUM_LIQUIDITY_AMOUNT * Uint128::from(3u8), }) @@ -194,7 +195,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "addr0000".to_string(), amount: Uint128::from(3_000u128), }) @@ -274,7 +275,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(100u128), @@ -287,7 +288,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "staking0000".to_string(), // LP tokens sent to specified receiver amount: Uint128::from(57u128), }) @@ -686,6 +687,7 @@ fn provide_liquidity_token_factory_lp() { assert_eq!(bank_send_msg, bank_send_msg_expected); } +#[cfg(not(feature = "osmosis"))] #[test] fn provide_liquidity_zero_amount() { let mut deps = mock_dependencies(&[Coin { @@ -796,6 +798,7 @@ fn provide_liquidity_zero_amount() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn provide_liquidity_invalid_minimum_lp_amount() { let mut deps = mock_dependencies(&[Coin { diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/queries.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/queries.rs index 16bc2f7a..161d2214 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/queries.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/queries.rs @@ -8,6 +8,7 @@ use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::pool_network::mock_querier::mock_dependencies; use white_whale::pool_network::trio::{InstantiateMsg, PoolFee, PoolResponse, QueryMsg}; +#[cfg(not(feature = "osmosis"))] #[test] fn test_simulations_asset_missmatch() { let mut deps = mock_dependencies(&[]); @@ -108,6 +109,7 @@ fn test_simulations_asset_missmatch() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_query_pool() { let total_share_amount = Uint128::from(111u128); diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs index d674f55d..75f6d582 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/swap.rs @@ -8,8 +8,8 @@ use crate::state::{ }; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, coins, from_binary, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, SubMsg, - SubMsgResponse, SubMsgResult, Uint128, WasmMsg, + attr, coins, from_json, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, + SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use white_whale::fee::Fee; @@ -20,6 +20,7 @@ use white_whale::pool_network::trio::{ SimulationResponse, }; +#[cfg(not(feature = "osmosis"))] #[test] fn test_compute_swap_with_huge_pool_variance() { let offer_pool = Uint128::from(395451850234u128); @@ -52,6 +53,7 @@ fn test_compute_swap_with_huge_pool_variance() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn try_native_to_token() { let total_share = Uint128::from(30000000000u128); @@ -173,7 +175,7 @@ fn try_native_to_token() { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: expected_burn_fee_amount, }) .unwrap(), @@ -269,7 +271,7 @@ fn try_native_to_token() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -322,7 +324,7 @@ fn try_native_to_token() { ) .unwrap(); - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -397,7 +399,7 @@ fn try_native_to_token() { assert_eq!( &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_return_amount, }) @@ -408,6 +410,7 @@ fn try_native_to_token() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn try_swap_invalid_token() { let total_share = Uint128::from(30000000000u128); @@ -519,6 +522,7 @@ fn try_swap_invalid_token() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn try_token_to_native() { let total_share = Uint128::from(20_000_000_000u128); @@ -626,7 +630,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::NativeToken { denom: "uusd".to_string(), }, @@ -735,7 +739,7 @@ fn try_token_to_native() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -789,7 +793,7 @@ fn try_token_to_native() { .unwrap(); // check reverse simulation res - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -812,6 +816,9 @@ fn try_token_to_native() { ) .unwrap(); + println!("reverse_simulation_res: {:?}", reverse_simulation_res); + println!("expected_swap_fee_amount: {:?}", expected_swap_fee_amount); + assert!( (offer_amount.u128() as i128 - reverse_simulation_res.offer_amount.u128() as i128).abs() < 3i128 @@ -876,7 +883,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { ask_asset: AssetInfo::Token { contract_addr: "asset0000".to_string(), }, @@ -895,6 +902,7 @@ fn try_token_to_native() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_swap_to_third_party() { let total_share = Uint128::from(30_000_000_000u128); @@ -1029,7 +1037,7 @@ fn test_swap_to_third_party() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs index 6b718104..dc8a84d5 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/testing.rs @@ -1,6 +1,6 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, to_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, + from_json, to_json_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::MinterResponse; @@ -24,6 +24,7 @@ use crate::error::ContractError; use crate::helpers::assert_slippage_tolerance; use crate::queries::query_trio_info; +#[cfg(not(feature = "osmosis"))] #[test] fn proper_initialization_cw20_lp() { let mut deps = mock_dependencies(&[]); @@ -78,7 +79,7 @@ fn proper_initialization_cw20_lp() { vec![SubMsg { msg: WasmMsg::Instantiate { code_id: 10u64, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: "uusd-mAAPL-mAAPL-LP".to_string(), symbol: "uLP".to_string(), decimals: 6, @@ -331,6 +332,7 @@ fn intialize_with_burnable_token_factory_asset() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_initialization_invalid_fees() { let mut deps = mock_dependencies(&[]); @@ -381,6 +383,7 @@ fn test_initialization_invalid_fees() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_initialization_invalid_amp() { let mut deps = mock_dependencies(&[]); @@ -437,6 +440,7 @@ fn test_initialization_invalid_amp() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn can_migrate_contract() { let mut deps = mock_dependencies(&[]); @@ -612,6 +616,7 @@ fn test_max_spread() { .unwrap(); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_update_config_unsuccessful() { let mut deps = mock_dependencies(&[]); @@ -704,6 +709,7 @@ fn test_update_config_unsuccessful() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_update_config_successful() { let mut deps = mock_dependencies(&[]); @@ -753,7 +759,7 @@ fn test_update_config_successful() { instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for original config assert_eq!(config.owner, Addr::unchecked("addr0000")); @@ -781,7 +787,7 @@ fn test_update_config_successful() { execute(deps.as_mut(), env, info, update_config_message).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for new config assert_eq!(config.owner, Addr::unchecked("new_admin")); diff --git a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs index 1dce1b4d..7577bd9d 100644 --- a/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs +++ b/contracts/liquidity_hub/pool-network/stableswap_3pool/src/tests/withdrawals.rs @@ -7,7 +7,7 @@ use crate::state::{get_fees_for_asset, store_fee, COLLECTED_PROTOCOL_FEES}; use cosmwasm_std::coin; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, SubMsg, SubMsgResponse, + attr, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -18,6 +18,7 @@ use white_whale::pool_network::denom::MsgBurn; use white_whale::pool_network::mock_querier::mock_dependencies; use white_whale::pool_network::trio::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, PoolFee}; +#[cfg(not(feature = "osmosis"))] #[test] fn withdraw_liquidity_cw20_lp() { let mut deps = mock_dependencies(&[Coin { @@ -110,7 +111,7 @@ fn withdraw_liquidity_cw20_lp() { // withdraw liquidity let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -167,7 +168,7 @@ fn withdraw_liquidity_cw20_lp() { msg_refund_1, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_1_refund_amount, }) @@ -179,7 +180,7 @@ fn withdraw_liquidity_cw20_lp() { msg_refund_2, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0001".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_2_refund_amount, }) @@ -191,7 +192,7 @@ fn withdraw_liquidity_cw20_lp() { msg_burn_liquidity, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(100u128), }) .unwrap(), @@ -416,6 +417,7 @@ fn withdraw_liquidity_token_factory_lp_wrong_asset() { assert_eq!(err, ContractError::AssetMismatch {}); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_withdrawal_unauthorized() { let mut deps = mock_dependencies(&[Coin { @@ -475,7 +477,7 @@ fn test_withdrawal_unauthorized() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -489,6 +491,7 @@ fn test_withdrawal_unauthorized() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_withdrawal_wrong_message() { let mut deps = mock_dependencies(&[Coin { @@ -548,7 +551,7 @@ fn test_withdrawal_wrong_message() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&"invalid_message").unwrap(), + msg: to_json_binary(&"invalid_message").unwrap(), amount: Uint128::from(100u128), }); diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/Cargo.toml b/contracts/liquidity_hub/pool-network/terraswap_factory/Cargo.toml index e7b4097a..5d9b2854 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/Cargo.toml +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/Cargo.toml @@ -25,6 +25,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] # for quicker tests, cargo test --lib diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs index bfcff909..f39ede1d 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/commands.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, wasm_execute, CosmosMsg, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, + to_json_binary, wasm_execute, CosmosMsg, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, WasmMsg, }; @@ -69,9 +69,9 @@ pub fn update_pair_config( pool_fees: Option, feature_toggle: Option, ) -> Result { - Ok(Response::new() + Ok(Response::default() .add_message(wasm_execute( - deps.api.addr_validate(pair_addr.as_str())?.to_string(), + deps.api.addr_validate(&pair_addr)?.to_string(), &pool_network::pair::ExecuteMsg::UpdateConfig { owner, fee_collector_addr, @@ -161,13 +161,13 @@ pub fn create_pair( funds: info.funds, admin: Some(env.contract.address.to_string()), label: pair_label, - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos, token_code_id: config.token_code_id, asset_decimals, pool_fees, fee_collector_addr: config.fee_collector_addr.to_string(), - pair_type, + pair_type: pair_type.clone(), token_factory_lp, })?, }), @@ -175,6 +175,7 @@ pub fn create_pair( })) } +#[allow(clippy::too_many_arguments)] /// Updates a trio config pub fn update_trio_config( deps: DepsMut, @@ -187,7 +188,7 @@ pub fn update_trio_config( ) -> Result { Ok(Response::new() .add_message(wasm_execute( - deps.api.addr_validate(trio_addr.as_str())?.to_string(), + deps.api.addr_validate(&trio_addr)?.to_string(), &pool_network::trio::ExecuteMsg::UpdateConfig { owner, fee_collector_addr, @@ -293,7 +294,7 @@ pub fn create_trio( funds: info.funds, admin: Some(env.contract.address.to_string()), label: trio_label, - msg: to_binary(&TrioInstantiateMsg { + msg: to_json_binary(&TrioInstantiateMsg { asset_infos, token_code_id: config.token_code_id, asset_decimals, @@ -400,7 +401,7 @@ pub fn execute_migrate_pair( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: contract, new_code_id: pair_code_id, - msg: to_binary(&PairMigrateMsg {})?, + msg: to_json_binary(&PairMigrateMsg {})?, })), ) } @@ -426,7 +427,7 @@ pub fn execute_migrate_trio( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: contract, new_code_id: trio_code_id, - msg: to_binary(&TrioMigrateMsg {})?, + msg: to_json_binary(&TrioMigrateMsg {})?, })), ) } diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs index f9e7d075..be14e623 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, }; use cw2::{get_contract_version, set_contract_version}; use protobuf::Message; @@ -224,17 +224,17 @@ fn create_trio_reply(deps: DepsMut, msg: Reply) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::query_config(deps)?), - QueryMsg::Pair { asset_infos } => to_binary(&queries::query_pair(deps, asset_infos)?), + QueryMsg::Config {} => to_json_binary(&queries::query_config(deps)?), + QueryMsg::Pair { asset_infos } => to_json_binary(&queries::query_pair(deps, asset_infos)?), QueryMsg::Pairs { start_after, limit } => { - to_binary(&queries::query_pairs(deps, start_after, limit)?) + to_json_binary(&queries::query_pairs(deps, start_after, limit)?) } - QueryMsg::Trio { asset_infos } => to_binary(&queries::query_trio(deps, asset_infos)?), + QueryMsg::Trio { asset_infos } => to_json_binary(&queries::query_trio(deps, asset_infos)?), QueryMsg::Trios { start_after, limit } => { - to_binary(&queries::query_trios(deps, start_after, limit)?) + to_json_binary(&queries::query_trios(deps, start_after, limit)?) } QueryMsg::NativeTokenDecimals { denom } => { - to_binary(&queries::query_native_token_decimal(deps, denom)?) + to_json_binary(&queries::query_native_token_decimal(deps, denom)?) } } } @@ -258,9 +258,11 @@ pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result Result<(), StdError> { Ok(()) } +#[cfg(not(feature = "osmosis"))] /// Migrate state of the factory for the StableSwap deployment pub fn migrate_to_v120(deps: DepsMut) -> Result<(), StdError> { // migrate the TmpPairInfo struct changed in c9395c4f9d2a7b163056db0de33ab9066090969d diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/queries.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/queries.rs index 15095aa1..4e2c6d04 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/queries.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/queries.rs @@ -10,15 +10,14 @@ use white_whale::pool_network::factory::{ /// Queries [Config] pub fn query_config(deps: Deps) -> StdResult { let config: Config = CONFIG.load(deps.storage)?; - let resp = ConfigResponse { + + Ok(ConfigResponse { owner: deps.api.addr_humanize(&config.owner)?.to_string(), token_code_id: config.token_code_id, pair_code_id: config.pair_code_id, trio_code_id: config.trio_code_id, fee_collector_addr: config.fee_collector_addr.to_string(), - }; - - Ok(resp) + }) } /// Queries info about a given Pair diff --git a/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs b/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs index 991753da..f9734b4e 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_factory/src/testing.rs @@ -2,7 +2,7 @@ use cosmwasm_std::testing::{ mock_dependencies_with_balance, mock_env, mock_info, MockApi, MockStorage, MOCK_CONTRACT_ADDR, }; use cosmwasm_std::{ - attr, coin, from_binary, to_binary, Api, CanonicalAddr, Coin, CosmosMsg, Decimal, OwnedDeps, + attr, coin, from_json, to_json_binary, Api, CanonicalAddr, Coin, CosmosMsg, Decimal, OwnedDeps, Reply, ReplyOn, Response, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; @@ -45,7 +45,7 @@ fn proper_initialization() { let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: ConfigResponse = from_binary(&query_res).unwrap(); + let config_res: ConfigResponse = from_json(&query_res).unwrap(); assert_eq!(123u64, config_res.token_code_id); assert_eq!(321u64, config_res.pair_code_id); assert_eq!("addr0000".to_string(), config_res.owner); @@ -93,6 +93,7 @@ fn update_config() { // update owner let info = mock_info("addr0000", &[]); + let msg = ExecuteMsg::UpdateConfig { owner: Some("addr0001".to_string()), pair_code_id: None, @@ -106,7 +107,7 @@ fn update_config() { // it worked, let's query the state let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: ConfigResponse = from_binary(&query_res).unwrap(); + let config_res: ConfigResponse = from_json(&query_res).unwrap(); assert_eq!(123u64, config_res.token_code_id); assert_eq!(321u64, config_res.pair_code_id); assert_eq!("addr0001".to_string(), config_res.owner); @@ -115,6 +116,7 @@ fn update_config() { // update left items let env = mock_env(); let info = mock_info("addr0001", &[]); + let msg = ExecuteMsg::UpdateConfig { owner: None, pair_code_id: Some(100u64), @@ -128,7 +130,7 @@ fn update_config() { // it worked, let's query the state let query_res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); - let config_res: ConfigResponse = from_binary(&query_res).unwrap(); + let config_res: ConfigResponse = from_json(&query_res).unwrap(); assert_eq!(200u64, config_res.token_code_id); assert_eq!(100u64, config_res.pair_code_id); assert_eq!(300u64, config_res.trio_code_id); @@ -214,19 +216,38 @@ fn create_pair() { }, ]; + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::percent(1u64), + }, + }; + let msg = ExecuteMsg::CreatePair { asset_infos: asset_infos.clone(), - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, + pool_fees: pool_fees.clone(), pair_type: PairType::ConstantProduct, token_factory_lp: false, }; @@ -249,6 +270,17 @@ fn create_pair() { attr("pair_type", "ConstantProduct"), ] ); + + let expected_msg = PairInstantiateMsg { + asset_infos: asset_infos.clone(), + token_code_id: 123u64, + asset_decimals: [6u8, 8u8], + pool_fees: pool_fees.clone(), + fee_collector_addr: "collector".to_string(), + pair_type: PairType::ConstantProduct, + token_factory_lp: false, + }; + assert_eq!( res.messages, vec![SubMsg { @@ -256,26 +288,7 @@ fn create_pair() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { - asset_infos: asset_infos.clone(), - token_code_id: 123u64, - asset_decimals: [6u8, 8u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, - fee_collector_addr: "collector".to_string(), - pair_type: PairType::ConstantProduct, - token_factory_lp: false, - }) - .unwrap(), + msg: to_json_binary(&expected_msg).unwrap(), code_id: 321u64, funds: [Coin { denom: "uusd".to_string(), @@ -320,19 +333,38 @@ fn create_stableswap_pair() { }, ]; + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::percent(1u64), + }, + }; + let msg = ExecuteMsg::CreatePair { asset_infos: asset_infos.clone(), - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, + pool_fees: pool_fees.clone(), pair_type: PairType::StableSwap { amp: 100 }, token_factory_lp: false, }; @@ -349,6 +381,17 @@ fn create_stableswap_pair() { attr("pair_type", "StableSwap"), ] ); + + let expected_msg = PairInstantiateMsg { + asset_infos: asset_infos.clone(), + token_code_id: 123u64, + asset_decimals: [6u8, 8u8], + pool_fees: pool_fees.clone(), + fee_collector_addr: "collector".to_string(), + pair_type: PairType::StableSwap { amp: 100 }, + token_factory_lp: false, + }; + assert_eq!( res.messages, vec![SubMsg { @@ -356,26 +399,7 @@ fn create_stableswap_pair() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { - asset_infos: asset_infos.clone(), - token_code_id: 123u64, - asset_decimals: [6u8, 8u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, - fee_collector_addr: "collector".to_string(), - pair_type: PairType::StableSwap { amp: 100 }, - token_factory_lp: false, - }) - .unwrap(), + msg: to_json_binary(&expected_msg).unwrap(), code_id: 321u64, funds: vec![], label: "uusd-mAAPL pair".to_string(), @@ -432,19 +456,38 @@ fn create_pair_native_token_and_ibc_token() { }, ]; + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::percent(1u64), + }, + }; + let msg = ExecuteMsg::CreatePair { asset_infos: asset_infos.clone(), - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, + pool_fees: pool_fees.clone(), pair_type: PairType::ConstantProduct, token_factory_lp: false, }; @@ -461,6 +504,17 @@ fn create_pair_native_token_and_ibc_token() { attr("pair_type", "ConstantProduct"), ] ); + + let expected_msg = PairInstantiateMsg { + asset_infos: asset_infos.clone(), + token_code_id: 123u64, + asset_decimals: [6u8, 6u8], + pool_fees: pool_fees.clone(), + fee_collector_addr: "collector".to_string(), + pair_type: PairType::ConstantProduct, + token_factory_lp: false, + }; + assert_eq!( res.messages, vec![SubMsg { @@ -468,26 +522,7 @@ fn create_pair_native_token_and_ibc_token() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { - asset_infos: asset_infos.clone(), - token_code_id: 123u64, - asset_decimals: [6u8, 6u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, - fee_collector_addr: "collector".to_string(), - pair_type: PairType::ConstantProduct, - token_factory_lp: false, - }) - .unwrap(), + msg: to_json_binary(&expected_msg).unwrap(), code_id: 321u64, funds: vec![], label: "uusd-ibc/2739...5EB2 pair".to_string(), @@ -551,19 +586,38 @@ fn create_ibc_tokens_pair() { }, ]; + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(1u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::percent(1u64), + }, + }; + let msg = ExecuteMsg::CreatePair { asset_infos: asset_infos.clone(), - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, + pool_fees: pool_fees.clone(), pair_type: PairType::ConstantProduct, token_factory_lp: false, }; @@ -580,6 +634,17 @@ fn create_ibc_tokens_pair() { attr("pair_type", "ConstantProduct"), ] ); + + let expected_msg = PairInstantiateMsg { + asset_infos: asset_infos.clone(), + token_code_id: 123u64, + asset_decimals: [6u8, 6u8], + pool_fees: pool_fees.clone(), + fee_collector_addr: "collector".to_string(), + pair_type: PairType::ConstantProduct, + token_factory_lp: false, + }; + assert_eq!( res.messages, vec![SubMsg { @@ -587,26 +652,7 @@ fn create_ibc_tokens_pair() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { - asset_infos: asset_infos.clone(), - token_code_id: 123u64, - asset_decimals: [6u8, 6u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(1u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, - fee_collector_addr: "collector".to_string(), - pair_type: PairType::ConstantProduct, - token_factory_lp: false, - }) - .unwrap(), + msg: to_json_binary(&expected_msg).unwrap(), code_id: 321u64, funds: vec![], label: "ibc/4CD5...3D04-ibc/2739...5EB2 pair".to_string(), @@ -706,7 +752,7 @@ fn create_pair_ethereum_asset_and_ibc_token() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&PairInstantiateMsg { + msg: to_json_binary(&PairInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 6u8], @@ -751,6 +797,7 @@ fn create_pair_ethereum_asset_and_ibc_token() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn fail_to_create_same_pair() { let mut deps = mock_dependencies(&[coin(10u128, "uusd".to_string())]); @@ -793,6 +840,7 @@ fn fail_to_create_same_pair() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn fail_to_create_existing_pair() { let mut deps = mock_dependencies(&[coin(10u128, "uusd".to_string())]); @@ -860,6 +908,7 @@ fn fail_to_create_existing_pair() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn fail_to_create_pair_with_inactive_denoms() { let mut deps = mock_dependencies(&[coin(10u128, "uusd".to_string())]); @@ -902,6 +951,7 @@ fn fail_to_create_pair_with_inactive_denoms() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn fail_to_create_pair_with_invalid_denom() { let mut deps = mock_dependencies(&[coin(10u128, "valid".to_string())]); @@ -982,6 +1032,7 @@ fn fail_to_create_pair_with_invalid_denom() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn fail_to_create_pair_with_unknown_token() { let mut deps = mock_dependencies(&[coin(10u128, "uusd".to_string())]); @@ -1036,6 +1087,7 @@ fn fail_to_create_pair_with_unknown_token() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn fail_to_create_pair_with_unknown_ibc_token() { let mut deps = mock_dependencies_with_balance(&[coin(10u128, "uusd".to_string())]); @@ -1172,7 +1224,7 @@ fn reply_test() { ) .unwrap(); - let pair_res: PairInfo = from_binary(&query_res).unwrap(); + let pair_res: PairInfo = from_json(&query_res).unwrap(); assert_eq!( pair_res, PairInfo { @@ -1216,7 +1268,7 @@ fn normal_add_allow_native_token() { }, ) .unwrap(); - let res: NativeTokenDecimalsResponse = from_binary(&res).unwrap(); + let res: NativeTokenDecimalsResponse = from_json(&res).unwrap(); assert_eq!(6u8, res.decimals) } @@ -1263,7 +1315,7 @@ fn append_add_allow_native_token_with_already_exist_token() { }, ) .unwrap(); - let res: NativeTokenDecimalsResponse = from_binary(&res).unwrap(); + let res: NativeTokenDecimalsResponse = from_json(&res).unwrap(); assert_eq!(6u8, res.decimals); let msg = ExecuteMsg::AddNativeTokenDecimals { @@ -1281,10 +1333,11 @@ fn append_add_allow_native_token_with_already_exist_token() { }, ) .unwrap(); - let res: NativeTokenDecimalsResponse = from_binary(&res).unwrap(); + let res: NativeTokenDecimalsResponse = from_json(&res).unwrap(); assert_eq!(7u8, res.decimals) } +#[cfg(not(feature = "osmosis"))] #[test] fn execute_transactions_unauthorized() { let mut deps = mock_dependencies(&[coin(10u128, "uusd".to_string())]); @@ -1377,7 +1430,7 @@ fn normal_migrate_pair() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 123u64, - msg: to_binary(&PairMigrateMsg {}).unwrap(), + msg: to_json_binary(&PairMigrateMsg {}).unwrap(), })), ); } @@ -1399,7 +1452,7 @@ fn normal_migrate_trio() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 123u64, - msg: to_binary(&TrioMigrateMsg {}).unwrap(), + msg: to_json_binary(&TrioMigrateMsg {}).unwrap(), })), ); } @@ -1421,7 +1474,7 @@ fn normal_migrate_pair_with_none_code_id_will_config_code_id() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 321u64, - msg: to_binary(&PairMigrateMsg {}).unwrap(), + msg: to_json_binary(&PairMigrateMsg {}).unwrap(), })), ); } @@ -1443,7 +1496,7 @@ fn normal_migrate_trio_with_none_code_id_will_config_code_id() { Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: "contract0000".to_string(), new_code_id: 456u64, - msg: to_binary(&TrioMigrateMsg {}).unwrap(), + msg: to_json_binary(&TrioMigrateMsg {}).unwrap(), })), ); } @@ -1575,6 +1628,7 @@ fn delete_pair_failed_if_not_found() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn update_pair_config() { let mut deps = mock_dependencies(&[coin(10u128, "uusd".to_string())]); @@ -1609,7 +1663,7 @@ fn update_pair_config() { .add_message(WasmMsg::Execute { contract_addr: "pair_addr".to_string(), funds: vec![], - msg: to_binary(&pool_network::pair::ExecuteMsg::UpdateConfig { + msg: to_json_binary(&pool_network::pair::ExecuteMsg::UpdateConfig { owner: Some("new_owner".to_string()), fee_collector_addr: None, pool_fees: Some(PoolFee { @@ -1630,6 +1684,7 @@ fn update_pair_config() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn create_trio_cw20_lp() { let mut deps = mock_dependencies(&[ @@ -1693,7 +1748,7 @@ fn create_trio_cw20_lp() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&TrioInstantiateMsg { + msg: to_json_binary(&TrioInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 8u8, 10u8], @@ -1738,6 +1793,7 @@ fn create_trio_cw20_lp() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn create_trio_with_native_tokens_token_factory_lp() { let mut deps = mock_dependencies(&[ @@ -1822,7 +1878,7 @@ fn create_trio_with_native_tokens_token_factory_lp() { gas_limit: None, reply_on: ReplyOn::Success, msg: WasmMsg::Instantiate { - msg: to_binary(&TrioInstantiateMsg { + msg: to_json_binary(&TrioInstantiateMsg { asset_infos: asset_infos.clone(), token_code_id: 123u64, asset_decimals: [6u8, 6u8, 6u8], diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/Cargo.toml b/contracts/liquidity_hub/pool-network/terraswap_pair/Cargo.toml index 0111fe44..63e7168d 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/Cargo.toml +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/Cargo.toml @@ -29,6 +29,7 @@ crate-type = ["cdylib", "rlib"] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] @@ -45,6 +46,7 @@ thiserror.workspace = true protobuf.workspace = true white-whale.workspace = true cosmwasm-schema.workspace = true +anybuf.workspace = true [dev-dependencies] cw-multi-test.workspace = true diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs index b6753f98..c0f98223 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/commands.rs @@ -1,15 +1,17 @@ -use cosmwasm_std::{ - from_binary, to_binary, Addr, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, OverflowError, - Response, StdError, StdResult, Uint128, WasmMsg, -}; -use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; - +#[cfg(feature = "osmosis")] +use anybuf::Anybuf; #[cfg(any( feature = "token_factory", feature = "osmosis_token_factory", feature = "injective" ))] use cosmwasm_std::coins; +use cosmwasm_std::{ + from_json, to_json_binary, Addr, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, OverflowError, + Response, StdError, StdResult, Uint128, WasmMsg, +}; +use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; + #[cfg(any( feature = "token_factory", feature = "osmosis_token_factory", @@ -49,7 +51,7 @@ pub fn receive_cw20( let contract_addr = info.sender.clone(); let feature_toggle: FeatureToggle = CONFIG.load(deps.storage)?.feature_toggle; - match from_binary(&cw20_msg.msg) { + match from_json(&cw20_msg.msg) { Ok(Cw20HookMsg::Swap { belief_price, max_spread, @@ -171,7 +173,7 @@ pub fn provide_liquidity( if let AssetInfo::Token { contract_addr, .. } = &pool.info { messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: info.sender.to_string(), recipient: env.contract.address.to_string(), amount: deposits[i], @@ -362,8 +364,13 @@ pub fn swap( let ask_decimal: u8; // To calculate pool amounts properly we should subtract user deposit and the protocol fees from the pool + #[cfg(not(feature = "osmosis"))] + let contract_addr = env.contract.address; + #[cfg(feature = "osmosis")] + let contract_addr = env.contract.address.clone(); + let pools = pair_info - .query_pools(&deps.querier, deps.api, env.contract.address)? + .query_pools(&deps.querier, deps.api, contract_addr)? .into_iter() .map(|mut pool| { // subtract the protocol fee from the pool @@ -396,13 +403,13 @@ pub fn swap( } let offer_amount = offer_asset.amount; - let pool_fees = CONFIG.load(deps.storage)?.pool_fees; + let config = CONFIG.load(deps.storage)?; let swap_computation = helpers::compute_swap( offer_pool.amount, ask_pool.amount, offer_amount, - pool_fees, + config.pool_fees, &pair_info.pair_type, offer_decimal, ask_decimal, @@ -413,10 +420,22 @@ pub fn swap( amount: swap_computation.return_amount, }; - let fees = swap_computation - .swap_fee_amount - .checked_add(swap_computation.protocol_fee_amount)? - .checked_add(swap_computation.burn_fee_amount)?; + let fees = { + let base_fees = swap_computation + .swap_fee_amount + .checked_add(swap_computation.protocol_fee_amount)? + .checked_add(swap_computation.burn_fee_amount)?; + + #[cfg(feature = "osmosis")] + { + base_fees.checked_add(swap_computation.osmosis_fee_amount)? + } + + #[cfg(not(feature = "osmosis"))] + { + base_fees + } + }; // check max spread limit if exist swap::assert_max_spread( @@ -451,6 +470,32 @@ pub fn swap( messages.push(burn_asset.into_burn_msg()?); } + #[cfg(feature = "osmosis")] + if !swap_computation.osmosis_fee_amount.is_zero() { + // send osmosis fee to the Community Pool + let denom = match ask_pool.info.clone() { + AssetInfo::Token { .. } => return Err(StdError::generic_err("Not supported").into()), + AssetInfo::NativeToken { denom } => denom, + }; + + //https://docs.cosmos.network/v0.45/core/proto-docs.html#cosmos.distribution.v1beta1.MsgFundCommunityPool + let community_pool_msg = CosmosMsg::Stargate { + type_url: "/cosmos.distribution.v1beta1.MsgFundCommunityPool".to_string(), + value: Anybuf::new() + .append_repeated_message( + 1, + &[&Anybuf::new() + .append_string(1, denom) + .append_string(2, swap_computation.osmosis_fee_amount.to_string())], + ) + .append_string(2, &env.contract.address) + .into_vec() + .into(), + }; + + messages.push(community_pool_msg); + } + // Store the protocol fees generated by this swap. The protocol fees are collected on the ask // asset as shown in [compute_swap] store_fee( @@ -489,6 +534,11 @@ pub fn swap( "burn_fee_amount", &swap_computation.burn_fee_amount.to_string(), ), + #[cfg(feature = "osmosis")] + ( + "osmosis_fee_amount", + &swap_computation.osmosis_fee_amount.to_string(), + ), ("swap_type", pair_info.pair_type.get_label()), ])) } @@ -613,7 +663,7 @@ fn mint_lp_token_msg( } else { Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -625,7 +675,7 @@ fn mint_lp_token_msg( ))] Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -653,7 +703,7 @@ fn burn_lp_token_msg( } else { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } @@ -664,7 +714,7 @@ fn burn_lp_token_msg( ))] Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_token, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs index 25145ae5..dc267f91 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, + to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, }; use cw2::{get_contract_version, set_contract_version}; @@ -65,7 +65,6 @@ pub fn instantiate( // check the fees are valid msg.pool_fees.is_valid()?; - // Set owner and initial pool fees let config = Config { owner: deps.api.addr_validate(info.sender.as_str())?, fee_collector_addr: deps.api.addr_validate(msg.fee_collector_addr.as_str())?, @@ -76,6 +75,7 @@ pub fn instantiate( swaps_enabled: true, }, }; + CONFIG.save(deps.storage, &config)?; // Instantiate the collected protocol fees @@ -203,23 +203,24 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Pair {} => Ok(to_binary(&queries::query_pair_info(deps)?)?), - QueryMsg::Pool {} => Ok(to_binary(&queries::query_pool(deps)?)?), - QueryMsg::Simulation { offer_asset } => { - Ok(to_binary(&queries::query_simulation(deps, offer_asset)?)?) - } - QueryMsg::ReverseSimulation { ask_asset } => Ok(to_binary( + QueryMsg::Pair {} => Ok(to_json_binary(&queries::query_pair_info(deps)?)?), + QueryMsg::Pool {} => Ok(to_json_binary(&queries::query_pool(deps)?)?), + QueryMsg::Simulation { offer_asset } => Ok(to_json_binary(&queries::query_simulation( + deps, + offer_asset, + )?)?), + QueryMsg::ReverseSimulation { ask_asset } => Ok(to_json_binary( &queries::query_reverse_simulation(deps, ask_asset)?, )?), - QueryMsg::Config {} => Ok(to_binary(&queries::query_config(deps)?)?), - QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_binary(&queries::query_fees( + QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?), + QueryMsg::ProtocolFees { asset_id, all_time } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, all_time, COLLECTED_PROTOCOL_FEES, Some(ALL_TIME_COLLECTED_PROTOCOL_FEES), )?)?), - QueryMsg::BurnedFees { asset_id } => Ok(to_binary(&queries::query_fees( + QueryMsg::BurnedFees { asset_id } => Ok(to_json_binary(&queries::query_fees( deps, asset_id, None, @@ -234,6 +235,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Result { use white_whale::migrate_guards::check_contract_name; + #[cfg(not(feature = "osmosis"))] use crate::migrations; check_contract_name(deps.storage, CONTRACT_NAME.to_string())?; @@ -253,13 +255,13 @@ pub fn migrate(mut deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { let offer_pool = Decimal256::decimal_with_precision(offer_pool, offer_precision)?; @@ -235,28 +270,63 @@ pub fn compute_swap( let protocol_fee_amount: Uint256 = pool_fees.protocol_fee.compute(return_amount); let burn_fee_amount: Uint256 = pool_fees.burn_fee.compute(return_amount); - let return_amount = return_amount - .checked_sub(swap_fee_amount)? - .checked_sub(protocol_fee_amount)? - .checked_sub(burn_fee_amount)?; + #[cfg(not(feature = "osmosis"))] + { + let return_amount = return_amount + .checked_sub(swap_fee_amount)? + .checked_sub(protocol_fee_amount)? + .checked_sub(burn_fee_amount)?; + + Ok(SwapComputation { + return_amount: return_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + spread_amount: spread_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + swap_fee_amount: swap_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + protocol_fee_amount: protocol_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + burn_fee_amount: burn_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + }) + } - Ok(SwapComputation { - return_amount: return_amount - .try_into() - .map_err(|_| ContractError::SwapOverflowError {})?, - spread_amount: spread_amount - .try_into() - .map_err(|_| ContractError::SwapOverflowError {})?, - swap_fee_amount: swap_fee_amount - .try_into() - .map_err(|_| ContractError::SwapOverflowError {})?, - protocol_fee_amount: protocol_fee_amount - .try_into() - .map_err(|_| ContractError::SwapOverflowError {})?, - burn_fee_amount: burn_fee_amount - .try_into() - .map_err(|_| ContractError::SwapOverflowError {})?, - }) + #[cfg(feature = "osmosis")] + { + let osmosis_fee_amount: Uint256 = pool_fees.osmosis_fee.compute(return_amount); + + let return_amount = return_amount + .checked_sub(swap_fee_amount)? + .checked_sub(protocol_fee_amount)? + .checked_sub(burn_fee_amount)? + .checked_sub(osmosis_fee_amount)?; + + Ok(SwapComputation { + return_amount: return_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + spread_amount: spread_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + swap_fee_amount: swap_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + protocol_fee_amount: protocol_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + burn_fee_amount: burn_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + osmosis_fee_amount: osmosis_fee_amount + .try_into() + .map_err(|_| ContractError::SwapOverflowError {})?, + }) + } } } } @@ -269,6 +339,8 @@ pub struct SwapComputation { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } pub fn compute_offer_amount( @@ -283,9 +355,22 @@ pub fn compute_offer_amount( // ask => offer // offer_amount = cp / (ask_pool - ask_amount / (1 - fees)) - offer_pool - let fees = pool_fees.swap_fee.to_decimal_256() - + pool_fees.protocol_fee.to_decimal_256() - + pool_fees.burn_fee.to_decimal_256(); + let fees = { + let base_fees = pool_fees.swap_fee.to_decimal_256() + + pool_fees.protocol_fee.to_decimal_256() + + pool_fees.burn_fee.to_decimal_256(); + + #[cfg(feature = "osmosis")] + { + base_fees + pool_fees.osmosis_fee.to_decimal_256() + } + + #[cfg(not(feature = "osmosis"))] + { + base_fees + } + }; + let one_minus_commission = Decimal256::one() - fees; let inv_one_minus_commission = Decimal256::one() / one_minus_commission; @@ -298,23 +383,37 @@ pub fn compute_offer_amount( let before_spread_deduction: Uint256 = offer_amount * Decimal256::from_ratio(ask_pool, offer_pool); - let spread_amount = if before_spread_deduction > before_commission_deduction { - before_spread_deduction - before_commission_deduction - } else { - Uint256::zero() - }; + let spread_amount = before_spread_deduction.saturating_sub(before_commission_deduction); let swap_fee_amount: Uint256 = pool_fees.swap_fee.compute(before_commission_deduction); let protocol_fee_amount: Uint256 = pool_fees.protocol_fee.compute(before_commission_deduction); let burn_fee_amount: Uint256 = pool_fees.burn_fee.compute(before_commission_deduction); - Ok(OfferAmountComputation { - offer_amount: offer_amount.try_into()?, - spread_amount: spread_amount.try_into()?, - swap_fee_amount: swap_fee_amount.try_into()?, - protocol_fee_amount: protocol_fee_amount.try_into()?, - burn_fee_amount: burn_fee_amount.try_into()?, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(OfferAmountComputation { + offer_amount: offer_amount.try_into()?, + spread_amount: spread_amount.try_into()?, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + }) + } + + #[cfg(feature = "osmosis")] + { + let osmosis_fee_amount: Uint256 = + pool_fees.osmosis_fee.compute(before_commission_deduction); + + Ok(OfferAmountComputation { + offer_amount: offer_amount.try_into()?, + spread_amount: spread_amount.try_into()?, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + osmosis_fee_amount: osmosis_fee_amount.try_into()?, + }) + } } /// Represents the offer amount computation values @@ -325,6 +424,8 @@ pub struct OfferAmountComputation { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } pub fn assert_slippage_tolerance( @@ -454,7 +555,7 @@ pub fn create_lp_token( msg: WasmMsg::Instantiate { admin: None, code_id: msg.token_code_id, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: lp_token_name.to_owned(), symbol: LP_SYMBOL.to_string(), decimals: 6, diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/migrations.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/migrations.rs index ef64bbdf..a2e9f73d 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/migrations.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/migrations.rs @@ -19,7 +19,7 @@ use crate::helpers::instantiate_fees; use crate::state::PAIR_INFO; use crate::state::{ALL_TIME_BURNED_FEES, CONFIG}; -#[cfg(not(feature = "injective"))] +#[cfg(all(not(feature = "injective"), not(feature = "osmosis")))] /// Migrate state of the factory from PascalCase to snake_case for the following items: /// [`PairInfoRaw`], [`PairInfo`] /// as identified by commit c8d8462c6933b93245acdc8abbe303287fdc1951 which changed the structs to use @@ -74,7 +74,7 @@ pub fn migrate_to_v110(deps: DepsMut) -> Result<(), StdError> { Ok(()) } -#[cfg(not(feature = "injective"))] +#[cfg(all(not(feature = "injective"), not(feature = "osmosis")))] pub fn migrate_to_v120(deps: DepsMut) -> Result<(), StdError> { #[cw_serde] struct ConfigV110 { @@ -124,7 +124,7 @@ pub fn migrate_to_v120(deps: DepsMut) -> Result<(), StdError> { Ok(()) } -#[cfg(not(feature = "injective"))] +#[cfg(all(not(feature = "injective"), not(feature = "osmosis")))] /// Migrate to the StableSwap deployment /// /// Default to a ConstantProduct pool diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/queries.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/queries.rs index f4ac84ec..6f2fc265 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/queries.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/queries.rs @@ -123,13 +123,28 @@ pub fn query_simulation( ask_decimal, )?; - Ok(SimulationResponse { - return_amount: swap_computation.return_amount, - spread_amount: swap_computation.spread_amount, - swap_fee_amount: swap_computation.swap_fee_amount, - protocol_fee_amount: swap_computation.protocol_fee_amount, - burn_fee_amount: swap_computation.burn_fee_amount, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(SimulationResponse { + return_amount: swap_computation.return_amount, + spread_amount: swap_computation.spread_amount, + swap_fee_amount: swap_computation.swap_fee_amount, + protocol_fee_amount: swap_computation.protocol_fee_amount, + burn_fee_amount: swap_computation.burn_fee_amount, + }) + } + + #[cfg(feature = "osmosis")] + { + Ok(SimulationResponse { + return_amount: swap_computation.return_amount, + spread_amount: swap_computation.spread_amount, + swap_fee_amount: swap_computation.swap_fee_amount, + protocol_fee_amount: swap_computation.protocol_fee_amount, + burn_fee_amount: swap_computation.burn_fee_amount, + osmosis_fee_amount: swap_computation.osmosis_fee_amount, + }) + } } /// Queries a swap reverse simulation. Used to derive the number of source tokens returned for @@ -190,13 +205,28 @@ pub fn query_reverse_simulation( pool_fees, )?; - Ok(ReverseSimulationResponse { - offer_amount: offer_amount_computation.offer_amount, - spread_amount: offer_amount_computation.spread_amount, - swap_fee_amount: offer_amount_computation.swap_fee_amount, - protocol_fee_amount: offer_amount_computation.protocol_fee_amount, - burn_fee_amount: offer_amount_computation.burn_fee_amount, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(ReverseSimulationResponse { + offer_amount: offer_amount_computation.offer_amount, + spread_amount: offer_amount_computation.spread_amount, + swap_fee_amount: offer_amount_computation.swap_fee_amount, + protocol_fee_amount: offer_amount_computation.protocol_fee_amount, + burn_fee_amount: offer_amount_computation.burn_fee_amount, + }) + } + + #[cfg(feature = "osmosis")] + { + Ok(ReverseSimulationResponse { + offer_amount: offer_amount_computation.offer_amount, + spread_amount: offer_amount_computation.spread_amount, + swap_fee_amount: offer_amount_computation.swap_fee_amount, + protocol_fee_amount: offer_amount_computation.protocol_fee_amount, + burn_fee_amount: offer_amount_computation.burn_fee_amount, + osmosis_fee_amount: offer_amount_computation.osmosis_fee_amount, + }) + } } PairType::StableSwap { amp } => { let offer_pool = Decimal256::decimal_with_precision(offer_pool.amount, offer_decimal)?; @@ -248,13 +278,30 @@ pub fn query_reverse_simulation( let protocol_fee_amount = pool_fees.protocol_fee.compute(before_fees_ask); let burn_fee_amount = pool_fees.burn_fee.compute(before_fees_ask); - Ok(ReverseSimulationResponse { - offer_amount, - spread_amount, - swap_fee_amount: swap_fee_amount.try_into()?, - protocol_fee_amount: protocol_fee_amount.try_into()?, - burn_fee_amount: burn_fee_amount.try_into()?, - }) + #[cfg(not(feature = "osmosis"))] + { + Ok(ReverseSimulationResponse { + offer_amount, + spread_amount, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + }) + } + + #[cfg(feature = "osmosis")] + { + let osmosis_fee_amount = pool_fees.osmosis_fee.compute(before_fees_ask); + + Ok(ReverseSimulationResponse { + offer_amount, + spread_amount, + swap_fee_amount: swap_fee_amount.try_into()?, + protocol_fee_amount: protocol_fee_amount.try_into()?, + burn_fee_amount: burn_fee_amount.try_into()?, + osmosis_fee_amount: osmosis_fee_amount.try_into()?, + }) + } } } } diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs index 117b7352..4ffad952 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/feature_toggle.rs @@ -1,7 +1,7 @@ use crate::contract::{execute, instantiate}; use crate::error::ContractError; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; -use cosmwasm_std::{to_binary, Coin, Decimal, Uint128}; +use cosmwasm_std::{to_json_binary, Coin, Decimal, Uint128}; use cw20::Cw20ReceiveMsg; use white_whale::fee::Fee; use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; @@ -11,6 +11,7 @@ use white_whale::pool_network::pair::{ Cw20HookMsg, ExecuteMsg, FeatureToggle, InstantiateMsg, PoolFee, }; +#[cfg(not(feature = "osmosis"))] #[test] fn test_feature_toggle_swap_disabled() { let mut deps = mock_dependencies(&[Coin { @@ -103,7 +104,7 @@ fn test_feature_toggle_swap_disabled() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -118,6 +119,7 @@ fn test_feature_toggle_swap_disabled() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_feature_toggle_withdrawals_disabled() { let mut deps = mock_dependencies(&[Coin { @@ -183,7 +185,7 @@ fn test_feature_toggle_withdrawals_disabled() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -197,6 +199,7 @@ fn test_feature_toggle_withdrawals_disabled() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_feature_toggle_deposits_disabled() { let mut deps = mock_dependencies(&[Coin { diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs index a979de45..f3459fc7 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/protocol_fees.rs @@ -3,7 +3,7 @@ use crate::queries::query_fees; use crate::state::{ALL_TIME_COLLECTED_PROTOCOL_FEES, COLLECTED_PROTOCOL_FEES}; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -12,6 +12,7 @@ use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; use white_whale::pool_network::mock_querier::mock_dependencies; use white_whale::pool_network::pair::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, PoolFee}; +#[cfg(not(feature = "osmosis"))] #[test] fn test_protocol_fees() { let total_share = Uint128::from(300_000_000_000u128); @@ -196,6 +197,7 @@ fn test_protocol_fees() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_collect_protocol_fees_successful() { let total_share = Uint128::from(300_000_000_000u128); @@ -299,7 +301,7 @@ fn test_collect_protocol_fees_successful() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -366,7 +368,7 @@ fn test_collect_protocol_fees_successful() { transfer_cw20_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees_for_token.first().unwrap().amount, }) @@ -424,6 +426,7 @@ fn test_collect_protocol_fees_successful() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_collect_protocol_fees_successful_1_fee_only() { let total_share = Uint128::from(300_000_000_000u128); @@ -548,7 +551,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() { transfer_cw20_token_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "collector".to_string(), amount: protocol_fees[1].amount, }) @@ -603,6 +606,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn protocol_fees() { let protocol_fee = PoolFee { @@ -682,3 +686,99 @@ fn protocol_fees() { }; assert_eq!(protocol_fee.is_valid(), Ok(())); } + +#[cfg(feature = "osmosis")] +#[test] +fn protocol_fees_osmosis() { + let protocol_fee = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(50), + }, + swap_fee: Fee { + share: Decimal::percent(50), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::zero(), + }, + }; + assert_eq!( + protocol_fee.is_valid(), + Err(StdError::generic_err("Invalid fees")) + ); + + let protocol_fee = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(200), + }, + swap_fee: Fee { + share: Decimal::percent(20), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::zero(), + }, + }; + assert_eq!( + protocol_fee.is_valid(), + Err(StdError::generic_err("Invalid fee")) + ); + + let protocol_fee = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(20), + }, + swap_fee: Fee { + share: Decimal::percent(200), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::zero(), + }, + }; + assert_eq!( + protocol_fee.is_valid(), + Err(StdError::generic_err("Invalid fee")) + ); + + let protocol_fee = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(40), + }, + swap_fee: Fee { + share: Decimal::percent(60), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::zero(), + }, + }; + assert_eq!( + protocol_fee.is_valid(), + Err(StdError::generic_err("Invalid fees")) + ); + + let protocol_fee = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(20), + }, + swap_fee: Fee { + share: Decimal::percent(60), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::percent(10), + }, + }; + assert_eq!(protocol_fee.is_valid(), Ok(())); +} diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs index 1d54b0f1..e26f6f17 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/provide_liquidity.rs @@ -2,7 +2,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; #[cfg(feature = "token_factory")] use cosmwasm_std::{coin, BankMsg}; use cosmwasm_std::{ - to_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, + to_json_binary, Coin, CosmosMsg, Decimal, Reply, Response, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -30,6 +30,7 @@ use cosmwasm_std::coin; #[cfg(feature = "injective")] use cw_multi_test::Executor; +#[cfg(not(feature = "osmosis"))] #[test] fn provide_liquidity_cw20_lp() { let mut deps = mock_dependencies(&[Coin { @@ -166,7 +167,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(2_000u128), @@ -179,7 +180,7 @@ fn provide_liquidity_cw20_lp() { mint_initial_lp_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "cosmos2contract".to_string(), amount: MINIMUM_LIQUIDITY_AMOUNT, }) @@ -191,7 +192,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "addr0000".to_string(), amount: Uint128::from(1_000u128), }) @@ -261,7 +262,7 @@ fn provide_liquidity_cw20_lp() { transfer_from_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "addr0000".to_string(), recipient: MOCK_CONTRACT_ADDR.to_string(), amount: Uint128::from(100u128), @@ -274,7 +275,7 @@ fn provide_liquidity_cw20_lp() { mint_msg, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "staking0000".to_string(), // LP tokens sent to specified receiver amount: Uint128::from(50u128), }) @@ -500,6 +501,7 @@ fn provide_liquidity_cw20_lp() { let _res = execute(deps.as_mut(), env, info, msg).unwrap(); } +#[cfg(not(feature = "osmosis"))] #[test] fn provide_liquidity_zero_amount() { let mut deps = mock_dependencies(&[Coin { @@ -600,6 +602,7 @@ fn provide_liquidity_zero_amount() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn provide_liquidity_invalid_minimum_lp_amount() { let mut deps = mock_dependencies(&[Coin { diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/queries.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/queries.rs index 29f85340..e2375687 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/queries.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/queries.rs @@ -8,6 +8,7 @@ use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; use white_whale::pool_network::mock_querier::mock_dependencies; use white_whale::pool_network::pair::{InstantiateMsg, PoolFee, PoolResponse, QueryMsg}; +#[cfg(not(feature = "osmosis"))] #[test] fn test_simulations_asset_missmatch() { let mut deps = mock_dependencies(&[]); @@ -89,6 +90,7 @@ fn test_simulations_asset_missmatch() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_query_pool() { let total_share_amount = Uint128::from(111u128); diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/stableswap.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/stableswap.rs index d31b28b0..e5a5b3b6 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/stableswap.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/stableswap.rs @@ -44,6 +44,7 @@ mod tests { assert_eq!(y, Uint128::new(980_053)); } + #[cfg(not(feature = "osmosis"))] #[test] fn does_stableswap_correctly() { let asset_pool_amount = Uint128::from(990_050u128); @@ -83,6 +84,7 @@ mod tests { ); } + #[cfg(not(feature = "osmosis"))] #[test] fn does_stableswap_correctly_with_smaller_asset_pool() { // test when asset_pool is smaller than collateral_pool @@ -124,6 +126,7 @@ mod tests { ); } + #[cfg(not(feature = "osmosis"))] #[test] #[allow(clippy::inconsistent_digit_grouping)] fn does_stableswap_with_different_precisions() { @@ -204,6 +207,7 @@ mod tests { ); } + #[cfg(not(feature = "osmosis"))] #[test] #[allow(clippy::inconsistent_digit_grouping)] fn does_stableswap_with_18_18_precision() { diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs index 4fa0a0ef..ec3e77e1 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/swap.rs @@ -1,16 +1,11 @@ -use crate::contract::{execute, instantiate, query, reply}; -use crate::error::ContractError; -use crate::helpers::compute_swap; -use crate::queries::query_fees; -use crate::state::{ - ALL_TIME_BURNED_FEES, ALL_TIME_COLLECTED_PROTOCOL_FEES, COLLECTED_PROTOCOL_FEES, -}; +use anybuf::Anybuf; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, coins, from_binary, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, SubMsg, - SubMsgResponse, SubMsgResult, Uint128, WasmMsg, + attr, coins, from_json, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, ReplyOn, + SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; + use white_whale::fee::Fee; use white_whale::pool_network::asset::{Asset, AssetInfo, PairType}; use white_whale::pool_network::mock_querier::mock_dependencies; @@ -19,6 +14,15 @@ use white_whale::pool_network::pair::{ SimulationResponse, }; +use crate::contract::{execute, instantiate, query, reply}; +use crate::error::ContractError; +use crate::helpers::compute_swap; +use crate::queries::query_fees; +use crate::state::{ + ALL_TIME_BURNED_FEES, ALL_TIME_COLLECTED_PROTOCOL_FEES, COLLECTED_PROTOCOL_FEES, +}; + +#[cfg(not(feature = "osmosis"))] #[test] fn test_compute_swap_with_huge_pool_variance() { let offer_pool = Uint128::from(395451850234u128); @@ -43,7 +47,7 @@ fn test_compute_swap_with_huge_pool_variance() { pool_fees, &PairType::ConstantProduct, 6, - 6 + 6, ) .unwrap() .return_amount, @@ -51,6 +55,7 @@ fn test_compute_swap_with_huge_pool_variance() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn try_native_to_token() { let total_share = Uint128::from(30000000000u128); @@ -76,6 +81,18 @@ fn try_native_to_token() { ), ]); + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + swap_fee: Fee { + share: Decimal::from_ratio(3u128, 1000u128), + }, + burn_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }; + let msg = InstantiateMsg { asset_infos: [ AssetInfo::NativeToken { @@ -87,17 +104,7 @@ fn try_native_to_token() { ], token_code_id: 10u64, asset_decimals: [6u8, 8u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::from_ratio(1u128, 1000u128), - }, - swap_fee: Fee { - share: Decimal::from_ratio(3u128, 1000u128), - }, - burn_fee: Fee { - share: Decimal::from_ratio(1u128, 1000u128), - }, - }, + pool_fees: pool_fees.clone(), fee_collector_addr: "collector".to_string(), pair_type: PairType::ConstantProduct, token_factory_lp: false, @@ -158,6 +165,7 @@ fn try_native_to_token() { let expected_swap_fee_amount = expected_ret_amount.multiply_ratio(3u128, 1000u128); // 0.3% let expected_protocol_fee_amount = expected_ret_amount.multiply_ratio(1u128, 1000u128); // 0.1% let expected_burn_fee_amount = expected_ret_amount.multiply_ratio(1u128, 1000u128); // 0.1% + let expected_return_amount = expected_ret_amount .checked_sub(expected_swap_fee_amount) .unwrap() @@ -172,7 +180,7 @@ fn try_native_to_token() { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: expected_burn_fee_amount, }) .unwrap(), @@ -268,7 +276,7 @@ fn try_native_to_token() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -315,7 +323,7 @@ fn try_native_to_token() { ) .unwrap(); - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -334,7 +342,7 @@ fn try_native_to_token() { assert!( (offer_amount.u128() as i128 - reverse_simulation_res.offer_amount.u128() as i128).abs() - < 3i128 + < 5i128 ); assert!( (expected_swap_fee_amount.u128() as i128 @@ -385,7 +393,7 @@ fn try_native_to_token() { assert_eq!( &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_return_amount, }) @@ -396,6 +404,7 @@ fn try_native_to_token() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn try_swap_invalid_token() { let total_share = Uint128::from(30000000000u128); @@ -523,6 +532,35 @@ fn try_token_to_native() { ), ]); + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + swap_fee: Fee { + share: Decimal::from_ratio(3u128, 1000u128), + }, + burn_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + swap_fee: Fee { + share: Decimal::from_ratio(3u128, 1000u128), + }, + burn_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + osmosis_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }; + let msg = InstantiateMsg { asset_infos: [ AssetInfo::NativeToken { @@ -533,18 +571,8 @@ fn try_token_to_native() { }, ], token_code_id: 10u64, - asset_decimals: [8u8, 8u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::from_ratio(1u128, 1000u128), - }, - swap_fee: Fee { - share: Decimal::from_ratio(3u128, 1000u128), - }, - burn_fee: Fee { - share: Decimal::from_ratio(1u128, 1000u128), - }, - }, + asset_decimals: [6u8, 8u8], + pool_fees: pool_fees.clone(), fee_collector_addr: "collector".to_string(), pair_type: PairType::ConstantProduct, token_factory_lp: false, @@ -595,7 +623,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: Some(Decimal::percent(5u64)), to: Some("third_party".to_string()), @@ -605,7 +633,10 @@ fn try_token_to_native() { let env = mock_env(); let info = mock_info("asset0000", &[]); - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + #[cfg(feature = "osmosis")] + assert_eq!(res.messages.len(), 3); + #[cfg(not(feature = "osmosis"))] assert_eq!(res.messages.len(), 2); let msg_transfer = res.messages.get(0).expect("no message"); @@ -619,25 +650,69 @@ fn try_token_to_native() { let expected_swap_fee_amount = expected_ret_amount.multiply_ratio(3u128, 1000u128); // 0.3% let expected_protocol_fee_amount = expected_ret_amount.multiply_ratio(1u128, 1000u128); // 0.1% let expected_burn_fee_amount = expected_ret_amount.multiply_ratio(1u128, 1000u128); // 0.1% - let expected_return_amount = expected_ret_amount - .checked_sub(expected_swap_fee_amount) - .unwrap() - .checked_sub(expected_protocol_fee_amount) - .unwrap() - .checked_sub(expected_burn_fee_amount) - .unwrap(); + #[cfg(feature = "osmosis")] + let expected_osmosis_fee_amount = expected_ret_amount.multiply_ratio(1u128, 1000u128); // 0.1% + + let expected_return_amount = { + let x = expected_ret_amount + .checked_sub(expected_swap_fee_amount) + .unwrap() + .checked_sub(expected_protocol_fee_amount) + .unwrap() + .checked_sub(expected_burn_fee_amount) + .unwrap(); + + #[cfg(feature = "osmosis")] + { + x.checked_sub(expected_osmosis_fee_amount).unwrap() + } - // since there is a burn_fee on the PoolFee, check burn message - // since we swapped to a native token, the burn message should be a BankMsg::Burn - let expected_burn_msg = SubMsg { - id: 0, - msg: CosmosMsg::Bank(BankMsg::Burn { - amount: coins(expected_burn_fee_amount.u128(), "uusd"), - }), - gas_limit: None, - reply_on: ReplyOn::Never, + #[cfg(not(feature = "osmosis"))] + { + x + } }; - assert_eq!(res.messages.last().unwrap().clone(), expected_burn_msg); + + #[cfg(not(feature = "osmosis"))] + { + let expected_burn_msg = SubMsg { + id: 0, + msg: CosmosMsg::Bank(BankMsg::Burn { + amount: coins(expected_burn_fee_amount.u128().into(), "uusd"), + }), + gas_limit: None, + reply_on: ReplyOn::Never, + }; + + assert_eq!(res.messages.last().unwrap().clone(), expected_burn_msg); + } + + #[cfg(feature = "osmosis")] + { + let community_pool_msg = CosmosMsg::Stargate { + type_url: "/cosmos.distribution.v1beta1.MsgFundCommunityPool".to_string(), + value: Anybuf::new() + .append_repeated_message( + 1, + &[&Anybuf::new() + .append_string(1, "uusd".to_string()) + .append_string(2, expected_osmosis_fee_amount.to_string())], + ) + .append_string(2, env.contract.address.to_string()) + .into_vec() + .into(), + }; + + // the last message is the osmosis fee send message + let expected_send_msg = SubMsg { + id: 0, + msg: community_pool_msg, + gas_limit: None, + reply_on: ReplyOn::Never, + }; + + assert_eq!(res.messages.last().unwrap().clone(), expected_send_msg); + } // as we swapped token to native, we accumulate the protocol fees in native let protocol_fees_for_native = query_fees( @@ -700,7 +775,7 @@ fn try_token_to_native() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -720,6 +795,11 @@ fn try_token_to_native() { assert_eq!(expected_return_amount, simulation_res.return_amount); assert_eq!(expected_swap_fee_amount, simulation_res.swap_fee_amount); assert_eq!(expected_burn_fee_amount, simulation_res.burn_fee_amount); + #[cfg(feature = "osmosis")] + assert_eq!( + expected_osmosis_fee_amount, + simulation_res.osmosis_fee_amount + ); assert_eq!(expected_spread_amount, simulation_res.spread_amount); assert_eq!( expected_protocol_fee_amount, @@ -748,7 +828,7 @@ fn try_token_to_native() { .unwrap(); // check reverse simulation res - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -767,7 +847,7 @@ fn try_token_to_native() { assert!( (offer_amount.u128() as i128 - reverse_simulation_res.offer_amount.u128() as i128).abs() - < 3i128 + < 5i128 ); assert!( (expected_swap_fee_amount.u128() as i128 @@ -793,6 +873,13 @@ fn try_token_to_native() { .abs() < 3i128 ); + #[cfg(feature = "osmosis")] + assert!( + (expected_osmosis_fee_amount.u128() as i128 + - reverse_simulation_res.osmosis_fee_amount.u128() as i128) + .abs() + < 3i128 + ); assert_eq!( res.attributes, @@ -811,6 +898,11 @@ fn try_token_to_native() { expected_protocol_fee_amount.to_string(), ), attr("burn_fee_amount", expected_burn_fee_amount.to_string()), + #[cfg(feature = "osmosis")] + attr( + "osmosis_fee_amount", + expected_osmosis_fee_amount.to_string() + ), attr("swap_type", "ConstantProduct"), ] ); @@ -830,7 +922,7 @@ fn try_token_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::Swap { + msg: to_json_binary(&Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -846,6 +938,7 @@ fn try_token_to_native() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_swap_to_third_party() { let total_share = Uint128::from(30_000_000_000u128); @@ -970,7 +1063,7 @@ fn test_swap_to_third_party() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -991,6 +1084,7 @@ fn test_swap_to_third_party() { assert_eq!(simulation_res.burn_fee_amount, Uint128::zero()); } +#[cfg(not(feature = "osmosis"))] #[test] fn stableswap_reverse_simulation() { let total_share = Uint128::from(1_000_000u128); @@ -1048,7 +1142,7 @@ fn stableswap_reverse_simulation() { .unwrap(); // check reverse simulation res - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1077,6 +1171,7 @@ fn stableswap_reverse_simulation() { ) } +#[cfg(not(feature = "osmosis"))] #[test] fn stableswap_with_different_precisions() { let total_share = Uint128::from(20_000_000_000u128); // 200_000.00000 @@ -1242,7 +1337,7 @@ fn stableswap_with_different_precisions() { ) .unwrap(); - let simulation_res: SimulationResponse = from_binary( + let simulation_res: SimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1289,7 +1384,7 @@ fn stableswap_with_different_precisions() { ) .unwrap(); - let reverse_simulation_res: ReverseSimulationResponse = from_binary( + let reverse_simulation_res: ReverseSimulationResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -1323,7 +1418,7 @@ fn stableswap_with_different_precisions() { expected_protocol_fee_amount.to_string(), ), attr("burn_fee_amount", expected_burn_fee_amount.to_string()), - attr("swap_type", "StableSwap") + attr("swap_type", "StableSwap"), ] ); @@ -1341,7 +1436,7 @@ fn stableswap_with_different_precisions() { assert_eq!( &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_return_amount, }) @@ -1352,6 +1447,7 @@ fn stableswap_with_different_precisions() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_stableswap_with_no_swap_amount() { let offer_pool = Uint128::from(25000000u128); @@ -1376,7 +1472,7 @@ fn test_stableswap_with_no_swap_amount() { pool_fees, &PairType::ConstantProduct, 6, - 6 + 6, ) .unwrap() .return_amount, diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs index 4105cb3d..d57eba05 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/testing.rs @@ -2,7 +2,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; #[cfg(feature = "token_factory")] use cosmwasm_std::CosmosMsg; use cosmwasm_std::{ - from_binary, to_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, + from_json, to_json_binary, Addr, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::MinterResponse; @@ -24,6 +24,7 @@ use crate::queries::query_pair_info; #[cfg(feature = "token_factory")] use crate::state::LP_SYMBOL; +#[cfg(not(feature = "osmosis"))] #[test] fn proper_initialization_cw20_lp() { let mut deps = mock_dependencies(&[]); @@ -69,7 +70,7 @@ fn proper_initialization_cw20_lp() { vec![SubMsg { msg: WasmMsg::Instantiate { code_id: 10u64, - msg: to_binary(&TokenInstantiateMsg { + msg: to_json_binary(&TokenInstantiateMsg { name: "uusd-mAAPL-LP".to_string(), symbol: "uLP".to_string(), decimals: 6, @@ -300,6 +301,7 @@ fn intialize_with_burnable_token_factory_asset() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_initialization_invalid_fees() { let mut deps = mock_dependencies(&[]); @@ -483,6 +485,7 @@ fn test_max_spread() { .unwrap_err(); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_update_config_unsuccessful() { let mut deps = mock_dependencies(&[]); @@ -581,6 +584,35 @@ fn test_update_config_successful() { (&"asset0000".to_string(), &[]), ]); + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + swap_fee: Fee { + share: Decimal::zero(), + }, + burn_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + swap_fee: Fee { + share: Decimal::zero(), + }, + burn_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + osmosis_fee: Fee { + share: Decimal::from_ratio(1u128, 1000u128), + }, + }; + let msg = InstantiateMsg { asset_infos: [ AssetInfo::NativeToken { @@ -592,17 +624,7 @@ fn test_update_config_successful() { ], token_code_id: 10u64, asset_decimals: [6u8, 8u8], - pool_fees: PoolFee { - protocol_fee: Fee { - share: Decimal::zero(), - }, - swap_fee: Fee { - share: Decimal::zero(), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }, + pool_fees: pool_fees.clone(), fee_collector_addr: "collector".to_string(), pair_type: PairType::ConstantProduct, token_factory_lp: false, @@ -614,39 +636,65 @@ fn test_update_config_successful() { instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for original config assert_eq!(config.owner, Addr::unchecked("addr0000")); assert!(config.feature_toggle.swaps_enabled); assert_eq!(config.pool_fees.swap_fee.share, Decimal::zero()); + #[cfg(feature = "osmosis")] + assert_eq!( + config.pool_fees.osmosis_fee.share, + Decimal::from_ratio(1u128, 1000u128) + ); + + #[cfg(not(feature = "osmosis"))] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(3u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + }; + + #[cfg(feature = "osmosis")] + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(1u64), + }, + swap_fee: Fee { + share: Decimal::percent(3u64), + }, + burn_fee: Fee { + share: Decimal::zero(), + }, + osmosis_fee: Fee { + share: Decimal::percent(5u64), + }, + }; let update_config_message = UpdateConfig { owner: Some("new_admin".to_string()), fee_collector_addr: Some("new_collector".to_string()), - pool_fees: Some(PoolFee { - protocol_fee: Fee { - share: Decimal::percent(1u64), - }, - swap_fee: Fee { - share: Decimal::percent(3u64), - }, - burn_fee: Fee { - share: Decimal::zero(), - }, - }), + pool_fees: Some(pool_fees), feature_toggle: None, }; execute(deps.as_mut(), env, info, update_config_message).unwrap(); let config: Config = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); // check for new config assert_eq!(config.owner, Addr::unchecked("new_admin")); assert_eq!(config.fee_collector_addr, Addr::unchecked("new_collector")); assert_eq!(config.pool_fees.swap_fee.share, Decimal::percent(3u64)); + #[cfg(feature = "osmosis")] + assert_eq!(config.pool_fees.osmosis_fee.share, Decimal::percent(5u64)); } #[test] diff --git a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs index b6c785bd..b03642a7 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_pair/src/tests/withdrawals.rs @@ -1,7 +1,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, to_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, Response, SubMsg, SubMsgResponse, - SubMsgResult, Uint128, WasmMsg, + attr, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, Reply, Response, SubMsg, + SubMsgResponse, SubMsgResult, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -22,6 +22,7 @@ use crate::contract::{execute, instantiate, reply}; use crate::error::ContractError; use crate::state::{get_fees_for_asset, store_fee, COLLECTED_PROTOCOL_FEES}; +#[cfg(not(feature = "osmosis"))] #[test] fn withdraw_xyk_liquidity_cw20_lp() { let mut deps = mock_dependencies(&[Coin { @@ -107,7 +108,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { // withdraw liquidity let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -154,7 +155,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { msg_refund_1, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_refund_amount, }) @@ -166,7 +167,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { msg_burn_liquidity, &SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(100u128), }) .unwrap(), @@ -184,6 +185,7 @@ fn withdraw_xyk_liquidity_cw20_lp() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn withdraw_stableswap_liquidity() { let mut deps = mock_dependencies(&[Coin { @@ -267,7 +269,7 @@ fn withdraw_stableswap_liquidity() { // withdraw liquidity let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -308,7 +310,7 @@ fn withdraw_stableswap_liquidity() { }), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: expected_token_refund_amount, }) @@ -317,7 +319,7 @@ fn withdraw_stableswap_liquidity() { }), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "liquidity0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(100u128), }) .unwrap(), @@ -333,6 +335,7 @@ fn withdraw_stableswap_liquidity() { ); } +#[cfg(not(feature = "osmosis"))] #[test] fn test_withdrawal_unauthorized() { let mut deps = mock_dependencies(&[Coin { @@ -385,7 +388,7 @@ fn test_withdrawal_unauthorized() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), + msg: to_json_binary(&Cw20HookMsg::WithdrawLiquidity {}).unwrap(), amount: Uint128::from(100u128), }); @@ -399,6 +402,7 @@ fn test_withdrawal_unauthorized() { } } +#[cfg(not(feature = "osmosis"))] #[test] fn test_withdrawal_wrong_message() { let mut deps = mock_dependencies(&[Coin { @@ -451,7 +455,7 @@ fn test_withdrawal_wrong_message() { // withdraw liquidity should fail let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), - msg: to_binary(&"invalid_message").unwrap(), + msg: to_json_binary(&"invalid_message").unwrap(), amount: Uint128::from(100u128), }); diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/Cargo.toml b/contracts/liquidity_hub/pool-network/terraswap_router/Cargo.toml index 042bd53c..f4e8c54c 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/Cargo.toml +++ b/contracts/liquidity_hub/pool-network/terraswap_router/Cargo.toml @@ -28,6 +28,7 @@ crate-type = ["cdylib", "rlib"] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs b/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs index 27724aaf..0c27ff42 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_router/src/contract.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, from_binary, to_binary, Addr, Api, Binary, CosmosMsg, Decimal, Deps, DepsMut, Env, + attr, from_json, to_json_binary, Addr, Api, Binary, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, WasmMsg, }; use cw2::{get_contract_version, set_contract_version}; @@ -125,7 +125,7 @@ pub fn receive_cw20( cw20_msg: Cw20ReceiveMsg, ) -> Result { let sender = deps.api.addr_validate(&cw20_msg.sender)?; - match from_binary(&cw20_msg.msg)? { + match from_json(&cw20_msg.msg)? { Cw20HookMsg::ExecuteSwapOperations { operations, minimum_receive, @@ -177,7 +177,7 @@ pub fn execute_swap_operations( Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: op, to: if operation_index == operations_len { Some(to.to_string()) @@ -197,7 +197,7 @@ pub fn execute_swap_operations( messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AssertMinimumReceive { + msg: to_json_binary(&ExecuteMsg::AssertMinimumReceive { asset_info: target_asset_info, prev_balance: receiver_balance, minimum_receive, @@ -279,11 +279,11 @@ fn add_swap_routes( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Config {} => Ok(to_binary(&query_config(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&query_config(deps)?)?), QueryMsg::SimulateSwapOperations { offer_amount, operations, - } => Ok(to_binary(&simulate_swap_operations( + } => Ok(to_json_binary(&simulate_swap_operations( deps, offer_amount, operations, @@ -291,18 +291,18 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Ok(to_binary(&reverse_simulate_swap_operations( + } => Ok(to_json_binary(&reverse_simulate_swap_operations( deps, ask_amount, operations, )?)?), QueryMsg::SwapRoute { offer_asset_info, ask_asset_info, - } => Ok(to_binary(&get_swap_route( + } => Ok(to_json_binary(&get_swap_route( deps, offer_asset_info, ask_asset_info, )?)?), - QueryMsg::SwapRoutes {} => Ok(to_binary(&get_swap_routes(deps)?)?), + QueryMsg::SwapRoutes {} => Ok(to_json_binary(&get_swap_routes(deps)?)?), } } diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs b/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs index 804b8df0..dd96e810 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_router/src/operations.rs @@ -1,5 +1,6 @@ use cosmwasm_std::{ - to_binary, Addr, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Response, WasmMsg, + to_json_binary, Addr, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Response, + WasmMsg, }; use crate::state::{Config, CONFIG}; @@ -81,7 +82,7 @@ pub fn asset_into_swap_msg( denom, amount: offer_asset.amount, }], - msg: to_binary(&PairExecuteMsg::Swap { + msg: to_json_binary(&PairExecuteMsg::Swap { offer_asset, belief_price: None, max_spread, @@ -91,10 +92,10 @@ pub fn asset_into_swap_msg( AssetInfo::Token { contract_addr } => Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: pair_contract.to_string(), amount: offer_asset.amount, - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread, to, diff --git a/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs b/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs index 8222d7eb..ab1e0986 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs +++ b/contracts/liquidity_hub/pool-network/terraswap_router/src/testing/tests.rs @@ -1,6 +1,7 @@ use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - attr, coin, from_binary, to_binary, Addr, Coin, CosmosMsg, StdError, SubMsg, Uint128, WasmMsg, + attr, coin, from_json, to_json_binary, Addr, Coin, CosmosMsg, StdError, SubMsg, Uint128, + WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use white_whale::pool_network; @@ -33,7 +34,7 @@ fn proper_initialization() { // it worked, let's query the state let config: ConfigResponse = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!("terraswapfactory", config.terraswap_factory.as_str()); } @@ -111,7 +112,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "ukrw".to_string(), @@ -128,7 +129,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0001".to_string(), @@ -145,7 +146,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -162,7 +163,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::AssertMinimumReceive { + msg: to_json_binary(&ExecuteMsg::AssertMinimumReceive { asset_info: AssetInfo::Token { contract_addr: "asset0002".to_string(), }, @@ -178,7 +179,7 @@ fn execute_swap_operations() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0000".to_string(), amount: Uint128::from(1000000u128), - msg: to_binary(&Cw20HookMsg::ExecuteSwapOperations { + msg: to_json_binary(&Cw20HookMsg::ExecuteSwapOperations { operations: vec![ SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { @@ -220,7 +221,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "ukrw".to_string(), @@ -237,7 +238,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0001".to_string(), @@ -254,7 +255,7 @@ fn execute_swap_operations() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -436,10 +437,10 @@ fn execute_swap_operation() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: "pair0000".to_string(), amount: Uint128::from(1000000u128), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: Some("addr0000".to_string()), @@ -544,7 +545,7 @@ fn query_buy_with_routes() { ); let res: SimulateSwapOperationsResponse = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!( res, SimulateSwapOperationsResponse { @@ -652,7 +653,7 @@ fn query_reverse_routes_with_from_native() { ); let res: SimulateSwapOperationsResponse = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!( res, @@ -690,7 +691,7 @@ fn query_reverse_routes_with_from_native() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "pair0000".to_string(), funds: vec![coin(target_amount, "ukrw")], - msg: to_binary(&PairExecuteMsg::Swap { + msg: to_json_binary(&PairExecuteMsg::Swap { offer_asset: Asset { info: AssetInfo::NativeToken { denom: "ukrw".to_string(), @@ -789,7 +790,7 @@ fn query_reverse_routes_with_to_native() { ); let res: SimulateSwapOperationsResponse = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!( res, @@ -803,7 +804,7 @@ fn query_reverse_routes_with_to_native() { let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { sender: "addr0".to_string(), amount: offer_amount, - msg: to_binary(&Cw20HookMsg::ExecuteSwapOperations { + msg: to_json_binary(&Cw20HookMsg::ExecuteSwapOperations { operations: vec![SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0000".to_string(), @@ -826,7 +827,7 @@ fn query_reverse_routes_with_to_native() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_CONTRACT_ADDR.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::ExecuteSwapOperation { + msg: to_json_binary(&ExecuteMsg::ExecuteSwapOperation { operation: SwapOperation::TerraSwap { offer_asset_info: AssetInfo::Token { contract_addr: "asset0000".to_string(), @@ -863,10 +864,10 @@ fn query_reverse_routes_with_to_native() { vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: "pair0000".to_string(), amount: Uint128::from(target_amount), - msg: to_binary(&pool_network::pair::Cw20HookMsg::Swap { + msg: to_json_binary(&pool_network::pair::Cw20HookMsg::Swap { belief_price: None, max_spread: None, to: None, @@ -1183,7 +1184,7 @@ fn add_swap_routes() { }; let res: Vec = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!(res, swap_route_1.swap_operations); } @@ -1569,7 +1570,7 @@ fn all_swap_routes() { let msg = QueryMsg::SwapRoutes {}; let res: Vec = - from_binary(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); assert_eq!(res.len(), 2usize); // Verify it has the correct swap routes assert_eq!(res[0].swap_route, swap_route_1.swap_operations); diff --git a/contracts/liquidity_hub/pool-network/terraswap_token/Cargo.toml b/contracts/liquidity_hub/pool-network/terraswap_token/Cargo.toml index 33e80052..87f4e792 100644 --- a/contracts/liquidity_hub/pool-network/terraswap_token/Cargo.toml +++ b/contracts/liquidity_hub/pool-network/terraswap_token/Cargo.toml @@ -14,6 +14,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/liquidity_hub/vault-network/vault/Cargo.toml b/contracts/liquidity_hub/vault-network/vault/Cargo.toml index a55ba4b7..65ba9897 100644 --- a/contracts/liquidity_hub/vault-network/vault/Cargo.toml +++ b/contracts/liquidity_hub/vault-network/vault/Cargo.toml @@ -15,6 +15,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/liquidity_hub/vault-network/vault/src/contract.rs b/contracts/liquidity_hub/vault-network/vault/src/contract.rs index be453023..7f9e9682 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/contract.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/contract.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - attr, entry_point, to_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, ReplyOn, + attr, entry_point, to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, ReplyOn, Response, StdError, StdResult, SubMsg, WasmMsg, }; use cw2::{get_contract_version, set_contract_version}; @@ -153,7 +153,7 @@ pub fn instantiate( msg: WasmMsg::Instantiate { admin: None, code_id: msg.token_id, - msg: to_binary(&white_whale::pool_network::token::InstantiateMsg { + msg: to_json_binary(&white_whale::pool_network::token::InstantiateMsg { name: lp_label.clone(), symbol: lp_symbol, decimals: 6, diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs index b5a10477..3094f292 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/callback/after_trade.rs @@ -97,7 +97,8 @@ mod test { use cosmwasm_std::{ coins, testing::{mock_env, mock_info}, - to_binary, Addr, BankMsg, CosmosMsg, Decimal, ReplyOn, Response, SubMsg, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, ReplyOn, Response, SubMsg, Uint128, + WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -311,7 +312,7 @@ mod test { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "vault_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(1), }) .unwrap(), diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs index e2c61bb8..f0ec8dc2 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/deposit.rs @@ -5,7 +5,7 @@ ))] use cosmwasm_std::coins; use cosmwasm_std::{ - to_binary, CosmosMsg, DepsMut, Env, MessageInfo, Response, Uint128, Uint256, WasmMsg, + to_json_binary, CosmosMsg, DepsMut, Env, MessageInfo, Response, Uint128, Uint256, WasmMsg, }; use cw20::{AllowanceResponse, Cw20ExecuteMsg}; @@ -81,7 +81,7 @@ pub fn deposit( messages.push( WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: info.sender.clone().into_string(), recipient: env.contract.address.clone().into_string(), amount, @@ -192,7 +192,7 @@ fn mint_lp_token_msg( } else { Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -204,7 +204,7 @@ fn mint_lp_token_msg( ))] Ok(vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient, amount })?, funds: vec![], })]) } @@ -214,7 +214,7 @@ mod test { use cosmwasm_std::{ coins, testing::{mock_dependencies, mock_env, mock_info}, - to_binary, Addr, BankMsg, CosmosMsg, Response, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, CosmosMsg, Response, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; use cw_multi_test::Executor; @@ -285,7 +285,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: env.contract.address.to_string(), amount: Uint128::new(1_000), }) @@ -294,7 +294,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "creator".to_string(), amount: Uint128::new(4_000), }) @@ -361,7 +361,7 @@ mod test { WasmMsg::Execute { contract_addr: "vault_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::TransferFrom { + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { owner: "creator".to_string(), recipient: env.contract.address.clone().into_string(), amount: Uint128::new(5_000), @@ -371,7 +371,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: env.contract.address.into_string(), amount: Uint128::new(1_000), }) @@ -380,7 +380,7 @@ mod test { WasmMsg::Execute { contract_addr: "lp_token".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Mint { + msg: to_json_binary(&Cw20ExecuteMsg::Mint { recipient: "creator".to_string(), amount: Uint128::new(4_000), }) diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs index 5d5b35ae..9ea8da16 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/flash_loan.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - coins, to_binary, Binary, CosmosMsg, DepsMut, Env, MessageInfo, OverflowError, Response, + coins, to_json_binary, Binary, CosmosMsg, DepsMut, Env, MessageInfo, OverflowError, Response, StdError, Uint128, WasmMsg, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; @@ -54,7 +54,7 @@ pub fn flash_loan( if let AssetInfo::Token { contract_addr } = config.asset_info.clone() { let loan_msg = WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: info.sender.clone().into_string(), amount, })?, @@ -84,7 +84,7 @@ pub fn flash_loan( messages.push( WasmMsg::Execute { contract_addr: env.contract.address.into_string(), - msg: to_binary(&ExecuteMsg::Callback(CallbackMsg::AfterTrade { + msg: to_json_binary(&ExecuteMsg::Callback(CallbackMsg::AfterTrade { old_balance, loan_amount: amount, }))?, @@ -104,7 +104,7 @@ mod test { use cosmwasm_std::{ coins, testing::{mock_dependencies, mock_dependencies_with_balance, mock_env}, - to_binary, Addr, BankMsg, Response, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, Response, Uint128, WasmMsg, }; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault::Config; @@ -147,7 +147,7 @@ mod test { mock_creator(), white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: Uint128::new(5_000), - msg: to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(), + msg: to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(), }, ); @@ -159,7 +159,7 @@ mod test { let mut deps = mock_dependencies_with_balance(&coins(10_000, "uluna")); let env = mock_env(); - let callback_msg = to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); + let callback_msg = to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); instantiate( deps.as_mut(), @@ -201,7 +201,7 @@ mod test { let mut deps = mock_dependencies_with_balance(&coins(10_000, "uluna")); let env = mock_env(); - let callback_msg = to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); + let callback_msg = to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); instantiate( deps.as_mut(), @@ -244,12 +244,14 @@ mod test { WasmMsg::Execute { contract_addr: env.contract.address.into_string(), funds: vec![], - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::Callback( - white_whale::vault_network::vault::CallbackMsg::AfterTrade { - old_balance: Uint128::new(10_000), - loan_amount: Uint128::new(5_000) - } - )) + msg: to_json_binary( + &white_whale::vault_network::vault::ExecuteMsg::Callback( + white_whale::vault_network::vault::CallbackMsg::AfterTrade { + old_balance: Uint128::new(10_000), + loan_amount: Uint128::new(5_000) + } + ) + ) .unwrap() } ]) @@ -268,7 +270,7 @@ mod test { vec![], ); - let callback_msg = to_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); + let callback_msg = to_json_binary(&BankMsg::Burn { amount: vec![] }).unwrap(); // inject config CONFIG @@ -313,7 +315,7 @@ mod test { WasmMsg::Execute { contract_addr: "vault_token".to_string(), funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: mock_creator().sender.into_string(), amount: Uint128::new(5_000) }) @@ -327,12 +329,14 @@ mod test { WasmMsg::Execute { contract_addr: env.contract.address.into_string(), funds: vec![], - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::Callback( - white_whale::vault_network::vault::CallbackMsg::AfterTrade { - old_balance: Uint128::new(10_000), - loan_amount: Uint128::new(5_000) - } - )) + msg: to_json_binary( + &white_whale::vault_network::vault::ExecuteMsg::Callback( + white_whale::vault_network::vault::CallbackMsg::AfterTrade { + old_balance: Uint128::new(10_000), + loan_amount: Uint128::new(5_000) + } + ) + ) .unwrap() } ]) diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs index b08de1b0..b0b0d5b0 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/mod.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{from_binary, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{from_json, DepsMut, Env, MessageInfo, Response}; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault::{Cw20HookMsg, Cw20ReceiveMsg}; @@ -27,14 +27,14 @@ pub fn receive( return Err(VaultError::ExternalCallback {}); } - match from_binary(&msg.msg)? { + match from_json(&msg.msg)? { Cw20HookMsg::Withdraw {} => withdraw(deps, env, msg.sender, msg.amount), } } #[cfg(test)] mod test { - use cosmwasm_std::{to_binary, Addr, Uint128}; + use cosmwasm_std::{to_json_binary, Addr, Uint128}; #[cfg(any( feature = "token_factory", @@ -89,7 +89,7 @@ mod test { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, ); @@ -136,7 +136,7 @@ mod test { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, ); diff --git a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs index fe5eacc9..82afb514 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/execute/receive/withdraw.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - coins, to_binary, BankMsg, CosmosMsg, Decimal, DepsMut, Env, Response, Uint128, WasmMsg, + coins, to_json_binary, BankMsg, CosmosMsg, Decimal, DepsMut, Env, Response, Uint128, WasmMsg, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; @@ -75,7 +75,7 @@ pub fn withdraw( .into(), AssetInfo::Token { contract_addr } => WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: sender.into_string(), amount: withdraw_amount, })?, @@ -116,7 +116,7 @@ fn burn_lp_asset_msg( } else { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } @@ -127,7 +127,7 @@ fn burn_lp_asset_msg( ))] Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: liquidity_asset, - msg: to_binary(&Cw20ExecuteMsg::Burn { amount })?, + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount })?, funds: vec![], })) } @@ -137,7 +137,7 @@ mod tests { use cosmwasm_std::{ coins, testing::{mock_env, mock_info}, - to_binary, Addr, BankMsg, Response, SubMsg, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, Response, SubMsg, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; use cw_multi_test::Executor; @@ -171,8 +171,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ); @@ -191,8 +193,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { sender: mock_creator().sender.into_string(), amount: Uint128::new(5_000), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ); @@ -248,8 +252,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { amount: Uint128::new(2_000), sender: mock_creator().sender.into_string(), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ); @@ -301,7 +307,7 @@ mod tests { &Cw20ExecuteMsg::Send { contract: vault_addr.to_string(), amount: Uint128::new(4_500), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, &[], @@ -409,7 +415,7 @@ mod tests { &Cw20ExecuteMsg::Send { contract: vault_addr.to_string(), amount: Uint128::new(4_500), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) + msg: to_json_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) .unwrap(), }, &[], @@ -507,8 +513,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { amount: Uint128::new(5_000), sender: mock_creator().sender.into_string(), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ) @@ -539,7 +547,7 @@ mod tests { reply_on: cosmwasm_std::ReplyOn::Never, msg: WasmMsg::Execute { contract_addr: "lp_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(5000) }) .unwrap(), @@ -617,8 +625,10 @@ mod tests { white_whale::vault_network::vault::Cw20ReceiveMsg { amount: Uint128::new(5_000), sender: mock_creator().sender.into_string(), - msg: to_binary(&white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}) - .unwrap(), + msg: to_json_binary( + &white_whale::vault_network::vault::Cw20HookMsg::Withdraw {}, + ) + .unwrap(), }, ), ) @@ -639,7 +649,7 @@ mod tests { reply_on: cosmwasm_std::ReplyOn::Never, msg: WasmMsg::Execute { contract_addr: "vault_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { amount: Uint128::new(4_999), recipient: mock_creator().sender.into_string(), }) @@ -654,7 +664,7 @@ mod tests { reply_on: cosmwasm_std::ReplyOn::Never, msg: WasmMsg::Execute { contract_addr: "lp_token".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(5000) }) .unwrap(), diff --git a/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs b/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs index b3f2eacc..c1f4efbe 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/queries/get_config.rs @@ -1,16 +1,16 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use crate::error::VaultError; use crate::state::CONFIG; pub fn get_config(deps: Deps) -> Result { - Ok(to_binary(&CONFIG.load(deps.storage)?)?) + Ok(to_json_binary(&CONFIG.load(deps.storage)?)?) } #[cfg(test)] mod test { use cosmwasm_std::{ - from_binary, + from_json, testing::{mock_dependencies, mock_env}, Addr, }; @@ -45,7 +45,7 @@ mod test { CONFIG.save(&mut deps.storage, &config).unwrap(); - let res: Config = from_binary( + let res: Config = from_json( &query( deps.as_ref(), env, diff --git a/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs b/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs index 9e2e2c1b..f695a04d 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/queries/get_payback_amount.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps, Uint128, Uint256}; +use cosmwasm_std::{to_json_binary, Binary, Deps, Uint128, Uint256}; use white_whale::vault_network::vault::PaybackAmountResponse; use crate::error::VaultError; @@ -18,7 +18,7 @@ pub fn get_payback_amount(deps: Deps, amount: Uint128) -> Result Result { if all_time { let fees = all_time_fees_storage_item.load(deps.storage)?; - return Ok(to_binary(&ProtocolFeesResponse { fees })?); + return Ok(to_json_binary(&ProtocolFeesResponse { fees })?); } let fees = fees_storage_item .ok_or_else(|| StdError::generic_err("fees_storage_item was None"))? .load(deps.storage)?; - Ok(to_binary(&ProtocolFeesResponse { fees })?) + Ok(to_json_binary(&ProtocolFeesResponse { fees })?) } #[cfg(test)] mod test { use cosmwasm_std::{ - from_binary, + from_json, testing::{mock_dependencies, mock_env}, Uint128, }; @@ -68,7 +68,7 @@ mod test { ) .unwrap(); - let res: ProtocolFeesResponse = from_binary( + let res: ProtocolFeesResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -115,7 +115,7 @@ mod test { ) .unwrap(); - let res: ProtocolFeesResponse = from_binary( + let res: ProtocolFeesResponse = from_json( &query( deps.as_ref(), mock_env(), @@ -154,8 +154,7 @@ mod test { .unwrap(); let res: ProtocolFeesResponse = - from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::BurnedFees {}).unwrap()) - .unwrap(); + from_json(&query(deps.as_ref(), mock_env(), QueryMsg::BurnedFees {}).unwrap()).unwrap(); assert_eq!( res, ProtocolFeesResponse { diff --git a/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs b/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs index 17d2c970..504d898d 100644 --- a/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs +++ b/contracts/liquidity_hub/vault-network/vault/src/queries/get_share.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Decimal, Deps, Env, Uint128}; +use cosmwasm_std::{to_json_binary, Binary, Decimal, Deps, Env, Uint128}; use cw20::{BalanceResponse, Cw20QueryMsg}; use white_whale::pool_network::asset::{get_total_share, AssetInfo}; @@ -40,12 +40,12 @@ pub fn get_share(deps: Deps, env: Env, amount: Uint128) -> Result QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -101,10 +101,10 @@ impl WasmMockQuerier { match &request { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { if contract_addr == "lp_token" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { decimals: 6, name: "lp_token".to_string(), symbol: "uLP".to_string(), @@ -120,7 +120,7 @@ impl WasmMockQuerier { } Cw20QueryMsg::Balance { address } => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&BalanceResponse { + to_json_binary(&BalanceResponse { balance: *self .token_querier .balances @@ -135,10 +135,10 @@ impl WasmMockQuerier { _ => panic!("DO NOT ENTER HERE"), } } else if contract_addr == "vault_token" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::Balance { address } => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&BalanceResponse { + to_json_binary(&BalanceResponse { balance: *self .token_querier .balances @@ -152,7 +152,7 @@ impl WasmMockQuerier { } Cw20QueryMsg::Allowance { owner, spender } => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&AllowanceResponse { + to_json_binary(&AllowanceResponse { allowance: *self .token_querier .allowances diff --git a/contracts/liquidity_hub/vault-network/vault_factory/Cargo.toml b/contracts/liquidity_hub/vault-network/vault_factory/Cargo.toml index dcfc3182..10095398 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/Cargo.toml +++ b/contracts/liquidity_hub/vault-network/vault_factory/Cargo.toml @@ -17,6 +17,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs index 9da0ac51..fd6cecad 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/create_vault.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, WasmMsg}; +use cosmwasm_std::{to_json_binary, DepsMut, Env, MessageInfo, ReplyOn, Response, SubMsg, WasmMsg}; use white_whale::fee::VaultFee; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault::InstantiateMsg; @@ -37,7 +37,7 @@ pub fn create_vault( msg: WasmMsg::Instantiate { admin: Some(env.contract.address.clone().into_string()), code_id: config.vault_id, - msg: to_binary(&InstantiateMsg { + msg: to_json_binary(&InstantiateMsg { owner: env.contract.address.into_string(), asset_info: asset_info.clone(), token_id: config.token_id, @@ -70,7 +70,8 @@ pub fn create_vault( #[cfg(test)] mod tests { use cosmwasm_std::{ - testing::mock_info, to_binary, Addr, Decimal, ReplyOn, Response, StdError, SubMsg, WasmMsg, + testing::mock_info, to_json_binary, Addr, Decimal, ReplyOn, Response, StdError, SubMsg, + WasmMsg, }; use cw_multi_test::Executor; use white_whale::fee::{Fee, VaultFee}; @@ -114,7 +115,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, @@ -159,7 +160,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, @@ -354,7 +355,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, @@ -400,7 +401,7 @@ mod tests { msg: WasmMsg::Instantiate { admin: Some(env.contract.address.to_string()), code_id: 5, - msg: to_binary(&white_whale::vault_network::vault::InstantiateMsg { + msg: to_json_binary(&white_whale::vault_network::vault::InstantiateMsg { owner: env.contract.address.to_string(), asset_info, token_id: 6, diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs index ddd62e14..bbd7770f 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/migrate_vaults.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, CosmosMsg, DepsMut, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, DepsMut, Response, WasmMsg}; use white_whale::vault_network::vault::MigrateMsg; @@ -42,7 +42,7 @@ fn migrate_vault_msg(vault_addr: Addr, code_id: u64) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Migrate { contract_addr: vault_addr.to_string(), new_code_id: code_id, - msg: to_binary(&MigrateMsg {})?, + msg: to_json_binary(&MigrateMsg {})?, })) } diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs index a1aac9ef..2febb1cd 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/execute/update_config.rs @@ -46,7 +46,7 @@ pub fn update_config( #[cfg(test)] mod tests { - use cosmwasm_std::{from_binary, testing::mock_info, Addr, Response}; + use cosmwasm_std::{from_json, testing::mock_info, Addr, Response}; use white_whale::vault_network::vault_factory::{Config, ExecuteMsg, QueryMsg}; use crate::{ @@ -83,7 +83,7 @@ mod tests { // check query let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config.owner, Addr::unchecked("other_acc")); // check storage @@ -118,7 +118,7 @@ mod tests { // check query let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config.fee_collector_addr, Addr::unchecked("other_acc")); // check storage @@ -160,7 +160,7 @@ mod tests { }; let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config, desired_config); // check storage @@ -202,7 +202,7 @@ mod tests { }; let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(config, desired_config); // check storage diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs index 50cbfee5..13b229f1 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/config.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use crate::{err::StdResult, state::CONFIG}; @@ -6,7 +6,7 @@ use crate::{err::StdResult, state::CONFIG}; pub fn get_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; - Ok(to_binary(&config)?) + Ok(to_json_binary(&config)?) } #[cfg(test)] diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs index 38cc8e0f..f924b49c 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/queries/vault.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use white_whale::pool_network::asset::AssetInfo; use white_whale::vault_network::vault_factory::{VaultInfo, VaultsResponse}; @@ -9,10 +9,10 @@ use crate::{asset::AssetReference, err::StdResult, state::VAULTS}; pub fn get_vault(deps: Deps, asset_info: AssetInfo) -> StdResult { let vault_option = VAULTS.may_load(deps.storage, asset_info.get_reference())?; if let Some((vault_addr, _)) = vault_option { - return Ok(to_binary(&vault_addr)?); + return Ok(to_json_binary(&vault_addr)?); } - Ok(to_binary(&vault_option)?) + Ok(to_json_binary(&vault_option)?) } pub fn get_vaults( @@ -21,7 +21,7 @@ pub fn get_vaults( limit: Option, ) -> StdResult { let vaults: Vec = read_vaults(deps.storage, deps.api, start_after, limit)?; - Ok(to_binary(&VaultsResponse { vaults })?) + Ok(to_json_binary(&VaultsResponse { vaults })?) } #[cfg(test)] diff --git a/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs b/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs index d0b7b167..9c31f8d2 100644 --- a/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs +++ b/contracts/liquidity_hub/vault-network/vault_factory/src/tests/mock_query.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - from_binary, + from_json, testing::{MockApi, MockQuerier, MockStorage}, Env, OwnedDeps, }; @@ -20,7 +20,7 @@ where { let (deps, env) = mock_instantiate(vault_id, token_id); - let res = from_binary(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); + let res = from_json(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); (res, deps, env) } diff --git a/contracts/liquidity_hub/vault-network/vault_router/Cargo.toml b/contracts/liquidity_hub/vault-network/vault_router/Cargo.toml index e6939bfe..09b86d45 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/Cargo.toml +++ b/contracts/liquidity_hub/vault-network/vault_router/Cargo.toml @@ -17,6 +17,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json b/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json index ad35024b..99527f94 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json +++ b/contracts/liquidity_hub/vault-network/vault_router/schema/raw/execute.json @@ -364,67 +364,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", - "type": "object", - "required": [ - "stargate" - ], - "properties": { - "stargate": { - "type": "object", - "required": [ - "type_url", - "value" - ], - "properties": { - "type_url": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ibc" - ], - "properties": { - "ibc": { - "$ref": "#/definitions/IbcMsg" - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -436,67 +375,6 @@ } }, "additionalProperties": false - }, - { - "type": "object", - "required": [ - "gov" - ], - "properties": { - "gov": { - "$ref": "#/definitions/GovMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false } ] }, @@ -504,305 +382,10 @@ "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", "type": "object" }, - "GovMsg": { - "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", - "oneOf": [ - { - "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", - "allOf": [ - { - "$ref": "#/definitions/VoteOption" - } - ] - } - } - } - }, - "additionalProperties": false - } - ] - }, - "IbcMsg": { - "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", - "oneOf": [ - { - "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "channel_id", - "timeout", - "to_address" - ], - "properties": { - "amount": { - "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "channel_id": { - "description": "exisiting channel to send the tokens over", - "type": "string" - }, - "timeout": { - "description": "when packet times out, measured on remote chain", - "allOf": [ - { - "$ref": "#/definitions/IbcTimeout" - } - ] - }, - "to_address": { - "description": "address on the remote chain to receive these tokens", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", - "type": "object", - "required": [ - "send_packet" - ], - "properties": { - "send_packet": { - "type": "object", - "required": [ - "channel_id", - "data", - "timeout" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "data": { - "$ref": "#/definitions/Binary" - }, - "timeout": { - "description": "when packet times out, measured on remote chain", - "allOf": [ - { - "$ref": "#/definitions/IbcTimeout" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", - "type": "object", - "required": [ - "close_channel" - ], - "properties": { - "close_channel": { - "type": "object", - "required": [ - "channel_id" - ], - "properties": { - "channel_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "IbcTimeout": { - "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", - "type": "object", - "properties": { - "block": { - "anyOf": [ - { - "$ref": "#/definitions/IbcTimeoutBlock" - }, - { - "type": "null" - } - ] - }, - "timestamp": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - } - }, - "IbcTimeoutBlock": { - "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", - "type": "object", - "required": [ - "height", - "revision" - ], - "properties": { - "height": { - "description": "block height after which the packet times out. the height within the given revision", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "VoteOption": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "no_with_veto" - ] - }, "WasmMsg": { "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", "oneOf": [ @@ -877,7 +460,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { diff --git a/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json b/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json index e58a27be..16fe0cca 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json +++ b/contracts/liquidity_hub/vault-network/vault_router/schema/vault_router.json @@ -389,67 +389,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", - "type": "object", - "required": [ - "stargate" - ], - "properties": { - "stargate": { - "type": "object", - "required": [ - "type_url", - "value" - ], - "properties": { - "type_url": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ibc" - ], - "properties": { - "ibc": { - "$ref": "#/definitions/IbcMsg" - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -461,67 +400,6 @@ } }, "additionalProperties": false - }, - { - "type": "object", - "required": [ - "gov" - ], - "properties": { - "gov": { - "$ref": "#/definitions/GovMsg" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false } ] }, @@ -529,305 +407,10 @@ "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", "type": "object" }, - "GovMsg": { - "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", - "oneOf": [ - { - "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", - "allOf": [ - { - "$ref": "#/definitions/VoteOption" - } - ] - } - } - } - }, - "additionalProperties": false - } - ] - }, - "IbcMsg": { - "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", - "oneOf": [ - { - "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "channel_id", - "timeout", - "to_address" - ], - "properties": { - "amount": { - "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "channel_id": { - "description": "exisiting channel to send the tokens over", - "type": "string" - }, - "timeout": { - "description": "when packet times out, measured on remote chain", - "allOf": [ - { - "$ref": "#/definitions/IbcTimeout" - } - ] - }, - "to_address": { - "description": "address on the remote chain to receive these tokens", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", - "type": "object", - "required": [ - "send_packet" - ], - "properties": { - "send_packet": { - "type": "object", - "required": [ - "channel_id", - "data", - "timeout" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "data": { - "$ref": "#/definitions/Binary" - }, - "timeout": { - "description": "when packet times out, measured on remote chain", - "allOf": [ - { - "$ref": "#/definitions/IbcTimeout" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", - "type": "object", - "required": [ - "close_channel" - ], - "properties": { - "close_channel": { - "type": "object", - "required": [ - "channel_id" - ], - "properties": { - "channel_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "IbcTimeout": { - "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", - "type": "object", - "properties": { - "block": { - "anyOf": [ - { - "$ref": "#/definitions/IbcTimeoutBlock" - }, - { - "type": "null" - } - ] - }, - "timestamp": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - } - }, - "IbcTimeoutBlock": { - "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", - "type": "object", - "required": [ - "height", - "revision" - ], - "properties": { - "height": { - "description": "block height after which the packet times out. the height within the given revision", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "VoteOption": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "no_with_veto" - ] - }, "WasmMsg": { "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", "oneOf": [ @@ -902,7 +485,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs b/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs index 9f5586b6..33cf9ecd 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/execute/complete_loan.rs @@ -1,5 +1,6 @@ use cosmwasm_std::{ - attr, coins, to_binary, Addr, BankMsg, CosmosMsg, DepsMut, Env, MessageInfo, Response, WasmMsg, + attr, coins, to_json_binary, Addr, BankMsg, CosmosMsg, DepsMut, Env, MessageInfo, Response, + WasmMsg, }; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::vault_network::vault::PaybackAmountResponse; @@ -76,7 +77,7 @@ pub fn complete_loan( AssetInfo::Token { contract_addr } => Ok(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: vault, amount: payback_amount.payback_amount, })?, @@ -97,7 +98,7 @@ pub fn complete_loan( AssetInfo::Token { contract_addr } => Ok(WasmMsg::Execute { contract_addr, funds: vec![], - msg: to_binary(&cw20::Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&cw20::Cw20ExecuteMsg::Transfer { recipient: initiator.clone().into_string(), amount: profit_amount, })?, diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs b/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs index db3f84f5..782f118e 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/execute/flash_loan.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, CosmosMsg, DepsMut, MessageInfo, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, CosmosMsg, DepsMut, MessageInfo, Response, WasmMsg}; use white_whale::pool_network::asset::Asset; use white_whale::vault_network::vault_router::ExecuteMsg; @@ -51,9 +51,9 @@ pub fn flash_loan( messages.push( WasmMsg::Execute { contract_addr: vault.to_string(), - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { + msg: to_json_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: asset.amount, - msg: to_binary(&ExecuteMsg::NextLoan { + msg: to_json_binary(&ExecuteMsg::NextLoan { initiator: info.sender, source_vault: vault.to_string(), source_vault_asset_info: asset.info.clone(), @@ -76,7 +76,7 @@ pub fn flash_loan( #[cfg(test)] mod tests { use cosmwasm_std::{ - coins, from_binary, to_binary, Attribute, BankMsg, CosmosMsg, Event, Response, Uint128, + coins, from_json, to_json_binary, Attribute, BankMsg, CosmosMsg, Event, Response, Uint128, WasmMsg, }; use cw_multi_test::Executor; @@ -110,7 +110,7 @@ mod tests { let payload = vec![WasmMsg::Execute { contract_addr: dummy_contract_addr.clone().into_string(), - msg: to_binary(&crate::tests::ExecuteMsg::Send { + msg: to_json_binary(&crate::tests::ExecuteMsg::Send { to_address: router_addr.clone(), amount: coins(transfer_amount, "uluna"), }) @@ -140,7 +140,7 @@ mod tests { // verify payload was executed let payload_amount = match payload.first().unwrap() { CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) => { - let msg: crate::tests::ExecuteMsg = from_binary(msg).unwrap(); + let msg: crate::tests::ExecuteMsg = from_json(msg).unwrap(); match msg { crate::tests::ExecuteMsg::Send { amount, .. } => amount, } @@ -296,7 +296,7 @@ mod tests { let payload = vec![WasmMsg::Execute { contract_addr: dummy_contract_addr.clone().into_string(), - msg: to_binary(&crate::tests::ExecuteMsg::Send { + msg: to_json_binary(&crate::tests::ExecuteMsg::Send { to_address: router_addr.clone(), amount: coins(transfer_amount, "uluna"), }) @@ -325,7 +325,7 @@ mod tests { let payload_amount = match payload.first().unwrap() { CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) => { - let msg: crate::tests::ExecuteMsg = from_binary(msg).unwrap(); + let msg: crate::tests::ExecuteMsg = from_json(msg).unwrap(); match msg { crate::tests::ExecuteMsg::Send { amount, .. } => amount, } diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs b/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs index ef9cf131..a24b72a5 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/execute/next_loan.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Addr, CosmosMsg, DepsMut, Env, MessageInfo, Response, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, DepsMut, Env, MessageInfo, Response, WasmMsg}; use white_whale::pool_network::asset::{Asset, AssetInfo}; use white_whale::vault_network::vault_router::ExecuteMsg; @@ -44,9 +44,9 @@ pub fn next_loan( vec![WasmMsg::Execute { contract_addr: vault.clone(), funds: vec![], - msg: to_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { + msg: to_json_binary(&white_whale::vault_network::vault::ExecuteMsg::FlashLoan { amount: asset.amount, - msg: to_binary(&ExecuteMsg::NextLoan { + msg: to_json_binary(&ExecuteMsg::NextLoan { initiator, source_vault: vault.to_string(), source_vault_asset_info: asset.info.clone(), @@ -64,7 +64,7 @@ pub fn next_loan( WasmMsg::Execute { contract_addr: env.contract.address.to_string(), funds: vec![], - msg: to_binary(&ExecuteMsg::CompleteLoan { + msg: to_json_binary(&ExecuteMsg::CompleteLoan { initiator, loaned_assets, })?, diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs b/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs index 1f080f4c..7941783d 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/queries/config.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_binary, Binary, Deps}; +use cosmwasm_std::{to_json_binary, Binary, Deps}; use crate::{err::StdResult, state::CONFIG}; @@ -6,7 +6,7 @@ use crate::{err::StdResult, state::CONFIG}; pub fn get_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; - Ok(to_binary(&config)?) + Ok(to_json_binary(&config)?) } #[cfg(test)] diff --git a/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs b/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs index 0b6414d9..89349648 100644 --- a/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs +++ b/contracts/liquidity_hub/vault-network/vault_router/src/tests/mock_query.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - from_binary, + from_json, testing::{MockApi, MockQuerier, MockStorage}, Env, OwnedDeps, }; @@ -19,7 +19,7 @@ where { let (deps, env) = mock_instantiate(factory_addr); - let res = from_binary(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); + let res = from_json(&query(deps.as_ref(), env.clone(), query_msg).unwrap()).unwrap(); (res, deps, env) } diff --git a/contracts/liquidity_hub/whale_lair/Cargo.toml b/contracts/liquidity_hub/whale_lair/Cargo.toml index e859e8ea..3074c9d2 100644 --- a/contracts/liquidity_hub/whale_lair/Cargo.toml +++ b/contracts/liquidity_hub/whale_lair/Cargo.toml @@ -23,6 +23,7 @@ crate-type = ["cdylib", "rlib"] [features] injective = ["white-whale/injective"] +osmosis = ["osmosis_token_factory"] token_factory = ["white-whale/token_factory"] osmosis_token_factory = ["white-whale/osmosis_token_factory"] # for more explicit tests, cargo test --features=backtraces diff --git a/contracts/liquidity_hub/whale_lair/src/contract.rs b/contracts/liquidity_hub/whale_lair/src/contract.rs index 0470cfa9..fc4bbe12 100644 --- a/contracts/liquidity_hub/whale_lair/src/contract.rs +++ b/contracts/liquidity_hub/whale_lair/src/contract.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{entry_point, Addr}; -use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::{get_contract_version, set_contract_version}; use semver::Version; use white_whale::pool_network::asset::AssetInfo; @@ -99,21 +99,21 @@ pub fn execute( #[entry_point] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => to_binary(&queries::query_config(deps)?), - QueryMsg::Bonded { address } => to_binary(&queries::query_bonded(deps, address)?), + QueryMsg::Config {} => to_json_binary(&queries::query_config(deps)?), + QueryMsg::Bonded { address } => to_json_binary(&queries::query_bonded(deps, address)?), QueryMsg::Unbonding { address, denom, start_after, limit, - } => to_binary(&queries::query_unbonding( + } => to_json_binary(&queries::query_unbonding( deps, address, denom, start_after, limit, )?), - QueryMsg::Withdrawable { address, denom } => to_binary(&queries::query_withdrawable( + QueryMsg::Withdrawable { address, denom } => to_json_binary(&queries::query_withdrawable( deps, env.block.time, address, @@ -128,15 +128,15 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { let timestamp = timestamp.unwrap_or(env.block.time); // TODO: Make better timestamp handling - to_binary(&queries::query_weight( + to_json_binary(&queries::query_weight( deps, timestamp, address, global_index, )?) } - QueryMsg::TotalBonded {} => to_binary(&queries::query_total_bonded(deps)?), - QueryMsg::GlobalIndex {} => to_binary(&queries::query_global_index(deps)?), + QueryMsg::TotalBonded {} => to_json_binary(&queries::query_total_bonded(deps)?), + QueryMsg::GlobalIndex {} => to_json_binary(&queries::query_global_index(deps)?), } } diff --git a/contracts/liquidity_hub/whale_lair/src/queries.rs b/contracts/liquidity_hub/whale_lair/src/queries.rs index e1cf9b0f..2fb39a5f 100644 --- a/contracts/liquidity_hub/whale_lair/src/queries.rs +++ b/contracts/liquidity_hub/whale_lair/src/queries.rs @@ -1,8 +1,8 @@ use std::collections::HashSet; use cosmwasm_std::{ - to_binary, Decimal, Deps, Order, QueryRequest, StdError, StdResult, Timestamp, Uint128, Uint64, - WasmQuery, + to_json_binary, Decimal, Deps, Order, QueryRequest, StdError, StdResult, Timestamp, Uint128, + Uint64, WasmQuery, }; use cw_storage_plus::Bound; @@ -64,7 +64,7 @@ pub(crate) fn query_bonded(deps: Deps, address: String) -> StdResult StdResult { + pub fn into_json_binary(self) -> StdResult { let msg = EpochChangedExecuteMsg::EpochChangedHook(self); - to_binary(&msg) + to_json_binary(&msg) } /// creates a cosmos_msg sending this struct to the named contract pub fn into_cosmos_msg>(self, contract_addr: T) -> StdResult { - let msg = self.into_binary()?; + let msg = self.into_json_binary()?; let execute = WasmMsg::Execute { contract_addr: contract_addr.into(), msg, diff --git a/packages/white-whale/src/fee.rs b/packages/white-whale/src/fee.rs index c49dce66..92628f02 100644 --- a/packages/white-whale/src/fee.rs +++ b/packages/white-whale/src/fee.rs @@ -12,7 +12,7 @@ impl Fee { amount * Decimal256::from(self.share) } - /// Computes the fee for the given amount + /// Converts a Fee to a Decimal256 pub fn to_decimal_256(&self) -> Decimal256 { Decimal256::from(self.share) } diff --git a/packages/white-whale/src/pool_network/asset.rs b/packages/white-whale/src/pool_network/asset.rs index e3823c93..4e48076a 100644 --- a/packages/white-whale/src/pool_network/asset.rs +++ b/packages/white-whale/src/pool_network/asset.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - coins, to_binary, Addr, Api, BankMsg, CanonicalAddr, Coin, CosmosMsg, Deps, MessageInfo, + coins, to_json_binary, Addr, Api, BankMsg, CanonicalAddr, Coin, CosmosMsg, Deps, MessageInfo, QuerierWrapper, StdError, StdResult, SubMsg, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -50,7 +50,7 @@ impl Asset { match &self.info { AssetInfo::Token { contract_addr } => Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: recipient.to_string(), amount, })?, @@ -74,7 +74,7 @@ impl Asset { let burn_msg = match self.info { AssetInfo::Token { contract_addr } => CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: self.amount, })?, funds: vec![], @@ -231,7 +231,7 @@ impl AssetInfo { #[cfg(feature = "injective")] { if is_ethereum_bridged_asset(&denom) { - return get_ethereum_bridged_asset_label(denom.clone()); + return get_ethereum_bridged_asset_label(denom); } } if is_ibc_token(&denom) { diff --git a/packages/white-whale/src/pool_network/mock_querier.rs b/packages/white-whale/src/pool_network/mock_querier.rs index b1564e6e..0e8258cf 100644 --- a/packages/white-whale/src/pool_network/mock_querier.rs +++ b/packages/white-whale/src/pool_network/mock_querier.rs @@ -5,8 +5,8 @@ use std::panic; use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, from_slice, to_binary, Coin, ContractInfoResponse, ContractResult, Empty, - OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, + from_json, to_json_binary, Coin, ContractInfoResponse, ContractResult, Empty, OwnedDeps, + Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; @@ -125,7 +125,7 @@ pub fn native_token_decimals_to_map(native_token_decimals: &[(String, u8)]) -> H impl Querier for WasmMockQuerier { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -141,7 +141,7 @@ impl Querier for WasmMockQuerier { impl Querier for WasmMockTrioQuerier { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -157,41 +157,41 @@ impl Querier for WasmMockTrioQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match from_binary(msg) { - Ok(FactoryQueryMsg::Pair { asset_infos }) => { - let key = [asset_infos[0].to_string(), asset_infos[1].to_string()].join(""); - let mut sort_key: Vec = key.chars().collect(); - sort_key.sort_by(|a, b| b.cmp(a)); - match self - .pool_factory_querier - .pairs - .get(&String::from_iter(sort_key.iter())) - { - Some(v) => SystemResult::Ok(ContractResult::Ok(to_binary(v).unwrap())), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No pair info exists".to_string(), - request: msg.as_slice().into(), - }), - } + QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => match from_json(msg) { + Ok(FactoryQueryMsg::Pair { asset_infos }) => { + let key = [asset_infos[0].to_string(), asset_infos[1].to_string()].join(""); + let mut sort_key: Vec = key.chars().collect(); + sort_key.sort_by(|a, b| b.cmp(a)); + match self + .pool_factory_querier + .pairs + .get(&String::from_iter(sort_key.iter())) + { + Some(v) => SystemResult::Ok(ContractResult::Ok(to_json_binary(v).unwrap())), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No pair info exists".to_string(), + request: msg.as_slice().into(), + }), } - Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { - match self.pool_factory_querier.native_token_decimals.get(&denom) { - Some(decimals) => SystemResult::Ok(ContractResult::Ok( - to_binary(&NativeTokenDecimalsResponse { - decimals: *decimals, - }) - .unwrap(), - )), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No decimal info exist".to_string(), - request: msg.as_slice().into(), - }), - } + } + Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { + match self.pool_factory_querier.native_token_decimals.get(&denom) { + Some(decimals) => SystemResult::Ok(ContractResult::Ok( + to_json_binary(&NativeTokenDecimalsResponse { + decimals: *decimals, + }) + .unwrap(), + )), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No decimal info exist".to_string(), + request: msg.as_slice().into(), + }), } - _ => match from_binary(msg) { - Ok(PairQueryMsg::Pool {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&PairPoolResponse { + } + _ => { + match from_json(msg) { + Ok(PairQueryMsg::Pool {}) => SystemResult::Ok(ContractResult::from( + to_json_binary(&PairPoolResponse { assets: vec![ Asset { info: AssetInfo::NativeToken { @@ -207,10 +207,10 @@ impl WasmMockQuerier { }, ], total_share: Uint128::new(2_000_000_000u128), - }))) - } + }), + )), Ok(PairQueryMsg::Pair {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&PairInfo { + SystemResult::Ok(ContractResult::from(to_json_binary(&PairInfo { asset_infos: [ AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -228,24 +228,50 @@ impl WasmMockQuerier { }))) } Ok(PairQueryMsg::Simulation { offer_asset }) => { - SystemResult::Ok(ContractResult::from(to_binary(&SimulationResponse { + #[cfg(not(feature = "osmosis"))] + let data = SimulationResponse { return_amount: offer_asset.amount, swap_fee_amount: Uint128::zero(), spread_amount: Uint128::zero(), protocol_fee_amount: Uint128::zero(), burn_fee_amount: Uint128::zero(), - }))) + }; + + #[cfg(feature = "osmosis")] + let data = SimulationResponse { + return_amount: offer_asset.amount, + swap_fee_amount: Uint128::zero(), + spread_amount: Uint128::zero(), + protocol_fee_amount: Uint128::zero(), + burn_fee_amount: Uint128::zero(), + osmosis_fee_amount: Uint128::zero(), + }; + + SystemResult::Ok(ContractResult::from(to_json_binary(&data))) } - Ok(PairQueryMsg::ReverseSimulation { ask_asset }) => SystemResult::Ok( - ContractResult::from(to_binary(&ReverseSimulationResponse { + Ok(PairQueryMsg::ReverseSimulation { ask_asset }) => { + #[cfg(not(feature = "osmosis"))] + let data = ReverseSimulationResponse { offer_amount: ask_asset.amount, swap_fee_amount: Uint128::zero(), spread_amount: Uint128::zero(), protocol_fee_amount: Uint128::zero(), burn_fee_amount: Uint128::zero(), - })), - ), - _ => match from_binary(msg).unwrap() { + }; + + #[cfg(feature = "osmosis")] + let data = ReverseSimulationResponse { + offer_amount: ask_asset.amount, + swap_fee_amount: Uint128::zero(), + spread_amount: Uint128::zero(), + protocol_fee_amount: Uint128::zero(), + burn_fee_amount: Uint128::zero(), + osmosis_fee_amount: Uint128::zero(), + }; + + SystemResult::Ok(ContractResult::from(to_json_binary(&data))) + } + _ => match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { let balances: &HashMap = match self.token_querier.balances.get(contract_addr) { @@ -267,7 +293,7 @@ impl WasmMockQuerier { } SystemResult::Ok(ContractResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: "mAAPL".to_string(), symbol: "mAAPL".to_string(), decimals: 8, @@ -294,7 +320,7 @@ impl WasmMockQuerier { Some(v) => *v, None => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { + to_json_binary(&Cw20BalanceResponse { balance: Uint128::zero(), }) .unwrap(), @@ -303,15 +329,15 @@ impl WasmMockQuerier { }; SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { balance }).unwrap(), + to_json_binary(&Cw20BalanceResponse { balance }).unwrap(), )) } _ => panic!("DO NOT ENTER HERE"), }, - }, + } } - } + }, QueryRequest::Wasm(WasmQuery::ContractInfo { .. }) => { let mut contract_info_response = ContractInfoResponse::default(); contract_info_response.code_id = 0u64; @@ -319,7 +345,7 @@ impl WasmMockQuerier { contract_info_response.admin = Some("creator".to_string()); SystemResult::Ok(ContractResult::Ok( - to_binary(&contract_info_response).unwrap(), + to_json_binary(&contract_info_response).unwrap(), )) } _ => self.base.handle_query(request), @@ -330,46 +356,46 @@ impl WasmMockQuerier { impl WasmMockTrioQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match from_binary(msg) { - Ok(FactoryQueryMsg::Trio { asset_infos }) => { - let key = [ - asset_infos[0].to_string(), - asset_infos[1].to_string(), - asset_infos[2].to_string(), - ] - .join(""); - let mut sort_key: Vec = key.chars().collect(); - sort_key.sort_by(|a, b| b.cmp(a)); - match self - .pool_factory_querier - .pairs - .get(&String::from_iter(sort_key.iter())) - { - Some(v) => SystemResult::Ok(ContractResult::Ok(to_binary(v).unwrap())), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No trio info exists".to_string(), - request: msg.as_slice().into(), - }), - } + QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => match from_json(msg) { + Ok(FactoryQueryMsg::Trio { asset_infos }) => { + let key = [ + asset_infos[0].to_string(), + asset_infos[1].to_string(), + asset_infos[2].to_string(), + ] + .join(""); + let mut sort_key: Vec = key.chars().collect(); + sort_key.sort_by(|a, b| b.cmp(a)); + match self + .pool_factory_querier + .pairs + .get(&String::from_iter(sort_key.iter())) + { + Some(v) => SystemResult::Ok(ContractResult::Ok(to_json_binary(v).unwrap())), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No trio info exists".to_string(), + request: msg.as_slice().into(), + }), } - Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { - match self.pool_factory_querier.native_token_decimals.get(&denom) { - Some(decimals) => SystemResult::Ok(ContractResult::Ok( - to_binary(&NativeTokenDecimalsResponse { - decimals: *decimals, - }) - .unwrap(), - )), - None => SystemResult::Err(SystemError::InvalidRequest { - error: "No decimal info exist".to_string(), - request: msg.as_slice().into(), - }), - } + } + Ok(FactoryQueryMsg::NativeTokenDecimals { denom }) => { + match self.pool_factory_querier.native_token_decimals.get(&denom) { + Some(decimals) => SystemResult::Ok(ContractResult::Ok( + to_json_binary(&NativeTokenDecimalsResponse { + decimals: *decimals, + }) + .unwrap(), + )), + None => SystemResult::Err(SystemError::InvalidRequest { + error: "No decimal info exist".to_string(), + request: msg.as_slice().into(), + }), } - _ => match from_binary(msg) { - Ok(TrioQueryMsg::Pool {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&TrioPoolResponse { + } + _ => { + match from_json(msg) { + Ok(TrioQueryMsg::Pool {}) => SystemResult::Ok(ContractResult::from( + to_json_binary(&TrioPoolResponse { assets: vec![ Asset { info: AssetInfo::NativeToken { @@ -391,10 +417,10 @@ impl WasmMockTrioQuerier { }, ], total_share: Uint128::new(3_000_000_000u128), - }))) - } + }), + )), Ok(TrioQueryMsg::Trio {}) => { - SystemResult::Ok(ContractResult::from(to_binary(&TrioInfo { + SystemResult::Ok(ContractResult::from(to_json_binary(&TrioInfo { asset_infos: [ AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -413,25 +439,51 @@ impl WasmMockTrioQuerier { }, }))) } - Ok(TrioQueryMsg::Simulation { offer_asset, .. }) => SystemResult::Ok( - ContractResult::from(to_binary(&trio::SimulationResponse { + Ok(TrioQueryMsg::Simulation { offer_asset, .. }) => { + #[cfg(not(feature = "osmosis"))] + let data = trio::SimulationResponse { return_amount: offer_asset.amount, swap_fee_amount: Uint128::zero(), spread_amount: Uint128::zero(), protocol_fee_amount: Uint128::zero(), burn_fee_amount: Uint128::zero(), - })), - ), - Ok(TrioQueryMsg::ReverseSimulation { ask_asset, .. }) => SystemResult::Ok( - ContractResult::from(to_binary(&trio::ReverseSimulationResponse { + }; + + #[cfg(feature = "osmosis")] + let data = trio::SimulationResponse { + return_amount: offer_asset.amount, + swap_fee_amount: Uint128::zero(), + spread_amount: Uint128::zero(), + protocol_fee_amount: Uint128::zero(), + burn_fee_amount: Uint128::zero(), + osmosis_fee_amount: Uint128::zero(), + }; + + SystemResult::Ok(ContractResult::from(to_json_binary(&data))) + } + Ok(TrioQueryMsg::ReverseSimulation { ask_asset, .. }) => { + #[cfg(not(feature = "osmosis"))] + let data = trio::ReverseSimulationResponse { offer_amount: ask_asset.amount, swap_fee_amount: Uint128::zero(), spread_amount: Uint128::zero(), protocol_fee_amount: Uint128::zero(), burn_fee_amount: Uint128::zero(), - })), - ), - _ => match from_binary(msg).unwrap() { + }; + + #[cfg(feature = "osmosis")] + let data = trio::ReverseSimulationResponse { + offer_amount: ask_asset.amount, + swap_fee_amount: Uint128::zero(), + spread_amount: Uint128::zero(), + protocol_fee_amount: Uint128::zero(), + burn_fee_amount: Uint128::zero(), + osmosis_fee_amount: Uint128::zero(), + }; + + SystemResult::Ok(ContractResult::from(to_json_binary(&data))) + } + _ => match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { let balances: &HashMap = match self.token_querier.balances.get(contract_addr) { @@ -453,7 +505,7 @@ impl WasmMockTrioQuerier { } SystemResult::Ok(ContractResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: "mAAPL".to_string(), symbol: "mAAPL".to_string(), decimals: 8, @@ -480,7 +532,7 @@ impl WasmMockTrioQuerier { Some(v) => *v, None => { return SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { + to_json_binary(&Cw20BalanceResponse { balance: Uint128::zero(), }) .unwrap(), @@ -489,15 +541,15 @@ impl WasmMockTrioQuerier { }; SystemResult::Ok(ContractResult::Ok( - to_binary(&Cw20BalanceResponse { balance }).unwrap(), + to_json_binary(&Cw20BalanceResponse { balance }).unwrap(), )) } _ => panic!("DO NOT ENTER HERE"), }, - }, + } } - } + }, QueryRequest::Wasm(WasmQuery::ContractInfo { .. }) => { let mut contract_info_response = ContractInfoResponse::default(); contract_info_response.code_id = 0u64; @@ -505,7 +557,7 @@ impl WasmMockTrioQuerier { contract_info_response.admin = Some("creator".to_string()); SystemResult::Ok(ContractResult::Ok( - to_binary(&contract_info_response).unwrap(), + to_json_binary(&contract_info_response).unwrap(), )) } _ => self.base.handle_query(request), @@ -595,7 +647,7 @@ mod mock_exception { fn none_factory_pair_will_err() { let deps = mock_dependencies(&[]); - let msg = to_binary(&FactoryQueryMsg::Pair { + let msg = to_json_binary(&FactoryQueryMsg::Pair { asset_infos: [ AssetInfo::NativeToken { denom: "uluna".to_string(), @@ -623,7 +675,7 @@ mod mock_exception { fn none_tokens_info_will_err() { let deps = mock_dependencies(&[]); - let msg = to_binary(&Cw20QueryMsg::TokenInfo {}).unwrap(); + let msg = to_json_binary(&Cw20QueryMsg::TokenInfo {}).unwrap(); assert_eq!( deps.querier @@ -642,7 +694,7 @@ mod mock_exception { fn none_tokens_balance_will_err() { let deps = mock_dependencies(&[]); - let msg = to_binary(&Cw20QueryMsg::Balance { + let msg = to_json_binary(&Cw20QueryMsg::Balance { address: "address0000".to_string(), }) .unwrap(); @@ -665,7 +717,7 @@ mod mock_exception { fn none_tokens_minter_will_panic() { let deps = mock_dependencies(&[]); - let msg = to_binary(&Cw20QueryMsg::Minter {}).unwrap(); + let msg = to_json_binary(&Cw20QueryMsg::Minter {}).unwrap(); deps.querier .handle_query(&QueryRequest::Wasm(WasmQuery::Smart { diff --git a/packages/white-whale/src/pool_network/pair.rs b/packages/white-whale/src/pool_network/pair.rs index 0c534434..8881dfa4 100644 --- a/packages/white-whale/src/pool_network/pair.rs +++ b/packages/white-whale/src/pool_network/pair.rs @@ -110,6 +110,8 @@ pub struct PoolFee { pub protocol_fee: Fee, pub swap_fee: Fee, pub burn_fee: Fee, + #[cfg(feature = "osmosis")] + pub osmosis_fee: Fee, } impl PoolFee { @@ -120,17 +122,38 @@ impl PoolFee { self.swap_fee.is_valid()?; self.burn_fee.is_valid()?; - if self - .protocol_fee - .share - .checked_add(self.swap_fee.share)? - .checked_add(self.burn_fee.share)? - >= Decimal::percent(100) - { + let total_fee = self.aggregate()?; + + // Check if the total fee exceeds 100% + if total_fee >= Decimal::percent(100) { return Err(StdError::generic_err("Invalid fees")); } + Ok(()) } + + /// aggregates all the fees into a single decimal + pub fn aggregate(&self) -> StdResult { + let total_fee = { + let base_fee = self + .protocol_fee + .share + .checked_add(self.swap_fee.share)? + .checked_add(self.burn_fee.share)?; + + #[cfg(feature = "osmosis")] + { + base_fee.checked_add(self.osmosis_fee.share)? + } + + #[cfg(not(feature = "osmosis"))] + { + base_fee + } + }; + + Ok(total_fee) + } } #[cw_serde] @@ -158,6 +181,8 @@ pub struct SimulationResponse { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } /// ReverseSimulationResponse returns reverse swap simulation response @@ -174,6 +199,8 @@ pub struct ReverseSimulationResponse { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } /// We currently take no arguments for migrations diff --git a/packages/white-whale/src/pool_network/querier.rs b/packages/white-whale/src/pool_network/querier.rs index 0ace1a5c..ba5a7dc1 100644 --- a/packages/white-whale/src/pool_network/querier.rs +++ b/packages/white-whale/src/pool_network/querier.rs @@ -6,7 +6,7 @@ use crate::pool_network::pair::{ use crate::pool_network::trio::QueryMsg as TrioQueryMsg; use cosmwasm_std::{ - to_binary, Addr, AllBalanceResponse, BalanceResponse, BankQuery, Coin, QuerierWrapper, + to_json_binary, Addr, AllBalanceResponse, BalanceResponse, BankQuery, Coin, QuerierWrapper, QueryRequest, StdResult, Uint128, WasmQuery, }; @@ -41,7 +41,7 @@ pub fn query_token_balance( ) -> StdResult { let res: Cw20BalanceResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20QueryMsg::Balance { + msg: to_json_binary(&Cw20QueryMsg::Balance { address: account_addr.to_string(), })?, }))?; @@ -56,7 +56,7 @@ pub fn query_token_info( ) -> StdResult { let token_info: TokenInfoResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20QueryMsg::TokenInfo {})?, + msg: to_json_binary(&Cw20QueryMsg::TokenInfo {})?, }))?; Ok(token_info) @@ -70,7 +70,7 @@ pub fn query_native_decimals( let res: NativeTokenDecimalsResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_contract.to_string(), - msg: to_binary(&FactoryQueryMsg::NativeTokenDecimals { denom })?, + msg: to_json_binary(&FactoryQueryMsg::NativeTokenDecimals { denom })?, }))?; Ok(res.decimals) } @@ -82,7 +82,7 @@ pub fn query_pair_info( ) -> StdResult { querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_contract.to_string(), - msg: to_binary(&FactoryQueryMsg::Pair { + msg: to_json_binary(&FactoryQueryMsg::Pair { asset_infos: asset_infos.clone(), })?, })) @@ -95,7 +95,7 @@ pub fn simulate( ) -> StdResult { querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair_contract.to_string(), - msg: to_binary(&PairQueryMsg::Simulation { + msg: to_json_binary(&PairQueryMsg::Simulation { offer_asset: offer_asset.clone(), })?, })) @@ -108,7 +108,7 @@ pub fn reverse_simulate( ) -> StdResult { querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair_contract.to_string(), - msg: to_binary(&PairQueryMsg::ReverseSimulation { + msg: to_json_binary(&PairQueryMsg::ReverseSimulation { ask_asset: ask_asset.clone(), })?, })) @@ -120,7 +120,7 @@ pub fn query_pair_info_from_pair( ) -> StdResult { let pair_info: PairInfo = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: pair_contract.to_string(), - msg: to_binary(&PairQueryMsg::Pair {})?, + msg: to_json_binary(&PairQueryMsg::Pair {})?, }))?; Ok(pair_info) @@ -132,7 +132,7 @@ pub fn query_trio_info_from_trio( ) -> StdResult { let trio_info: TrioInfo = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: trio_contract.to_string(), - msg: to_binary(&TrioQueryMsg::Trio {})?, + msg: to_json_binary(&TrioQueryMsg::Trio {})?, }))?; Ok(trio_info) diff --git a/packages/white-whale/src/pool_network/testing.rs b/packages/white-whale/src/pool_network/testing.rs index b0936716..5d4e9154 100644 --- a/packages/white-whale/src/pool_network/testing.rs +++ b/packages/white-whale/src/pool_network/testing.rs @@ -6,8 +6,8 @@ use crate::pool_network::querier::{ use cosmwasm_std::testing::MOCK_CONTRACT_ADDR; use cosmwasm_std::{ - coin, to_binary, Addr, Api, BankMsg, Coin, CosmosMsg, MessageInfo, StdError, SubMsg, Uint128, - WasmMsg, + coin, to_json_binary, Addr, Api, BankMsg, Coin, CosmosMsg, MessageInfo, StdError, SubMsg, + Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -195,7 +195,7 @@ fn test_asset() { .unwrap(), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: Uint128::from(123123u128), }) @@ -210,7 +210,7 @@ fn test_asset() { .unwrap(), SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "asset0000".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "addr0000".to_string(), amount: Uint128::from(123123u128), }) diff --git a/packages/white-whale/src/pool_network/trio.rs b/packages/white-whale/src/pool_network/trio.rs index 7410b8d4..12c86187 100644 --- a/packages/white-whale/src/pool_network/trio.rs +++ b/packages/white-whale/src/pool_network/trio.rs @@ -125,6 +125,8 @@ pub struct PoolFee { pub protocol_fee: Fee, pub swap_fee: Fee, pub burn_fee: Fee, + #[cfg(feature = "osmosis")] + pub osmosis_fee: Fee, } impl PoolFee { @@ -135,17 +137,38 @@ impl PoolFee { self.swap_fee.is_valid()?; self.burn_fee.is_valid()?; - if self - .protocol_fee - .share - .checked_add(self.swap_fee.share)? - .checked_add(self.burn_fee.share)? - >= Decimal::percent(100) - { + let total_fee = self.aggregate()?; + + // Check if the total fee exceeds 100% + if total_fee >= Decimal::percent(100) { return Err(StdError::generic_err("Invalid fees")); } + Ok(()) } + + /// aggregates all the fees into a single decimal + pub fn aggregate(&self) -> StdResult { + let total_fee = { + let base_fee = self + .protocol_fee + .share + .checked_add(self.swap_fee.share)? + .checked_add(self.burn_fee.share)?; + + #[cfg(feature = "osmosis")] + { + base_fee.checked_add(self.osmosis_fee.share)? + } + + #[cfg(not(feature = "osmosis"))] + { + base_fee + } + }; + + Ok(total_fee) + } } #[cw_serde] @@ -177,6 +200,8 @@ pub struct SimulationResponse { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } /// ProtocolFeesResponse returns protocol fees response @@ -193,6 +218,8 @@ pub struct ReverseSimulationResponse { pub swap_fee_amount: Uint128, pub protocol_fee_amount: Uint128, pub burn_fee_amount: Uint128, + #[cfg(feature = "osmosis")] + pub osmosis_fee_amount: Uint128, } /// We currently take no arguments for migrations diff --git a/scripts/build_release.sh b/scripts/build_release.sh index 363a807b..498a2d81 100755 --- a/scripts/build_release.sh +++ b/scripts/build_release.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash set -e +projectRootPath=$(realpath "$0" | sed 's|\(.*\)/.*|\1|' | cd ../ | pwd) + # Displays tool usage function display_usage() { echo "Release builder" @@ -31,7 +33,22 @@ flag="" case $chain in -juno | terra | osmosis) +osmosis) + flag="-osmosis" + echo " $projectRootPath/Cargo.toml" + + # backup the Cargo.toml file + cp $projectRootPath/Cargo.toml $projectRootPath/Cargo.toml.bak + + # add the osmosis feature flag to the Cargo.toml file so it optimizes correctly + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' '/white-whale =/ s/features = \[\]/features = \["osmosis"\]/' $projectRootPath/Cargo.toml + else + sed -i '/white-whale =/ s/features = \[\]/features = \["osmosis"\]/' $projectRootPath/Cargo.toml + fi + + ;; +juno | terra | chihuahua) flag="-osmosis_token_factory" ;; migaloo) @@ -40,7 +57,7 @@ migaloo) injective) flag="-injective" ;; -chihuahua | comdex | orai | sei) ;; +comdex | orai | sei) ;; \*) echo "Network $chain not defined" @@ -66,9 +83,9 @@ docker_options=( # Optimized builds if [[ "$arch" == "aarch64" || "$arch" == "arm64" ]]; then - docker_command=("docker" "run" "${docker_options[@]}" "cosmwasm/workspace-optimizer-arm64:0.14.0$flag") + docker_command=("docker" "run" "${docker_options[@]}" "cosmwasm/optimizer-arm64:0.15.0$flag") else - docker_command=("docker" "run" "${docker_options[@]}" "cosmwasm/workspace-optimizer:0.14.0$flag") + docker_command=("docker" "run" "${docker_options[@]}" "cosmwasm/optimizer:0.15.0$flag") fi echo "${docker_command[@]}" @@ -81,3 +98,8 @@ $projectRootPath/scripts/check_artifacts_size.sh # Check generated wasm file sizes $projectRootPath/scripts/get_artifacts_versions.sh + +if [[ "$chain" == "osmosis" ]]; then + #if the chain is osmosis, restore the Cargo.toml file + mv $projectRootPath/Cargo.toml.bak $projectRootPath/Cargo.toml +fi diff --git a/scripts/deployment/deploy_env/base.env b/scripts/deployment/deploy_env/base.env index 53037c05..c50efa2b 100644 --- a/scripts/deployment/deploy_env/base.env +++ b/scripts/deployment/deploy_env/base.env @@ -1,6 +1,6 @@ if [ -n "$ZSH_VERSION" ]; then # Using an array for TXFLAG - TXFLAG=(--node $RPC --chain-id $CHAIN_ID --gas-prices 0.55$DENOM --gas auto --gas-adjustment 1.5 -y -b block --output json) + TXFLAG=(--node $RPC --chain-id $CHAIN_ID --gas-prices 0.55$DENOM --gas auto --gas-adjustment 1.5 -y -b sync --output json) else # Using a string for TXFLAG TXFLAG="--node $RPC --chain-id $CHAIN_ID --gas-prices 0.55$DENOM --gas auto --gas-adjustment 1.5 -y -b block --output json" diff --git a/scripts/deployment/deploy_env/testnets/osmosis.env b/scripts/deployment/deploy_env/testnets/osmosis.env new file mode 100644 index 00000000..f2a3e1b3 --- /dev/null +++ b/scripts/deployment/deploy_env/testnets/osmosis.env @@ -0,0 +1,4 @@ +export CHAIN_ID="osmo-test-5" +export DENOM="uosmo" +export BINARY="osmosisd" +export RPC="https://rpc.osmotest5.osmosis.zone:443" \ No newline at end of file