From 667065441a220b577a359b4f8131b992b6917304 Mon Sep 17 00:00:00 2001 From: ismellike Date: Wed, 18 Sep 2024 10:32:21 -0500 Subject: [PATCH] Squashed commit of the following: commit a5399800dc599facb11a654684f017148ec7cadc Merge: 56316703 b3b2ce70 Author: ismellike Date: Wed Sep 18 10:29:49 2024 -0500 Merge branch 'pr/cw-orch-interface' into improvements/cw-abc commit b3b2ce70d26059893398447a0493f0f5ee02b3c0 Author: ismellike Date: Wed Sep 18 10:14:18 2024 -0500 Update osmosis-test-tube to match cw-orch commit 56316703ade451e8d0bbcb401e29d5b980e460b6 Author: ismellike Date: Tue Sep 17 15:25:57 2024 -0500 Cleanup dao-testing commit 5dc69cabbf53ff8208fcf989c909dd21e469f1b9 Author: ismellike Date: Tue Sep 17 12:42:11 2024 -0500 Update schemas commit b84971c59138afe26d3349a86ca787ea764568bb Author: ismellike Date: Tue Sep 17 12:06:36 2024 -0500 Return result in to_curve_fn commit 9dd313ec39c851d7024e4f968e45af0493758a5b Author: ismellike Date: Tue Sep 17 11:14:43 2024 -0500 Improved queries, tests, and error handling on cw-abc commit 848cecdafe8938135c2ffe13eac20ec3afd50541 Merge: 85654cf0 455880f5 Author: ismellike Date: Tue Sep 17 09:27:32 2024 -0500 Merge branch 'cw-abc' into improvements/cw-abc commit 85654cf0d5cf2d1b4c5f37d8b4e99608ee1e28a0 Author: ismellike Date: Tue Sep 10 05:37:43 2024 -0500 Added cw_orch fn_name for proposal executes follows the same naming as `dao_proposal_sudo` execute commit 685211d934c510f55cdc1a531a0802ef0016fc4a Author: Jake Hartnell Date: Wed Aug 14 17:59:24 2024 -0400 Fix removing uninstalled packages commit a9efb44abb104778790cf16f012ec2710a59ff46 Author: Jake Hartnell Date: Wed Aug 14 17:57:36 2024 -0400 Attempt to free up more disk space commit 6660b23df886593c70f20b396495b7c91182bafa Author: Jake Hartnell Date: Wed Aug 14 17:52:42 2024 -0400 Attempt to free up disk space commit 3990e13c3d64dc3dad6deafab08e2eb3910587ca Author: hard-nett Date: Thu Jul 25 02:08:47 2024 +0000 dao cw-orch interface commit 0cc80ced1b33f29a2e3d0eaba98e28c44975d5d6 Author: hard-nett Date: Thu Jul 25 00:42:30 2024 +0000 cw-orch test suite for contracts commit c255d1ec1a6ec8727ce272ba5119cc1b593da292 Author: Gabe Date: Wed Jul 24 11:58:59 2024 -0500 Exclude scripts from workspace commit 06bca643fa91f302f2e4fe47edca3aaef9a81ded Author: Gabe Date: Wed Jul 24 10:37:57 2024 -0500 Update external.rs commit 0ae02a1dcc8f6c238479eed2d7929b5870848ab8 Author: Gabe Date: Wed Jul 24 10:34:31 2024 -0500 Remove dao-interface-master from scripts commit f5b9df58f6f334ab7617908c6dd8c2e4243f3fad Author: hard-nett Date: Wed Jul 24 22:49:38 2024 +0000 cargo lock commit ed3020df2c3195c585cb8db5bdc1312d4e97364b Author: hard-nett Date: Wed Jul 24 20:20:20 2024 +0000 bump ismellike cleanups commit 3bdf843a8a08d2e4f71a2a48517802e520e4ab97 Author: hard-nett Date: Wed Jul 24 15:42:12 2024 +0000 lint commit cad98379970fe9ef5c0947e00386b2e3a03254be Author: hard-nett Date: Wed Jul 24 15:27:45 2024 +0000 remove tf issuer init for now commit 73fe8c88baed586653b803c9d1d7e77b14a342ff Author: Gabe Date: Wed Jul 24 01:22:53 2024 -0500 Clippy fixes commit dc43643bd75b7f27740624af59547c37673adc5f Author: Gabe Date: Tue Jul 23 17:12:34 2024 -0500 Update integration_tests.yml commit 9e36aede2770fc5ba5204e062ad23e6ce75703b8 Author: Gabe Date: Tue Jul 23 16:00:04 2024 -0500 Fix tokio dependency commit 0bb200e90c2c6c158f0e4285f2db9731aec14a78 Author: hard-nett Date: Tue Jul 23 23:28:10 2024 +0000 cleanup script imports commit 776ebe3fae3fcd87c393eb7249dd0b91c46ecf76 Author: hard-nett Date: Tue Jul 23 23:08:05 2024 +0000 good btsg cw-orch bump commit 3b14168cae9e3aa1509664098189b01188f79312 Author: hard-nett Date: Tue Jul 23 23:06:45 2024 +0000 bump commit bf0b66872264d15b304e55eaa7cec0ef2871ed49 Author: hard-nett Date: Tue Jul 23 22:47:45 2024 +0000 bump correct init commit f2570de2a9a1a461de417418e001dea808fcf08c Author: hard-nett Date: Tue Jul 23 21:37:15 2024 +0000 correct import commit 65091bd321bb495856a5edbd8dfe590559cd1e88 Author: hard-nett Date: Tue Jul 23 21:23:30 2024 +0000 add btsg-ft-factory to cw-orch setup commit e836dd159674e702f073a815e6b8ad1e2ec2cfc9 Author: Gabe Date: Tue Jul 23 11:09:32 2024 -0500 Add more payable flags + distribution contracts to external commit 79f70528616e96275a3c9eec397b8cfb01724513 Author: Gabe Date: Mon Jul 22 17:13:40 2024 -0500 Add orch payable flag to dao-voting-token-staked stake commit 713366dd2876f355eda5f8674b9fd5640694c57c Author: Gabe Date: Mon Jul 22 17:10:45 2024 -0500 Squashed commit of the following: commit f0dceb1c5bddf23b15304449c6b276f0b8576d8d Author: noah Date: Mon Jul 22 14:48:52 2024 -0400 replaced todo with descriptive error (#858) commit aa0fa5f748e8f0c25d8d86daf2b3ca4bed2f5f43 Author: noah Date: Mon Jul 22 14:48:45 2024 -0400 reorganized publish more (#857) commit cf86aedbcdc50bbdfa3846cb037324a901620ea6 Author: noah Date: Mon Jul 22 13:51:46 2024 -0400 added pre-propose v2.4.1 migration tests (#856) commit be861a863a4228d19c2df95ba81de8a891d4643b Author: Jake Hartnell Date: Mon Jul 22 19:45:58 2024 +0200 Add new contracts to publishing script. (#853) commit 71dd1093be2eb4b8cdce646ed2fe1f879de6e120 Author: noah Date: Mon Jul 22 03:56:52 2024 -0400 updated migrate versions (#855) commit 7e6f5cea76a00214af6f21d694b7218138fe7317 Author: noah Date: Mon Jul 22 03:54:17 2024 -0400 started adding pre-propose migration to v2.5.0 (#854) commit 7646730b117f598b4c036417d6ddd661e493550b Author: bekauz Date: Mon Jul 22 09:43:58 2024 +0200 DAO rewards distributor emission rate updates (#848) commit ce946ac9e528152b446b500e9e45cceef9daa85d Author: noah Date: Fri Jul 19 16:23:14 2024 -0400 add info query to pre-propose-base (#852) commit ebc79143e4eb37ef9840d3850d437bc46335ef2d Author: noah Date: Thu Jul 18 13:12:14 2024 -0400 Support instantiate2 in `cw-admin-factory` (#851) commit 8c37b9ec679122d67a29ec80c011612265ae5baf Author: noah Date: Wed Jul 17 16:03:09 2024 -0400 BitSong fantoken factory (#845) commit 9cea2d166e5d973ff50e647ede63e3b3ba3ac827 Author: hard-nett Date: Tue Jul 23 20:38:00 2024 +0000 add external contract cw-orch suites commit 2478f28d9eb9a309030fdff7a825827d79830698 Author: hard-nett Date: Mon Jul 22 16:35:28 2024 +0000 bump /external commit c5995c0e4aff42d38bf68357bb3f976cbf1d8670 Author: Gabe Date: Fri Jul 19 12:08:16 2024 -0500 Revert basic.yml i think caching is causing issues with the cargo.lock commit 48c0067d750ebaf3aea9aef2c8e53f7bfaecbb65 Author: Gabe Date: Fri Jul 19 12:06:17 2024 -0500 Lint + not(target_arch = "wasm32") in lib.rs commit 1d68601483c18d1c26707a9107322ab37be46ac4 Author: Gabe Date: Fri Jul 19 02:40:02 2024 -0500 Update to cw-orch .24.1 commit bcbaa7ef9cc51cb8704b0ba0f03405e1527686a4 Author: Gabriel Lopez Date: Thu Jul 18 20:56:03 2024 -0500 Revert integration_tests.yml commit ae81938c9a8832dfbc064ecade3b412d8a55c022 Author: Gabriel Lopez Date: Wed Jul 17 13:18:11 2024 -0500 Update basic.yml to cache only cargo deps Nightly toolchain is required for integration_tests commit a90d77c527569a2217f0c02ba3697b0dcf646f69 Author: Gabriel Lopez Date: Wed Jul 17 12:45:09 2024 -0500 Set integration_tests toolchain to latest stable commit 485b7f79582a8a76ae13533544cffb0ed6a75c3b Author: hard-nett Date: Sat Jul 13 18:53:38 2024 +0000 add cw-orch to external contract commit 449e481d69fd25bf7fa83c451359310ac04d5812 Author: Gabriel Lopez Date: Thu Jul 11 02:21:52 2024 -0500 Cargo schema + fix orch wasm build and tests commit 5ccaa5ebc8dc65b60682782b8f34c45da6eee13a Author: Gabriel Lopez Date: Thu Jul 11 00:40:32 2024 -0500 Fix cargo stuff commit 3ff1cc7b894d05f2f4b8e93b9ed4a0aae72cf670 Author: Gabriel Lopez Date: Wed Jul 10 23:47:50 2024 -0500 Add cache to basic.yml commit 2c4db48387e961f55d7380c6556a99852e000e93 Author: Gabriel Lopez Date: Wed Jul 10 23:47:40 2024 -0500 Fix lints Also updates just lint to match basic.yml commit 1cce2eafe8e1d28f5bca7e8f50ea9f813722b6c7 Author: Kayanski Date: Fri May 17 09:09:32 2024 +0000 Added other derives commit 7bf054c74a279100a27bf8236bffb036dbdf632c Author: Kayanski Date: Fri May 17 09:06:45 2024 +0000 Added derive fns commit 302b1aa1b582949bc76fc5485077af60e1bc704a Author: Kayanski Date: Fri May 17 08:54:07 2024 +0000 Fix tests commit 7999ce878eaa16429bba4d1bd344fad1fb770d00 Author: Kayanski Date: Fri May 17 08:52:54 2024 +0000 Added Queryfns on voting commit d06b3772129a4d8a1f1e10eab4929500764e4872 Author: Kayanski Date: Fri May 17 08:06:38 2024 +0000 Finalize test changes commit 364d12d202daeab38ad74b3d3368cded67a8751a Author: Kayanski Date: Fri May 17 07:40:35 2024 +0000 More tests commit 5fa3d4465a6bbaa2e9c70d5390bbef35aa517bb1 Author: Kayanski Date: Thu May 16 17:24:41 2024 +0000 Added tests with cw-orch commit 75d7492016fa27548a83a3206550d43d8e8ac7d5 Author: Kayanski Date: Thu May 16 14:41:02 2024 +0000 First test modifications commit 455880f57727961f61ed5660c30e0c32b64d64ef Author: ismellike Date: Mon May 20 13:06:39 2024 -0500 Fix issue with instantiating cw-abc with hatchers (#830) allow self to call method commit f656e8abc0832e46073b86581c9d4a58b6b6aad8 Author: ismellike Date: Tue May 14 13:44:13 2024 -0500 ABC Improvements (#818) * Make hatcher_allowlist a map Also cleans up state when going from Hatch -> Open Various spell-checking fixes * Allow existing tokens to be used with ABC's I think it's important for an existing token to be supported by an ABC. Token DAO's will be able to set up liquidity more easily by simply allowing mint & burn functionality after instantiating the ABC while holding ownership of it. *Also adds a query for hatcher allowlist *fixes spell checks I ran into *moves TokenInfo from dao-voting-token-staked to dao-interface for use in cw-abc * Complete funding pool logic Renamed fees_recipient to funding_pool_forwarding for better naming Made funding_pool_forwarding optional Allow updating the funding_pool_forwarding by owner Allow withdrawing from the funding pool by owner * Implement a circuit breaker Adds IS_PAUSED state that is checked in execute entry Also fixes naming in commands * Add query for initial supply at ABC creation * Allow donation into the reserve pool Also fixes donation state being lost after multiple donations * Move cw-abc curves to its own package cw-curves * Improve validation for max_supply * Support DAO membership in hatcher allowlist Could use a test here Also fixes some warnings and flag for cw-std * Clippy fix * Only clone decimals from curve_state also reorg buy command to be closer to sell command for readability * QoL improvements Derive copy on DecimalPlaces Catch OverflowError directly in ContractError Do not set initial supply as supply - will further remove allowing initial supplies * Revert support for initial supply * Fix clippy unnecessary clones * Donate only into the funding pool * Add a test for donate and withdraw from funding pool * Add test for dao hatchers + update schemas Also removes unused deps from cw-abc which now live in cw-curves * Update Cargo.toml * Buy & Sell Quotes Let users know the curve state and returned amount after x payment * Complete DAO hatchers w/ priority queue Disallow selling in the hatch phase Do not validate max_contribution against max_raise * Fix priority queue ordering on ties also clippy fixes * Couple more clippy fixes commit 6d4b430c1dcdef97723ec9ccfe295266d5f2e947 Author: Jake Hartnell Date: Tue Mar 26 14:35:44 2024 +0100 Post rebase fixups commit 6ab116dbfc9616e2aa4596726f8df12b2321c7da Author: Jake Hartnell Date: Mon Jan 8 16:52:52 2024 -0800 Clean up small TODO commit 371d72422c7a38a4375476db56f630cd7e6512b8 Author: Jake Hartnell Date: Mon Jan 8 15:36:58 2024 -0800 Remove unused deps commit 7e923efb026ae0e470d69e32052865ccd645f582 Author: Jake Hartnell Date: Tue Jan 2 22:51:51 2024 -0800 Bump nightly version in CI commit a0eb61992cb5d5b50166b7cdb81bd5ef90e163e3 Author: Jake Hartnell Date: Tue Jan 2 20:44:12 2024 -0800 Fix clippy errors and test errors commit 301b45af489506f28695efc1a6b1d10479a33d8b Author: Jake Hartnell Date: Fri Dec 29 14:07:42 2023 -0800 Basic Integration Tests commit 389484f58d02f081ba7bbd6c85f25197ae57b942 Author: Jake Hartnell Date: Sat Dec 23 15:19:18 2023 -0800 Fix wasm build commit 4d4d70e84f6389d5c7aebf3b26ec2383f187dbe6 Author: Jake Hartnell Date: Sat Dec 23 14:45:14 2023 -0800 dao-abc-factory contract Creates new cw-abc DAOs. commit 02e26e06753a3cedd5efbc015b160382ad51ea1f Author: Jake Hartnell Date: Sat Dec 23 13:13:06 2023 -0800 Remove token-bindings dep commit 00b80d9af73ef1f49d297695e0e4fb55e040b5fd Author: Jake Hartnell Date: Sat Dec 23 13:09:40 2023 -0800 Fix cargo file after rebase commit 9d069ebcc0043894eb3deb5fddb302da48d9aa24 Author: Jake Hartnell Date: Tue Dec 12 14:46:50 2023 -0800 Remove unused old tests commit 84811db889afb3914f143d2fe8fca42f88d898f4 Author: Jake Hartnell Date: Tue Dec 12 14:41:41 2023 -0800 Remove TokenFactoryMsg and TokenFactoryQuery, no token-bindings dep commit 33927a1f23daf8ce4ac2b64b26a7a76335bad181 Author: Jake Hartnell Date: Tue Dec 12 14:30:03 2023 -0800 More queries, update schema commit 71832ce82fa832075eb45cbbefd11629b04914f7 Author: Jake Hartnell Date: Wed Dec 6 13:01:57 2023 -0800 Rename variables to make them more consistent and understandable commit 0db6203cb9b159bd1934a0cf000ee0e08f23db95 Author: Jake Hartnell Date: Wed Dec 6 12:49:34 2023 -0800 Add more information to the readme commit 5be336ac84bba94a33ff1b4b46894229e466bf1c Author: Jake Hartnell Date: Tue Dec 5 17:16:41 2023 -0800 Update schema commit 9c8768e30cd9f0df3999ef3070241c1f7dcff26c Author: Jake Hartnell Date: Tue Dec 5 17:09:04 2023 -0800 Fix exit fees commit 4080c016235956b7842c820f09bb8f9f60421f8a Author: Jake Hartnell Date: Tue Dec 5 16:15:38 2023 -0800 Bug fixes, implement fees commit c88246917dbb894e72e6e49e0024c38ac8e4956e Author: Jake Hartnell Date: Mon Dec 4 18:33:27 2023 -0800 to_binary -> to_json_binary commit be5cc1e111ae54ce40d8725bf52dae819aaeb67b Author: Jake Hartnell Date: Mon Dec 4 17:47:32 2023 -0800 Next pass at adding info to readme commit f3b1216aaa8ef6e1aa943ea546dc176de286f7c8 Author: Jake Hartnell Date: Mon Nov 20 14:54:14 2023 +0100 Attempt at update curve tests commit 60d7f61f5155b36fac93aa97b0ffdbaa348335e0 Author: Jake Hartnell Date: Mon Nov 20 14:25:21 2023 +0100 More tests! commit 69cd33b500ec0b521e7751b6b75f943bd196d1bd Author: Jake Hartnell Date: Mon Nov 20 14:02:37 2023 +0100 Fix some tests commit 8ef65d8220f66573f63059733e4936b4bd66772d Author: Jake Hartnell Date: Fri Nov 17 17:35:11 2023 +0100 Update schema commit 638b102f560a90cf93d41fae24cb891036586d0d Author: Jake Hartnell Date: Fri Nov 17 16:59:19 2023 +0100 Rename methods, cleanup unused variables commit 9e700570dfd39645ffb878a35e45683362dcc041 Author: Jake Hartnell Date: Fri Nov 17 16:54:59 2023 +0100 Close curve, update curve, set max supply methods commit 30dd7a5e9e07e7746d1c19310007814a7f42d082 Author: Jake Hartnell Date: Fri Nov 17 14:36:50 2023 +0100 Clean up, add notes for future work commit 9f39048aec7558306bd0a485e9b691cfd550135b Author: Jake Hartnell Date: Thu Nov 16 17:11:11 2023 +0100 Max Supply commit ea21f4f95f73acb51adbee43d5b8421b0164a321 Author: Jake Hartnell Date: Thu Nov 16 16:47:40 2023 +0100 Contribution limits commit 5fc2de805d1c15ced8f0a62d63805e8bf42f7849 Author: Jake Hartnell Date: Thu Nov 16 15:04:37 2023 +0100 Refactor update phase config, fix metadata, clean up commit ecdfb9dd45b9644c1933f3a7ba2414a28abce226 Author: Jake Hartnell Date: Sun Nov 12 22:19:51 2023 +0100 Happy path test, make notes commit 4930042b95c777c3a8332117eb0cc76b51c468b0 Author: Jake Hartnell Date: Thu Nov 9 15:56:33 2023 +0100 Clean up, clippy, workspace deps, notes commit 8985177c1445f6cdcf77835dd2503e5773b4fe6a Author: Jake Hartnell Date: Mon Nov 6 15:57:42 2023 +0100 Note commit b5c173b11870239b385d78f2c6fe1f79beaae104 Author: Jake Hartnell Date: Mon Nov 6 15:57:29 2023 +0100 Attempt to fix burn commit 6f80580a36eab87192349915a8f53f20c46ed744 Author: Jake Hartnell Date: Thu Nov 2 18:12:32 2023 +0100 More cleanup for clippy commit b7247f4b705ea5eb6359872b9563421b80bfb3af Author: Jake Hartnell Date: Mon Oct 30 20:39:43 2023 +0100 Rebase cleanup, fix up tests commit fc19b74122eaca51f3685a9f9fa959cd3a9bff02 Author: Jake Hartnell Date: Fri Sep 1 13:38:46 2023 -0700 Fixups, burning tokens still doesn't work commit 50eff274dfb8ba53a794462b4dfc5b6e6cca28a6 Author: Jake Hartnell Date: Thu Aug 31 09:21:13 2023 -0700 Minting tokens works! commit 93f16f68ec35b314e956d4703726ae098b2038da Author: Jake Hartnell Date: Wed Aug 30 18:40:08 2023 -0700 Fix tests, need to investigate why this broke commit 7d6b60013cb8ed0b6fcbe467d15597871b67078a Author: Jake Hartnell Date: Wed Aug 30 17:39:24 2023 -0700 Get instantiation working with test-tube commit 2f6bba46e45c765324030c1ea51a711cf23318d6 Author: Jake Hartnell Date: Wed Aug 30 17:09:25 2023 -0700 Get test-tube tests running commit fc5d5d6847e9679b83d1aa6c4309b92487e5482e Author: Jake Hartnell Date: Wed Aug 30 16:23:14 2023 -0700 Clean up and notes commit a72ad9536f709299b694037ad8be1d6ae2f5b54a Author: Jake Hartnell Date: Wed Aug 30 16:22:59 2023 -0700 Update schema commit 988cf5d571a6585d14c2cd24edfdfd4f3fef8e5e Author: Jake Hartnell Date: Wed Aug 30 16:05:01 2023 -0700 Refactor commit f05541b725e3f5302faf5eafee1b6bb8ddd0eb28 Author: Jake Hartnell Date: Wed Aug 30 15:31:27 2023 -0700 Remove old attempt at fixing cw-multi-test commit df6ebad0379a2252ecc8e82855db90e5c5a8dbdb Author: Jake Hartnell Date: Wed Aug 30 15:30:44 2023 -0700 Refactor cw-abc contract to work with cw-tokenfactory-issuer commit 98b02039761ed9a16f22c8c65dd4c732434f8ebe Author: Jake Hartnell Date: Wed Aug 30 14:46:07 2023 -0700 Start prepping for refactor and tests commit 3b4965abb0da12a3a52f05b9cf36a5c1353d87ab Author: Jake Hartnell Date: Thu Aug 10 21:54:37 2023 +0200 Attempt to get tests working commit 84244ed8aa0cdc01d8289da77d0a48c77cb2e5c4 Author: Jake Hartnell Date: Sun Jul 9 18:24:19 2023 +0200 Remove boot / cw-orch, get cw-multi-test working with custom messages commit 6097ea4892b39d7b1dd20bcb8f8fd5f41fe6ee3d Author: Dat-Andre <114091333+Dat-Andre@users.noreply.github.com> Date: Mon May 8 22:17:13 2023 +0100 697 (#702) * update cw-orch dependency * add getrandom dependency to .toml --------- Co-authored-by: Jake Hartnell commit 0f390c3070a2a27b7a8a33aaf95e9d9cdbd0cd98 Author: Jake Hartnell Date: Tue May 2 13:21:49 2023 -0700 Comments clean up commit 52c6a987450a5bdd7db93d1bf6b4239e7e57387e Author: adairrr <32375605+adairrr@users.noreply.github.com> Date: Wed Apr 26 00:30:21 2023 +0300 cw-abc: Updated hatch phase mechanics, donations, queries (#699) * Separate hatcher allowlist * Donation feature * Initial sell exit tax * Hatchers to amount * Hatch phase exit tax * TokenMsg methods * Format * Hatchers query * Fix bug where float was not taken into account in supply * Buy and sell refactoring * Update hatch phase config * Update phase config enum * Add adairrr to authors * Initial boot integration with custom msgs * Initial testing infrastructure * Abstract-OS to AbstractSDK commit aceb8ba04e065133171fe41f65f418f2f6622e5b Author: adairrr <32375605+adairrr@users.noreply.github.com> Date: Sun Apr 23 04:52:07 2023 +0300 Initial phase integration to cw-abc (#698) * CwAbcResult * Hatch phase configuration and init msg refactor * Initial instantiate test * Implement separate phrases and phrase configs * Remove vesting phase and update funding pool * Separate commands and queries * Update init msg with string configs * Phase config query * MinMax and config query * Add some todos * cw-ownable integration commit 088143c2724e28793ba6f5d8e623ba15fcba1fe6 Author: Jake Hartnell Date: Wed Apr 19 18:55:01 2023 -0700 Initial commit --- Cargo.lock | 6084 ----------------- Cargo.toml | 25 +- .../dao-dao-core/schema/dao-dao-core.json | 2 +- contracts/external/cw-abc/.cargo/config | 6 + contracts/external/cw-abc/Cargo.toml | 62 + contracts/external/cw-abc/NOTICE | 15 + contracts/external/cw-abc/README.md | 150 + contracts/external/cw-abc/examples/schema.rs | 11 + contracts/external/cw-abc/schema/cw-abc.json | 2671 ++++++++ contracts/external/cw-abc/src/abc.rs | 218 + contracts/external/cw-abc/src/commands.rs | 632 ++ contracts/external/cw-abc/src/contract.rs | 310 + contracts/external/cw-abc/src/error.rs | 69 + contracts/external/cw-abc/src/helpers.rs | 109 + contracts/external/cw-abc/src/lib.rs | 14 + contracts/external/cw-abc/src/msg.rs | 263 + contracts/external/cw-abc/src/queries.rs | 182 + contracts/external/cw-abc/src/state.rs | 145 + contracts/external/cw-abc/src/tests.rs | 843 +++ .../external/cw-admin-factory/Cargo.toml | 2 +- .../external/cw-admin-factory/src/lib.rs | 2 +- .../schema/cw-tokenfactory-issuer.json | 16 +- .../cw-tokenfactory-issuer/src/msg.rs | 21 +- .../cw-tokenfactory-issuer/src/queries.rs | 4 +- .../tests/cases/burn.rs | 2 +- .../tests/cases/denom_metadata.rs | 6 + .../cw-tokenfactory-issuer/tests/test_env.rs | 2 +- contracts/external/cw-vesting/README.md | 4 +- .../external/dao-abc-factory/.cargo/config | 4 + contracts/external/dao-abc-factory/Cargo.toml | 51 + contracts/external/dao-abc-factory/README | 4 + .../dao-abc-factory/examples/schema.rs | 10 + .../schema/dao-abc-factory.json | 645 ++ .../external/dao-abc-factory/src/contract.rs | 187 + .../external/dao-abc-factory/src/error.rs | 28 + contracts/external/dao-abc-factory/src/lib.rs | 8 + contracts/external/dao-abc-factory/src/msg.rs | 25 + .../src/test_tube/integration_tests.rs | 147 + .../dao-abc-factory/src/test_tube/mod.rs | 9 + .../dao-abc-factory/src/test_tube/test_env.rs | 558 ++ .../schema/dao-proposal-single.json | 2 +- .../proposal/dao-proposal-single/src/msg.rs | 2 +- .../dao-proposal-single/src/proposal.rs | 8 +- .../test/dao-proposal-hook-counter/src/msg.rs | 1 + .../voting/dao-voting-cw20-staked/src/msg.rs | 1 + .../voting/dao-voting-cw721-staked/src/msg.rs | 1 + .../src/testing/integration_tests.rs | 2 +- .../dao-voting-token-staked/src/contract.rs | 13 +- .../voting/dao-voting-token-staked/src/msg.rs | 1 + .../src/tests/test_tube/integration_tests.rs | 11 +- .../src/tests/test_tube/test_env.rs | 4 +- packages/cw-curves/Cargo.toml | 20 + packages/cw-curves/README.md | 6 + packages/cw-curves/src/curve.rs | 120 + packages/cw-curves/src/curves/constant.rs | 86 + packages/cw-curves/src/curves/linear.rs | 76 + packages/cw-curves/src/curves/mod.rs | 8 + packages/cw-curves/src/curves/square_root.rs | 78 + packages/cw-curves/src/lib.rs | 8 + packages/cw-curves/src/tests.rs | 111 + packages/cw-curves/src/utils.rs | 95 + packages/cw-orch/Cargo.toml | 5 +- packages/cw-orch/src/external/cw_abc.rs | 20 + packages/cw-orch/src/external/mod.rs | 2 + packages/cw-orch/src/tests.rs | 18 +- packages/cw-paginate-storage/src/lib.rs | 2 +- packages/cw-tokenfactory-types/src/msg.rs | 2 + packages/dao-interface/src/msg.rs | 2 +- packages/dao-testing/Cargo.toml | 10 +- packages/dao-testing/src/lib.rs | 4 + .../dao-testing/src/test_tube/cw4_group.rs | 2 +- .../dao-testing/src/test_tube/cw721_base.rs | 2 +- packages/dao-testing/src/test_tube/cw_abc.rs | 181 + .../src/test_tube/cw_admin_factory.rs | 3 +- .../src/test_tube/cw_tokenfactory_issuer.rs | 2 +- .../src/test_tube/dao_abc_factory.rs | 129 + .../dao-testing/src/test_tube/dao_dao_core.rs | 2 +- .../src/test_tube/dao_proposal_single.rs | 2 +- .../src/test_tube/dao_test_custom_factory.rs | 2 +- .../src/test_tube/dao_voting_cw4.rs | 2 +- .../src/test_tube/dao_voting_token_staked.rs | 129 + packages/dao-testing/src/test_tube/mod.rs | 28 +- packages/dao-voting/src/voting.rs | 4 +- 83 files changed, 8575 insertions(+), 6178 deletions(-) delete mode 100644 Cargo.lock create mode 100644 contracts/external/cw-abc/.cargo/config create mode 100644 contracts/external/cw-abc/Cargo.toml create mode 100644 contracts/external/cw-abc/NOTICE create mode 100644 contracts/external/cw-abc/README.md create mode 100644 contracts/external/cw-abc/examples/schema.rs create mode 100644 contracts/external/cw-abc/schema/cw-abc.json create mode 100644 contracts/external/cw-abc/src/abc.rs create mode 100644 contracts/external/cw-abc/src/commands.rs create mode 100644 contracts/external/cw-abc/src/contract.rs create mode 100644 contracts/external/cw-abc/src/error.rs create mode 100644 contracts/external/cw-abc/src/helpers.rs create mode 100644 contracts/external/cw-abc/src/lib.rs create mode 100644 contracts/external/cw-abc/src/msg.rs create mode 100644 contracts/external/cw-abc/src/queries.rs create mode 100644 contracts/external/cw-abc/src/state.rs create mode 100644 contracts/external/cw-abc/src/tests.rs create mode 100644 contracts/external/dao-abc-factory/.cargo/config create mode 100644 contracts/external/dao-abc-factory/Cargo.toml create mode 100644 contracts/external/dao-abc-factory/README create mode 100644 contracts/external/dao-abc-factory/examples/schema.rs create mode 100644 contracts/external/dao-abc-factory/schema/dao-abc-factory.json create mode 100644 contracts/external/dao-abc-factory/src/contract.rs create mode 100644 contracts/external/dao-abc-factory/src/error.rs create mode 100644 contracts/external/dao-abc-factory/src/lib.rs create mode 100644 contracts/external/dao-abc-factory/src/msg.rs create mode 100644 contracts/external/dao-abc-factory/src/test_tube/integration_tests.rs create mode 100644 contracts/external/dao-abc-factory/src/test_tube/mod.rs create mode 100644 contracts/external/dao-abc-factory/src/test_tube/test_env.rs create mode 100644 packages/cw-curves/Cargo.toml create mode 100644 packages/cw-curves/README.md create mode 100644 packages/cw-curves/src/curve.rs create mode 100644 packages/cw-curves/src/curves/constant.rs create mode 100644 packages/cw-curves/src/curves/linear.rs create mode 100644 packages/cw-curves/src/curves/mod.rs create mode 100644 packages/cw-curves/src/curves/square_root.rs create mode 100644 packages/cw-curves/src/lib.rs create mode 100644 packages/cw-curves/src/tests.rs create mode 100644 packages/cw-curves/src/utils.rs create mode 100644 packages/cw-orch/src/external/cw_abc.rs create mode 100644 packages/dao-testing/src/test_tube/cw_abc.rs create mode 100644 packages/dao-testing/src/test_tube/dao_abc_factory.rs create mode 100644 packages/dao-testing/src/test_tube/dao_voting_token_staked.rs diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index f02ee8fda..000000000 --- a/Cargo.lock +++ /dev/null @@ -1,6084 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "abstract-cw-multi-test" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c77f8d4bac08f74fbc4fce8943cb2d35e742682b6cae8cb65555d6cd3830feb" -dependencies = [ - "anyhow", - "bech32 0.11.0", - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw20-ics20", - "derivative", - "hex", - "itertools 0.12.1", - "log", - "prost 0.12.3", - "schemars", - "serde", - "serde_json", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "abstract-cw-plus-interface" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7441425a805439500492977107d154af02b1702aa044945775c245d0b3469968" -dependencies = [ - "abstract-cw1", - "abstract-cw1-subkeys", - "abstract-cw1-whitelist", - "abstract-cw20-base", - "abstract-cw20-ics20", - "abstract-cw3-fixed-multisig", - "abstract-cw3-flex-multisig", - "abstract-cw4-group", - "abstract-cw4-stake", - "cosmwasm-std", - "cw-orch 0.22.2", -] - -[[package]] -name = "abstract-cw1" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0895c076ab6a5165133a453f983ec9ccc9b6c41de256b6eb74e523eb555b3ebb" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "abstract-cw1-subkeys" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab08cdd6008afa38a52427943bf4aef9541bde78cc9c14849a53ad2608a1161e" -dependencies = [ - "abstract-cw1", - "abstract-cw1-whitelist", - "abstract-cw2", - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw1-whitelist" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171a0b5b3694627cf0fa554500d72431169d4013fffd14650d2b7d660230a205" -dependencies = [ - "abstract-cw1", - "abstract-cw2", - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw2" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945af4c176b4539be2a74c06aa166287ba964ab58aec98c644addd812431f141" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw20" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d5e4b8084c3a2b3e42502e6c4fe3ed985dc72e86eb612bcc527f4a0443fa42" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "abstract-cw20-base" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d300dec7d602e00841c5ab6fe598d4d290bab32e489c6885c607633c4f3fe67" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw20-ics20" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027678ddb0e62b4aba5f0167d2b0a3ec0182e1e32c47759be7e30b56775598ee" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw3" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c080cc760333d1d3477857aeac19aa7e6e661f1e58d04a7a78212913d49bf517" -dependencies = [ - "abstract-cw20", - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw3-fixed-multisig" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1882e05bef33bd1c6b25e735eda8a23332a78c4df0b24a18ca56a8ca8ed6f222" -dependencies = [ - "abstract-cw2", - "abstract-cw3", - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw3-flex-multisig" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92379f3e7c467f081312d6953eb8d300456efa352c9f7c5ef095ad99083d92db" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "abstract-cw3", - "abstract-cw3-fixed-multisig", - "abstract-cw4", - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw4" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aacb0124dce37ee6f2b5636684285bcbaa65a1678980f95ea76366ab74a8912" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", -] - -[[package]] -name = "abstract-cw4-group" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0af5ef484ba1d48fee8485452c81ac3465ba16a5941db90bda4dd6b58b50a9a6" -dependencies = [ - "abstract-cw2", - "abstract-cw4", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw4-stake" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1eb9985e8b752396a2c5d8fde8ebf65ea81070a95f167a3d31af0746f8e4b4e" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "abstract-cw4", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "addr2line" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "async-trait" -version = "0.1.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "base16ct" -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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bech32" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" - -[[package]] -name = "bindgen" -version = "0.68.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" -dependencies = [ - "bitflags 2.6.0", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.77", - "which", -] - -[[package]] -name = "bip32" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" -dependencies = [ - "bs58", - "hmac", - "k256 0.11.6", - "once_cell", - "pbkdf2", - "rand_core 0.6.4", - "ripemd", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" - -[[package]] -name = "bootstrap-env" -version = "0.2.0" -dependencies = [ - "anyhow", - "cosm-orc", - "cosmwasm-std", - "cw-admin-factory", - "cw-utils 1.0.3", - "cw20 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "env_logger", - "serde", - "serde_json", - "serde_yaml", - "tokio", -] - -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" -dependencies = [ - "sha2 0.9.9", -] - -[[package]] -name = "btsg-ft-factory" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-token-staked", - "osmosis-std-derive", - "prost 0.12.3", - "prost-derive 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" -dependencies = [ - "shlex", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "num-traits", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "config" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" -dependencies = [ - "async-trait", - "json5", - "lazy_static", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml", - "yaml-rust", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cosm-orc" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6676a17fddc94aac5fe07bad646d99b7f7cef1f0cc2c74b61af25733cbbb9f08" -dependencies = [ - "config", - "cosm-tome", - "erased-serde", - "log", - "serde", - "serde_json", - "thiserror", - "tokio", -] - -[[package]] -name = "cosm-tome" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "596064e3608349aa302eb68b2df8ed3a66bbb51d9b470dbd9afff70843e44642" -dependencies = [ - "async-trait", - "cosmrs 0.10.0", - "regex", - "schemars", - "serde", - "serde_json", - "thiserror", - "tonic 0.8.3", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b42021d8488665b1a0d9748f1f81df7235362d194f44481e2e61bf376b77b4" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.23.9", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673d31bd830c0772d78545de20d975129b6ab2f7db4e4e9313c3b8777d319194" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.26.0", - "tonic 0.8.3", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.32.2", - "tonic 0.9.2", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e23f6ab56d5f031cde05b8b82a5fefd3a1a223595c79e32317a97189e612bc" -dependencies = [ - "prost 0.12.3", - "prost-types 0.12.3", - "tendermint-proto 0.35.0", -] - -[[package]] -name = "cosmrs" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3903590099dcf1ea580d9353034c9ba1dbf55d1389a5bd2ade98535c3445d1f9" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.14.0", - "ecdsa 0.14.8", - "eyre", - "getrandom", - "k256 0.11.6", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.23.9", - "tendermint-rpc 0.23.9", - "thiserror", -] - -[[package]] -name = "cosmrs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa07096219b1817432b8f1e47c22e928c64bbfd231fc08f0a98f0e7ddd602b7" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.15.0", - "ecdsa 0.14.8", - "eyre", - "getrandom", - "k256 0.11.6", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.26.0", - "tendermint-rpc 0.26.0", - "thiserror", -] - -[[package]] -name = "cosmwasm-crypto" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" -dependencies = [ - "digest 0.10.7", - "ed25519-zebra", - "k256 0.13.3", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" -dependencies = [ - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" -dependencies = [ - "cosmwasm-schema-derive", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-std" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" -dependencies = [ - "base64 0.21.7", - "bech32 0.9.1", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm", - "sha2 0.10.8", - "static_assertions", - "thiserror", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-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", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-address-like" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" -dependencies = [ - "cosmwasm-std", -] - -[[package]] -name = "cw-admin-factory" -version = "2.5.0" -dependencies = [ - "bech32 0.9.1", - "cosmwasm-schema", - "cosmwasm-std", - "cw-admin-factory", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", - "osmosis-test-tube", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64bfeaf55f8dba5646cc3daddce17cd23a60f8e0c3fbacbe6735d287d7a6e33a" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468b8f2696f625c8e15b5468f9420c8eabfaf23cb4fd7e6c660fc7e0cc8d77b8" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-paginate-storage 0.1.0", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw721 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-core-interface" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c93e684945473777ebed2bcaf9f0af2291653f79d5c81774c6826350ba6d88de" -dependencies = [ - "cosmwasm-std", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw2 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw-core-interface" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "cosmwasm-std", - "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw2 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw-core-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20a77489d2dc8a1c12cb0b9671b6cbdca88f12fe65e1a4ee9899490f7669dcc" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-core-macros" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-denom" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decaa8be7ffa8090dc62d8bb8ee97cd3f41f815a41ba08de1d40cacef6c3cb4b" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw20 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-denom" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-fund-distributor" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-voting-cw20-staked", - "thiserror", -] - -[[package]] -name = "cw-hooks" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "097ee97b99ecc90372eac3bcaf698d940a15f806f2ba1e1e901c729f6523e16e" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "cw-hooks" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" -dependencies = [ - "anyhow", - "bech32 0.9.1", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "derivative", - "itertools 0.12.1", - "prost 0.12.3", - "schemars", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-orch" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1ddc937c28c59ccf2765fa05ddc0437644d3b283408a7cc64f7b371b0b9309" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cw-orch-contract-derive", - "cw-orch-core", - "cw-orch-fns-derive 0.19.1", - "cw-orch-mock 0.22.4", - "cw-orch-traits 0.22.0", - "cw-utils 1.0.3", - "hex", - "log", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-orch" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c81cb500eb2f9be31a0f90c7ce66572ee4a790ffbae1c6b42ff2e3f9faf3479" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cw-orch-contract-derive", - "cw-orch-core", - "cw-orch-fns-derive 0.22.0", - "cw-orch-mock 0.23.2", - "cw-orch-traits 0.23.3", - "cw-utils 1.0.3", - "hex", - "log", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-orch-contract-derive" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc8ba75692fc7bd30e91c78fad2dc208a738e4e6ea26b232f9352c320e35543" -dependencies = [ - "convert_case", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "cw-orch-core" -version = "1.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9466093ad8bf067f9eebbe25835ada3ea155726ca557d9d1c7681538078ef24f" -dependencies = [ - "abstract-cw-multi-test", - "anyhow", - "cosmos-sdk-proto 0.21.1", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "dirs", - "log", - "serde", - "serde_json", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-orch-fns-derive" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9acb7a15bfacc52abdf312a9fffb139883c1effb6ea7e645cd39580a8527463" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-orch-fns-derive" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e21b23116a0702f540d7fa3f16e8276682d860b589fed56259220ad59d768e" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-orch-mock" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae9536620b86ee78c2729fd8449538feb4f6257a9809c72c5f9e461e720cf3b" -dependencies = [ - "abstract-cw-multi-test", - "cosmwasm-std", - "cw-orch-core", - "cw-utils 1.0.3", - "log", - "serde", - "sha2 0.10.8", -] - -[[package]] -name = "cw-orch-mock" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57beb30d841bde79df51c9402741ef926ca8ef7ecd3570aa180074f767ac04d3" -dependencies = [ - "abstract-cw-multi-test", - "cosmwasm-std", - "cw-orch-core", - "cw-utils 1.0.3", - "log", - "serde", - "sha2 0.10.8", -] - -[[package]] -name = "cw-orch-traits" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5959ce29e9d8a52594b47933a0a2736ea94dd9bf5e29b220cbdbe2b097f07c3a" -dependencies = [ - "cw-orch-core", - "prost 0.12.3", - "prost-types 0.12.3", -] - -[[package]] -name = "cw-orch-traits" -version = "0.23.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e6b81dc282724c9c6334a499f4867e575458e69fe5b99034d4f962860f3357" -dependencies = [ - "cw-orch-core", - "prost 0.12.3", - "prost-types 0.12.3", -] - -[[package]] -name = "cw-ownable" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-address-like", - "cw-ownable-derive", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "thiserror", -] - -[[package]] -name = "cw-ownable-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-paginate-storage" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b854833e07c557dee02d1b61a21bb0731743bb2e3bbdc3e446a0d8a38af40ec4" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.13.4", - "serde", -] - -[[package]] -name = "cw-paginate-storage" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9740c02c59072ad00de64cc60aae6ca492103dcefc0f7d3cc6f77d768f2ec70" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-paginate-storage" -version = "2.5.0" -dependencies = [ - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-payroll-factory" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw-vesting", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", - "wynd-utils", -] - -[[package]] -name = "cw-proposal-single" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6408483e1ac17a7e2b98ef6fa1379776964353bcbf501942d22ee1c1323117" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw3", - "dao-voting 0.1.0", - "indexable-hooks", - "proposal-hooks", - "schemars", - "serde", - "thiserror", - "vote-hooks", -] - -[[package]] -name = "cw-stake-tracker" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-wormhole", -] - -[[package]] -name = "cw-storage-plus" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-token-swap" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-tokenfactory-issuer" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-types", - "cw2 1.1.2", - "dao-interface 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "prost 0.12.3", - "prost-derive 0.12.3", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cw-tokenfactory-types" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "dao-interface 2.5.0", - "osmosis-std", - "osmosis-std-derive", - "prost 0.12.3", - "prost-derive 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "cw-utils" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef842a1792e4285beff7b3b518705f760fa4111dc1e296e53f3e92d1ef7f6220" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 0.16.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-vesting" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-stake-tracker", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw-wormhole", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-testing", - "serde", - "thiserror", - "wynd-utils", -] - -[[package]] -name = "cw-wormhole" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw2" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.16.0", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9671d7edef5608acaf5b2f1e473ee3f501eced2cd4f7392e2106c8cf02ba0720" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "cw20-base" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f6fc8c4cd451b418fa4f1ac2ea70595811fa9d8b4033617fe47953d7a93ceb" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "cw2 0.11.1", - "cw20 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-ics20" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76221201da08fed611c857ea3aa21c031a4a7dc771a8b1750559ca987335dc02" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-stake" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f0d51ce27a97b51f66d737183845bc6d82f46f4b246dc959d1265d86906ccc" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-stake" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 0.2.6", - "dao-hooks 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "cw20-stake-external-rewards" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 0.13.4", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-hooks 2.5.0", - "stake-cw20-external-rewards", - "thiserror", -] - -[[package]] -name = "cw20-stake-reward-distributor" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "stake-cw20-reward-distributor", - "thiserror", -] - -[[package]] -name = "cw20-staked-balance-voting" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf8c2ee92372d35c3a48fd6ddd490a1a4426902748017dd0b7f551d06484e28" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw3" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw4" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw4" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", -] - -[[package]] -name = "cw4-group" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6c95c89153e7831c8306c8eba40a3daa76f9c7b8f5179dd0b8628aca168ec7a" -dependencies = [ - "cosmwasm-std", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw4 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-group" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-voting" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw4 0.13.4", - "cw4-group 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035818368a74c07dd9ed5c5a93340199ba251530162010b9f34c3809e3b97df1" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw721" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 0.16.0", - "schemars", - "serde", -] - -[[package]] -name = "cw721" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "cw721-base" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.16.0", - "cw-utils 0.16.0", - "cw2 0.16.0", - "cw721 0.16.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-base" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.16.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-controllers" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "thiserror", -] - -[[package]] -name = "cw721-roles" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-cw721-extensions", - "dao-testing", - "dao-voting-cw721-staked", - "serde", - "thiserror", -] - -[[package]] -name = "dao-callback-messages" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "dao-interface 2.5.0", -] - -[[package]] -name = "dao-cw-orch" -version = "2.5.0" -dependencies = [ - "btsg-ft-factory", - "cosmwasm-std", - "cw-admin-factory", - "cw-fund-distributor", - "cw-orch 0.24.1", - "cw-payroll-factory", - "cw-token-swap", - "cw-tokenfactory-issuer", - "cw-vesting", - "cw20-stake 2.5.0", - "cw20-stake-external-rewards", - "cw20-stake-reward-distributor", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-migrator", - "dao-pre-propose-approval-single 2.5.0", - "dao-pre-propose-approver", - "dao-pre-propose-multiple 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-condorcet", - "dao-proposal-hook-counter", - "dao-proposal-multiple 2.5.0", - "dao-proposal-single 2.5.0", - "dao-proposal-sudo", - "dao-rewards-distributor", - "dao-test-custom-factory", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-roles", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "serde", -] - -[[package]] -name = "dao-cw721-extensions" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-orch 0.24.1", - "cw4 1.1.2", -] - -[[package]] -name = "dao-dao-core" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd16c5f6f2760c66546e1e2f3781106dd796c8920847e78e5984922767cbc68" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-paginate-storage 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw721 0.18.0", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-dao-core" -version = "2.5.0" -dependencies = [ - "abstract-cw-plus-interface", - "abstract-cw20", - "abstract-cw20-base", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-callback-messages", - "dao-cw-orch", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-sudo", - "dao-voting-cw20-balance", - "thiserror", -] - -[[package]] -name = "dao-dao-macros" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c3f39b7aaf9d913d0de8c8742c151011da00662acdbe95c33a5f7bad1b835a" -dependencies = [ - "cosmwasm-schema", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dao-dao-macros" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dao-hooks" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c85abbadefe491d571f709464a8cfd2fb78b63b0cb6e6ef49104df249e28acc" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw4 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-hooks" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "cw4 1.1.2", - "dao-pre-propose-base 2.5.0", - "dao-voting 2.5.0", -] - -[[package]] -name = "dao-interface" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4895da96b53c77592f6728fd21dfed4b9aff653fac8d1ee5dceb96353c7045" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw721 0.18.0", - "osmosis-std", -] - -[[package]] -name = "dao-interface" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-orch 0.24.1", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw721 0.18.0", - "osmosis-std", -] - -[[package]] -name = "dao-migrator" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 0.13.4", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 0.2.6", - "cw20-stake 2.5.0", - "cw20-staked-balance-voting", - "cw4 0.13.4", - "cw4-voting", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approval-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4fe4e5b50b3081272557069dbecaf1e0984d1f2932d2e61418712460f8fd313" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-paginate-storage 2.4.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approval-single" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-approval-single 2.4.1", - "dao-pre-propose-base 2.5.0", - "dao-proposal-single 2.4.1", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approver" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-approval-single 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-pre-propose-base" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd285523d7dea35a0dd76f0a5f20c190935922a7b58fe0ec753eb407e68d718b" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.4.1", - "cw-hooks 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "dao-interface 2.4.1", - "dao-voting 2.4.1", - "serde", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-base" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.4.1", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-multiple" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6158aeddd2e080c730f1a2ac3814351cbcd38d61c38209dcf1e203d0e554a5" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-pre-propose-multiple" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-multiple 2.4.1", - "dao-proposal-multiple 2.4.1", - "dao-proposal-multiple 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-pre-propose-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f96fb1898f94ea4fe5771f8ab5c2bc6237782e06bb599f070713d11d38c19e" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-pre-propose-single" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-single 2.4.1", - "dao-proposal-single 2.4.1", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-proposal-condorcet" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.5.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-proposal-hook-counter" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "thiserror", -] - -[[package]] -name = "dao-proposal-multiple" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fac47816150063ef09b555f3466f8be99612b76860a20fba7c85bd1854beba" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-hooks 2.4.1", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-pre-propose-multiple 2.4.1", - "dao-voting 0.1.0", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-proposal-multiple" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-multiple 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "rand", - "thiserror", -] - -[[package]] -name = "dao-proposal-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce91710cfcff1af520cd0e885eee6972aeefbefc1c9da18349e66ab959269bb" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-hooks 2.4.1", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-voting 0.1.0", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-proposal-single" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-dao-core 2.5.0", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "thiserror", -] - -[[package]] -name = "dao-proposal-sudo" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-rewards-distributor" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "semver", - "thiserror", -] - -[[package]] -name = "dao-test-custom-factory" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-testing" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-admin-factory", - "cw-core", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-proposal-single", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw-vesting", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-multiple 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-condorcet", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-roles", - "dao-voting-cw721-staked", - "dao-voting-onft-staked", - "dao-voting-token-staked", - "osmosis-std", - "osmosis-test-tube", - "rand", - "serde", - "serde_json", - "stake-cw20", -] - -[[package]] -name = "dao-voting" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442d770933e3b3ecab4cfb4d6e9d054082b007d35fda3cf0c3d3ddd1cfa91782" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945898e8e168eada7ed06fa713d679e541673ee0dd8c70aee8d1f224ccd031a0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.4.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-voting" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw20 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw20-balance" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw20-staked" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw4" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba59e19abd4d51d6c3a37a84fb0c8cfe90e2f2ab551a610ec6749fcd09fc9e86" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-voting-cw4" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw721-roles" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-controllers", - "cw721-roles", - "dao-cw721-extensions", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "thiserror", -] - -[[package]] -name = "dao-voting-cw721-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-controllers", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting-onft-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721-controllers", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "omniflix-std", - "osmosis-test-tube", - "prost 0.12.3", - "prost-derive 0.12.3", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting-token-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-orch 0.24.1", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw2 1.1.2", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "serde", - "thiserror", -] - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "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.9", - "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", -] - -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek", - "ed25519", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "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.3", - "subtle", - "zeroize", -] - -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "eyre", - "paste", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "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", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.5.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-proxy" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "hyper-rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "tower-service", - "webpki", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper", - "log", - "rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "webpki", - "webpki-roots", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexable-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d70922e1e0e68d99ec1a24446c70756cc3e56deaddb505b1f4b43914522d809" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "integration-tests" -version = "0.1.0" -dependencies = [ - "anyhow", - "assert_matches", - "cosm-orc", - "cosm-tome", - "cosmos-sdk-proto 0.19.0", - "cosmwasm-std", - "cw-utils 1.0.3", - "cw-vesting", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw721-staked", - "env_logger", - "once_cell", - "rand", - "serde", - "serde_json", - "test-context", - "tokio", -] - -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" -dependencies = [ - "pest", - "pest_derive", - "serde", -] - -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", - "sha3", -] - -[[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.8", - "signature 2.2.0", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" - -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - -[[package]] -name = "omniflix-std" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a662bd7782ef6ad1af3747a2b73d37f8e6a230bb7b1624d96c05b3567501600" -dependencies = [ - "chrono", - "cosmwasm-std", - "omniflix-std-derive", - "prost 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "omniflix-std-derive" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbd85582e3ef1a23fa7b12e0415ea604260c114e72faf40d829c2c40f1c745e" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - -[[package]] -name = "osmosis-std" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d7aa053bc3fad557ac90a0377688b400c395e2537f0f1de3293a15cad2e970" -dependencies = [ - "chrono", - "cosmwasm-std", - "osmosis-std-derive", - "prost 0.11.9", - "prost-types 0.11.9", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "osmosis-std-derive" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ebdfd1bc8ed04db596e110c6baa9b174b04f6ed1ec22c666ddc5cb3fa91bd7" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "osmosis-test-tube" -version = "20.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1534a419d9e2c27b0b4869e68496b92abca93464b82efbdd1f1b43467f2938" -dependencies = [ - "base64 0.21.7", - "bindgen", - "cosmrs 0.9.0", - "cosmwasm-std", - "osmosis-std", - "prost 0.11.9", - "serde", - "serde_json", - "test-tube", - "thiserror", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "peg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c73c26c01b8c87956cea613c907c9d6ecffd8d18a2a5908e5de0adfaa185cea" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664d22978e2815783adbdd2c588b455b1bd625299ce36b2a99881ac9627e6d8d" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d5487022d5d33f4c30d91c22afa240ce2a644e87fe08caad974d4eab6badbe" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "pest_meta" -version = "2.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0091754bbd0ea592c4deb3a122ce8ecbb0753b738aa82bc055fcc2eccc8d8174" -dependencies = [ - "once_cell", - "pest", - "sha2 0.10.8", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "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.9", - "spki 0.7.3", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" -dependencies = [ - "proc-macro2", - "syn 2.0.77", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proposal-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a2f15b848398bad689771b35313c7e7095e772d444e299dbdb54b906691f8a" -dependencies = [ - "cosmwasm-std", - "indexable-hooks", - "schemars", - "serde", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" -dependencies = [ - "bytes", - "prost-derive 0.12.3", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-derive" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" -dependencies = [ - "anyhow", - "itertools 0.11.0", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", -] - -[[package]] -name = "prost-types" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" -dependencies = [ - "prost 0.12.3", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "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 = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "ron" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" -dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "serde", -] - -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls", - "schannel", - "security-framework", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.77", -] - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct 0.2.0", - "der 0.7.9", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-cw-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "serde_json" -version = "1.0.128" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.5.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "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]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.9", -] - -[[package]] -name = "stake-cw20" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfbd45133276dbe4d6588899f4d4d06fdb9f16921fd1394affc0bccc9a5cb0b6" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.11.1", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "cw2 0.11.1", - "cw20 0.11.1", - "cw20-base 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "stake-cw20-external-rewards" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9bbc1e4b7a932957a05a76921015a849b234c3f25e59fe1fd0d2eab71654bc" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "stake-cw20-reward-distributor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4260ff7aec6dddb43cb5f1104ef5cebe2787853bc83af9172ce5b828b577c4c5" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "tendermint" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467f82178deeebcd357e1273a0c0b77b9a8a0313ef7c07074baebe99d87851f4" -dependencies = [ - "async-trait", - "bytes", - "ed25519", - "ed25519-dalek", - "flex-error", - "futures", - "k256 0.11.6", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "ripemd160", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.9.9", - "signature 1.6.4", - "subtle", - "subtle-encoding", - "tendermint-proto 0.23.9", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa1d2d0ec1b531ba7d196f0dbee5e78ed2a82bfba928e88dff64aeec0b26073" -dependencies = [ - "async-trait", - "bytes", - "ed25519", - "ed25519-dalek", - "flex-error", - "futures", - "k256 0.11.6", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "ripemd160", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.9.9", - "signature 1.6.4", - "subtle", - "subtle-encoding", - "tendermint-proto 0.26.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-config" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42ee0abc27ef5fc34080cce8d43c189950d331631546e7dfb983b6274fa327" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.23.9", - "toml", - "url", -] - -[[package]] -name = "tendermint-config" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202a2f19502c03b353d8157694ed24fbc58c3dd64a92a5b0cb80b79c82af5be4" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.26.0", - "toml", - "url", -] - -[[package]] -name = "tendermint-proto" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ce80bf536476db81ecc9ebab834dc329c9c1509a694f211a73858814bfe023" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "974d6330a19dfa6720e9f663fc59101d207a817db3f9c730d3f31caaa565b574" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff525d5540a9fc535c38dc0d92a98da3ee36fcdfbda99cecb9f3cce5cd4d41d7" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.4.2", - "num-traits", - "prost 0.12.3", - "prost-types 0.12.3", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-rpc" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f14aafe3528a0f75e9f3f410b525617b2de16c4b7830a21f717eee62882ec60" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls", - "peg", - "pin-project", - "serde", - "serde_bytes", - "serde_json", - "subtle-encoding", - "tendermint 0.23.9", - "tendermint-config 0.23.9", - "tendermint-proto 0.23.9", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tendermint-rpc" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d87fa5429bd2ee39c4809dd546096daf432de9b71157bc12c182ab5bae7ea7" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls", - "peg", - "pin-project", - "serde", - "serde_bytes", - "serde_json", - "subtle", - "subtle-encoding", - "tendermint 0.26.0", - "tendermint-config 0.26.0", - "tendermint-proto 0.26.0", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test-context" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6965c21232186af0092233c18030fe607cfc3960dbabb209325272458eeea" -dependencies = [ - "async-trait", - "futures", - "test-context-macros", -] - -[[package]] -name = "test-context-macros" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d506c7664333e246f564949bee4ed39062aa0f11918e6f5a95f553cdad65c274" -dependencies = [ - "quote", - "syn 2.0.77", -] - -[[package]] -name = "test-tube" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e79c7af10967dd3383ee5aae3810637cc3f2fd040f87f862c02151db060628" -dependencies = [ - "base64 0.13.1", - "cosmrs 0.9.0", - "cosmwasm-std", - "osmosis-std", - "prost 0.11.9", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "thiserror" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "time" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" -dependencies = [ - "libc", - "num_threads", - "time-macros", -] - -[[package]] -name = "time-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.38.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-stream" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "tonic" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.13.1", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "prost-derive 0.11.9", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vote-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef617ad17edd195f8a3bce72498bfcc406a27cecfc23828f562fa91a3e2fb141" -dependencies = [ - "cosmwasm-std", - "indexable-hooks", - "schemars", - "serde", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.77", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "wynd-utils" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa37b3fba808df599acc6f0d7523b465baf47a0b0361867c4f1635eb53f72aa" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] diff --git a/Cargo.toml b/Cargo.toml index 1e7c16b75..747fb9c96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,9 @@ cosm-tome = "0.2" cosmos-sdk-proto = "0.19" cosmwasm-schema = { version = "1.5.4" } cosmwasm-std = { version = "1.5.4", features = ["ibc3", "cosmwasm_1_1"] } +cw-address-like = "1.0.4" cw-controllers = "1.1" +cw-orch-osmosis-test-tube = "0.3" cw-multi-test = { version = "0.20.1", features = ["cosmwasm_1_1"] } cw-storage-plus = { version = "1.1" } cw-utils = "1.0" @@ -55,15 +57,19 @@ cw4-group = "1.1" cw721 = "0.18" cw721-base = "0.18" env_logger = "0.10" +getrandom = "0.2" +integer-sqrt = "0.1.5" +integer-cbrt = "0.1.2" once_cell = "1.18" omniflix-std = "0.1.8" -osmosis-std = "0.20.1" +osmosis-std = "0.25.0" osmosis-std-derive = "0.20.1" -osmosis-test-tube = "20.1.1" +osmosis-test-tube = "25.0.0" proc-macro2 = "1.0" -prost = { version = "=0.12.3", features = ["prost-derive"] } -prost-types = { version = "=0.12.3", default-features = false } -prost-derive = "=0.12.3" +prost = { version = "0.12.3", features = ["prost-derive"] } +prost-types = { version = "0.12.3", default-features = false } +prost-derive = "0.12.3" +rust_decimal = "1.14.3" quote = "1.0" rand = "0.8" schemars = "0.8" @@ -76,19 +82,24 @@ sg-multi-test = "3.1.0" sg-std = "3.1.0" sg721 = "3.1.0" sg721-base = "3.1.0" +speculoos = "0.11.0" syn = { version = "1.0", features = ["derive"] } test-context = "0.1" thiserror = { version = "1.0" } wynd-utils = "0.4" cw-orch = "0.24.1" -tokio = "=1.38.1" +tokio = "1.40.0" # One commit ahead of version 0.3.0. Allows initialization with an # optional owner. cw-ownable = "0.5" + +dao-callback-messages = { path = "./contracts/test/dao-callback-messages", version = "2.5.0" } btsg-ft-factory = { path = "./contracts/external/btsg-ft-factory", version = "2.5.0" } +cw-abc = { path = "./contracts/external/cw-abc", version = "2.5.0" } cw-admin-factory = { path = "./contracts/external/cw-admin-factory", version = "2.5.0" } +cw-curves = { path = "./packages/cw-curves", version = "2.5.0" } cw-denom = { path = "./packages/cw-denom", version = "2.5.0" } cw-fund-distributor = { path = "./contracts/distribution/cw-fund-distributor", version = "2.5.0" } cw-hooks = { path = "./packages/cw-hooks", version = "2.5.0" } @@ -103,7 +114,7 @@ cw-wormhole = { path = "./packages/cw-wormhole", version = "2.5.0" } cw20-stake = { path = "./contracts/staking/cw20-stake", version = "2.5.0" } cw721-controllers = { path = "./packages/cw721-controllers", version = "2.5.0" } cw721-roles = { path = "./contracts/external/cw721-roles", version = "2.5.0" } -dao-callback-messages = { path = "./contracts/test/dao-callback-messages", version = "2.5.0" } +dao-abc-factory = { path = "./contracts/external/dao-abc-factory", version = "2.5.0" } dao-cw721-extensions = { path = "./packages/dao-cw721-extensions", version = "2.5.0" } dao-dao-core = { path = "./contracts/dao-dao-core", version = "2.5.0" } dao-dao-macros = { path = "./packages/dao-dao-macros", version = "2.5.0" } diff --git a/contracts/dao-dao-core/schema/dao-dao-core.json b/contracts/dao-dao-core/schema/dao-dao-core.json index 23e45fd01..c65c6a47e 100644 --- a/contracts/dao-dao-core/schema/dao-dao-core.json +++ b/contracts/dao-dao-core/schema/dao-dao-core.json @@ -1851,7 +1851,7 @@ "additionalProperties": false }, { - "description": "Lists all of the items associted with the contract. For example, given the items `{ \"group\": \"foo\", \"subdao\": \"bar\"}` this query would return `[(\"group\", \"foo\"), (\"subdao\", \"bar\")]`.", + "description": "Lists all of the items associated with the contract. For example, given the items `{ \"group\": \"foo\", \"subdao\": \"bar\"}` this query would return `[(\"group\", \"foo\"), (\"subdao\", \"bar\")]`.", "type": "object", "required": [ "list_items" diff --git a/contracts/external/cw-abc/.cargo/config b/contracts/external/cw-abc/.cargo/config new file mode 100644 index 000000000..8d4bc738b --- /dev/null +++ b/contracts/external/cw-abc/.cargo/config @@ -0,0 +1,6 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +wasm-debug = "build --target wasm32-unknown-unknown" +unit-test = "test --lib" +integration-test = "test --test integration" +schema = "run --example schema" diff --git a/contracts/external/cw-abc/Cargo.toml b/contracts/external/cw-abc/Cargo.toml new file mode 100644 index 000000000..7057df5af --- /dev/null +++ b/contracts/external/cw-abc/Cargo.toml @@ -0,0 +1,62 @@ +[package] +name = "cw-abc" +authors = [ + "Ethan Frey ", + "Jake Hartnell", + "Adair ", + "Gabe ", +] +description = "Implements an Augmented Bonding Curve" +# Inherits license from previous work +license = "Apache-2.0" +edition = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lib] +crate-type = ["cdylib", "rlib"] +doctest = false + +[features] +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +# use test tube feature to enable test-tube integration tests, for example +# cargo test --features "test-tube" +test-tube = [] +# when writing tests you may wish to enable test-tube as a default feature +# default = ["test-tube"] + +[dependencies] +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw-storage-plus = { workspace = true } +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-address-like = { workspace = true } +cw-ownable = { workspace = true } +cw-paginate-storage = { workspace = true } +cw-tokenfactory-issuer = { workspace = true, features = [ + "library", + "osmosis_tokenfactory", +] } +dao-interface = { workspace = true } +getrandom = { workspace = true, features = ["js"] } +thiserror = { workspace = true } +cw-curves = { workspace = true } +cw-orch = { workspace = true } + +[dev-dependencies] +speculoos = { workspace = true } +anyhow = { workspace = true } +cw-multi-test = { workspace = true } +dao-testing = { workspace = true, features = ["test-tube"] } +serde = { workspace = true } +serde_json = { workspace = true } +dao-voting-token-staked = { workspace = true } +dao-proposal-single = { workspace = true } +dao-voting = { workspace = true } +dao-cw-orch = { path = "../../../packages/cw-orch" } +cw-abc = { workspace = true } +cw-orch-osmosis-test-tube = { workspace = true } +dao-proposal-sudo = { workspace = true } diff --git a/contracts/external/cw-abc/NOTICE b/contracts/external/cw-abc/NOTICE new file mode 100644 index 000000000..12ff9ef26 --- /dev/null +++ b/contracts/external/cw-abc/NOTICE @@ -0,0 +1,15 @@ +CW20-Bonding: Bonding Curve to release CW20 token +Copyright 2020-21 Ethan Frey +Copyright 2021-22 Confio GmbH + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/contracts/external/cw-abc/README.md b/contracts/external/cw-abc/README.md new file mode 100644 index 000000000..05d2c175e --- /dev/null +++ b/contracts/external/cw-abc/README.md @@ -0,0 +1,150 @@ +# cw-abc + +Implements an [Augmented Bonding Curve](https://medium.com/commonsstack/deep-dive-augmented-bonding-curves-b5ca4fad4436). + +Forked from and heavily inspired by the work on [cw20-bonding](https://github.com/cosmwasm/cw-tokens/tree/main/contracts/cw20-bonding). This contract uses native and token factory tokens instead. + +NOTE: this contract is NOT AUDITED and experimental. NOT RECOMMENDED FOR PRODUCTION USE. Use at your own risk. + +## What are Augmented Bonding Curves? +Before we get to the *Augmented* part, we must first describe bonding curves themselves. + +### Token Bonding Curves + +"A token bonding curve (TBC) is a mathematical curve that defines a relationship between price and token supply." ~[Aavegotchi Wiki](https://wiki.aavegotchi.com/en/curve) + +Each bonding curve has a pricing function, also known as the price curve (or `curve_fn` in our implementation). The `curve_fn` is used to determine the price of the asset. + +With bonding curves, we will always know what the price of an asset will be based on supply! More on benefits later. + +This contract implements two methods: +- `Buy {}` is called with sending along some reserve currency (such as $USDC, or whatever the bonding curve is backed by). The reserve currency is stored by the bonding curve contract, and new tokens are minted and sent to the user. +- `Sell {}` is called along with sending some supply currency (the token minted by the bonding curve). The supply tokens are burned, and reserve currency is returned. + +It is possible to use this contact as a basic bonding curve, without any of the augmented features. + +#### Math + +Given a price curve `f(x)` = price of the `x`th token, we want to figure out how to buy into and sell from the bonding curve. In fact we can look at the total supply issued. let `F(x)` be the integral of `f(x)`. We have issued `x` tokens for `F(x)` sent to the contract. Or, in reverse, if we send `x` tokens to the contract, it will mint `F^-1(x)` tokens. + +From this we can create some formulas. Assume we currently have issued `S` tokens in exchange for `N = F(S)` input tokens. If someone sends us `x` tokens, how much will we issue? + +`F^-1(N+x) - F^-1(N)` = `F^-1(N+x) - S` + +And if we sell `x` tokens, how much we will get out: + +`F(S) - F(S-x)` = `N - F(S-x)` + +Just one calculation each side. To be safe, make sure to round down and always check against `F(S)` when using `F^-1(S)` to estimate how much should be issued. This will also safely give us how many tokens to return. + +There is built in support for safely [raising i128 to an integer power](https://doc.rust-lang.org/std/primitive.i128.html#method.checked_pow). There is also a crate to [provide nth-root of for all integers](https://docs.rs/num-integer/0.1.43/num_integer/trait.Roots.html). With these two, we can handle most math except for logs/exponents. + +Compare this to [writing it all in solidity](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7b7ff729b82ea73ea168e495d9c94cb901ae95ce/contracts/math/Power.sol) + +Examples: + +Price Constant: `f(x) = k` and `F(x) = kx` and `F^-1(x) = x/k` + +Price Linear: `f(x) = kx` and `F(x) = kx^2/2` and `F^-1(x) = (2x/k)^(0.5)` + +Price Square Root: `f(x) = x^0.5` and `F(x) = x^1.5/1.5` and `F^-1(x) = (1.5*x)^(2/3)` + +[You can read more about bonding curve math here](https://yos.io/2018/11/10/bonding-curves/). + +#### Benefits + +There are a number of benefits to bonding curves: +- There is enough liquidity to back the entire supply without having to list tokens on DEXs +- Easier to wind down projects (there is no going to zero) +- Transparent pricing: looking at the curve will tell you a lot about what kind of project it is. + +### Augmented Bonding Curves + +Augmented Bonding Curves are nothing new, some articles that inspired this implementation: +- https://medium.com/commonsstack/deep-dive-augmented-bonding-curves-b5ca4fad4436 +- https://tokeneconomy.co/token-bonding-curves-in-practice-3eb904720cb8 + +At a high level, augmented bonding curves extend bonding curves with new functionality: +- Entry and exit fees +- Different phases representing the life cycles of projects + +## Features + +Example Instantiation message: + +``` json +{ + "fees_recipient": "address that receives fees", + "token_issuer_code_id": 0, + "supply": { + "subdenom": "utokenname", + "metadata": { + "name": "tokenname", + "description": "Token description.", + "symbol": "TOKEN", + "display": "Token", + }, + "decimals": 6, + "max_supply": "100000000000000" + }, + "reserve": { + "denom": "ujuno", + "decimals": 6, + }, + "curve_type": { + "linear": { + "slope": "2", + "scale": 1 + } + }, + "phase_config": { + "hatch": { + "contribution_limits": { + "min": "10000000", + "max": "100000000000" + }, + "initial_raise": { + "min": "10000000", + "max": "100000000000" + }, + "entry_fee": "0.25" + }, + "open": { + "exit_fee": "0.01", + "entry_fee": "0.01" + }, + "closed": {} + }, + "hatcher_allowlist": [ + { + "addr": "dao_address", + "config": { + "config_type": { "dao": { "priority": 1 } }, + "contribution_limits_override": { + "min": "100000000", + "max": "99999999999999" + } + } + }, + { + "addr": "address", + "config": { + "config_type": { "address": {} } + } + } + ], +} +``` + +- `fees_recipient`: the address that will receive fees (usually a DAO). +- `token_issuer_code_id`: the CosmWasm code ID for a `cw-tokenfactory_issuer` contract. +- `supply`: info about the token that will be minted by the curve. This is the token that is created by the bonding curve. +- `reserve`: this is the token that is used to mint the supply token. +- `curve_type`: information about the pricing curve. +- `phase_config`: configuration for the different phase of the augmented bonding curve. +- `hatcher_allowlist`: the list of address allowed to participate in a hatch. + +## Future Work +- [ ] Optionally vest tokens during the hatch phase +- [ ] Implement an expanded set of pricing curves to choose from + diff --git a/contracts/external/cw-abc/examples/schema.rs b/contracts/external/cw-abc/examples/schema.rs new file mode 100644 index 000000000..aea9bb4b8 --- /dev/null +++ b/contracts/external/cw-abc/examples/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use cw_abc::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + } +} diff --git a/contracts/external/cw-abc/schema/cw-abc.json b/contracts/external/cw-abc/schema/cw-abc.json new file mode 100644 index 000000000..999c99579 --- /dev/null +++ b/contracts/external/cw-abc/schema/cw-abc.json @@ -0,0 +1,2671 @@ +{ + "contract_name": "cw-abc", + "contract_version": "2.5.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "curve_type", + "phase_config", + "reserve", + "supply", + "token_issuer_code_id" + ], + "properties": { + "curve_type": { + "description": "Curve type for this contract", + "allOf": [ + { + "$ref": "#/definitions/CurveType" + } + ] + }, + "funding_pool_forwarding": { + "description": "An optional address for automatically forwarding funding pool gains", + "type": [ + "string", + "null" + ] + }, + "hatcher_allowlist": { + "description": "TODO different ways of doing this, for example DAO members? Using a whitelist contract? Merkle tree? Hatcher allowlist", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/HatcherAllowlistEntryMsg" + } + }, + "phase_config": { + "description": "Hatch configuration information", + "allOf": [ + { + "$ref": "#/definitions/CommonsPhaseConfig" + } + ] + }, + "reserve": { + "description": "Reserve token information", + "allOf": [ + { + "$ref": "#/definitions/ReserveToken" + } + ] + }, + "supply": { + "description": "Supply token information", + "allOf": [ + { + "$ref": "#/definitions/SupplyToken" + } + ] + }, + "token_issuer_code_id": { + "description": "The code id of the cw-tokenfactory-issuer contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "ClosedConfig": { + "type": "object", + "additionalProperties": false + }, + "CommonsPhaseConfig": { + "type": "object", + "required": [ + "closed", + "hatch", + "open" + ], + "properties": { + "closed": { + "description": "The Closed phase where the Commons is closed to new members.", + "allOf": [ + { + "$ref": "#/definitions/ClosedConfig" + } + ] + }, + "hatch": { + "description": "The Hatch phase where initial contributors (Hatchers) participate in a hatch sale.", + "allOf": [ + { + "$ref": "#/definitions/HatchConfig" + } + ] + }, + "open": { + "description": "TODO Vest tokens after hatch phase The Vesting phase where tokens minted during the Hatch phase are locked (burning is disabled) to combat early speculation/arbitrage. pub vesting: VestingConfig, The Open phase where anyone can mint tokens by contributing the reserve token into the curve and becoming members of the Commons.", + "allOf": [ + { + "$ref": "#/definitions/OpenConfig" + } + ] + } + }, + "additionalProperties": false + }, + "CurveType": { + "oneOf": [ + { + "description": "Constant always returns `value * 10^-scale` as spot price", + "type": "object", + "required": [ + "constant" + ], + "properties": { + "constant": { + "type": "object", + "required": [ + "scale", + "value" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "value": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Linear returns `slope * 10^-scale * supply` as spot price", + "type": "object", + "required": [ + "linear" + ], + "properties": { + "linear": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price", + "type": "object", + "required": [ + "square_root" + ], + "properties": { + "square_root": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "DenomUnit": { + "description": "DenomUnit represents a struct that describes a given denomination unit of the basic token.", + "type": "object", + "required": [ + "aliases", + "denom", + "exponent" + ], + "properties": { + "aliases": { + "description": "aliases is a list of string aliases for the given denom", + "type": "array", + "items": { + "type": "string" + } + }, + "denom": { + "description": "denom represents the string name of the given denom unit (e.g uatom).", + "type": "string" + }, + "exponent": { + "description": "exponent represents power of 10 exponent that one must raise the base_denom to in order to equal the given DenomUnit's denom 1 denom = 1^exponent base_denom (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with exponent = 6, thus: 1 atom = 10^6 uatom).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "HatchConfig": { + "type": "object", + "required": [ + "contribution_limits", + "entry_fee", + "initial_raise" + ], + "properties": { + "contribution_limits": { + "description": "The minimum and maximum contribution amounts (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + }, + "entry_fee": { + "description": "The initial allocation (θ), percentage of the initial raise allocated to the Funding Pool", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "initial_raise": { + "description": "The initial raise range (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + } + }, + "additionalProperties": false + }, + "HatcherAllowlistConfigMsg": { + "type": "object", + "required": [ + "config_type" + ], + "properties": { + "config_type": { + "description": "The type of the configuration", + "allOf": [ + { + "$ref": "#/definitions/HatcherAllowlistConfigType" + } + ] + }, + "contribution_limits_override": { + "description": "An optional override of the hatch_config's contribution limit", + "anyOf": [ + { + "$ref": "#/definitions/MinMax" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HatcherAllowlistConfigType": { + "oneOf": [ + { + "type": "object", + "required": [ + "d_a_o" + ], + "properties": { + "d_a_o": { + "type": "object", + "properties": { + "priority": { + "description": "The optional priority for checking a DAO config None will append the item to the end of the priority queue (least priority)", + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "HatcherAllowlistEntryMsg": { + "type": "object", + "required": [ + "addr", + "config" + ], + "properties": { + "addr": { + "type": "string" + }, + "config": { + "$ref": "#/definitions/HatcherAllowlistConfigMsg" + } + }, + "additionalProperties": false + }, + "MinMax": { + "description": "Struct for minimum and maximum values", + "type": "object", + "required": [ + "max", + "min" + ], + "properties": { + "max": { + "$ref": "#/definitions/Uint128" + }, + "min": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "NewDenomMetadata": { + "type": "object", + "required": [ + "description", + "display", + "name", + "symbol" + ], + "properties": { + "additional_denom_units": { + "description": "Used define additional units of the token (e.g. \"tiger\") These must have an exponent larger than 0.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/DenomUnit" + } + }, + "description": { + "description": "The description of the token", + "type": "string" + }, + "display": { + "description": "The unit commonly used in communication (e.g. \"cat\")", + "type": "string" + }, + "name": { + "description": "The name of the token (e.g. \"Cat Coin\")", + "type": "string" + }, + "symbol": { + "description": "The ticker symbol of the token (e.g. \"CAT\")", + "type": "string" + } + }, + "additionalProperties": false + }, + "OpenConfig": { + "type": "object", + "required": [ + "entry_fee", + "exit_fee" + ], + "properties": { + "entry_fee": { + "description": "Percentage of capital put into the Reserve Pool during the Open phase when buying from the curve.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "exit_fee": { + "description": "Exit taxation ratio", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "ReserveToken": { + "type": "object", + "required": [ + "decimals", + "denom" + ], + "properties": { + "decimals": { + "description": "Number of decimal places for the reserve token, needed for proper curve math. Same format as decimals above, eg. if it is uatom, where 1 unit is 10^-6 ATOM, use 6 here", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "denom": { + "description": "Reserve token denom (only support native for now)", + "type": "string" + } + }, + "additionalProperties": false + }, + "SupplyToken": { + "type": "object", + "required": [ + "decimals", + "subdenom" + ], + "properties": { + "decimals": { + "description": "Number of decimal places for the supply token, needed for proper curve math. Default for token factory is 6", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "max_supply": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "metadata": { + "description": "Metadata for the supply token to create", + "anyOf": [ + { + "$ref": "#/definitions/NewDenomMetadata" + }, + { + "type": "null" + } + ] + }, + "subdenom": { + "description": "The denom to create for the supply token", + "type": "string" + } + }, + "additionalProperties": false + }, + "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" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Buy will attempt to purchase as many supply tokens as possible. You must send only reserve tokens.", + "type": "object", + "required": [ + "buy" + ], + "properties": { + "buy": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Sell burns supply tokens in return for the reserve token. You must send only supply tokens.", + "type": "object", + "required": [ + "sell" + ], + "properties": { + "sell": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Donate will donate tokens to the funding pool. You must send only reserve tokens.", + "type": "object", + "required": [ + "donate" + ], + "properties": { + "donate": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Withdraw will withdraw tokens from the funding pool.", + "type": "object", + "required": [ + "withdraw" + ], + "properties": { + "withdraw": { + "type": "object", + "properties": { + "amount": { + "description": "The amount to withdraw (defaults to full amount).", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Sets (or unsets if set to None) the maximum supply", + "type": "object", + "required": [ + "update_max_supply" + ], + "properties": { + "update_max_supply": { + "type": "object", + "properties": { + "max_supply": { + "description": "The maximum supply able to be minted.", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Updates the curve type used for pricing tokens. Only callable by owner. TODO think about other potential limitations on this.", + "type": "object", + "required": [ + "update_curve" + ], + "properties": { + "update_curve": { + "type": "object", + "required": [ + "curve_type" + ], + "properties": { + "curve_type": { + "$ref": "#/definitions/CurveType" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the hatch phase allowlist. Only callable by owner.", + "type": "object", + "required": [ + "update_hatch_allowlist" + ], + "properties": { + "update_hatch_allowlist": { + "type": "object", + "required": [ + "to_add", + "to_remove" + ], + "properties": { + "to_add": { + "description": "Addresses to be added.", + "type": "array", + "items": { + "$ref": "#/definitions/HatcherAllowlistEntryMsg" + } + }, + "to_remove": { + "description": "Addresses to be removed.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Toggles the paused state (circuit breaker)", + "type": "object", + "required": [ + "toggle_pause" + ], + "properties": { + "toggle_pause": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the funding pool forwarding. Only callable by owner.", + "type": "object", + "required": [ + "update_funding_pool_forwarding" + ], + "properties": { + "update_funding_pool_forwarding": { + "type": "object", + "properties": { + "address": { + "description": "The address to receive the funding pool forwarding. Set to None to stop forwarding.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the configuration of a certain phase. This can only be called by the owner.", + "type": "object", + "required": [ + "update_phase_config" + ], + "properties": { + "update_phase_config": { + "$ref": "#/definitions/UpdatePhaseConfigMsg" + } + }, + "additionalProperties": false + }, + { + "description": "Closing the bonding curve means no more buys are enabled and exit tax is set to zero. For example, this could be used in the event of a project shutting down.", + "type": "object", + "required": [ + "close" + ], + "properties": { + "close": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the contract's ownership. The `action` to be provided can be either to propose transferring ownership to an account, accept a pending ownership transfer, or renounce the ownership permanently.", + "type": "object", + "required": [ + "update_ownership" + ], + "properties": { + "update_ownership": { + "$ref": "#/definitions/Action" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Action": { + "description": "Actions that can be taken to alter the contract's ownership", + "oneOf": [ + { + "description": "Propose to transfer the contract's ownership to another account, optionally with an expiry time.\n\nCan only be called by the contract's current owner.\n\nAny existing pending ownership transfer is overwritten.", + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "new_owner" + ], + "properties": { + "expiry": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "new_owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept the pending ownership transfer.\n\nCan only be called by the pending owner.", + "type": "string", + "enum": [ + "accept_ownership" + ] + }, + { + "description": "Give up the contract's ownership and the possibility of appointing a new owner.\n\nCan only be invoked by the contract's current owner.\n\nAny existing pending ownership transfer is canceled.", + "type": "string", + "enum": [ + "renounce_ownership" + ] + } + ] + }, + "CurveType": { + "oneOf": [ + { + "description": "Constant always returns `value * 10^-scale` as spot price", + "type": "object", + "required": [ + "constant" + ], + "properties": { + "constant": { + "type": "object", + "required": [ + "scale", + "value" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "value": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Linear returns `slope * 10^-scale * supply` as spot price", + "type": "object", + "required": [ + "linear" + ], + "properties": { + "linear": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price", + "type": "object", + "required": [ + "square_root" + ], + "properties": { + "square_root": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "HatcherAllowlistConfigMsg": { + "type": "object", + "required": [ + "config_type" + ], + "properties": { + "config_type": { + "description": "The type of the configuration", + "allOf": [ + { + "$ref": "#/definitions/HatcherAllowlistConfigType" + } + ] + }, + "contribution_limits_override": { + "description": "An optional override of the hatch_config's contribution limit", + "anyOf": [ + { + "$ref": "#/definitions/MinMax" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HatcherAllowlistConfigType": { + "oneOf": [ + { + "type": "object", + "required": [ + "d_a_o" + ], + "properties": { + "d_a_o": { + "type": "object", + "properties": { + "priority": { + "description": "The optional priority for checking a DAO config None will append the item to the end of the priority queue (least priority)", + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "HatcherAllowlistEntryMsg": { + "type": "object", + "required": [ + "addr", + "config" + ], + "properties": { + "addr": { + "type": "string" + }, + "config": { + "$ref": "#/definitions/HatcherAllowlistConfigMsg" + } + }, + "additionalProperties": false + }, + "MinMax": { + "description": "Struct for minimum and maximum values", + "type": "object", + "required": [ + "max", + "min" + ], + "properties": { + "max": { + "$ref": "#/definitions/Uint128" + }, + "min": { + "$ref": "#/definitions/Uint128" + } + }, + "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" + }, + "UpdatePhaseConfigMsg": { + "description": "Update the phase configurations. These can only be called by the owner.", + "oneOf": [ + { + "description": "Update the hatch phase configuration", + "type": "object", + "required": [ + "hatch" + ], + "properties": { + "hatch": { + "type": "object", + "properties": { + "contribution_limits": { + "anyOf": [ + { + "$ref": "#/definitions/MinMax" + }, + { + "type": "null" + } + ] + }, + "entry_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "initial_raise": { + "anyOf": [ + { + "$ref": "#/definitions/MinMax" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the open phase configuration.", + "type": "object", + "required": [ + "open" + ], + "properties": { + "open": { + "type": "object", + "properties": { + "entry_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "exit_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the closed phase configuration. TODO Set the curve type to be used on close?", + "type": "object", + "required": [ + "closed" + ], + "properties": { + "closed": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns the reserve and supply quantities, as well as the spot price to buy 1 token Returns [`CurveInfoResponse`]", + "type": "object", + "required": [ + "curve_info" + ], + "properties": { + "curve_info": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns information about the curve type (i.e. linear, constant, etc.)", + "type": "object", + "required": [ + "curve_type" + ], + "properties": { + "curve_type": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns Token Factory Denom for the supply", + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns a list of the donors and their donations Returns [`DonationsResponse`]", + "type": "object", + "required": [ + "donations" + ], + "properties": { + "donations": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "is_paused" + ], + "properties": { + "is_paused": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the funding pool forwarding config for the contract. This is the address that receives any fees collected from bonding curve operation and donations", + "type": "object", + "required": [ + "funding_pool_forwarding" + ], + "properties": { + "funding_pool_forwarding": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "List the hatchers and their contributions Returns [`HatchersResponse`]", + "type": "object", + "required": [ + "hatchers" + ], + "properties": { + "hatchers": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the contribution of a hatcher", + "type": "object", + "required": [ + "hatcher" + ], + "properties": { + "hatcher": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Lists the hatcher allowlist Returns [`HatcherAllowlistResponse`]", + "type": "object", + "required": [ + "hatcher_allowlist" + ], + "properties": { + "hatcher_allowlist": { + "type": "object", + "properties": { + "config_type": { + "anyOf": [ + { + "$ref": "#/definitions/HatcherAllowlistConfigType" + }, + { + "type": "null" + } + ] + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the Maximum Supply of the supply token", + "type": "object", + "required": [ + "max_supply" + ], + "properties": { + "max_supply": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of tokens to receive from buying", + "type": "object", + "required": [ + "buy_quote" + ], + "properties": { + "buy_quote": { + "type": "object", + "required": [ + "payment" + ], + "properties": { + "payment": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of tokens to receive from selling", + "type": "object", + "required": [ + "sell_quote" + ], + "properties": { + "sell_quote": { + "type": "object", + "required": [ + "payment" + ], + "properties": { + "payment": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the current phase", + "type": "object", + "required": [ + "phase" + ], + "properties": { + "phase": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the current phase configuration Returns [`CommonsPhaseConfigResponse`]", + "type": "object", + "required": [ + "phase_config" + ], + "properties": { + "phase_config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the address of the cw-tokenfactory-issuer contract", + "type": "object", + "required": [ + "token_contract" + ], + "properties": { + "token_contract": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the supply denom", + "type": "object", + "required": [ + "supply_denom" + ], + "properties": { + "supply_denom": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the dumped state", + "type": "object", + "required": [ + "dump_state" + ], + "properties": { + "dump_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the contract's ownership information", + "type": "object", + "required": [ + "ownership" + ], + "properties": { + "ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "HatcherAllowlistConfigType": { + "oneOf": [ + { + "type": "object", + "required": [ + "d_a_o" + ], + "properties": { + "d_a_o": { + "type": "object", + "properties": { + "priority": { + "description": "The optional priority for checking a DAO config None will append the item to the end of the priority queue (least priority)", + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "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" + } + } + }, + "migrate": null, + "sudo": null, + "responses": { + "buy_quote": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QuoteResponse", + "type": "object", + "required": [ + "amount", + "funded", + "new_reserve", + "new_supply" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "funded": { + "$ref": "#/definitions/Uint128" + }, + "new_reserve": { + "$ref": "#/definitions/Uint128" + }, + "new_supply": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false, + "definitions": { + "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" + } + } + }, + "curve_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CurveInfoResponse", + "type": "object", + "required": [ + "funding", + "reserve", + "reserve_denom", + "spot_price", + "supply" + ], + "properties": { + "funding": { + "description": "The amount of tokens in the funding pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "reserve": { + "description": "How many reserve tokens have been received", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "reserve_denom": { + "description": "Current reserve denom", + "type": "string" + }, + "spot_price": { + "description": "Current spot price of the token", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "supply": { + "description": "How many supply tokens have been issued", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "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" + } + } + }, + "curve_type": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CurveType", + "oneOf": [ + { + "description": "Constant always returns `value * 10^-scale` as spot price", + "type": "object", + "required": [ + "constant" + ], + "properties": { + "constant": { + "type": "object", + "required": [ + "scale", + "value" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "value": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Linear returns `slope * 10^-scale * supply` as spot price", + "type": "object", + "required": [ + "linear" + ], + "properties": { + "linear": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price", + "type": "object", + "required": [ + "square_root" + ], + "properties": { + "square_root": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "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" + } + } + }, + "denom": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DenomResponse", + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "donations": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DonationsResponse", + "type": "object", + "required": [ + "donations" + ], + "properties": { + "donations": { + "description": "The donators mapped to their donation in the reserve token", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/Addr" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "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" + } + } + }, + "dump_state": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DumpStateResponse", + "type": "object", + "required": [ + "curve_info", + "curve_type", + "is_paused", + "phase_config", + "supply_denom" + ], + "properties": { + "curve_info": { + "$ref": "#/definitions/CurveInfoResponse" + }, + "curve_type": { + "$ref": "#/definitions/CurveType" + }, + "is_paused": { + "type": "boolean" + }, + "max_supply": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "phase_config": { + "$ref": "#/definitions/CommonsPhaseConfigResponse" + }, + "supply_denom": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "ClosedConfig": { + "type": "object", + "additionalProperties": false + }, + "CommonsPhase": { + "type": "string", + "enum": [ + "hatch", + "open", + "closed" + ] + }, + "CommonsPhaseConfig": { + "type": "object", + "required": [ + "closed", + "hatch", + "open" + ], + "properties": { + "closed": { + "description": "The Closed phase where the Commons is closed to new members.", + "allOf": [ + { + "$ref": "#/definitions/ClosedConfig" + } + ] + }, + "hatch": { + "description": "The Hatch phase where initial contributors (Hatchers) participate in a hatch sale.", + "allOf": [ + { + "$ref": "#/definitions/HatchConfig" + } + ] + }, + "open": { + "description": "TODO Vest tokens after hatch phase The Vesting phase where tokens minted during the Hatch phase are locked (burning is disabled) to combat early speculation/arbitrage. pub vesting: VestingConfig, The Open phase where anyone can mint tokens by contributing the reserve token into the curve and becoming members of the Commons.", + "allOf": [ + { + "$ref": "#/definitions/OpenConfig" + } + ] + } + }, + "additionalProperties": false + }, + "CommonsPhaseConfigResponse": { + "type": "object", + "required": [ + "phase", + "phase_config" + ], + "properties": { + "phase": { + "description": "Current phase", + "allOf": [ + { + "$ref": "#/definitions/CommonsPhase" + } + ] + }, + "phase_config": { + "description": "The phase configuration", + "allOf": [ + { + "$ref": "#/definitions/CommonsPhaseConfig" + } + ] + } + }, + "additionalProperties": false + }, + "CurveInfoResponse": { + "type": "object", + "required": [ + "funding", + "reserve", + "reserve_denom", + "spot_price", + "supply" + ], + "properties": { + "funding": { + "description": "The amount of tokens in the funding pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "reserve": { + "description": "How many reserve tokens have been received", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "reserve_denom": { + "description": "Current reserve denom", + "type": "string" + }, + "spot_price": { + "description": "Current spot price of the token", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "supply": { + "description": "How many supply tokens have been issued", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false + }, + "CurveType": { + "oneOf": [ + { + "description": "Constant always returns `value * 10^-scale` as spot price", + "type": "object", + "required": [ + "constant" + ], + "properties": { + "constant": { + "type": "object", + "required": [ + "scale", + "value" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "value": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Linear returns `slope * 10^-scale * supply` as spot price", + "type": "object", + "required": [ + "linear" + ], + "properties": { + "linear": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price", + "type": "object", + "required": [ + "square_root" + ], + "properties": { + "square_root": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "HatchConfig": { + "type": "object", + "required": [ + "contribution_limits", + "entry_fee", + "initial_raise" + ], + "properties": { + "contribution_limits": { + "description": "The minimum and maximum contribution amounts (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + }, + "entry_fee": { + "description": "The initial allocation (θ), percentage of the initial raise allocated to the Funding Pool", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "initial_raise": { + "description": "The initial raise range (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + } + }, + "additionalProperties": false + }, + "MinMax": { + "description": "Struct for minimum and maximum values", + "type": "object", + "required": [ + "max", + "min" + ], + "properties": { + "max": { + "$ref": "#/definitions/Uint128" + }, + "min": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "OpenConfig": { + "type": "object", + "required": [ + "entry_fee", + "exit_fee" + ], + "properties": { + "entry_fee": { + "description": "Percentage of capital put into the Reserve Pool during the Open phase when buying from the curve.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "exit_fee": { + "description": "Exit taxation ratio", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "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" + } + } + }, + "funding_pool_forwarding": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, + "hatcher": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "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" + }, + "hatcher_allowlist": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "HatcherAllowlistResponse", + "type": "object", + "properties": { + "allowlist": { + "description": "Hatcher allowlist", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/HatcherAllowlistEntry" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "HatcherAllowlistConfig": { + "description": "The configuration for a member of the hatcher allowlist", + "type": "object", + "required": [ + "config_height", + "config_type" + ], + "properties": { + "config_height": { + "description": "The height of the config insertion For use when checking allowlist of DAO configs", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "config_type": { + "description": "The type of the configuration", + "allOf": [ + { + "$ref": "#/definitions/HatcherAllowlistConfigType" + } + ] + }, + "contribution_limits_override": { + "description": "An optional override of the hatch_config's contribution limit", + "anyOf": [ + { + "$ref": "#/definitions/MinMax" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HatcherAllowlistConfigType": { + "oneOf": [ + { + "type": "object", + "required": [ + "d_a_o" + ], + "properties": { + "d_a_o": { + "type": "object", + "properties": { + "priority": { + "description": "The optional priority for checking a DAO config None will append the item to the end of the priority queue (least priority)", + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "HatcherAllowlistEntry": { + "type": "object", + "required": [ + "addr", + "config" + ], + "properties": { + "addr": { + "$ref": "#/definitions/Addr" + }, + "config": { + "$ref": "#/definitions/HatcherAllowlistConfig" + } + }, + "additionalProperties": false + }, + "MinMax": { + "description": "Struct for minimum and maximum values", + "type": "object", + "required": [ + "max", + "min" + ], + "properties": { + "max": { + "$ref": "#/definitions/Uint128" + }, + "min": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "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" + } + } + }, + "hatchers": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "HatchersResponse", + "type": "object", + "required": [ + "hatchers" + ], + "properties": { + "hatchers": { + "description": "The hatchers mapped to their contribution in the reserve token", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/Addr" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "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" + } + } + }, + "is_paused": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Boolean", + "type": "boolean" + }, + "max_supply": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Uint128", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ], + "definitions": { + "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" + } + } + }, + "ownership": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Ownership_for_String", + "description": "The contract's ownership info", + "type": "object", + "properties": { + "owner": { + "description": "The contract's current owner. `None` if the ownership has been renounced.", + "type": [ + "string", + "null" + ] + }, + "pending_expiry": { + "description": "The deadline for the pending owner to accept the ownership. `None` if there isn't a pending ownership transfer, or if a transfer exists and it doesn't have a deadline.", + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "pending_owner": { + "description": "The account who has been proposed to take over the ownership. `None` if there isn't a pending ownership transfer.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "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" + } + ] + }, + "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" + } + } + }, + "phase": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CommonsPhase", + "type": "string", + "enum": [ + "hatch", + "open", + "closed" + ] + }, + "phase_config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CommonsPhaseConfigResponse", + "type": "object", + "required": [ + "phase", + "phase_config" + ], + "properties": { + "phase": { + "description": "Current phase", + "allOf": [ + { + "$ref": "#/definitions/CommonsPhase" + } + ] + }, + "phase_config": { + "description": "The phase configuration", + "allOf": [ + { + "$ref": "#/definitions/CommonsPhaseConfig" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "ClosedConfig": { + "type": "object", + "additionalProperties": false + }, + "CommonsPhase": { + "type": "string", + "enum": [ + "hatch", + "open", + "closed" + ] + }, + "CommonsPhaseConfig": { + "type": "object", + "required": [ + "closed", + "hatch", + "open" + ], + "properties": { + "closed": { + "description": "The Closed phase where the Commons is closed to new members.", + "allOf": [ + { + "$ref": "#/definitions/ClosedConfig" + } + ] + }, + "hatch": { + "description": "The Hatch phase where initial contributors (Hatchers) participate in a hatch sale.", + "allOf": [ + { + "$ref": "#/definitions/HatchConfig" + } + ] + }, + "open": { + "description": "TODO Vest tokens after hatch phase The Vesting phase where tokens minted during the Hatch phase are locked (burning is disabled) to combat early speculation/arbitrage. pub vesting: VestingConfig, The Open phase where anyone can mint tokens by contributing the reserve token into the curve and becoming members of the Commons.", + "allOf": [ + { + "$ref": "#/definitions/OpenConfig" + } + ] + } + }, + "additionalProperties": false + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "HatchConfig": { + "type": "object", + "required": [ + "contribution_limits", + "entry_fee", + "initial_raise" + ], + "properties": { + "contribution_limits": { + "description": "The minimum and maximum contribution amounts (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + }, + "entry_fee": { + "description": "The initial allocation (θ), percentage of the initial raise allocated to the Funding Pool", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "initial_raise": { + "description": "The initial raise range (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + } + }, + "additionalProperties": false + }, + "MinMax": { + "description": "Struct for minimum and maximum values", + "type": "object", + "required": [ + "max", + "min" + ], + "properties": { + "max": { + "$ref": "#/definitions/Uint128" + }, + "min": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "OpenConfig": { + "type": "object", + "required": [ + "entry_fee", + "exit_fee" + ], + "properties": { + "entry_fee": { + "description": "Percentage of capital put into the Reserve Pool during the Open phase when buying from the curve.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "exit_fee": { + "description": "Exit taxation ratio", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "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" + } + } + }, + "sell_quote": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QuoteResponse", + "type": "object", + "required": [ + "amount", + "funded", + "new_reserve", + "new_supply" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "funded": { + "$ref": "#/definitions/Uint128" + }, + "new_reserve": { + "$ref": "#/definitions/Uint128" + }, + "new_supply": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false, + "definitions": { + "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" + } + } + }, + "supply_denom": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "String", + "type": "string" + }, + "token_contract": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Addr", + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} diff --git a/contracts/external/cw-abc/src/abc.rs b/contracts/external/cw-abc/src/abc.rs new file mode 100644 index 000000000..2f56d8a3a --- /dev/null +++ b/contracts/external/cw-abc/src/abc.rs @@ -0,0 +1,218 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ensure, Decimal, StdResult, Uint128}; +use cw_curves::{ + curves::{Constant, Linear, SquareRoot}, + utils::decimal, + Curve, DecimalPlaces, +}; +use dao_interface::token::NewDenomMetadata; + +use crate::ContractError; + +#[cw_serde] +pub struct SupplyToken { + /// The denom to create for the supply token + pub subdenom: String, + /// Metadata for the supply token to create + pub metadata: Option, + /// Number of decimal places for the supply token, needed for proper curve math. + /// Default for token factory is 6 + pub decimals: u8, + // Optional maximum supply + pub max_supply: Option, +} + +#[cw_serde] +pub struct ReserveToken { + /// Reserve token denom (only support native for now) + pub denom: String, + /// Number of decimal places for the reserve token, needed for proper curve math. + /// Same format as decimals above, eg. if it is uatom, where 1 unit is 10^-6 ATOM, use 6 here + pub decimals: u8, +} + +/// Struct for minimum and maximum values +#[cw_serde] +pub struct MinMax { + pub min: Uint128, + pub max: Uint128, +} + +impl Copy for MinMax {} + +#[cw_serde] +pub struct HatchConfig { + /// The minimum and maximum contribution amounts (min, max) in the reserve token + pub contribution_limits: MinMax, + /// The initial raise range (min, max) in the reserve token + pub initial_raise: MinMax, + /// The initial allocation (θ), percentage of the initial raise allocated to the Funding Pool + pub entry_fee: Decimal, +} + +impl Copy for HatchConfig {} + +impl HatchConfig { + /// Validate the hatch config + pub fn validate(&self) -> Result<(), ContractError> { + ensure!( + self.initial_raise.min < self.initial_raise.max, + ContractError::HatchPhaseConfigError( + "Initial raise minimum value must be less than maximum value.".to_string() + ) + ); + + ensure!( + self.entry_fee <= Decimal::percent(100u64), + ContractError::HatchPhaseConfigError( + "Initial allocation percentage must be between 0 and 100.".to_string() + ) + ); + + Ok(()) + } +} + +#[cw_serde] +pub struct OpenConfig { + /// Percentage of capital put into the Reserve Pool during the Open phase + /// when buying from the curve. + pub entry_fee: Decimal, + /// Exit taxation ratio + pub exit_fee: Decimal, +} + +impl OpenConfig { + /// Validate the open config + pub fn validate(&self) -> Result<(), ContractError> { + ensure!( + self.entry_fee <= Decimal::percent(100u64), + ContractError::OpenPhaseConfigError( + "Reserve percentage must be between 0 and 100.".to_string() + ) + ); + + ensure!( + self.exit_fee <= Decimal::percent(100u64), + ContractError::OpenPhaseConfigError( + "Exit taxation percentage must be between 0 and 100.".to_string() + ) + ); + + Ok(()) + } +} + +#[cw_serde] +pub struct ClosedConfig {} + +impl ClosedConfig { + /// Validate the closed config + pub fn validate(&self) -> Result<(), ContractError> { + Ok(()) + } +} + +#[cw_serde] +pub struct CommonsPhaseConfig { + /// The Hatch phase where initial contributors (Hatchers) participate in a hatch sale. + pub hatch: HatchConfig, + /// TODO Vest tokens after hatch phase + /// The Vesting phase where tokens minted during the Hatch phase are locked (burning is disabled) to combat early speculation/arbitrage. + /// pub vesting: VestingConfig, + /// The Open phase where anyone can mint tokens by contributing the reserve token into the curve and becoming members of the Commons. + pub open: OpenConfig, + /// The Closed phase where the Commons is closed to new members. + pub closed: ClosedConfig, +} + +#[cw_serde] +pub enum CommonsPhase { + Hatch, + Open, + Closed, +} + +impl CommonsPhase { + pub fn expect_hatch(&self) -> Result<(), ContractError> { + ensure!( + matches!(self, CommonsPhase::Hatch), + ContractError::InvalidPhase { + expected: "Hatch".to_string(), + actual: format!("{:?}", self) + } + ); + Ok(()) + } + + pub fn expect_open(&self) -> Result<(), ContractError> { + ensure!( + matches!(self, CommonsPhase::Open), + ContractError::InvalidPhase { + expected: "Open".to_string(), + actual: format!("{:?}", self) + } + ); + Ok(()) + } + + pub fn expect_closed(&self) -> Result<(), ContractError> { + ensure!( + matches!(self, CommonsPhase::Closed), + ContractError::InvalidPhase { + expected: "Closed".to_string(), + actual: format!("{:?}", self) + } + ); + Ok(()) + } +} + +impl CommonsPhaseConfig { + /// Validate that the commons configuration is valid + pub fn validate(&self) -> Result<(), ContractError> { + self.hatch.validate()?; + self.open.validate()?; + self.closed.validate()?; + + Ok(()) + } +} + +pub type CurveFn = Box Box>; + +// TODO Curve type validation? +// TODO add S-curve and taylor series +#[cw_serde] +pub enum CurveType { + /// Constant always returns `value * 10^-scale` as spot price + Constant { value: Uint128, scale: u32 }, + /// Linear returns `slope * 10^-scale * supply` as spot price + Linear { slope: Uint128, scale: u32 }, + /// SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price + SquareRoot { slope: Uint128, scale: u32 }, +} + +impl CurveType { + pub fn to_curve_fn(&self) -> StdResult { + match self.clone() { + CurveType::Constant { value, scale } => { + let value = decimal(value, scale)?; + let calc = + move |places| -> Box { Box::new(Constant::new(value, places)) }; + Ok(Box::new(calc)) + } + CurveType::Linear { slope, scale } => { + let slope = decimal(slope, scale)?; + let calc = move |places| -> Box { Box::new(Linear::new(slope, places)) }; + Ok(Box::new(calc)) + } + CurveType::SquareRoot { slope, scale } => { + let slope = decimal(slope, scale)?; + let calc = + move |places| -> Box { Box::new(SquareRoot::new(slope, places)) }; + Ok(Box::new(calc)) + } + } + } +} diff --git a/contracts/external/cw-abc/src/commands.rs b/contracts/external/cw-abc/src/commands.rs new file mode 100644 index 000000000..0116c4b05 --- /dev/null +++ b/contracts/external/cw-abc/src/commands.rs @@ -0,0 +1,632 @@ +use cosmwasm_std::{ + to_json_binary, Addr, BankMsg, Coin, CosmosMsg, DepsMut, Env, MessageInfo, QuerierWrapper, + Response, StdResult, Storage, Uint128, WasmMsg, +}; +use cw_tokenfactory_issuer::msg::ExecuteMsg as IssuerExecuteMsg; +use cw_utils::must_pay; +use std::ops::Deref; + +use crate::abc::{CommonsPhase, CurveType, HatchConfig, MinMax}; +use crate::helpers::{calculate_buy_quote, calculate_sell_quote}; +use crate::msg::{HatcherAllowlistEntryMsg, UpdatePhaseConfigMsg}; +use crate::state::{ + hatcher_allowlist, HatcherAllowlistConfig, HatcherAllowlistConfigType, CURVE_STATE, CURVE_TYPE, + DONATIONS, FUNDING_POOL_FORWARDING, HATCHERS, HATCHER_DAO_PRIORITY_QUEUE, IS_PAUSED, + MAX_SUPPLY, PHASE, PHASE_CONFIG, SUPPLY_DENOM, TOKEN_ISSUER_CONTRACT, +}; +use crate::ContractError; + +pub fn buy(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + let curve_type = CURVE_TYPE.load(deps.storage)?; + let mut curve_state = CURVE_STATE.load(deps.storage)?; + + let payment = must_pay(&info, &curve_state.reserve_denom)?; + + // Load the phase config and phase + let phase_config = PHASE_CONFIG.load(deps.storage)?; + let mut phase = PHASE.load(deps.storage)?; + + // Calculate the curve state from the buy + let buy_quote = calculate_buy_quote(payment, &curve_type, &curve_state, &phase, &phase_config)?; + + // Validate phase + match &phase { + CommonsPhase::Hatch => { + // Check that the potential hatcher is allowlisted + let hatch_config = assert_allowlisted( + deps.querier, + deps.storage, + &info.sender, + &phase_config.hatch, + )?; + + // Update hatcher contribution + let contribution = + HATCHERS.update(deps.storage, &info.sender, |amount| -> StdResult<_> { + Ok(amount.unwrap_or_default() + payment) + })?; + + // Check contribution is within limits + if contribution < hatch_config.contribution_limits.min + || contribution > hatch_config.contribution_limits.max + { + return Err(ContractError::ContributionLimit { + min: hatch_config.contribution_limits.min, + max: hatch_config.contribution_limits.max, + }); + } + + // Check if the initial_raise max has been met + if buy_quote.new_reserve >= hatch_config.initial_raise.max { + // Transition to the Open phase + phase = CommonsPhase::Open; + + // Can clean up state here + hatcher_allowlist().clear(deps.storage); + + PHASE.save(deps.storage, &phase)?; + } + } + CommonsPhase::Open => {} + CommonsPhase::Closed => { + return Err(ContractError::CommonsClosed {}); + } + }; + + // Check that the minted amount has not exceeded the max supply (if configured) + if let Some(max_supply) = MAX_SUPPLY.may_load(deps.storage)? { + if buy_quote.new_supply > max_supply { + return Err(ContractError::CannotExceedMaxSupply { max: max_supply }); + } + } + + // Mint tokens for sender by calling mint on the cw-tokenfactory-issuer contract + let issuer_addr = TOKEN_ISSUER_CONTRACT.load(deps.storage)?; + let mut msgs: Vec = vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: issuer_addr.to_string(), + msg: to_json_binary(&IssuerExecuteMsg::Mint { + to_address: info.sender.to_string(), + amount: buy_quote.amount, + })?, + funds: vec![], + })]; + + // Send funding to fee recipient + if buy_quote.funded > Uint128::zero() { + if let Some(funding_pool_forwarding) = FUNDING_POOL_FORWARDING.may_load(deps.storage)? { + msgs.push(CosmosMsg::Bank(BankMsg::Send { + to_address: funding_pool_forwarding.to_string(), + amount: vec![Coin { + amount: buy_quote.funded, + denom: curve_state.reserve_denom.clone(), + }], + })) + } else { + curve_state.funding += buy_quote.funded; + } + }; + + // Save the new curve state + curve_state.supply = buy_quote.new_supply; + curve_state.reserve = buy_quote.new_reserve; + + CURVE_STATE.save(deps.storage, &curve_state)?; + + Ok(Response::new() + .add_messages(msgs) + .add_attribute("action", "buy") + .add_attribute("from", info.sender) + .add_attribute("amount", payment) + .add_attribute("reserved", buy_quote.new_reserve) + .add_attribute("minted", buy_quote.amount) + .add_attribute("funded", buy_quote.funded) + .add_attribute("supply", buy_quote.new_supply)) +} + +/// Sell tokens on the bonding curve +pub fn sell(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + let curve_type = CURVE_TYPE.load(deps.storage)?; + let supply_denom = SUPPLY_DENOM.load(deps.storage)?; + let burn_amount = must_pay(&info, &supply_denom)?; + + let mut curve_state = CURVE_STATE.load(deps.storage)?; + + // Load the phase configuration and the current phase + let phase_config = PHASE_CONFIG.load(deps.storage)?; + let phase = PHASE.load(deps.storage)?; + + // Calculate the sell quote + let sell_quote = calculate_sell_quote( + burn_amount, + &curve_type, + &curve_state, + &phase, + &phase_config, + )?; + + let mut send_msgs: Vec = vec![CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![Coin { + amount: sell_quote.amount, + denom: curve_state.reserve_denom.clone(), + }], + })]; + + let issuer_addr = TOKEN_ISSUER_CONTRACT.load(deps.storage)?; + + // Burn the sent supply tokens + let burn_msgs: Vec = vec![ + // Send tokens to the issuer contract to be burned + CosmosMsg::Bank(BankMsg::Send { + to_address: issuer_addr.to_string().clone(), + amount: vec![Coin { + amount: burn_amount, + denom: supply_denom, + }], + }), + // Execute burn on the cw-tokenfactory-issuer contract + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: issuer_addr.to_string(), + msg: to_json_binary(&IssuerExecuteMsg::Burn { + from_address: issuer_addr.to_string(), + amount: burn_amount, + })?, + funds: vec![], + }), + ]; + + // Send exit fee to the funding pool + if sell_quote.funded > Uint128::zero() { + if let Some(funding_pool_forwarding) = FUNDING_POOL_FORWARDING.may_load(deps.storage)? { + send_msgs.push(CosmosMsg::Bank(BankMsg::Send { + to_address: funding_pool_forwarding.to_string(), + amount: vec![Coin { + amount: sell_quote.funded, + denom: curve_state.reserve_denom.clone(), + }], + })) + } else { + curve_state.funding += sell_quote.funded; + } + } + + // Update the curve state + curve_state.reserve = sell_quote.new_reserve; + curve_state.supply = sell_quote.new_supply; + CURVE_STATE.save(deps.storage, &curve_state)?; + + Ok(Response::new() + .add_messages(burn_msgs) + .add_messages(send_msgs) + .add_attribute("action", "sell") + .add_attribute("from", info.sender) + .add_attribute("amount", burn_amount) + .add_attribute("reserved", sell_quote.new_reserve) + .add_attribute("supply", sell_quote.new_supply) + .add_attribute("burned", sell_quote.amount) + .add_attribute("funded", sell_quote.funded)) +} + +/// Transitions the bonding curve to a closed phase where only sells are allowed +pub fn close(deps: DepsMut, info: MessageInfo) -> Result { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + PHASE.save(deps.storage, &CommonsPhase::Closed)?; + + Ok(Response::new().add_attribute("action", "close")) +} + +/// Send a donation to the funding pool +pub fn donate(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + let mut curve_state = CURVE_STATE.load(deps.storage)?; + + let payment = must_pay(&info, &curve_state.reserve_denom)?; + + let msgs = + if let Some(funding_pool_forwarding) = FUNDING_POOL_FORWARDING.may_load(deps.storage)? { + vec![CosmosMsg::Bank(BankMsg::Send { + to_address: funding_pool_forwarding.to_string(), + amount: info.funds, + })] + } else { + curve_state.funding += payment; + + CURVE_STATE.save(deps.storage, &curve_state)?; + + vec![] + }; + + // No minting of tokens is necessary, the supply stays the same + let total_donation = + DONATIONS.update(deps.storage, &info.sender, |maybe_amount| -> StdResult<_> { + if let Some(amount) = maybe_amount { + Ok(amount.checked_add(payment)?) + } else { + Ok(payment) + } + })?; + + Ok(Response::new() + .add_attribute("action", "donate") + .add_attribute("donor", info.sender) + .add_attribute("amount", payment) + .add_attribute("total_donation", total_donation) + .add_messages(msgs)) +} + +/// Withdraw funds from the funding pool (only callable by owner) +pub fn withdraw( + deps: DepsMut, + _env: Env, + info: MessageInfo, + amount: Option, +) -> Result { + // Validate ownership + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + let mut curve_state = CURVE_STATE.load(deps.storage)?; + + // Get amount to withdraw + let amount = amount.unwrap_or(curve_state.funding); + + // Construct the withdraw message + let msg = CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![Coin { + denom: curve_state.reserve_denom.clone(), + amount, + }], + }); + + // Update the curve state + curve_state.funding = curve_state.funding.checked_sub(amount)?; + CURVE_STATE.save(deps.storage, &curve_state)?; + + Ok(Response::new() + .add_attribute("action", "withdraw") + .add_attribute("withdrawer", info.sender) + .add_attribute("amount", amount) + .add_message(msg)) +} + +/// Updates the funding pool forwarding (only callable by owner) +pub fn update_funding_pool_forwarding( + deps: DepsMut, + env: Env, + info: MessageInfo, + address: Option, +) -> Result { + // Validate ownership + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + // Update the funding pool forwarding + match &address { + Some(address) => { + FUNDING_POOL_FORWARDING.save(deps.storage, &deps.api.addr_validate(address)?)?; + } + None => FUNDING_POOL_FORWARDING.remove(deps.storage), + }; + + Ok(Response::new() + .add_attribute("action", "update_funding_pool_forwarding") + .add_attribute( + "address", + address.unwrap_or(env.contract.address.to_string()), + )) +} + +/// Check if the sender is allowlisted for the hatch phase +fn assert_allowlisted( + querier: QuerierWrapper, + storage: &dyn Storage, + hatcher: &Addr, + hatch_config: &HatchConfig, +) -> Result { + if !hatcher_allowlist().is_empty(storage) { + // Specific configs should trump everything + if hatcher_allowlist().has(storage, hatcher) { + let config = hatcher_allowlist().load(storage, hatcher)?; + + // Do not allow DAO's to purchase themselves when allowlisted as a DAO + if matches!( + config.config_type, + HatcherAllowlistConfigType::DAO { priority: _ } + ) { + return Err(ContractError::SenderNotAllowlisted { + sender: hatcher.to_string(), + }); + } + + return Ok(HatchConfig { + contribution_limits: config + .contribution_limits_override + .unwrap_or(hatch_config.contribution_limits), + ..*hatch_config + }); + } + + // If not allowlisted as individual, then check any DAO allowlists + return Ok(HatchConfig { + contribution_limits: assert_allowlisted_through_daos(querier, storage, hatcher)? + .unwrap_or(hatch_config.contribution_limits), + ..*hatch_config + }); + } + + Ok(*hatch_config) +} + +fn assert_allowlisted_through_daos( + querier: QuerierWrapper, + storage: &dyn Storage, + hatcher: &Addr, +) -> Result, ContractError> { + if let Some(hatcher_dao_priority_queue) = HATCHER_DAO_PRIORITY_QUEUE.may_load(storage)? { + for entry in hatcher_dao_priority_queue { + let voting_power_response_result: StdResult< + dao_interface::voting::VotingPowerAtHeightResponse, + > = querier.query_wasm_smart( + entry.addr, + &dao_interface::msg::QueryMsg::VotingPowerAtHeight { + address: hatcher.to_string(), + height: Some(entry.config.config_height), + }, + ); + + if let Ok(voting_power_response) = voting_power_response_result { + if voting_power_response.power > Uint128::zero() { + return Ok(entry.config.contribution_limits_override); + } + } + } + } + + Err(ContractError::SenderNotAllowlisted { + sender: hatcher.to_string(), + }) +} + +/// Set the maximum supply (only callable by owner) +/// If `max_supply` is set to None there will be no limit.` +pub fn update_max_supply( + deps: DepsMut, + info: MessageInfo, + max_supply: Option, +) -> Result { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + match max_supply { + Some(max) => MAX_SUPPLY.save(deps.storage, &max)?, + None => MAX_SUPPLY.remove(deps.storage), + } + + Ok(Response::new() + .add_attribute("action", "update_max_supply") + .add_attribute("value", max_supply.unwrap_or(Uint128::MAX).to_string())) +} + +/// Toggles the paused state (only callable by owner) +pub fn toggle_pause(deps: DepsMut, info: MessageInfo) -> Result { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + let is_paused = + IS_PAUSED.update(deps.storage, |is_paused| -> StdResult<_> { Ok(!is_paused) })?; + + Ok(Response::new() + .add_attribute("action", "toggle_pause") + .add_attribute("is_paused", is_paused.to_string())) +} + +/// Add and remove addresses from the hatcher allowlist (only callable by owner and self) +pub fn update_hatch_allowlist( + deps: DepsMut, + env: Env, + info: MessageInfo, + to_add: Vec, + to_remove: Vec, +) -> Result { + if env.contract.address != info.sender { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + } + + let list = hatcher_allowlist(); + + // Add addresses to the allowlist + for allow in to_add { + let entry = allow.into_entry(deps.as_ref(), env.block.height)?; + + let old_data = list.may_load(deps.storage, &entry.addr)?; + + list.replace( + deps.storage, + &entry.addr, + Some(&entry.config), + old_data.as_ref(), + )?; + + // If the old data was previously a DAO config, then it should be removed + if let Some(old_data) = old_data { + try_remove_from_priority_queue(deps.storage, &entry.addr, &old_data)?; + } + + match allow.config.config_type { + HatcherAllowlistConfigType::DAO { priority } => { + if !HATCHER_DAO_PRIORITY_QUEUE.exists(deps.storage) { + HATCHER_DAO_PRIORITY_QUEUE.save(deps.storage, &vec![entry])?; + } else { + HATCHER_DAO_PRIORITY_QUEUE.update( + deps.storage, + |mut queue| -> StdResult<_> { + match priority { + Some(priority_value) => { + // Insert based on priority + let pos = queue + .binary_search_by(|entry| { + match &entry.config.config_type { + HatcherAllowlistConfigType::DAO { + priority: Some(entry_priority), + } => entry_priority + .cmp(&priority_value) + .then(std::cmp::Ordering::Less), + _ => std::cmp::Ordering::Less, // Treat non-DAO or DAO without priority as lower priority + } + }) + .unwrap_or_else(|e| e); + queue.insert(pos, entry); + } + None => { + // Append to the end if no priority + queue.push(entry); + } + } + + Ok(queue) + }, + )?; + } + } + HatcherAllowlistConfigType::Address {} => {} + } + } + + // Remove addresses from the allowlist + for deny in to_remove { + let addr = deps.api.addr_validate(deny.as_str())?; + + let old_data = list.may_load(deps.storage, &addr)?; + + if let Some(old_data) = old_data { + list.replace(deps.storage, &addr, None, Some(&old_data))?; + + try_remove_from_priority_queue(deps.storage, &addr, &old_data)?; + } + } + + Ok(Response::new().add_attributes(vec![("action", "update_hatch_allowlist")])) +} + +fn try_remove_from_priority_queue( + storage: &mut dyn Storage, + addr: &Addr, + config: &HatcherAllowlistConfig, +) -> Result<(), ContractError> { + if matches!( + config.config_type, + HatcherAllowlistConfigType::DAO { priority: _ } + ) && HATCHER_DAO_PRIORITY_QUEUE.exists(storage) + { + HATCHER_DAO_PRIORITY_QUEUE.update(storage, |mut x| -> StdResult<_> { + if let Some(i) = x.iter().position(|y| y.addr == addr) { + x.remove(i); + } + + Ok(x) + })?; + } + + Ok(()) +} + +/// Update the configuration of a particular phase (only callable by owner) +pub fn update_phase_config( + deps: DepsMut, + _env: Env, + info: MessageInfo, + update_phase_config_msg: UpdatePhaseConfigMsg, +) -> Result { + // Assert that the sender is the contract owner + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + // Load phase and phase config + let phase = PHASE.load(deps.storage)?; + + // Load the current phase config + let mut phase_config = PHASE_CONFIG.load(deps.storage)?; + + match update_phase_config_msg { + UpdatePhaseConfigMsg::Hatch { + initial_raise, + entry_fee, + contribution_limits, + } => { + // Check we are in the hatch phase + phase.expect_hatch()?; + + // Update the hatch config if new values are provided + if let Some(contribution_limits) = contribution_limits { + phase_config.hatch.contribution_limits = contribution_limits; + } + if let Some(initial_raise) = initial_raise { + phase_config.hatch.initial_raise = initial_raise; + } + if let Some(entry_fee) = entry_fee { + phase_config.hatch.entry_fee = entry_fee; + } + + // Validate config + phase_config.hatch.validate()?; + PHASE_CONFIG.save(deps.storage, &phase_config)?; + + Ok(Response::new().add_attribute("action", "update_hatch_phase_config")) + } + UpdatePhaseConfigMsg::Open { + exit_fee, + entry_fee, + } => { + // Check we are in the open phase + phase.expect_open()?; + + // Update the hatch config if new values are provided + if let Some(entry_fee) = entry_fee { + phase_config.open.entry_fee = entry_fee; + } + if let Some(exit_fee) = exit_fee { + phase_config.open.exit_fee = exit_fee; + } + + // Validate config + phase_config.open.validate()?; + PHASE_CONFIG.save(deps.storage, &phase_config)?; + + Ok(Response::new().add_attribute("action", "update_open_phase_config")) + } + // TODO what should the closed phase configuration be, is there one? + _ => todo!(), + } +} + +/// Update the bonding curve. (only callable by owner) +/// NOTE: this changes the pricing. Use with caution. +/// TODO: what other limitations do we want to put on this? +pub fn update_curve( + deps: DepsMut, + info: MessageInfo, + curve_type: CurveType, +) -> Result { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + CURVE_TYPE.save(deps.storage, &curve_type)?; + + Ok(Response::new().add_attribute("action", "close")) +} + +/// Update the ownership of the contract +pub fn update_ownership( + deps: DepsMut, + env: &Env, + info: &MessageInfo, + action: cw_ownable::Action, +) -> Result { + let ownership = cw_ownable::update_ownership( + DepsMut { + storage: deps.storage, + api: deps.api, + querier: QuerierWrapper::new(deps.querier.deref()), + }, + &env.block, + &info.sender, + action, + )?; + + Ok(Response::default().add_attributes(ownership.into_attributes())) +} diff --git a/contracts/external/cw-abc/src/contract.rs b/contracts/external/cw-abc/src/contract.rs new file mode 100644 index 000000000..9ae0e6a25 --- /dev/null +++ b/contracts/external/cw-abc/src/contract.rs @@ -0,0 +1,310 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, + SubMsg, Uint128, WasmMsg, +}; +use cw2::set_contract_version; +use cw_curves::DecimalPlaces; +use cw_tokenfactory_issuer::msg::{ + DenomUnit, ExecuteMsg as IssuerExecuteMsg, InstantiateMsg as IssuerInstantiateMsg, Metadata, +}; +use cw_utils::parse_reply_instantiate_data; + +use crate::abc::{CommonsPhase, CurveFn}; +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::{ + CurveState, CURVE_STATE, CURVE_TYPE, FUNDING_POOL_FORWARDING, IS_PAUSED, MAX_SUPPLY, PHASE, + PHASE_CONFIG, SUPPLY_DENOM, TEMP_SUPPLY, TOKEN_ISSUER_CONTRACT, +}; +use crate::{commands, queries}; + +// version info for migration info +pub(crate) const CONTRACT_NAME: &str = "crates.io:cw-abc"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +const INSTANTIATE_TOKEN_FACTORY_ISSUER_REPLY_ID: u64 = 0; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + let InstantiateMsg { + token_issuer_code_id, + funding_pool_forwarding, + supply, + reserve, + curve_type, + phase_config, + hatcher_allowlist, + } = msg; + + phase_config.validate()?; + + // Validate and store the funding pool forwarding + if let Some(funding_pool_forwarding) = funding_pool_forwarding { + FUNDING_POOL_FORWARDING.save( + deps.storage, + &deps.api.addr_validate(&funding_pool_forwarding)?, + )?; + } + + if supply.subdenom.is_empty() { + return Err(ContractError::SupplyTokenError( + "Token subdenom must not be empty.".to_string(), + )); + } + + if let Some(max_supply) = supply.max_supply { + MAX_SUPPLY.save(deps.storage, &max_supply)?; + } + + // Save the curve type + CURVE_TYPE.save(deps.storage, &curve_type)?; + + PHASE_CONFIG.save(deps.storage, &phase_config)?; + + // TODO don't hardcode this? Make it configurable? Hatch config can be optional + PHASE.save(deps.storage, &CommonsPhase::Hatch)?; + + // Initialize owner to sender + cw_ownable::initialize_owner(deps.storage, deps.api, Some(info.sender.as_str()))?; + + // Setup the curve state + let normalization_places = DecimalPlaces::new(supply.decimals, reserve.decimals); + let curve_state = CurveState::new(reserve.denom, normalization_places); + + // Save subdenom for handling in the reply + TEMP_SUPPLY.save(deps.storage, &supply)?; + + // Instantiate cw-token-factory-issuer contract + let msg = SubMsg::reply_always( + WasmMsg::Instantiate { + // Contract is immutable, no admin + admin: None, + code_id: token_issuer_code_id, + msg: to_json_binary(&IssuerInstantiateMsg::NewToken { + subdenom: supply.subdenom, + })?, + funds: info.funds, + label: "cw-tokenfactory-issuer".to_string(), + }, + INSTANTIATE_TOKEN_FACTORY_ISSUER_REPLY_ID, + ); + + // Save the curve state + CURVE_STATE.save(deps.storage, &curve_state)?; + + // Set the paused state + IS_PAUSED.save(deps.storage, &false)?; + + // Set hatcher allowlist through internal method + let msgs = if let Some(hatcher_allowlist) = hatcher_allowlist { + vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.to_string(), + msg: to_json_binary(&ExecuteMsg::UpdateHatchAllowlist { + to_add: hatcher_allowlist, + to_remove: vec![], + })?, + funds: vec![], + })] + } else { + vec![] + }; + + Ok(Response::default().add_messages(msgs).add_submessage(msg)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + // If paused, then only the owner can perform actions + if IS_PAUSED.load(deps.storage)? { + cw_ownable::assert_owner(deps.storage, &info.sender) + .map_err(|_| ContractError::Paused {})?; + } + + match msg { + ExecuteMsg::Buy {} => commands::buy(deps, env, info), + ExecuteMsg::Sell {} => commands::sell(deps, env, info), + ExecuteMsg::Close {} => commands::close(deps, info), + ExecuteMsg::Donate {} => commands::donate(deps, env, info), + ExecuteMsg::Withdraw { amount } => commands::withdraw(deps, env, info, amount), + ExecuteMsg::UpdateFundingPoolForwarding { address } => { + commands::update_funding_pool_forwarding(deps, env, info, address) + } + ExecuteMsg::UpdateMaxSupply { max_supply } => { + commands::update_max_supply(deps, info, max_supply) + } + ExecuteMsg::UpdateCurve { curve_type } => commands::update_curve(deps, info, curve_type), + ExecuteMsg::UpdateHatchAllowlist { to_add, to_remove } => { + commands::update_hatch_allowlist(deps, env, info, to_add, to_remove) + } + ExecuteMsg::TogglePause {} => commands::toggle_pause(deps, info), + ExecuteMsg::UpdatePhaseConfig(update_msg) => { + commands::update_phase_config(deps, env, info, update_msg) + } + ExecuteMsg::UpdateOwnership(action) => { + commands::update_ownership(deps, &env, &info, action) + } + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { + // default implementation stores curve info as enum, you can do something else in a derived + // contract and just pass in your custom curve to do_execute + let curve_type = CURVE_TYPE.load(deps.storage)?; + let curve_fn = curve_type.to_curve_fn()?; + do_query(deps, env, msg, curve_fn) +} + +/// We pull out logic here, so we can import this from another contract and set a different Curve. +/// This contacts sets a curve with an enum in [`InstantiateMsg`] and stored in state, but you may want +/// to use custom math not included - make this easily reusable +pub fn do_query(deps: Deps, _env: Env, msg: QueryMsg, curve_fn: CurveFn) -> StdResult { + match msg { + // custom queries + QueryMsg::CurveInfo {} => to_json_binary(&queries::query_curve_info(deps, curve_fn)?), + QueryMsg::CurveType {} => to_json_binary(&CURVE_TYPE.load(deps.storage)?), + QueryMsg::Denom {} => to_json_binary(&queries::get_denom(deps)?), + QueryMsg::Donations { start_after, limit } => { + to_json_binary(&queries::query_donations(deps, start_after, limit)?) + } + QueryMsg::FundingPoolForwarding {} => { + to_json_binary(&FUNDING_POOL_FORWARDING.may_load(deps.storage)?) + } + QueryMsg::Hatchers { start_after, limit } => { + to_json_binary(&queries::query_hatchers(deps, start_after, limit)?) + } + QueryMsg::Hatcher { addr } => to_json_binary(&queries::query_hatcher(deps, addr)?), + QueryMsg::HatcherAllowlist { + start_after, + limit, + config_type, + } => to_json_binary(&queries::query_hatcher_allowlist( + deps, + start_after, + limit, + config_type, + )?), + QueryMsg::IsPaused {} => to_json_binary(&IS_PAUSED.load(deps.storage)?), + QueryMsg::MaxSupply {} => to_json_binary(&queries::query_max_supply(deps)?), + QueryMsg::Ownership {} => to_json_binary(&cw_ownable::get_ownership(deps.storage)?), + QueryMsg::PhaseConfig {} => to_json_binary(&queries::query_phase_config(deps)?), + QueryMsg::Phase {} => to_json_binary(&PHASE.load(deps.storage)?), + QueryMsg::TokenContract {} => to_json_binary(&TOKEN_ISSUER_CONTRACT.load(deps.storage)?), + QueryMsg::BuyQuote { payment } => to_json_binary(&queries::query_buy_quote(deps, payment)?), + QueryMsg::SellQuote { payment } => { + to_json_binary(&queries::query_sell_quote(deps, payment)?) + } + QueryMsg::SupplyDenom {} => to_json_binary(&SUPPLY_DENOM.load(deps.storage)?), + QueryMsg::DumpState {} => to_json_binary(&queries::query_dump_state(deps, curve_fn)?), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Set contract to version to latest + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result { + match msg.id { + INSTANTIATE_TOKEN_FACTORY_ISSUER_REPLY_ID => { + // Parse and save address of cw-tokenfactory-issuer + let issuer_addr = parse_reply_instantiate_data(msg)?.contract_address; + TOKEN_ISSUER_CONTRACT.save(deps.storage, &deps.api.addr_validate(&issuer_addr)?)?; + + // Load the temporary supply + let supply = TEMP_SUPPLY.load(deps.storage)?; + + // Clear the temporary state + TEMP_SUPPLY.remove(deps.storage); + + // Format the denom and save it + // By default, the prefix for token factory tokens is "factory" + let denom = format!("factory/{}/{}", &issuer_addr, supply.subdenom); + + SUPPLY_DENOM.save(deps.storage, &denom)?; + + // Msgs to be executed to finalize setup + let mut msgs: Vec = vec![ + // Grant an allowance to mint + WasmMsg::Execute { + contract_addr: issuer_addr.clone(), + msg: to_json_binary(&IssuerExecuteMsg::SetMinterAllowance { + address: env.contract.address.to_string(), + // Allowance needs to be max as this the is the amount of tokens + // the minter is allowed to mint, not to be confused with max supply + // which we have to enforce elsewhere. + allowance: Uint128::MAX, + })?, + funds: vec![], + }, + // Grant an allowance to burn + WasmMsg::Execute { + contract_addr: issuer_addr.clone(), + msg: to_json_binary(&IssuerExecuteMsg::SetBurnerAllowance { + address: env.contract.address.to_string(), + allowance: Uint128::MAX, + })?, + funds: vec![], + }, + ]; + + // If metadata, set it by calling the contract + if let Some(metadata) = supply.metadata { + // The first denom_unit must be the same as the tf and base denom. + // It must have an exponent of 0. This the smallest unit of the token. + // For more info: https://docs.cosmos.network/main/architecture/adr-024-coin-metadata + let mut denom_units = vec![DenomUnit { + denom: denom.clone(), + exponent: 0, + aliases: vec![supply.subdenom], + }]; + + // Caller can optionally define additional units + if let Some(mut additional_units) = metadata.additional_denom_units { + denom_units.append(&mut additional_units); + } + + // Sort denom units by exponent, must be in ascending order + denom_units.sort_by(|a, b| a.exponent.cmp(&b.exponent)); + + msgs.push(WasmMsg::Execute { + contract_addr: issuer_addr.clone(), + msg: to_json_binary(&IssuerExecuteMsg::SetDenomMetadata { + metadata: Metadata { + description: metadata.description, + denom_units, + base: denom.clone(), + display: metadata.display, + name: metadata.name, + symbol: metadata.symbol, + }, + })?, + funds: vec![], + }); + } + + Ok(Response::new() + .add_attribute("cw-tokenfactory-issuer-address", issuer_addr) + .add_attribute("denom", denom) + .add_messages(msgs)) + } + _ => Err(ContractError::UnknownReplyId { id: msg.id }), + } +} diff --git a/contracts/external/cw-abc/src/error.rs b/contracts/external/cw-abc/src/error.rs new file mode 100644 index 000000000..ef59faafc --- /dev/null +++ b/contracts/external/cw-abc/src/error.rs @@ -0,0 +1,69 @@ +use cosmwasm_std::{CheckedMultiplyFractionError, OverflowError, StdError, Uint128}; +use cw_utils::{ParseReplyError, PaymentError}; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("{0}")] + Overflow(#[from] OverflowError), + + #[error(transparent)] + Payment(#[from] PaymentError), + + #[error(transparent)] + ParseReplyError(#[from] ParseReplyError), + + #[error("{0}")] + Ownership(#[from] cw_ownable::OwnershipError), + + #[error("{0}")] + CheckedMultiplyFraction(#[from] CheckedMultiplyFractionError), + + #[error("Cannot mint more tokens than the maximum supply of {max}")] + CannotExceedMaxSupply { max: Uint128 }, + + #[error("The commons is closed to new contributions")] + CommonsClosed {}, + + #[error("The commons is locked against liquidations")] + CommonsHatch {}, + + #[error("Contribution must be less than or equal to {max} and greater than or equal to {min}")] + ContributionLimit { min: Uint128, max: Uint128 }, + + #[error("Hatch phase config error {0}")] + HatchPhaseConfigError(String), + + #[error("Invalid exit fee, must be less than 100%.")] + InvalidExitFee {}, + + #[error("Invalid subdenom: {subdenom:?}")] + InvalidSubdenom { subdenom: String }, + + #[error("Invalid phase, expected {expected:?}, actual {actual:?}")] + InvalidPhase { expected: String, actual: String }, + + #[error("Invalid sell amount")] + MismatchedSellAmount {}, + + #[error("Open phase config error {0}")] + OpenPhaseConfigError(String), + + #[error("Sender {sender:?} is not in the hatcher allowlist.")] + SenderNotAllowlisted { sender: String }, + + #[error("Supply token error {0}")] + SupplyTokenError(String), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("Got a submessage reply with unknown id: {id}")] + UnknownReplyId { id: u64 }, + + #[error("Contract is paused")] + Paused {}, +} diff --git a/contracts/external/cw-abc/src/helpers.rs b/contracts/external/cw-abc/src/helpers.rs new file mode 100644 index 000000000..06982ec90 --- /dev/null +++ b/contracts/external/cw-abc/src/helpers.rs @@ -0,0 +1,109 @@ +use cosmwasm_std::{Decimal, Deps, StdResult, Uint128}; + +use crate::{ + abc::{CommonsPhase, CommonsPhaseConfig, CurveType}, + msg::{HatcherAllowlistEntryMsg, QuoteResponse}, + state::{CurveState, HatcherAllowlistConfig, HatcherAllowlistEntry}, + ContractError, +}; + +/// Calculate the buy quote for a payment +pub fn calculate_buy_quote( + payment: Uint128, + curve_type: &CurveType, + curve_state: &CurveState, + phase: &CommonsPhase, + phase_config: &CommonsPhaseConfig, +) -> Result { + // Generate the bonding curve + let curve_fn = curve_type.to_curve_fn()?; + let curve = curve_fn(curve_state.decimals); + + // Calculate the reserved and funded amounts based on the Commons phase + let (reserved, funded) = match phase { + CommonsPhase::Hatch => calculate_reserved_and_funded(payment, phase_config.hatch.entry_fee), + CommonsPhase::Open => calculate_reserved_and_funded(payment, phase_config.open.entry_fee), + CommonsPhase::Closed => Err(ContractError::CommonsClosed {}), + }?; + + // Update the reserve and calculate the new supply from the new reserve + let new_reserve = curve_state.reserve.checked_add(reserved)?; + let new_supply = curve.supply(new_reserve)?; + + // Calculate the difference between the new and old supply to get the minted tokens + let minted = new_supply.checked_sub(curve_state.supply)?; + + Ok(QuoteResponse { + new_reserve, + funded, + amount: minted, + new_supply, + }) +} + +/// Calculate the sell quote for a payment +pub fn calculate_sell_quote( + payment: Uint128, + curve_type: &CurveType, + curve_state: &CurveState, + phase: &CommonsPhase, + phase_config: &CommonsPhaseConfig, +) -> Result { + // Generate the bonding curve + let curve_fn = curve_type.to_curve_fn()?; + let curve = curve_fn(curve_state.decimals); + + // Reduce the supply by the amount being burned + let new_supply = curve_state.supply.checked_sub(payment)?; + + // Determine the exit fee based on the current Commons phase + let exit_fee = match &phase { + CommonsPhase::Hatch => Err(ContractError::CommonsHatch {}), + CommonsPhase::Open => Ok(phase_config.open.exit_fee), + CommonsPhase::Closed => Ok(Decimal::zero()), + }?; + + // Calculate the new reserve based on the new supply + let new_reserve = curve.reserve(new_supply)?; + + // Calculate how many reserve tokens to release based on the amount being burned + let released_reserve = curve_state.reserve.checked_sub(new_reserve)?; + + // Calculate the reserved and funded amounts based on the exit fee + let (reserved, funded) = calculate_reserved_and_funded(released_reserve, exit_fee)?; + + Ok(QuoteResponse { + new_reserve, + funded, + amount: reserved, + new_supply, + }) +} + +/// Return the reserved and funded amounts based on the payment and the allocation ratio +pub(crate) fn calculate_reserved_and_funded( + payment: Uint128, + allocation_ratio: Decimal, +) -> Result<(Uint128, Uint128), ContractError> { + if allocation_ratio.is_zero() { + return Ok((payment, Uint128::zero())); + } + + let funded = payment.checked_mul_floor(allocation_ratio)?; + let reserved = payment - funded; // Since allocation_ratio is < 1, this subtraction is safe + + Ok((reserved, funded)) +} + +impl HatcherAllowlistEntryMsg { + pub fn into_entry(&self, deps: Deps, height: u64) -> StdResult { + Ok(HatcherAllowlistEntry { + addr: deps.api.addr_validate(&self.addr)?, + config: HatcherAllowlistConfig { + config_type: self.config.config_type, + contribution_limits_override: self.config.contribution_limits_override, + config_height: height, + }, + }) + } +} diff --git a/contracts/external/cw-abc/src/lib.rs b/contracts/external/cw-abc/src/lib.rs new file mode 100644 index 000000000..ad7dfb86c --- /dev/null +++ b/contracts/external/cw-abc/src/lib.rs @@ -0,0 +1,14 @@ +pub mod abc; +pub(crate) mod commands; +pub mod contract; +mod error; +pub(crate) mod helpers; +pub mod msg; +mod queries; +pub mod state; + +pub use crate::error::ContractError; + +#[cfg(test)] +#[cfg(feature = "test-tube")] +mod tests; diff --git a/contracts/external/cw-abc/src/msg.rs b/contracts/external/cw-abc/src/msg.rs new file mode 100644 index 000000000..08f3b8f61 --- /dev/null +++ b/contracts/external/cw-abc/src/msg.rs @@ -0,0 +1,263 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{Addr, Decimal, Uint128}; + +use crate::{ + abc::{CommonsPhase, CommonsPhaseConfig, CurveType, MinMax, ReserveToken, SupplyToken}, + state::{HatcherAllowlistConfigType, HatcherAllowlistEntry}, +}; + +#[cw_serde] +pub struct InstantiateMsg { + /// The code id of the cw-tokenfactory-issuer contract + pub token_issuer_code_id: u64, + + /// An optional address for automatically forwarding funding pool gains + pub funding_pool_forwarding: Option, + + /// Supply token information + pub supply: SupplyToken, + + /// Reserve token information + pub reserve: ReserveToken, + + /// Curve type for this contract + pub curve_type: CurveType, + + /// Hatch configuration information + pub phase_config: CommonsPhaseConfig, + + /// TODO different ways of doing this, for example DAO members? + /// Using a whitelist contract? Merkle tree? + /// Hatcher allowlist + pub hatcher_allowlist: Option>, +} + +/// Update the phase configurations. +/// These can only be called by the owner. +#[cw_serde] +pub enum UpdatePhaseConfigMsg { + /// Update the hatch phase configuration + Hatch { + contribution_limits: Option, + // TODO what is the minimum used for? + initial_raise: Option, + entry_fee: Option, + }, + /// Update the open phase configuration. + Open { + exit_fee: Option, + entry_fee: Option, + }, + /// Update the closed phase configuration. + /// TODO Set the curve type to be used on close? + Closed {}, +} + +#[cw_ownable::cw_ownable_execute] +#[cw_serde] +#[derive(cw_orch::ExecuteFns)] +pub enum ExecuteMsg { + /// Buy will attempt to purchase as many supply tokens as possible. + /// You must send only reserve tokens. + #[cw_orch(payable)] + Buy {}, + /// Sell burns supply tokens in return for the reserve token. + /// You must send only supply tokens. + #[cw_orch(payable)] + Sell {}, + /// Donate will donate tokens to the funding pool. + /// You must send only reserve tokens. + #[cw_orch(payable)] + Donate {}, + /// Withdraw will withdraw tokens from the funding pool. + Withdraw { + /// The amount to withdraw (defaults to full amount). + amount: Option, + }, + /// Sets (or unsets if set to None) the maximum supply + UpdateMaxSupply { + /// The maximum supply able to be minted. + max_supply: Option, + }, + /// Updates the curve type used for pricing tokens. + /// Only callable by owner. + /// TODO think about other potential limitations on this. + UpdateCurve { curve_type: CurveType }, + /// Update the hatch phase allowlist. + /// Only callable by owner. + UpdateHatchAllowlist { + /// Addresses to be added. + to_add: Vec, + /// Addresses to be removed. + to_remove: Vec, + }, + /// Toggles the paused state (circuit breaker) + TogglePause {}, + /// Update the funding pool forwarding. + /// Only callable by owner. + UpdateFundingPoolForwarding { + /// The address to receive the funding pool forwarding. + /// Set to None to stop forwarding. + address: Option, + }, + /// Update the configuration of a certain phase. + /// This can only be called by the owner. + UpdatePhaseConfig(UpdatePhaseConfigMsg), + /// Closing the bonding curve means no more buys are enabled and exit tax is set + /// to zero. + /// For example, this could be used in the event of a project shutting down. + Close {}, +} + +#[cw_ownable::cw_ownable_query] +#[cw_serde] +#[derive(QueryResponses, cw_orch::QueryFns)] +pub enum QueryMsg { + /// Returns the reserve and supply quantities, as well as the spot price to buy 1 token + /// Returns [`CurveInfoResponse`] + #[returns(CurveInfoResponse)] + CurveInfo {}, + /// Returns information about the curve type (i.e. linear, constant, etc.) + #[returns(CurveType)] + CurveType {}, + /// Returns Token Factory Denom for the supply + #[returns(DenomResponse)] + Denom {}, + /// Returns a list of the donors and their donations + /// Returns [`DonationsResponse`] + #[returns(DonationsResponse)] + Donations { + start_after: Option, + limit: Option, + }, + #[returns(bool)] + IsPaused {}, + /// Returns the funding pool forwarding config for the contract. This is the address that + /// receives any fees collected from bonding curve operation and donations + #[returns(Option<::cosmwasm_std::Addr>)] + FundingPoolForwarding {}, + /// List the hatchers and their contributions + /// Returns [`HatchersResponse`] + #[returns(HatchersResponse)] + Hatchers { + start_after: Option, + limit: Option, + }, + /// Returns the contribution of a hatcher + #[returns(Uint128)] + Hatcher { addr: String }, + /// Lists the hatcher allowlist + /// Returns [`HatcherAllowlistResponse`] + #[returns(HatcherAllowlistResponse)] + HatcherAllowlist { + start_after: Option, + limit: Option, + config_type: Option, + }, + /// Returns the Maximum Supply of the supply token + #[returns(Option)] + MaxSupply {}, + /// Returns the amount of tokens to receive from buying + #[returns(QuoteResponse)] + BuyQuote { payment: Uint128 }, + /// Returns the amount of tokens to receive from selling + #[returns(QuoteResponse)] + SellQuote { payment: Uint128 }, + /// Returns the current phase + #[returns(CommonsPhase)] + Phase {}, + /// Returns the current phase configuration + /// Returns [`CommonsPhaseConfigResponse`] + #[returns(CommonsPhaseConfigResponse)] + PhaseConfig {}, + /// Returns the address of the cw-tokenfactory-issuer contract + #[returns(::cosmwasm_std::Addr)] + TokenContract {}, + /// Returns the supply denom + #[returns(String)] + SupplyDenom {}, + /// Returns the dumped state + #[returns(DumpStateResponse)] + DumpState {}, +} + +#[cw_serde] +pub struct DumpStateResponse { + pub supply_denom: String, + pub phase_config: CommonsPhaseConfigResponse, + pub is_paused: bool, + pub curve_info: CurveInfoResponse, + pub curve_type: CurveType, + pub max_supply: Option, +} + +#[cw_serde] +pub struct HatcherAllowlistEntryMsg { + pub addr: String, + pub config: HatcherAllowlistConfigMsg, +} + +#[cw_serde] +pub struct HatcherAllowlistConfigMsg { + /// The type of the configuration + pub config_type: HatcherAllowlistConfigType, + /// An optional override of the hatch_config's contribution limit + pub contribution_limits_override: Option, +} + +#[cw_serde] +pub struct CurveInfoResponse { + /// How many reserve tokens have been received + pub reserve: Uint128, + /// How many supply tokens have been issued + pub supply: Uint128, + /// The amount of tokens in the funding pool + pub funding: Uint128, + /// Current spot price of the token + pub spot_price: Decimal, + /// Current reserve denom + pub reserve_denom: String, +} + +#[cw_serde] +pub struct DenomResponse { + pub denom: String, +} + +#[cw_serde] +pub struct HatcherAllowlistResponse { + /// Hatcher allowlist + pub allowlist: Option>, +} + +#[cw_serde] +pub struct CommonsPhaseConfigResponse { + /// The phase configuration + pub phase_config: CommonsPhaseConfig, + + /// Current phase + pub phase: CommonsPhase, +} + +#[cw_serde] +pub struct DonationsResponse { + /// The donators mapped to their donation in the reserve token + pub donations: Vec<(Addr, Uint128)>, +} + +#[cw_serde] +pub struct HatchersResponse { + /// The hatchers mapped to their contribution in the reserve token + pub hatchers: Vec<(Addr, Uint128)>, +} + +#[cw_serde] +pub struct QuoteResponse { + pub new_reserve: Uint128, + pub funded: Uint128, + pub amount: Uint128, + pub new_supply: Uint128, +} + +#[cw_serde] +pub struct MigrateMsg {} diff --git a/contracts/external/cw-abc/src/queries.rs b/contracts/external/cw-abc/src/queries.rs new file mode 100644 index 000000000..b76af7c76 --- /dev/null +++ b/contracts/external/cw-abc/src/queries.rs @@ -0,0 +1,182 @@ +use crate::abc::CurveFn; +use crate::helpers::{calculate_buy_quote, calculate_sell_quote}; +use crate::msg::{ + CommonsPhaseConfigResponse, CurveInfoResponse, DenomResponse, DonationsResponse, + DumpStateResponse, HatcherAllowlistResponse, HatchersResponse, QuoteResponse, +}; +use crate::state::{ + hatcher_allowlist, CurveState, HatcherAllowlistConfigType, HatcherAllowlistEntry, CURVE_STATE, + CURVE_TYPE, DONATIONS, HATCHERS, IS_PAUSED, MAX_SUPPLY, PHASE, PHASE_CONFIG, SUPPLY_DENOM, +}; +use cosmwasm_std::{Deps, Order, QuerierWrapper, StdError, StdResult, Uint128}; +use cw_storage_plus::Bound; +use std::ops::Deref; + +/// Get the current state of the curve +pub fn query_curve_info(deps: Deps, curve_fn: CurveFn) -> StdResult { + let CurveState { + reserve, + supply, + reserve_denom, + decimals, + funding, + } = CURVE_STATE.load(deps.storage)?; + + // This we can get from the local digits stored in instantiate + let curve = curve_fn(decimals); + let spot_price = curve.spot_price(supply)?; + + Ok(CurveInfoResponse { + reserve, + supply, + funding, + spot_price, + reserve_denom, + }) +} + +/// Returns information about the supply Denom +pub fn get_denom(deps: Deps) -> StdResult { + let denom = SUPPLY_DENOM.load(deps.storage)?; + Ok(DenomResponse { denom }) +} + +pub fn query_donations( + deps: Deps, + start_after: Option, + limit: Option, +) -> StdResult { + let donations = cw_paginate_storage::paginate_map( + Deps { + storage: deps.storage, + api: deps.api, + querier: QuerierWrapper::new(deps.querier.deref()), + }, + &DONATIONS, + start_after + .map(|addr| deps.api.addr_validate(&addr)) + .transpose()? + .as_ref(), + limit, + Order::Descending, + )?; + + Ok(DonationsResponse { donations }) +} + +/// Query hatchers who contributed during the hatch phase +pub fn query_hatchers( + deps: Deps, + start_after: Option, + limit: Option, +) -> StdResult { + let hatchers = cw_paginate_storage::paginate_map( + Deps { + storage: deps.storage, + api: deps.api, + querier: QuerierWrapper::new(deps.querier.deref()), + }, + &HATCHERS, + start_after + .map(|addr| deps.api.addr_validate(&addr)) + .transpose()? + .as_ref(), + limit, + Order::Descending, + )?; + + Ok(HatchersResponse { hatchers }) +} + +/// Query the contribution of a hatcher +pub fn query_hatcher(deps: Deps, addr: String) -> StdResult { + let addr = deps.api.addr_validate(&addr)?; + + HATCHERS.load(deps.storage, &addr) +} + +/// Query hatcher allowlist +pub fn query_hatcher_allowlist( + deps: Deps, + start_after: Option, + limit: Option, + config_type: Option, +) -> StdResult { + if hatcher_allowlist().is_empty(deps.storage) { + return Ok(HatcherAllowlistResponse { allowlist: None }); + } + + let binding = start_after + .map(|x| deps.api.addr_validate(&x)) + .transpose()?; + let start_after_bound = binding.as_ref().map(Bound::exclusive); + + let iter = match config_type { + Some(config_type) => hatcher_allowlist() + .idx + .config_type + .prefix(config_type.to_string()) + .range(deps.storage, start_after_bound, None, Order::Ascending), + None => hatcher_allowlist().range(deps.storage, start_after_bound, None, Order::Ascending), + } + .map(|result| result.map(|(addr, config)| HatcherAllowlistEntry { addr, config })); + + let allowlist = match limit { + Some(limit) => iter + .take(limit.try_into().unwrap()) + .collect::>(), + None => iter.collect::>(), + }?; + + Ok(HatcherAllowlistResponse { + allowlist: Some(allowlist), + }) +} + +/// Query the max supply of the supply token +pub fn query_max_supply(deps: Deps) -> StdResult> { + MAX_SUPPLY.may_load(deps.storage) +} + +/// Load and return the phase config +pub fn query_phase_config(deps: Deps) -> StdResult { + let phase = PHASE.load(deps.storage)?; + let phase_config = PHASE_CONFIG.load(deps.storage)?; + Ok(CommonsPhaseConfigResponse { + phase_config, + phase, + }) +} + +/// Get a buy quote +pub fn query_buy_quote(deps: Deps, payment: Uint128) -> StdResult { + let curve_type = CURVE_TYPE.load(deps.storage)?; + let curve_state = CURVE_STATE.load(deps.storage)?; + let phase_config = PHASE_CONFIG.load(deps.storage)?; + let phase = PHASE.load(deps.storage)?; + + calculate_buy_quote(payment, &curve_type, &curve_state, &phase, &phase_config) + .map_err(|e| StdError::generic_err(e.to_string())) +} + +/// Get a sell quote +pub fn query_sell_quote(deps: Deps, payment: Uint128) -> StdResult { + let curve_type = CURVE_TYPE.load(deps.storage)?; + let curve_state = CURVE_STATE.load(deps.storage)?; + let phase_config = PHASE_CONFIG.load(deps.storage)?; + let phase = PHASE.load(deps.storage)?; + + calculate_sell_quote(payment, &curve_type, &curve_state, &phase, &phase_config) + .map_err(|e| StdError::generic_err(e.to_string())) +} + +pub fn query_dump_state(deps: Deps, curve_fn: CurveFn) -> StdResult { + Ok(DumpStateResponse { + supply_denom: SUPPLY_DENOM.load(deps.storage)?, + phase_config: query_phase_config(deps)?, + is_paused: IS_PAUSED.load(deps.storage)?, + curve_info: query_curve_info(deps, curve_fn)?, + curve_type: CURVE_TYPE.load(deps.storage)?, + max_supply: MAX_SUPPLY.may_load(deps.storage)?, + }) +} diff --git a/contracts/external/cw-abc/src/state.rs b/contracts/external/cw-abc/src/state.rs new file mode 100644 index 000000000..74393cf0a --- /dev/null +++ b/contracts/external/cw-abc/src/state.rs @@ -0,0 +1,145 @@ +use std::fmt::{self, Display}; + +use crate::abc::{CommonsPhase, CommonsPhaseConfig, CurveType, MinMax, SupplyToken}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Uint128, Uint64}; +use cw_curves::DecimalPlaces; +use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; + +/// Supply is dynamic and tracks the current supply of staked and ERC20 tokens. +#[cw_serde] +pub struct CurveState { + /// reserve is how many native tokens exist bonded to the validator + pub reserve: Uint128, + /// funding is how many native tokens exist unbonded and in the contract + pub funding: Uint128, + /// supply is how many tokens this contract has issued + pub supply: Uint128, + + /// the denom of the reserve token + pub reserve_denom: String, + + /// how to normalize reserve and supply + pub decimals: DecimalPlaces, +} + +impl CurveState { + pub fn new(reserve_denom: String, decimals: DecimalPlaces) -> Self { + CurveState { + reserve: Uint128::zero(), + funding: Uint128::zero(), + supply: Uint128::zero(), + reserve_denom, + decimals, + } + } +} + +/// The configuration for a member of the hatcher allowlist +#[cw_serde] +pub struct HatcherAllowlistConfig { + /// The type of the configuration + pub config_type: HatcherAllowlistConfigType, + /// An optional override of the hatch_config's contribution limit + pub contribution_limits_override: Option, + /// The height of the config insertion + /// For use when checking allowlist of DAO configs + pub config_height: u64, +} + +#[cw_serde] +pub struct HatcherAllowlistEntry { + pub addr: Addr, + pub config: HatcherAllowlistConfig, +} + +#[cw_serde] +pub enum HatcherAllowlistConfigType { + DAO { + /// The optional priority for checking a DAO config + /// None will append the item to the end of the priority queue (least priority) + priority: Option, + }, + Address {}, +} + +impl Copy for HatcherAllowlistConfigType {} + +impl Display for HatcherAllowlistConfigType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + HatcherAllowlistConfigType::DAO { priority: _ } => write!(f, "DAO"), + HatcherAllowlistConfigType::Address {} => write!(f, "Address"), + } + } +} + +pub struct HatcherAllowlistIndexes<'a> { + pub config_type: MultiIndex<'a, String, HatcherAllowlistConfig, &'a Addr>, +} + +impl<'a> IndexList for HatcherAllowlistIndexes<'a> { + fn get_indexes( + &'_ self, + ) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.config_type]; + Box::new(v.into_iter()) + } +} + +pub fn hatcher_allowlist<'a>( +) -> IndexedMap<'a, &'a Addr, HatcherAllowlistConfig, HatcherAllowlistIndexes<'a>> { + let indexes = HatcherAllowlistIndexes { + config_type: MultiIndex::new( + |_, x: &HatcherAllowlistConfig| x.config_type.to_string(), + "hatcher_allowlist", + "hatcher_allowlist__config_type", + ), + }; + + IndexedMap::new("hatcher_allowlist", indexes) +} + +/// The hatcher allowlist with configurations +pub const HATCHER_ALLOWLIST: Map<&Addr, HatcherAllowlistConfig> = Map::new("hatcher_allowlist"); + +/// The DAO portion of the hatcher allowlist implemented as a priority queue +/// If someone is a member of multiple allowlisted DAO's, we want to be able to control the checking order +pub const HATCHER_DAO_PRIORITY_QUEUE: Item> = + Item::new("HATCHER_DAO_PRIORITY_QUEUE"); + +/// The paused state for implementing a circuit breaker +pub const IS_PAUSED: Item = Item::new("is_paused"); + +pub const CURVE_STATE: Item = Item::new("curve_state"); + +pub const CURVE_TYPE: Item = Item::new("curve_type"); + +/// The address for automatically forwarding funding pool gains +pub const FUNDING_POOL_FORWARDING: Item = Item::new("funding_pool_forwarding"); + +/// The denom used for the supply token +pub const SUPPLY_DENOM: Item = Item::new("denom"); + +/// The maximum supply of the supply token, new tokens cannot be minted beyond this cap +pub const MAX_SUPPLY: Item = Item::new("max_supply"); + +/// Keep track of who has contributed to the hatch phase +/// TODO: cw-set? This should be a map because in the open-phase we need to be able +/// to ascertain the amount contributed by a user +pub static HATCHERS: Map<&Addr, Uint128> = Map::new("hatchers"); + +/// Keep track of the donated amounts per user +pub static DONATIONS: Map<&Addr, Uint128> = Map::new("donations"); + +/// The phase configuration of the Augmented Bonding Curve +pub static PHASE_CONFIG: Item = Item::new("phase_config"); + +/// The phase state of the Augmented Bonding Curve +pub static PHASE: Item = Item::new("phase"); + +/// Temporarily holds the supply config when creating a new Token Factory denom +pub const TEMP_SUPPLY: Item = Item::new("temp_supply"); + +/// The address of the cw-tokenfactory-issuer contract +pub const TOKEN_ISSUER_CONTRACT: Item = Item::new("token_issuer_contract"); diff --git a/contracts/external/cw-abc/src/tests.rs b/contracts/external/cw-abc/src/tests.rs new file mode 100644 index 000000000..784bdb534 --- /dev/null +++ b/contracts/external/cw-abc/src/tests.rs @@ -0,0 +1,843 @@ +use anyhow::Result; +use cosmwasm_std::{coin, coins, to_json_binary, Decimal, Uint128, Uint64}; +use cw_abc::msg::{ExecuteMsgFns, QueryMsgFns}; +use cw_abc::msg::{HatcherAllowlistConfigMsg, HatcherAllowlistEntryMsg, InstantiateMsg}; +use cw_abc::{ + abc::{ + ClosedConfig, CommonsPhase, CommonsPhaseConfig, CurveType, HatchConfig, MinMax, OpenConfig, + ReserveToken, SupplyToken, + }, + state::HatcherAllowlistConfigType, +}; +use cw_orch::prelude::*; +use cw_orch_osmosis_test_tube::osmosis_test_tube::{Account, SigningAccount}; +use cw_orch_osmosis_test_tube::OsmosisTestTube; +use dao_cw_orch::{ + DaoDaoCore, DaoExternalCwAbc, DaoExternalTokenfactoryIssuer, DaoProposalSudo, + DaoVotingTokenStaked, +}; +use dao_interface::msg::QueryMsgFns as DaoQueryMsgFns; +use dao_interface::state::{Admin, ModuleInstantiateInfo}; +use dao_interface::token::{DenomUnit, InitialBalance, NewDenomMetadata, NewTokenInfo}; +use dao_voting_token_staked::msg::TokenInfo; +use dao_voting_token_staked::msg::{ExecuteMsgFns as _, QueryMsgFns as _}; +use speculoos::assert_that; +use speculoos::string::StrAssertions; +use std::rc::Rc; + +const TEST_RESERVE_DENOM: &str = "uosmo"; + +struct TestAccounts { + creator: Rc, + buyer: Rc, + donor: Rc, +} + +fn setup() -> Result<( + OsmosisTestTube, + DaoExternalCwAbc, + u64, + TestAccounts, +)> { + let mut chain = OsmosisTestTube::new(coins(1_000_000_000_000, TEST_RESERVE_DENOM)); + + let creator = chain.init_account(coins(1_000_000_000_000, TEST_RESERVE_DENOM))?; + let buyer = chain.init_account(coins(1_000_000_000_000, TEST_RESERVE_DENOM))?; + let donor = chain.init_account(coins(1_000_000_000_000, TEST_RESERVE_DENOM))?; + + let accounts = TestAccounts { + creator, + buyer, + donor, + }; + + // Upload ABC contract + let abc = DaoExternalCwAbc::new("cw_abc", chain.clone()); + abc.upload()?; + + // Upload cw-tokenfactory-issuer + let token_factory_issuer = + DaoExternalTokenfactoryIssuer::new("cw_tokenfactory_issuer", chain.clone()); + token_factory_issuer.upload()?; + + Ok((chain, abc, token_factory_issuer.code_id()?, accounts)) +} + +fn default_instantiate( + token_issuer_code_id: u64, + curve_type: CurveType, + funding_pool_forwarding: Option, +) -> InstantiateMsg { + InstantiateMsg { + token_issuer_code_id, + funding_pool_forwarding, + supply: SupplyToken { + subdenom: "abc".to_string(), + metadata: None, + decimals: 6, + max_supply: None, + }, + reserve: ReserveToken { + denom: TEST_RESERVE_DENOM.to_string(), + decimals: 6, + }, + curve_type, + phase_config: CommonsPhaseConfig { + hatch: HatchConfig { + contribution_limits: MinMax { + min: Uint128::new(100), + max: Uint128::new(1000000), + }, + initial_raise: MinMax { + min: Uint128::new(1000), + max: Uint128::new(10000), + }, + entry_fee: Decimal::percent(10), + }, + open: OpenConfig { + entry_fee: Decimal::percent(5), + exit_fee: Decimal::percent(5), + }, + closed: ClosedConfig {}, + }, + hatcher_allowlist: None, + } +} + +#[test] +fn donate_should_fail_with_no_funds() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let result = abc.call_as(&accounts.donor).donate(&[]); + assert_that!(result.unwrap_err().to_string()).contains("No funds sent"); + + Ok(()) +} + +#[test] +fn donate_should_fail_with_incorrect_denom() -> Result<()> { + let (mut chain, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + chain.add_balance(accounts.donor.address(), coins(100000u128, "fake"))?; + + let result = abc.call_as(&accounts.donor).donate(&[coin(1, "fake")]); + assert_that!(result.unwrap_err().to_string()).contains("Must send reserve token"); + + Ok(()) +} + +#[test] +fn donate_should_forward_to_funding_pool() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::SquareRoot { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate( + token_issuer_code_id, + curve_type, + Some(accounts.creator.as_ref().address()), + ); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let donation_amount = 5u128; + abc.call_as(&accounts.donor) + .donate(&[coin(donation_amount, TEST_RESERVE_DENOM)])?; + + let curve_state = abc.curve_info()?; + assert_eq!(curve_state.funding, Uint128::zero()); + + let donation_response = abc.donations(None, None)?; + assert!(donation_response.donations.len() == 1); + + Ok(()) +} + +#[test] +fn test_donate_and_withdraw() -> Result<()> { + let (mut chain, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::SquareRoot { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let donation_amount = 5u128; + abc.call_as(&accounts.donor) + .donate(&[coin(donation_amount, TEST_RESERVE_DENOM)])?; + + let curve_state = abc.curve_info()?; + assert_eq!(curve_state.funding, Uint128::new(donation_amount)); + + // Random user can't withdraw + let random = chain.init_account(coins(1_000_000, TEST_RESERVE_DENOM))?; + let result = abc.call_as(&random).withdraw(None); + assert_that!(result.unwrap_err().to_string()).contains("not the contract's current owner"); + + // Creator can withdraw + abc.call_as(&accounts.creator).withdraw(None)?; + + let curve_state = abc.curve_info()?; + assert_eq!(curve_state.funding, Uint128::zero()); + + Ok(()) +} + +#[test] +fn test_pause() -> Result<()> { + let (mut chain, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::SquareRoot { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + assert!(!abc.is_paused()?); + + // Random user can't pause + let random = chain.init_account(coins(1_000_000, TEST_RESERVE_DENOM))?; + let result = abc.call_as(&random).toggle_pause(); + assert_that!(result.unwrap_err().to_string()).contains("not the contract's current owner"); + + // Creator can pause + abc.call_as(&accounts.creator).toggle_pause()?; + assert!(abc.is_paused()?); + + // Can't execute when paused + let result = abc + .call_as(&accounts.buyer) + .buy(&[coin(100, TEST_RESERVE_DENOM)]); + assert_that!(result.unwrap_err().to_string()).contains("Contract is paused"); + + // Creator can unpause + abc.call_as(&accounts.creator).toggle_pause()?; + assert!(!abc.is_paused()?); + + Ok(()) +} + +#[test] +fn test_buy_in_hatch_phase() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let buy_amount = 1000u128; + abc.call_as(&accounts.buyer) + .buy(&[coin(buy_amount, TEST_RESERVE_DENOM)])?; + + let curve_info = abc.curve_info()?; + assert!(curve_info.supply > Uint128::zero()); + // Buy amount - entry fee + assert_eq!(curve_info.reserve, Uint128::new(buy_amount - 100u128)); + + let phase = abc.phase()?; + assert_eq!(phase, CommonsPhase::Hatch); + + Ok(()) +} + +#[test] +fn test_transition_to_open_phase() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let buy_amount = 1000000u128; // Max raise amount + abc.call_as(&accounts.buyer) + .buy(&[coin(buy_amount, TEST_RESERVE_DENOM)])?; + + let phase = abc.phase()?; + assert_eq!(phase, CommonsPhase::Open); + + let supply_denom = abc.supply_denom()?; + + // Now try to sell + let sell_amount = Uint128::new(1000); + abc.call_as(&accounts.buyer) + .sell(&[coin(sell_amount.u128(), supply_denom)])?; + + Ok(()) +} + +#[test] +fn test_sell_in_hatch_phase() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let buy_amount = 1000u128; + abc.call_as(&accounts.buyer) + .buy(&[coin(buy_amount, TEST_RESERVE_DENOM)])?; + + let supply_denom = abc.supply_denom()?; + + let sell_amount = Uint128::new(100); + let result = abc + .call_as(&accounts.buyer) + .sell(&[coin(sell_amount.u128(), supply_denom)]); + assert_that!(result.unwrap_err().to_string()).contains("commons is locked"); + + Ok(()) +} + +#[test] +fn test_update_curve_parameters() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let new_curve_type = CurveType::SquareRoot { + slope: Uint128::new(2), + scale: 1, + }; + abc.call_as(&accounts.creator) + .update_curve(new_curve_type.clone())?; + + let updated_curve_type = abc.curve_type()?; + assert_eq!(updated_curve_type, new_curve_type); + + Ok(()) +} + +#[test] +fn test_query_functions() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + let curve_info = abc.curve_info()?; + assert_eq!(curve_info.reserve, Uint128::zero()); + assert_eq!(curve_info.supply, Uint128::zero()); + + let phase = abc.phase()?; + assert_eq!(phase, CommonsPhase::Hatch); + + let curve_type = abc.curve_type()?; + assert_eq!( + curve_type, + CurveType::Linear { + slope: Uint128::new(1), + scale: 1 + } + ); + + Ok(()) +} + +#[test] +fn test_contribution_limits() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let mut msg = default_instantiate(token_issuer_code_id, curve_type, None); + msg.phase_config.hatch.contribution_limits = MinMax { + min: Uint128::new(100), + max: Uint128::new(1000), + }; + + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + // Test minimum contribution limit + let result = abc + .call_as(&accounts.buyer) + .buy(&[coin(99, TEST_RESERVE_DENOM)]); + assert_that!(result.unwrap_err().to_string()) + .contains("Contribution must be less than or equal to"); + + // Test maximum contribution limit + let result = abc + .call_as(&accounts.buyer) + .buy(&[coin(1001, TEST_RESERVE_DENOM)]); + assert_that!(result.unwrap_err().to_string()) + .contains("Contribution must be less than or equal to"); + + // Test valid contribution + let result = abc + .call_as(&accounts.buyer) + .buy(&[coin(500, TEST_RESERVE_DENOM)]); + assert!(result.is_ok()); + + Ok(()) +} + +#[test] +fn test_max_supply() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Constant { + scale: 0, + value: Uint128::new(1), + }; + let mut msg = default_instantiate(token_issuer_code_id, curve_type, None); + msg.supply.max_supply = Some(Uint128::new(10000)); + msg.phase_config.hatch.entry_fee = Decimal::zero(); + + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + // Buy tokens up to max supply + abc.call_as(&accounts.buyer) + .buy(&[coin(10000, TEST_RESERVE_DENOM)])?; + + // Attempt to buy more tokens + let result = abc + .call_as(&accounts.buyer) + .buy(&[coin(100, TEST_RESERVE_DENOM)]); + assert_that!(result.unwrap_err().to_string()).contains("Cannot mint more tokens"); + + // Verify max supply + let curve_info = abc.curve_info()?; + assert_eq!(curve_info.supply, Uint128::new(10000)); + + Ok(()) +} + +#[test] +fn test_closing_curve() -> Result<()> { + let (_, abc, token_issuer_code_id, accounts) = setup()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + // Buy tokens to transition to open phase + abc.call_as(&accounts.buyer) + .buy(&[coin(1000000, TEST_RESERVE_DENOM)])?; + + // Close the curve + abc.call_as(&accounts.creator).close()?; + + // Verify curve is closed + assert_eq!(abc.phase()?, CommonsPhase::Closed); + + // Attempt to buy tokens (should fail) + let result = abc + .call_as(&accounts.buyer) + .buy(&[coin(500, TEST_RESERVE_DENOM)]); + assert_that!(result.unwrap_err().to_string()) + .contains("commons is closed to new contributions"); + + // Sell tokens (should succeed with no exit fee) + let curve_denom = abc.supply_denom()?; + let result = abc + .call_as(&accounts.buyer) + .sell(&[coin(1000, &curve_denom)]); + assert!(result.is_ok()); + + Ok(()) +} + +#[test] +fn test_dao_hatcher_functionality() -> Result<()> { + let (mut chain, abc, token_issuer_code_id, accounts) = setup()?; + let dao_core = DaoDaoCore::new("dao_dao", chain.clone()); + dao_core.upload()?; + let dao_proposal_sudo = DaoProposalSudo::new("dao_proposal_sudo", chain.clone()); + dao_proposal_sudo.upload()?; + let dao_voting_token = DaoVotingTokenStaked::new("dao_voting_token", chain.clone()); + dao_voting_token.upload()?; + + // Setup multiple DAOs + let dao_addrs = (0..6) + .map(|_| { + setup_dao( + &dao_core, + &dao_voting_token, + &dao_proposal_sudo, + token_issuer_code_id, + &accounts.creator, + vec![&accounts.buyer], + ) + }) + .collect::>>()?; + chain.next_block()?; + + let curve_type = CurveType::Linear { + slope: Uint128::new(1), + scale: 1, + }; + let msg = default_instantiate(token_issuer_code_id, curve_type, None); + + abc.call_as(&accounts.creator) + .instantiate(&msg, None, None)?; + + // Add DAOs to allowlist with different priorities and contribution limits + for (i, dao_addr) in dao_addrs.iter().enumerate().take(5) { + abc.call_as(&accounts.creator).update_hatch_allowlist( + vec![HatcherAllowlistEntryMsg { + addr: dao_addr.to_string(), + config: HatcherAllowlistConfigMsg { + config_type: HatcherAllowlistConfigType::DAO { + priority: Some(Uint64::MAX - Uint64::new(i as u64)), + }, + contribution_limits_override: Some(MinMax { + min: Uint128::one(), + max: Uint128::from(10u128) * Uint128::from(i as u128 + 1u128), + }), + }, + }], + vec![], + )?; + } + + // Add a DAO tied for the highest priority + abc.call_as(&accounts.creator).update_hatch_allowlist( + vec![HatcherAllowlistEntryMsg { + addr: dao_addrs[5].to_string(), + config: HatcherAllowlistConfigMsg { + config_type: HatcherAllowlistConfigType::DAO { + priority: Some(Uint64::MAX - Uint64::new(4)), + }, + contribution_limits_override: Some(MinMax { + min: Uint128::one(), + max: Uint128::from(1000u128), + }), + }, + }], + vec![], + )?; + + // Add a DAO without priority + let dao_no_priority = setup_dao( + &dao_core, + &dao_voting_token, + &dao_proposal_sudo, + token_issuer_code_id, + &accounts.creator, + vec![&accounts.donor], + )?; + abc.call_as(&accounts.creator).update_hatch_allowlist( + vec![HatcherAllowlistEntryMsg { + addr: dao_no_priority.to_string(), + config: HatcherAllowlistConfigMsg { + config_type: HatcherAllowlistConfigType::DAO { priority: None }, + contribution_limits_override: Some(MinMax { + min: Uint128::one(), + max: Uint128::from(100u128), + }), + }, + }], + vec![], + )?; + chain.next_block()?; + + // Check contribution limit (should be 50, the highest priority DAO's limit) + let err = abc + .call_as(&accounts.buyer) + .buy(&[coin(51, TEST_RESERVE_DENOM)]) + .unwrap_err(); + assert_that!(err.to_string()).contains("Contribution must be less than or equal to"); + + // Remove the highest priority DAO + abc.call_as(&accounts.creator) + .update_hatch_allowlist(vec![], vec![dao_addrs[4].to_string()])?; + + // Check new contribution limit (should be 1000, the next highest priority DAO's limit) + abc.call_as(&accounts.buyer) + .buy(&[coin(1000, TEST_RESERVE_DENOM)])?; + + // Add an individual address to the allowlist + let individual = chain.init_account(coins(1_000_000_000_000, TEST_RESERVE_DENOM))?; + + abc.call_as(&accounts.creator).update_hatch_allowlist( + vec![HatcherAllowlistEntryMsg { + addr: individual.address(), + config: HatcherAllowlistConfigMsg { + config_type: HatcherAllowlistConfigType::Address {}, + contribution_limits_override: Some(MinMax { + min: Uint128::one(), + max: Uint128::from(2000u128), + }), + }, + }], + vec![], + )?; + chain.next_block()?; + + // Check that the individual address limit takes precedence + abc.call_as(&individual) + .buy(&[coin(2000, TEST_RESERVE_DENOM)])?; + + // Non-DAO member cannot buy tokens + let result = abc + .call_as(&accounts.creator) + .buy(&[coin(50, TEST_RESERVE_DENOM)]); + assert_that!(result.unwrap_err().to_string()).contains("not in the hatcher allowlist"); + + // DAO member without priority can buy tokens within their limit + abc.call_as(&accounts.donor) + .buy(&[coin(100, TEST_RESERVE_DENOM)])?; + + Ok(()) +} + +#[test] +pub fn arena() -> Result<()> { + let (mut chain, abc, token_issuer_code_id, accounts) = setup()?; + let dao = chain.init_account(coins(1_000_000_000_000, TEST_RESERVE_DENOM))?; + let buyer = chain.init_account(coins(1_000_000_000_000_000, TEST_RESERVE_DENOM))?; + + let msg = InstantiateMsg { + token_issuer_code_id, + funding_pool_forwarding: None, + supply: SupplyToken { + subdenom: "uarena".to_string(), + metadata: Some(NewDenomMetadata { + name: "Arena Token".to_string(), + description: "The governance token of the Arena DAO".to_string(), + symbol: "ARENA".to_string(), + display: "arena".to_string(), + additional_denom_units: Some(vec![DenomUnit { + denom: "arena".to_string(), + exponent: 6, + aliases: vec![], + }]), + }), + decimals: 6, + max_supply: Some(Uint128::new(1_000_000_000_000)), + }, + reserve: ReserveToken { + denom: TEST_RESERVE_DENOM.to_string(), + decimals: 6, + }, + curve_type: CurveType::SquareRoot { + slope: Uint128::new(3), + scale: 7, + }, + phase_config: CommonsPhaseConfig { + hatch: HatchConfig { + contribution_limits: MinMax { + min: Uint128::new(100_000), + max: Uint128::new(1_000_000), + }, + initial_raise: MinMax { + min: Uint128::zero(), + max: Uint128::new(92_951_601), + }, + entry_fee: Decimal::zero(), + }, + open: OpenConfig { + entry_fee: Decimal::from_atomics(999965u128, 6)?, + exit_fee: Decimal::zero(), + }, + closed: ClosedConfig {}, + }, + hatcher_allowlist: Some(vec![ + HatcherAllowlistEntryMsg { + addr: accounts.creator.address(), + config: HatcherAllowlistConfigMsg { + config_type: HatcherAllowlistConfigType::Address {}, + contribution_limits_override: Some(MinMax { + min: Uint128::zero(), + max: Uint128::new(17_888_544), + }), + }, + }, + HatcherAllowlistEntryMsg { + addr: dao.address(), + config: HatcherAllowlistConfigMsg { + config_type: HatcherAllowlistConfigType::Address {}, + contribution_limits_override: Some(MinMax { + min: Uint128::zero(), + max: Uint128::new(75_063_057), + }), + }, + }, + ]), + }; + + abc.call_as(&dao).instantiate(&msg, None, None)?; + + // Founder allocation + abc.call_as(&accounts.creator) + .buy(&coins(17_888_544, TEST_RESERVE_DENOM))?; + + // Get denom + let supply_denom = abc.supply_denom()?; + + // Check balance + let balance = chain.query_balance(&accounts.creator.address(), &supply_denom)?; + assert_eq!(balance, Uint128::new(200_000_001_000)); + + // Arena Gladiators + Treasury + abc.call_as(&dao) + .buy(&coins(75_063_057, TEST_RESERVE_DENOM))?; + + // Check we're in the open phase now + let phase_config = abc.phase_config()?; + assert_eq!(phase_config.phase, CommonsPhase::Open); + + // Check the current supply + let curve_info = abc.curve_info()?; + assert_eq!(curve_info.supply, Uint128::new(600_000_002_000)); + + // User buys the rest + abc.call_as(&buyer) + .buy(&coins(3_058_525_685_714, TEST_RESERVE_DENOM))?; + + // Check the supply + let curve_info = abc.curve_info()?; + assert_eq!(curve_info.supply, Uint128::new(1_000_000_000_000)); + + // Check the funding pool + assert_eq!(curve_info.funding, Uint128::new(3_058_418_637_315)); + + // Max supply reached + let result = abc.call_as(&buyer).buy(&coins(1, TEST_RESERVE_DENOM)); + assert_that!(result.unwrap_err().to_string()).contains("Cannot mint more tokens"); + + // Sell some into the curve + abc.call_as(&dao) + .sell(&coins(1_000_000, supply_denom.clone()))?; + + // Buying a very small amount results in rounding issues + let result = abc.call_as(&buyer).buy(&coins(1000, TEST_RESERVE_DENOM)); + assert!(result.is_err()); + + Ok(()) +} + +// Helper function to setup a DAO +fn setup_dao( + dao_core: &DaoDaoCore, + dao_voting_token: &DaoVotingTokenStaked, + dao_proposal_sudo: &DaoProposalSudo, + token_issuer_code_id: u64, + admin: &Rc, + members: Vec<&Rc>, +) -> Result { + dao_core.call_as(admin).instantiate( + &dao_interface::msg::InstantiateMsg { + admin: None, + name: "DAO DAO".to_string(), + description: "A DAO that makes DAO tooling".to_string(), + image_url: None, + automatically_add_cw20s: false, + automatically_add_cw721s: false, + voting_module_instantiate_info: ModuleInstantiateInfo { + code_id: dao_voting_token.code_id()?, + msg: to_json_binary(&dao_voting_token_staked::msg::InstantiateMsg { + token_info: TokenInfo::New(NewTokenInfo { + token_issuer_code_id, + subdenom: "cat".to_string(), + metadata: Some(NewDenomMetadata { + description: "Awesome token, get it meow!".to_string(), + additional_denom_units: Some(vec![DenomUnit { + denom: "cat".to_string(), + exponent: 6, + aliases: vec![], + }]), + display: "cat".to_string(), + name: "Cat Token".to_string(), + symbol: "CAT".to_string(), + }), + initial_balances: members + .iter() + .map(|x| InitialBalance { + address: x.address(), + amount: Uint128::new(100), + }) + .collect(), + initial_dao_balance: None, + }), + unstaking_duration: None, + active_threshold: None, + }) + .unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "DAO DAO Voting Module".to_string(), + }, + proposal_modules_instantiate_info: vec![ModuleInstantiateInfo { + code_id: dao_proposal_sudo.code_id()?, + msg: to_json_binary(&dao_proposal_sudo::msg::InstantiateMsg { + root: admin.address(), + })?, + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "DAO Proposal Sudo".to_string(), + }], + initial_items: None, + dao_uri: None, + }, + None, + None, + )?; + + let voting_module = dao_core.voting_module()?; + + dao_voting_token.set_address(&Addr::unchecked(voting_module)); + let denom = dao_voting_token.denom()?.denom; + + for caller in members.iter() { + dao_voting_token + .call_as(caller) + .stake(&coins(100, denom.clone()))?; + } + + Ok(dao_core.address()?) +} diff --git a/contracts/external/cw-admin-factory/Cargo.toml b/contracts/external/cw-admin-factory/Cargo.toml index 92e299c2f..61077d893 100644 --- a/contracts/external/cw-admin-factory/Cargo.toml +++ b/contracts/external/cw-admin-factory/Cargo.toml @@ -40,7 +40,7 @@ cw4 = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } dao-interface = { workspace = true } dao-proposal-single = { workspace = true } -dao-testing = { workspace = true } +dao-testing = { workspace = true, features = ["test-tube"] } dao-voting = { workspace = true } dao-voting-cw4 = { workspace = true } osmosis-test-tube = { workspace = true } diff --git a/contracts/external/cw-admin-factory/src/lib.rs b/contracts/external/cw-admin-factory/src/lib.rs index 6ea49d00c..4b242a062 100644 --- a/contracts/external/cw-admin-factory/src/lib.rs +++ b/contracts/external/cw-admin-factory/src/lib.rs @@ -8,7 +8,7 @@ pub mod state; #[cfg(test)] mod tests; -// Integrationg tests using an actual chain binary, requires +// Integration tests using an actual chain binary, requires // the "test-tube" feature to be enabled // cargo test --features test-tube #[cfg(test)] diff --git a/contracts/external/cw-tokenfactory-issuer/schema/cw-tokenfactory-issuer.json b/contracts/external/cw-tokenfactory-issuer/schema/cw-tokenfactory-issuer.json index 6b5e40a2a..19f03eae3 100644 --- a/contracts/external/cw-tokenfactory-issuer/schema/cw-tokenfactory-issuer.json +++ b/contracts/external/cw-tokenfactory-issuer/schema/cw-tokenfactory-issuer.json @@ -21,7 +21,7 @@ ], "properties": { "subdenom": { - "description": "component of fulldenom (`factory//`).", + "description": "component of full denom (`factory//`).", "type": "string" } }, @@ -31,7 +31,7 @@ "additionalProperties": false }, { - "description": "`ExistingToken` will use already created token. So to set this up, Token Factory admin for the existing token needs trasfer admin over to this contract, and optionally set the `BeforeSendHook` manually.", + "description": "`ExistingToken` will use already created token. So to set this up, Token Factory admin for the existing token needs transfer admin over to this contract, and optionally set the `BeforeSendHook` manually.", "type": "object", "required": [ "existing_token" @@ -60,7 +60,7 @@ "description": "State changing methods available to this smart contract.", "oneOf": [ { - "description": "Allow adds the target address to the allowlist to be able to send or recieve tokens even if the token is frozen. Token Factory's BeforeSendHook listener must be set to this contract in order for this feature to work.\n\nThis functionality is intedended for DAOs who do not wish to have a their tokens liquid while bootstrapping their DAO. For example, a DAO may wish to white list a Token Staking contract (to allow users to stake their tokens in the DAO) or a Merkle Drop contract (to allow users to claim their tokens).", + "description": "Allow adds the target address to the allowlist to be able to send or receive tokens even if the token is frozen. Token Factory's BeforeSendHook listener must be set to this contract in order for this feature to work.\n\nThis functionality is intended for DAOs who do not wish to have a their tokens liquid while bootstrapping their DAO. For example, a DAO may wish to white list a Token Staking contract (to allow users to stake their tokens in the DAO) or a Merkle Drop contract (to allow users to claim their tokens).", "type": "object", "required": [ "allow" @@ -86,7 +86,7 @@ "additionalProperties": false }, { - "description": "Burn token to address. Burn allowance is required and wiil be deducted after successful burn.", + "description": "Burn token to address. Burn allowance is required and will be deducted after successful burn.", "type": "object", "required": [ "burn" @@ -112,7 +112,7 @@ "additionalProperties": false }, { - "description": "Mint token to address. Mint allowance is required and wiil be deducted after successful mint.", + "description": "Mint token to address. Mint allowance is required and will be deducted after successful mint.", "type": "object", "required": [ "mint" @@ -138,7 +138,7 @@ "additionalProperties": false }, { - "description": "Deny adds the target address to the denylist, whis prevents them from sending/receiving the token attached to this contract tokenfactory's BeforeSendHook listener must be set to this contract in order for this feature to work as intended.", + "description": "Deny adds the target address to the denylist, which prevents them from sending/receiving the token attached to this contract tokenfactory's BeforeSendHook listener must be set to this contract in order for this feature to work as intended.", "type": "object", "required": [ "deny" @@ -601,7 +601,7 @@ "additionalProperties": false }, { - "description": "Enumerates over all burn allownances. Response: AllowancesResponse", + "description": "Enumerates over all burn allowances. Response: AllowancesResponse", "type": "object", "required": [ "burn_allowances" @@ -653,7 +653,7 @@ "additionalProperties": false }, { - "description": "Enumerates over all mint allownances. Response: AllowancesResponse", + "description": "Enumerates over all mint allowances. Response: AllowancesResponse", "type": "object", "required": [ "mint_allowances" diff --git a/contracts/external/cw-tokenfactory-issuer/src/msg.rs b/contracts/external/cw-tokenfactory-issuer/src/msg.rs index 6170cddc8..05f5ce01b 100644 --- a/contracts/external/cw-tokenfactory-issuer/src/msg.rs +++ b/contracts/external/cw-tokenfactory-issuer/src/msg.rs @@ -1,3 +1,4 @@ +#[allow(unused_imports)] use crate::state::BeforeSendHookInfo; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Coin, Uint128}; @@ -12,11 +13,11 @@ pub enum InstantiateMsg { /// Newly created token will have full denom as `factory//`. /// It will be attached to the contract setup the beforesend listener automatically. NewToken { - /// component of fulldenom (`factory//`). + /// component of full denom (`factory//`). subdenom: String, }, /// `ExistingToken` will use already created token. So to set this up, - /// Token Factory admin for the existing token needs trasfer admin over + /// Token Factory admin for the existing token needs transfer admin over /// to this contract, and optionally set the `BeforeSendHook` manually. ExistingToken { denom: String }, } @@ -25,25 +26,25 @@ pub enum InstantiateMsg { #[cw_serde] #[derive(cw_orch::ExecuteFns)] pub enum ExecuteMsg { - /// Allow adds the target address to the allowlist to be able to send or recieve tokens even if the token + /// Allow adds the target address to the allowlist to be able to send or receive tokens even if the token /// is frozen. Token Factory's BeforeSendHook listener must be set to this contract in order for this feature /// to work. /// - /// This functionality is intedended for DAOs who do not wish to have a their tokens liquid while bootstrapping + /// This functionality is intended for DAOs who do not wish to have a their tokens liquid while bootstrapping /// their DAO. For example, a DAO may wish to white list a Token Staking contract (to allow users to stake their /// tokens in the DAO) or a Merkle Drop contract (to allow users to claim their tokens). Allow { address: String, status: bool }, - /// Burn token to address. Burn allowance is required and wiil be deducted after successful burn. + /// Burn token to address. Burn allowance is required and will be deducted after successful burn. Burn { from_address: String, amount: Uint128, }, - /// Mint token to address. Mint allowance is required and wiil be deducted after successful mint. + /// Mint token to address. Mint allowance is required and will be deducted after successful mint. Mint { to_address: String, amount: Uint128 }, - /// Deny adds the target address to the denylist, whis prevents them from sending/receiving the token attached + /// Deny adds the target address to the denylist, which prevents them from sending/receiving the token attached /// to this contract tokenfactory's BeforeSendHook listener must be set to this contract in order for this /// feature to work as intended. Deny { address: String, status: bool }, @@ -126,7 +127,7 @@ pub enum QueryMsg { #[returns(AllowanceResponse)] BurnAllowance { address: String }, - /// Enumerates over all burn allownances. Response: AllowancesResponse + /// Enumerates over all burn allowances. Response: AllowancesResponse #[returns(AllowancesResponse)] BurnAllowances { start_after: Option, @@ -137,7 +138,7 @@ pub enum QueryMsg { #[returns(AllowanceResponse)] MintAllowance { address: String }, - /// Enumerates over all mint allownances. Response: AllowancesResponse + /// Enumerates over all mint allowances. Response: AllowancesResponse #[returns(AllowancesResponse)] MintAllowances { start_after: Option, @@ -205,7 +206,7 @@ pub struct DenomResponse { } /// Returns the current owner of this issuer contract who is allowed to -/// call priviledged methods. +/// call privileged methods. #[cw_serde] pub struct OwnerResponse { pub address: String, diff --git a/contracts/external/cw-tokenfactory-issuer/src/queries.rs b/contracts/external/cw-tokenfactory-issuer/src/queries.rs index a6b7f3b5d..6e8025c55 100644 --- a/contracts/external/cw-tokenfactory-issuer/src/queries.rs +++ b/contracts/external/cw-tokenfactory-issuer/src/queries.rs @@ -79,7 +79,7 @@ pub fn query_allowances( .collect() } -/// Enumerates over all allownances. Response: AllowancesResponse +/// Enumerates over all allowances. Response: AllowancesResponse pub fn query_mint_allowances( deps: Deps, start_after: Option, @@ -90,7 +90,7 @@ pub fn query_mint_allowances( }) } -/// Enumerates over all burn allownances. Response: AllowancesResponse +/// Enumerates over all burn allowances. Response: AllowancesResponse pub fn query_burn_allowances( deps: Deps, start_after: Option, diff --git a/contracts/external/cw-tokenfactory-issuer/tests/cases/burn.rs b/contracts/external/cw-tokenfactory-issuer/tests/cases/burn.rs index 6c63e1e38..08ac2abee 100644 --- a/contracts/external/cw-tokenfactory-issuer/tests/cases/burn.rs +++ b/contracts/external/cw-tokenfactory-issuer/tests/cases/burn.rs @@ -209,7 +209,7 @@ fn burn_more_than_balance_should_fail_and_not_deduct_allowance() { assert_eq!( err, RunnerError::ExecuteError { - msg: format!("failed to execute message; message index: 0: dispatch: submessages: {balance}{denom} is smaller than {burn_amount}{denom}: insufficient funds") + msg: format!("failed to execute message; message index: 0: dispatch: submessages: spendable balance {balance}{denom} is smaller than {burn_amount}{denom}: insufficient funds") } ); diff --git a/contracts/external/cw-tokenfactory-issuer/tests/cases/denom_metadata.rs b/contracts/external/cw-tokenfactory-issuer/tests/cases/denom_metadata.rs index 660f238a3..7c36bfba6 100644 --- a/contracts/external/cw-tokenfactory-issuer/tests/cases/denom_metadata.rs +++ b/contracts/external/cw-tokenfactory-issuer/tests/cases/denom_metadata.rs @@ -30,6 +30,8 @@ fn set_denom_metadata_by_contract_owner_should_work() { display: "sthb".to_string(), name: "Stable Thai Baht".to_string(), symbol: "STHB".to_string(), + uri: String::default(), + uri_hash: String::default(), }; env.cw_tokenfactory_issuer .set_denom_metadata(metadata, owner) @@ -64,6 +66,8 @@ fn set_denom_metadata_by_contract_non_owner_should_fail() { display: "sthb".to_string(), name: "Stable Thai Baht".to_string(), symbol: "STHB".to_string(), + uri: String::default(), + uri_hash: String::default(), }; // Set denom metadata @@ -108,6 +112,8 @@ fn set_denom_metadata_with_base_denom_unit_should_overides_default_base_denom_un display: "sthb".to_string(), name: "Stable Thai Baht".to_string(), symbol: "STHB".to_string(), + uri: String::default(), + uri_hash: String::default(), }; // Set denom metadata diff --git a/contracts/external/cw-tokenfactory-issuer/tests/test_env.rs b/contracts/external/cw-tokenfactory-issuer/tests/test_env.rs index 99e9b92cd..213f1ec76 100644 --- a/contracts/external/cw-tokenfactory-issuer/tests/test_env.rs +++ b/contracts/external/cw-tokenfactory-issuer/tests/test_env.rs @@ -149,7 +149,7 @@ impl TokenfactoryIssuer { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("cw_tokenfactory_issuer"), &[token_creation_fee], signer, )? diff --git a/contracts/external/cw-vesting/README.md b/contracts/external/cw-vesting/README.md index acd62106e..5e5b163fd 100644 --- a/contracts/external/cw-vesting/README.md +++ b/contracts/external/cw-vesting/README.md @@ -34,13 +34,13 @@ It supports 2 types of [curves](https://docs.rs/wynd-utils/0.4.1/wynd_utils/enum ##### Piecewise Linear -Piecsewise Curves can be used to create more complicated vesting +Piecewise Curves can be used to create more complicated vesting schedules. For example, let's say we have a schedule that vests 50% over 1 month and the remaining 50% over 1 year. We can implement this complex schedule with a Piecewise Linear curve. Piecewise Linear curves take a `steps` parameter which is a list of -tuples `(timestamp, vested)`. It will then linearally interpolate +tuples `(timestamp, vested)`. It will then linearly interpolate between those points to create the vesting curve. For example, given the points `(0, 0), (2, 2), (4, 8)`, it would create a vesting curve that looks like this: diff --git a/contracts/external/dao-abc-factory/.cargo/config b/contracts/external/dao-abc-factory/.cargo/config new file mode 100644 index 000000000..336b618a1 --- /dev/null +++ b/contracts/external/dao-abc-factory/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/contracts/external/dao-abc-factory/Cargo.toml b/contracts/external/dao-abc-factory/Cargo.toml new file mode 100644 index 000000000..c00a596af --- /dev/null +++ b/contracts/external/dao-abc-factory/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "dao-abc-factory" +authors = ["Jake Hartnell"] +description = "A factory contract for cw-abc, intended for use with DAO DAO." +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin)'] } + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +# use test tube feature to enable test-tube integration tests, for example +# cargo test --features "test-tube" +test-tube = [] +# # when writing tests you may wish to enable test-tube as a default feature +# default = ["test-tube"] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-abc = { workspace = true, features = ["library"] } +cw2 = { workspace = true } +cw-ownable = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +thiserror = { workspace = true } +dao-dao-macros = { workspace = true } +dao-interface = { workspace = true } +dao-voting = { workspace = true } +cw-tokenfactory-issuer = { workspace = true, features = ["library"] } + +[dev-dependencies] +anyhow = { workspace = true } +cw-multi-test = { workspace = true } +cw-tokenfactory-issuer = { workspace = true } +dao-proposal-single = { workspace = true } +dao-proposal-hook-counter = { workspace = true } +dao-testing = { workspace = true, features = ["test-tube"] } +dao-voting-token-staked = { workspace = true } +osmosis-std = { workspace = true } +osmosis-test-tube = { workspace = true } +serde = { workspace = true } diff --git a/contracts/external/dao-abc-factory/README b/contracts/external/dao-abc-factory/README new file mode 100644 index 000000000..0322b0f4d --- /dev/null +++ b/contracts/external/dao-abc-factory/README @@ -0,0 +1,4 @@ +# DAO ABC Factory +Used for creating DAOs with `dao-voting-token-staked` and `cw-abc`. + +NOTE: this contract is NOT AUDITED, use at your own risk. diff --git a/contracts/external/dao-abc-factory/examples/schema.rs b/contracts/external/dao-abc-factory/examples/schema.rs new file mode 100644 index 000000000..1c48cc544 --- /dev/null +++ b/contracts/external/dao-abc-factory/examples/schema.rs @@ -0,0 +1,10 @@ +use cosmwasm_schema::write_api; +use dao_abc_factory::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + } +} diff --git a/contracts/external/dao-abc-factory/schema/dao-abc-factory.json b/contracts/external/dao-abc-factory/schema/dao-abc-factory.json new file mode 100644 index 000000000..5bfbc5751 --- /dev/null +++ b/contracts/external/dao-abc-factory/schema/dao-abc-factory.json @@ -0,0 +1,645 @@ +{ + "contract_name": "dao-abc-factory", + "contract_version": "2.5.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "abc_factory" + ], + "properties": { + "abc_factory": { + "type": "object", + "required": [ + "code_id", + "instantiate_msg" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "instantiate_msg": { + "$ref": "#/definitions/InstantiateMsg" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "ClosedConfig": { + "type": "object", + "additionalProperties": false + }, + "CommonsPhaseConfig": { + "type": "object", + "required": [ + "closed", + "hatch", + "open" + ], + "properties": { + "closed": { + "description": "The Closed phase where the Commons is closed to new members.", + "allOf": [ + { + "$ref": "#/definitions/ClosedConfig" + } + ] + }, + "hatch": { + "description": "The Hatch phase where initial contributors (Hatchers) participate in a hatch sale.", + "allOf": [ + { + "$ref": "#/definitions/HatchConfig" + } + ] + }, + "open": { + "description": "TODO Vest tokens after hatch phase The Vesting phase where tokens minted during the Hatch phase are locked (burning is disabled) to combat early speculation/arbitrage. pub vesting: VestingConfig, The Open phase where anyone can mint tokens by contributing the reserve token into the curve and becoming members of the Commons.", + "allOf": [ + { + "$ref": "#/definitions/OpenConfig" + } + ] + } + }, + "additionalProperties": false + }, + "CurveType": { + "oneOf": [ + { + "description": "Constant always returns `value * 10^-scale` as spot price", + "type": "object", + "required": [ + "constant" + ], + "properties": { + "constant": { + "type": "object", + "required": [ + "scale", + "value" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "value": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Linear returns `slope * 10^-scale * supply` as spot price", + "type": "object", + "required": [ + "linear" + ], + "properties": { + "linear": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "SquareRoot returns `slope * 10^-scale * supply^0.5` as spot price", + "type": "object", + "required": [ + "square_root" + ], + "properties": { + "square_root": { + "type": "object", + "required": [ + "scale", + "slope" + ], + "properties": { + "scale": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "slope": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "DenomUnit": { + "description": "DenomUnit represents a struct that describes a given denomination unit of the basic token.", + "type": "object", + "required": [ + "aliases", + "denom", + "exponent" + ], + "properties": { + "aliases": { + "description": "aliases is a list of string aliases for the given denom", + "type": "array", + "items": { + "type": "string" + } + }, + "denom": { + "description": "denom represents the string name of the given denom unit (e.g uatom).", + "type": "string" + }, + "exponent": { + "description": "exponent represents power of 10 exponent that one must raise the base_denom to in order to equal the given DenomUnit's denom 1 denom = 1^exponent base_denom (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with exponent = 6, thus: 1 atom = 10^6 uatom).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "HatchConfig": { + "type": "object", + "required": [ + "contribution_limits", + "entry_fee", + "initial_raise" + ], + "properties": { + "contribution_limits": { + "description": "The minimum and maximum contribution amounts (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + }, + "entry_fee": { + "description": "The initial allocation (θ), percentage of the initial raise allocated to the Funding Pool", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "initial_raise": { + "description": "The initial raise range (min, max) in the reserve token", + "allOf": [ + { + "$ref": "#/definitions/MinMax" + } + ] + } + }, + "additionalProperties": false + }, + "HatcherAllowlistConfigMsg": { + "type": "object", + "required": [ + "config_type" + ], + "properties": { + "config_type": { + "description": "The type of the configuration", + "allOf": [ + { + "$ref": "#/definitions/HatcherAllowlistConfigType" + } + ] + }, + "contribution_limits_override": { + "description": "An optional override of the hatch_config's contribution limit", + "anyOf": [ + { + "$ref": "#/definitions/MinMax" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HatcherAllowlistConfigType": { + "oneOf": [ + { + "type": "object", + "required": [ + "d_a_o" + ], + "properties": { + "d_a_o": { + "type": "object", + "properties": { + "priority": { + "description": "The optional priority for checking a DAO config None will append the item to the end of the priority queue (least priority)", + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "HatcherAllowlistEntryMsg": { + "type": "object", + "required": [ + "addr", + "config" + ], + "properties": { + "addr": { + "type": "string" + }, + "config": { + "$ref": "#/definitions/HatcherAllowlistConfigMsg" + } + }, + "additionalProperties": false + }, + "InstantiateMsg": { + "type": "object", + "required": [ + "curve_type", + "phase_config", + "reserve", + "supply", + "token_issuer_code_id" + ], + "properties": { + "curve_type": { + "description": "Curve type for this contract", + "allOf": [ + { + "$ref": "#/definitions/CurveType" + } + ] + }, + "funding_pool_forwarding": { + "description": "An optional address for automatically forwarding funding pool gains", + "type": [ + "string", + "null" + ] + }, + "hatcher_allowlist": { + "description": "TODO different ways of doing this, for example DAO members? Using a whitelist contract? Merkle tree? Hatcher allowlist", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/HatcherAllowlistEntryMsg" + } + }, + "phase_config": { + "description": "Hatch configuration information", + "allOf": [ + { + "$ref": "#/definitions/CommonsPhaseConfig" + } + ] + }, + "reserve": { + "description": "Reserve token information", + "allOf": [ + { + "$ref": "#/definitions/ReserveToken" + } + ] + }, + "supply": { + "description": "Supply token information", + "allOf": [ + { + "$ref": "#/definitions/SupplyToken" + } + ] + }, + "token_issuer_code_id": { + "description": "The code id of the cw-tokenfactory-issuer contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "MinMax": { + "description": "Struct for minimum and maximum values", + "type": "object", + "required": [ + "max", + "min" + ], + "properties": { + "max": { + "$ref": "#/definitions/Uint128" + }, + "min": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "NewDenomMetadata": { + "type": "object", + "required": [ + "description", + "display", + "name", + "symbol" + ], + "properties": { + "additional_denom_units": { + "description": "Used define additional units of the token (e.g. \"tiger\") These must have an exponent larger than 0.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/DenomUnit" + } + }, + "description": { + "description": "The description of the token", + "type": "string" + }, + "display": { + "description": "The unit commonly used in communication (e.g. \"cat\")", + "type": "string" + }, + "name": { + "description": "The name of the token (e.g. \"Cat Coin\")", + "type": "string" + }, + "symbol": { + "description": "The ticker symbol of the token (e.g. \"CAT\")", + "type": "string" + } + }, + "additionalProperties": false + }, + "OpenConfig": { + "type": "object", + "required": [ + "entry_fee", + "exit_fee" + ], + "properties": { + "entry_fee": { + "description": "Percentage of capital put into the Reserve Pool during the Open phase when buying from the curve.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "exit_fee": { + "description": "Exit taxation ratio", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "ReserveToken": { + "type": "object", + "required": [ + "decimals", + "denom" + ], + "properties": { + "decimals": { + "description": "Number of decimal places for the reserve token, needed for proper curve math. Same format as decimals above, eg. if it is uatom, where 1 unit is 10^-6 ATOM, use 6 here", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "denom": { + "description": "Reserve token denom (only support native for now)", + "type": "string" + } + }, + "additionalProperties": false + }, + "SupplyToken": { + "type": "object", + "required": [ + "decimals", + "subdenom" + ], + "properties": { + "decimals": { + "description": "Number of decimal places for the supply token, needed for proper curve math. Default for token factory is 6", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "max_supply": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "metadata": { + "description": "Metadata for the supply token to create", + "anyOf": [ + { + "$ref": "#/definitions/NewDenomMetadata" + }, + { + "type": "null" + } + ] + }, + "subdenom": { + "description": "The denom to create for the supply token", + "type": "string" + } + }, + "additionalProperties": false + }, + "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" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "info" + ], + "properties": { + "info": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "daos" + ], + "properties": { + "daos": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": null, + "sudo": null, + "responses": { + "daos": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_Addr", + "type": "array", + "items": { + "$ref": "#/definitions/Addr" + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, + "info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InfoResponse", + "type": "object", + "required": [ + "info" + ], + "properties": { + "info": { + "$ref": "#/definitions/ContractVersion" + } + }, + "additionalProperties": false, + "definitions": { + "ContractVersion": { + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false + } + } + } + } +} diff --git a/contracts/external/dao-abc-factory/src/contract.rs b/contracts/external/dao-abc-factory/src/contract.rs new file mode 100644 index 000000000..b2836742f --- /dev/null +++ b/contracts/external/dao-abc-factory/src/contract.rs @@ -0,0 +1,187 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, Reply, + Response, StdResult, SubMsg, WasmMsg, +}; +use cw2::set_contract_version; +use cw_abc::msg::{ + DenomResponse, ExecuteMsg as AbcExecuteMsg, InstantiateMsg as AbcInstantiateMsg, + QueryMsg as AbcQueryMsg, +}; +use cw_storage_plus::{Bound, Item, Map}; +use cw_utils::parse_reply_instantiate_data; +use dao_interface::{ + state::ModuleInstantiateCallback, token::TokenFactoryCallback, + voting::Query as VotingModuleQueryMsg, +}; + +use crate::{ + error::ContractError, + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, +}; + +const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +const INSTANTIATE_ABC_REPLY_ID: u64 = 1; + +const DAOS: Map = Map::new("daos"); +const CURRENT_DAO: Item = Item::new("current_dao"); +const VOTING_MODULE: Item = Item::new("voting_module"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Response::new().add_attribute("method", "instantiate")) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::AbcFactory { + code_id, + instantiate_msg, + } => execute_token_factory_factory(deps, env, info, code_id, instantiate_msg), + } +} + +pub fn execute_token_factory_factory( + deps: DepsMut, + _env: Env, + info: MessageInfo, + code_id: u64, + msg: AbcInstantiateMsg, +) -> Result { + // Save voting module address + VOTING_MODULE.save(deps.storage, &info.sender)?; + + // Query for DAO + let dao: Addr = deps + .querier + .query_wasm_smart(info.sender, &VotingModuleQueryMsg::Dao {})?; + + DAOS.save(deps.storage, dao.clone(), &Empty {})?; + CURRENT_DAO.save(deps.storage, &dao)?; + + // Instantiate new contract, further setup is handled in the + // SubMsg reply. + let msg = SubMsg::reply_on_success( + WasmMsg::Instantiate { + // No admin as we want the bonding curve contract to be immutable + admin: None, + code_id, + msg: to_json_binary(&msg)?, + funds: vec![], + label: "cw_abc".to_string(), + }, + INSTANTIATE_ABC_REPLY_ID, + ); + + Ok(Response::new().add_submessage(msg)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Info {} => query_info(deps), + QueryMsg::Daos { start_after, limit } => query_daos(deps, start_after, limit), + } +} + +pub fn query_info(deps: Deps) -> StdResult { + let info = cw2::get_contract_version(deps.storage)?; + to_json_binary(&dao_interface::voting::InfoResponse { info }) +} + +pub fn query_daos( + deps: Deps, + start_after: Option, + limit: Option, +) -> StdResult { + to_json_binary( + &DAOS + .keys( + deps.storage, + None, + start_after + .map(|s| deps.api.addr_validate(&s)) + .transpose()? + .map(Bound::exclusive), + Order::Descending, + ) + .take(limit.unwrap_or(25) as usize) + .collect::>>()?, + ) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { + match msg.id { + INSTANTIATE_ABC_REPLY_ID => { + // Load DAO + let dao = CURRENT_DAO.load(deps.storage)?; + + // Parse issuer address from instantiate reply + let abc_addr = parse_reply_instantiate_data(msg)?.contract_address; + + // Query for denom + let denom: DenomResponse = deps + .querier + .query_wasm_smart(abc_addr.clone(), &AbcQueryMsg::Denom {})?; + + // Query for token contract + let token_contract: Addr = deps + .querier + .query_wasm_smart(abc_addr.clone(), &AbcQueryMsg::TokenContract {})?; + + // Update the owner to be the DAO + let msg = WasmMsg::Execute { + contract_addr: abc_addr.clone(), + msg: to_json_binary(&AbcExecuteMsg::UpdateOwnership( + cw_ownable::Action::TransferOwnership { + new_owner: dao.to_string(), + expiry: None, + }, + ))?, + funds: vec![], + }; + + // DAO must accept ownership transfer. Here we include a + // ModuleInstantiateCallback message that will be called by the + // dao-dao-core contract when voting module instantiation is + // complete. + let callback = ModuleInstantiateCallback { + msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: abc_addr.clone(), + msg: to_json_binary(&AbcExecuteMsg::UpdateOwnership( + cw_ownable::Action::AcceptOwnership {}, + ))?, + funds: vec![], + })], + }; + + // Responses for `dao-voting-token-staked` MUST include a + // TokenFactoryCallback. + Ok(Response::new() + .add_message(msg) + .set_data(to_json_binary(&TokenFactoryCallback { + denom: denom.denom, + token_contract: Some(token_contract.to_string()), + module_instantiate_callback: Some(callback), + })?)) + } + _ => Err(ContractError::UnknownReplyId { id: msg.id }), + } +} diff --git a/contracts/external/dao-abc-factory/src/error.rs b/contracts/external/dao-abc-factory/src/error.rs new file mode 100644 index 000000000..4a29782c7 --- /dev/null +++ b/contracts/external/dao-abc-factory/src/error.rs @@ -0,0 +1,28 @@ +use cosmwasm_std::StdError; +use cw_utils::{ParseReplyError, PaymentError}; +use dao_voting::threshold::ActiveThresholdError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error(transparent)] + ActiveThresholdError(#[from] ActiveThresholdError), + + #[error(transparent)] + ParseReplyError(#[from] ParseReplyError), + + #[error(transparent)] + PaymentError(#[from] PaymentError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("Got a submessage reply with unknown id: {id}")] + UnknownReplyId { id: u64 }, + + #[error("Factory message must serialize to WasmMsg::Execute")] + UnsupportedFactoryMsg {}, +} diff --git a/contracts/external/dao-abc-factory/src/lib.rs b/contracts/external/dao-abc-factory/src/lib.rs new file mode 100644 index 000000000..286ec8c24 --- /dev/null +++ b/contracts/external/dao-abc-factory/src/lib.rs @@ -0,0 +1,8 @@ +pub mod contract; +mod error; +pub mod msg; + +pub use crate::error::ContractError; + +#[cfg(test)] +mod test_tube; diff --git a/contracts/external/dao-abc-factory/src/msg.rs b/contracts/external/dao-abc-factory/src/msg.rs new file mode 100644 index 000000000..143224330 --- /dev/null +++ b/contracts/external/dao-abc-factory/src/msg.rs @@ -0,0 +1,25 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cw_abc::msg::InstantiateMsg as AbcInstantiateMsg; + +#[cw_serde] +pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + AbcFactory { + instantiate_msg: AbcInstantiateMsg, + code_id: u64, + }, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(dao_interface::voting::InfoResponse)] + Info {}, + #[returns(Vec)] + Daos { + start_after: Option, + limit: Option, + }, +} diff --git a/contracts/external/dao-abc-factory/src/test_tube/integration_tests.rs b/contracts/external/dao-abc-factory/src/test_tube/integration_tests.rs new file mode 100644 index 000000000..5b3bd3126 --- /dev/null +++ b/contracts/external/dao-abc-factory/src/test_tube/integration_tests.rs @@ -0,0 +1,147 @@ +use cosmwasm_std::{coins, Addr, Coin, Uint128}; +use cw_ownable::Ownership; +use dao_interface::voting::{DenomResponse, IsActiveResponse, VotingPowerAtHeightResponse}; +use dao_voting_token_staked::msg::{ + ExecuteMsg as VotingTokenExecuteMsg, QueryMsg as VotingTokenQueryMsg, +}; +use osmosis_test_tube::{Account, OsmosisTestApp}; + +use super::test_env::{TestEnv, TestEnvBuilder, RESERVE}; + +#[test] +fn test_full_integration_correct_setup() { + let app = OsmosisTestApp::new(); + let env = TestEnvBuilder::new(); + let TestEnv { + dao, + tf_issuer, + cw_abc, + vp_contract, + .. + } = env.full_dao_setup(&app); + + // Issuer owner should be set to the abc contract + let issuer_admin = tf_issuer + .query::>(&cw_tokenfactory_issuer::msg::QueryMsg::Ownership {}) + .unwrap() + .owner; + assert_eq!( + issuer_admin, + Some(Addr::unchecked(cw_abc.contract_addr.clone())) + ); + + // Abc contract should have DAO as owner + let abc_admin = cw_abc + .query::>(&cw_abc::msg::QueryMsg::Ownership {}) + .unwrap() + .owner; + assert_eq!( + abc_admin, + Some(Addr::unchecked(dao.unwrap().contract_addr.clone())) + ); + + let issuer_denom = tf_issuer + .query::( + &cw_tokenfactory_issuer::msg::QueryMsg::Denom {}, + ) + .unwrap() + .denom; + + let abc_denom = cw_abc + .query::(&cw_abc::msg::QueryMsg::Denom {}) + .unwrap() + .denom; + + let vp_denom = vp_contract + .query::(&VotingTokenQueryMsg::Denom {}) + .unwrap() + .denom; + + // Denoms for contracts should be the same + assert_eq!(issuer_denom, abc_denom); + assert_eq!(issuer_denom, vp_denom); +} + +#[test] +fn test_stake_unstake_new_denom() { + let app = OsmosisTestApp::new(); + let env = TestEnvBuilder::new(); + let TestEnv { + vp_contract, + accounts, + cw_abc, + .. + } = env.full_dao_setup(&app); + + let denom = vp_contract + .query::(&VotingTokenQueryMsg::Denom {}) + .unwrap() + .denom; + + // Buy tokens off of bonding curve + cw_abc + .execute( + &cw_abc::msg::ExecuteMsg::Buy {}, + &coins(100000, RESERVE), + &accounts[0], + ) + .unwrap(); + + // Stake 100 tokens + let stake_msg = VotingTokenExecuteMsg::Stake {}; + vp_contract + .execute(&stake_msg, &[Coin::new(100, denom)], &accounts[0]) + .unwrap(); + + app.increase_time(1); + + // Query voting power + let voting_power: VotingPowerAtHeightResponse = vp_contract + .query(&VotingTokenQueryMsg::VotingPowerAtHeight { + address: accounts[0].address(), + height: None, + }) + .unwrap(); + assert_eq!(voting_power.power, Uint128::new(100)); + + // DAO is active (default threshold is absolute count of 75) + let active = vp_contract + .query::(&VotingTokenQueryMsg::IsActive {}) + .unwrap() + .active; + assert!(active); + + // Unstake 50 tokens + let unstake_msg = VotingTokenExecuteMsg::Unstake { + amount: Uint128::new(50), + }; + vp_contract + .execute(&unstake_msg, &[], &accounts[0]) + .unwrap(); + app.increase_time(1); + let voting_power: VotingPowerAtHeightResponse = vp_contract + .query(&VotingTokenQueryMsg::VotingPowerAtHeight { + address: accounts[0].address(), + height: None, + }) + .unwrap(); + assert_eq!(voting_power.power, Uint128::new(50)); + + // DAO is not active + let active = vp_contract + .query::(&VotingTokenQueryMsg::IsActive {}) + .unwrap() + .active; + assert!(!active); + + // Can't claim before unstaking period (2 seconds) + vp_contract + .execute(&VotingTokenExecuteMsg::Claim {}, &[], &accounts[0]) + .unwrap_err(); + + // Pass time, unstaking duration is set to 2 seconds + app.increase_time(5); + vp_contract + .execute(&VotingTokenExecuteMsg::Claim {}, &[], &accounts[0]) + .unwrap(); +} diff --git a/contracts/external/dao-abc-factory/src/test_tube/mod.rs b/contracts/external/dao-abc-factory/src/test_tube/mod.rs new file mode 100644 index 000000000..796c18a34 --- /dev/null +++ b/contracts/external/dao-abc-factory/src/test_tube/mod.rs @@ -0,0 +1,9 @@ +// Ignore integration tests for code coverage since there will be problems with dynamic linking libosmosistesttube +// and also, tarpaulin will not be able read coverage out of wasm binary anyway +#![cfg(not(tarpaulin))] + +#[cfg(feature = "test-tube")] +mod integration_tests; + +#[cfg(feature = "test-tube")] +mod test_env; diff --git a/contracts/external/dao-abc-factory/src/test_tube/test_env.rs b/contracts/external/dao-abc-factory/src/test_tube/test_env.rs new file mode 100644 index 000000000..d57f6d57b --- /dev/null +++ b/contracts/external/dao-abc-factory/src/test_tube/test_env.rs @@ -0,0 +1,558 @@ +// The code is used in tests but reported as dead code +// see https://github.com/rust-lang/rust/issues/46379 +#![allow(dead_code)] + +use crate::{ + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + ContractError, +}; + +use cosmwasm_std::{to_json_binary, Addr, Coin, Decimal, Uint128, WasmMsg}; +use cw_abc::abc::{ + ClosedConfig, CommonsPhaseConfig, CurveType, HatchConfig, MinMax, OpenConfig, ReserveToken, + SupplyToken, +}; +use cw_utils::Duration; +use dao_interface::{ + msg::QueryMsg as DaoQueryMsg, + state::{Admin, ModuleInstantiateInfo, ProposalModule}, +}; +use dao_voting::{ + pre_propose::PreProposeInfo, threshold::PercentageThreshold, threshold::Threshold, +}; +use dao_voting_token_staked::msg::{QueryMsg as TokenVotingQueryMsg, TokenInfo}; + +use dao_testing::test_tube::{ + cw_abc::CwAbc, cw_tokenfactory_issuer::TokenfactoryIssuer, dao_dao_core::DaoCore, + dao_proposal_single::DaoProposalSingle, dao_voting_token_staked::TokenVotingContract, +}; +use dao_voting::threshold::ActiveThreshold; +use osmosis_test_tube::{ + osmosis_std::types::{ + cosmos::bank::v1beta1::QueryAllBalancesRequest, + cosmwasm::wasm::v1::MsgExecuteContractResponse, + }, + Account, Bank, Module, OsmosisTestApp, RunnerError, RunnerExecuteResult, RunnerResult, + SigningAccount, Wasm, +}; +use serde::de::DeserializeOwned; +use std::path::PathBuf; + +pub const DENOM: &str = "ucat"; +pub const JUNO: &str = "ujuno"; + +// Needs to match what's configured for test-tube +pub const RESERVE: &str = "uosmo"; + +pub struct TestEnv<'a> { + pub app: &'a OsmosisTestApp, + pub dao: Option>, + pub proposal_single: Option>, + pub vp_contract: TokenVotingContract<'a>, + pub tf_issuer: TokenfactoryIssuer<'a>, + pub dao_abc_factory: AbcFactoryContract<'a>, + pub accounts: Vec, + pub cw_abc: CwAbc<'a>, +} + +impl<'a> TestEnv<'a> { + pub fn get_tf_issuer_code_id(&self) -> u64 { + self.tf_issuer.code_id + } + + pub fn bank(&self) -> Bank<'_, OsmosisTestApp> { + Bank::new(self.app) + } + + pub fn assert_account_balances( + &self, + account: SigningAccount, + expected_balances: Vec, + ignore_denoms: Vec<&str>, + ) { + let account_balances: Vec = Bank::new(self.app) + .query_all_balances(&QueryAllBalancesRequest { + address: account.address(), + pagination: None, + }) + .unwrap() + .balances + .into_iter() + .map(|coin| Coin::new(coin.amount.parse().unwrap(), coin.denom)) + .filter(|coin| !ignore_denoms.contains(&coin.denom.as_str())) + .collect(); + + assert_eq!(account_balances, expected_balances); + } + + pub fn assert_contract_balances(&self, expected_balances: &[Coin]) { + let contract_balances: Vec = Bank::new(self.app) + .query_all_balances(&QueryAllBalancesRequest { + address: self.vp_contract.contract_addr.clone(), + pagination: None, + }) + .unwrap() + .balances + .into_iter() + .map(|coin| Coin::new(coin.amount.parse().unwrap(), coin.denom)) + .collect(); + + assert_eq!(contract_balances, expected_balances); + } +} + +pub struct TestEnvBuilder { + pub accounts: Vec, + pub instantiate_msg: Option, +} + +impl TestEnvBuilder { + pub fn new() -> Self { + Self { + accounts: vec![], + instantiate_msg: None, + } + } + + // Minimal default setup with just the key contracts + pub fn default_setup(self, app: &'_ OsmosisTestApp) -> TestEnv<'_> { + let accounts = app + .init_accounts(&[Coin::new(1000000000000000u128, "uosmo")], 10) + .unwrap(); + + let issuer_id = TokenfactoryIssuer::upload(app, &accounts[0]).unwrap(); + let abc_id = CwAbc::upload(app, &accounts[0]).unwrap(); + + // Upload and instantiate abc factory + let dao_abc_factory = + AbcFactoryContract::new(app, &InstantiateMsg {}, &accounts[0]).unwrap(); + + let vp_contract = TokenVotingContract::new( + app, + &dao_voting_token_staked::msg::InstantiateMsg { + token_info: TokenInfo::Factory( + to_json_binary(&WasmMsg::Execute { + contract_addr: dao_abc_factory.contract_addr.clone(), + msg: to_json_binary(&ExecuteMsg::AbcFactory { + instantiate_msg: cw_abc::msg::InstantiateMsg { + token_issuer_code_id: issuer_id, + funding_pool_forwarding: Some(accounts[0].address()), + supply: SupplyToken { + subdenom: DENOM.to_string(), + metadata: None, + decimals: 6, + max_supply: Some(Uint128::from(1000000000u128)), + }, + reserve: ReserveToken { + denom: RESERVE.to_string(), + decimals: 6, + }, + phase_config: CommonsPhaseConfig { + hatch: HatchConfig { + contribution_limits: MinMax { + min: Uint128::from(10u128), + max: Uint128::from(1000000u128), + }, + initial_raise: MinMax { + min: Uint128::from(10u128), + max: Uint128::from(1000000u128), + }, + entry_fee: Decimal::percent(10u64), + }, + open: OpenConfig { + entry_fee: Decimal::percent(10u64), + exit_fee: Decimal::percent(10u64), + }, + closed: ClosedConfig {}, + }, + hatcher_allowlist: None, + curve_type: CurveType::Constant { + value: Uint128::one(), + scale: 1, + }, + }, + code_id: abc_id, + }) + .unwrap(), + funds: vec![], + }) + .unwrap(), + ), + unstaking_duration: Some(Duration::Time(2)), + active_threshold: Some(ActiveThreshold::AbsoluteCount { + count: Uint128::new(75), + }), + }, + &accounts[0], + ) + .unwrap(); + + let issuer_addr = + TokenVotingContract::query(&vp_contract, &TokenVotingQueryMsg::TokenContract {}) + .unwrap(); + + let tf_issuer = TokenfactoryIssuer::new_with_values(app, issuer_id, issuer_addr).unwrap(); + + // The abc contract is the owner of the issuer + let abc_addr = tf_issuer + .query::>( + &cw_tokenfactory_issuer::msg::QueryMsg::Ownership {}, + ) + .unwrap() + .owner; + let cw_abc = CwAbc::new_with_values(app, abc_id, abc_addr.unwrap().to_string()).unwrap(); + + TestEnv { + app, + accounts, + cw_abc, + dao: None, + proposal_single: None, + tf_issuer, + vp_contract, + dao_abc_factory, + } + } + + // Full DAO setup + pub fn full_dao_setup(self, app: &'_ OsmosisTestApp) -> TestEnv<'_> { + let accounts = app + .init_accounts(&[Coin::new(1000000000000000u128, "uosmo")], 10) + .unwrap(); + + // Upload all needed code ids + let issuer_id = TokenfactoryIssuer::upload(app, &accounts[0]).unwrap(); + let vp_contract_id = TokenVotingContract::upload(app, &accounts[0]).unwrap(); + let proposal_single_id = DaoProposalSingle::upload(app, &accounts[0]).unwrap(); + let abc_id = CwAbc::upload(app, &accounts[0]).unwrap(); + + // Upload and instantiate abc factory + let dao_abc_factory = + AbcFactoryContract::new(app, &InstantiateMsg {}, &accounts[0]).unwrap(); + + let msg = dao_interface::msg::InstantiateMsg { + dao_uri: None, + admin: None, + name: "DAO DAO".to_string(), + description: "A DAO that makes DAO tooling".to_string(), + image_url: None, + automatically_add_cw20s: false, + automatically_add_cw721s: false, + voting_module_instantiate_info: ModuleInstantiateInfo { + code_id: vp_contract_id, + msg: to_json_binary(&dao_voting_token_staked::msg::InstantiateMsg { + token_info: TokenInfo::Factory( + to_json_binary(&WasmMsg::Execute { + contract_addr: dao_abc_factory.contract_addr.clone(), + msg: to_json_binary(&ExecuteMsg::AbcFactory { + instantiate_msg: cw_abc::msg::InstantiateMsg { + token_issuer_code_id: issuer_id, + funding_pool_forwarding: Some(accounts[0].address()), + supply: SupplyToken { + subdenom: DENOM.to_string(), + metadata: None, + decimals: 6, + max_supply: Some(Uint128::from(1000000000u128)), + }, + reserve: ReserveToken { + denom: RESERVE.to_string(), + decimals: 6, + }, + phase_config: CommonsPhaseConfig { + hatch: HatchConfig { + contribution_limits: MinMax { + min: Uint128::from(10u128), + max: Uint128::from(1000000u128), + }, + initial_raise: MinMax { + min: Uint128::from(10u128), + max: Uint128::from(1000000u128), + }, + entry_fee: Decimal::percent(10u64), + }, + open: OpenConfig { + entry_fee: Decimal::percent(10u64), + exit_fee: Decimal::percent(10u64), + }, + closed: ClosedConfig {}, + }, + hatcher_allowlist: None, + curve_type: CurveType::Constant { + value: Uint128::one(), + scale: 1, + }, + }, + code_id: abc_id, + }) + .unwrap(), + funds: vec![], + }) + .unwrap(), + ), + unstaking_duration: Some(Duration::Time(2)), + active_threshold: Some(ActiveThreshold::AbsoluteCount { + count: Uint128::new(75), + }), + }) + .unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "DAO DAO Voting Module".to_string(), + }, + proposal_modules_instantiate_info: vec![ModuleInstantiateInfo { + code_id: proposal_single_id, + msg: to_json_binary(&dao_proposal_single::msg::InstantiateMsg { + min_voting_period: None, + threshold: Threshold::ThresholdQuorum { + threshold: PercentageThreshold::Majority {}, + quorum: PercentageThreshold::Percent(Decimal::percent(35)), + }, + max_voting_period: Duration::Time(432000), + allow_revoting: false, + only_members_execute: true, + close_proposal_on_execution_failure: false, + pre_propose_info: PreProposeInfo::AnyoneMayPropose {}, + veto: None, + }) + .unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "DAO DAO Proposal Module".to_string(), + }], + initial_items: None, + }; + + // Instantiate DAO + let dao = DaoCore::new(app, &msg, &accounts[0], &[]).unwrap(); + + // Get voting module address, setup vp_contract helper + let vp_addr: Addr = dao.query(&DaoQueryMsg::VotingModule {}).unwrap(); + let vp_contract = + TokenVotingContract::new_with_values(app, vp_contract_id, vp_addr.to_string()).unwrap(); + + // Get proposal module address, setup proposal_single helper + let proposal_modules: Vec = dao + .query(&DaoQueryMsg::ProposalModules { + limit: None, + start_after: None, + }) + .unwrap(); + let proposal_single = DaoProposalSingle::new_with_values( + app, + proposal_single_id, + proposal_modules[0].address.to_string(), + ) + .unwrap(); + + // Get issuer address, setup tf_issuer helper + let issuer_addr = + TokenVotingContract::query(&vp_contract, &TokenVotingQueryMsg::TokenContract {}) + .unwrap(); + let tf_issuer = TokenfactoryIssuer::new_with_values(app, issuer_id, issuer_addr).unwrap(); + + // Get ABC Contract address + // The abc contract is the owner of the issuer + let abc_addr = tf_issuer + .query::>( + &cw_tokenfactory_issuer::msg::QueryMsg::Ownership {}, + ) + .unwrap() + .owner; + let cw_abc = CwAbc::new_with_values(app, abc_id, abc_addr.unwrap().to_string()).unwrap(); + + TestEnv { + app, + dao: Some(dao), + cw_abc, + vp_contract, + proposal_single: Some(proposal_single), + tf_issuer, + accounts, + dao_abc_factory, + } + } + + pub fn upload_issuer(self, app: &'_ OsmosisTestApp, signer: &SigningAccount) -> u64 { + TokenfactoryIssuer::upload(app, signer).unwrap() + } + + pub fn set_accounts(mut self, accounts: Vec) -> Self { + self.accounts = accounts; + self + } + + pub fn with_account(mut self, account: SigningAccount) -> Self { + self.accounts.push(account); + self + } + + pub fn with_instantiate_msg(mut self, msg: InstantiateMsg) -> Self { + self.instantiate_msg = Some(msg); + self + } +} + +#[derive(Debug)] +pub struct AbcFactoryContract<'a> { + pub app: &'a OsmosisTestApp, + pub contract_addr: String, + pub code_id: u64, +} + +impl<'a> AbcFactoryContract<'a> { + pub fn new( + app: &'a OsmosisTestApp, + instantiate_msg: &InstantiateMsg, + signer: &SigningAccount, + ) -> Result { + let wasm = Wasm::new(app); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + let contract_addr = wasm + .instantiate( + code_id, + &instantiate_msg, + Some(&signer.address()), + None, + &[], + signer, + )? + .data + .address; + + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + pub fn new_with_values( + app: &'a OsmosisTestApp, + code_id: u64, + contract_addr: String, + ) -> Result { + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + /// uploads contract and returns a code ID + pub fn upload(app: &OsmosisTestApp, signer: &SigningAccount) -> Result { + let wasm = Wasm::new(app); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + Ok(code_id) + } + + pub fn instantiate( + app: &'a OsmosisTestApp, + code_id: u64, + instantiate_msg: &InstantiateMsg, + signer: &SigningAccount, + ) -> Result { + let wasm = Wasm::new(app); + let contract_addr = wasm + .instantiate( + code_id, + &instantiate_msg, + Some(&signer.address()), + None, + &[], + signer, + )? + .data + .address; + + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + pub fn execute( + &self, + msg: &ExecuteMsg, + funds: &[Coin], + signer: &SigningAccount, + ) -> RunnerExecuteResult { + let wasm = Wasm::new(self.app); + wasm.execute(&self.contract_addr, msg, funds, signer) + } + + pub fn query(&self, msg: &QueryMsg) -> RunnerResult + where + T: ?Sized + DeserializeOwned, + { + let wasm = Wasm::new(self.app); + wasm.query(&self.contract_addr, msg) + } + + fn get_wasm_byte_code() -> Vec { + let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let byte_code = std::fs::read( + manifest_path + .join("..") + .join("..") + .join("..") + .join("artifacts") + .join("dao_abc_factory.wasm"), + ); + match byte_code { + Ok(byte_code) => byte_code, + // On arm processors, the above path is not found, so we try the following path + Err(_) => std::fs::read( + manifest_path + .join("..") + .join("..") + .join("..") + .join("artifacts") + .join("dao_abc_factory-aarch64.wasm"), + ) + .unwrap(), + } + } + + pub fn execute_error(err: ContractError) -> RunnerError { + RunnerError::ExecuteError { + msg: format!( + "failed to execute message; message index: 0: {}: execute wasm contract failed", + err + ), + } + } + + pub fn execute_submessage_error(err: ContractError) -> RunnerError { + RunnerError::ExecuteError { + msg: format!( + "failed to execute message; message index: 0: dispatch: submessages: reply: {}: execute wasm contract failed", + err + ), + } + } +} + +pub fn assert_contract_err(expected: ContractError, actual: RunnerError) { + match actual { + RunnerError::ExecuteError { msg } => { + if !msg.contains(&expected.to_string()) { + panic!( + "assertion failed:\n\n must contain \t: \"{}\",\n actual \t: \"{}\"\n", + expected, msg + ) + } + } + _ => panic!("unexpected error, expect execute error but got: {}", actual), + }; +} diff --git a/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json b/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json index fdd578d12..1cabb5355 100644 --- a/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json +++ b/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json @@ -32,7 +32,7 @@ ] }, "min_voting_period": { - "description": "The minimum amount of time a proposal must be open before passing. A proposal may fail before this amount of time has elapsed, but it will not pass. This can be useful for preventing governance attacks wherein an attacker aquires a large number of tokens and forces a proposal through.", + "description": "The minimum amount of time a proposal must be open before passing. A proposal may fail before this amount of time has elapsed, but it will not pass. This can be useful for preventing governance attacks wherein an attacker acquires a large number of tokens and forces a proposal through.", "anyOf": [ { "$ref": "#/definitions/Duration" diff --git a/contracts/proposal/dao-proposal-single/src/msg.rs b/contracts/proposal/dao-proposal-single/src/msg.rs index dd500f1eb..d6e38cf12 100644 --- a/contracts/proposal/dao-proposal-single/src/msg.rs +++ b/contracts/proposal/dao-proposal-single/src/msg.rs @@ -16,7 +16,7 @@ pub struct InstantiateMsg { /// The minimum amount of time a proposal must be open before /// passing. A proposal may fail before this amount of time has /// elapsed, but it will not pass. This can be useful for - /// preventing governance attacks wherein an attacker aquires a + /// preventing governance attacks wherein an attacker acquires a /// large number of tokens and forces a proposal through. pub min_voting_period: Option, /// If set to true only members may execute passed diff --git a/contracts/proposal/dao-proposal-single/src/proposal.rs b/contracts/proposal/dao-proposal-single/src/proposal.rs index a597f3754..1fd483446 100644 --- a/contracts/proposal/dao-proposal-single/src/proposal.rs +++ b/contracts/proposal/dao-proposal-single/src/proposal.rs @@ -184,7 +184,7 @@ impl SingleChoiceProposal { // and there are possible votes, then this is // rejected if there is a single no vote. // - // We need this check becuase otherwise when + // We need this check because otherwise when // we invert the threshold (`Decimal::one() - // threshold`) we get a 0% requirement for no // votes. Zero no votes do indeed meet a 0% @@ -217,7 +217,7 @@ impl SingleChoiceProposal { // and there are possible votes, then this is // rejected if there is a single no vote. // - // We need this check becuase + // We need this check because // otherwise when we invert the // threshold (`Decimal::one() - // threshold`) we get a 0% requirement @@ -954,7 +954,7 @@ mod test { )); // Total power of 33. 13 total votes. 8 no votes, 3 yes, 2 // abstain. 39.3% turnout. Expired. As it is expired we see if - // the 8 no votes excede the 50% failing threshold, which they + // the 8 no votes exceed the 50% failing threshold, which they // do. assert!(check_is_rejected( quorum.clone(), @@ -980,7 +980,7 @@ mod test { // Over quorum, but under threshold fails if the proposal is // not expired. If the proposal is expired though it passes as // the total vote count used is the number of votes, and not - // the total number of votes avaliable. + // the total number of votes available. assert!(check_is_rejected( quorum.clone(), failing.clone(), diff --git a/contracts/test/dao-proposal-hook-counter/src/msg.rs b/contracts/test/dao-proposal-hook-counter/src/msg.rs index 9a4a6f5e6..a23c5aded 100644 --- a/contracts/test/dao-proposal-hook-counter/src/msg.rs +++ b/contracts/test/dao-proposal-hook-counter/src/msg.rs @@ -1,4 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +#[allow(unused_imports)] use cosmwasm_std::Uint128; use dao_hooks::{proposal::ProposalHookMsg, stake::StakeChangedHookMsg, vote::VoteHookMsg}; diff --git a/contracts/voting/dao-voting-cw20-staked/src/msg.rs b/contracts/voting/dao-voting-cw20-staked/src/msg.rs index 0031d0deb..e9f4d51f9 100644 --- a/contracts/voting/dao-voting-cw20-staked/src/msg.rs +++ b/contracts/voting/dao-voting-cw20-staked/src/msg.rs @@ -5,6 +5,7 @@ use cw20_base::msg::InstantiateMarketingInfo; use cw_utils::Duration; use dao_dao_macros::{active_query, cw20_token_query, voting_module_query}; +#[allow(unused_imports)] use dao_voting::threshold::{ActiveThreshold, ActiveThresholdResponse}; /// Information about the staking contract to be used with this voting diff --git a/contracts/voting/dao-voting-cw721-staked/src/msg.rs b/contracts/voting/dao-voting-cw721-staked/src/msg.rs index d318ddb48..657d5b9d7 100644 --- a/contracts/voting/dao-voting-cw721-staked/src/msg.rs +++ b/contracts/voting/dao-voting-cw721-staked/src/msg.rs @@ -3,6 +3,7 @@ use cosmwasm_std::Binary; use cw721::Cw721ReceiveMsg; use cw_utils::Duration; use dao_dao_macros::{active_query, voting_module_query}; +#[allow(unused_imports)] use dao_voting::threshold::{ActiveThreshold, ActiveThresholdResponse}; #[cw_serde] diff --git a/contracts/voting/dao-voting-cw721-staked/src/testing/integration_tests.rs b/contracts/voting/dao-voting-cw721-staked/src/testing/integration_tests.rs index aedf0ca32..bc598f624 100644 --- a/contracts/voting/dao-voting-cw721-staked/src/testing/integration_tests.rs +++ b/contracts/voting/dao-voting-cw721-staked/src/testing/integration_tests.rs @@ -128,7 +128,7 @@ fn test_full_integration_with_factory() { // Error is insufficient funds as no funds were sent assert_eq!( RunnerError::ExecuteError { - msg: "failed to execute message; message index: 0: dispatch: submessages: 0uosmo is smaller than 1000uosmo: insufficient funds".to_string() + msg: "failed to execute message; message index: 0: dispatch: submessages: spendable balance is smaller than 1000uosmo: insufficient funds".to_string() }, err ); diff --git a/contracts/voting/dao-voting-token-staked/src/contract.rs b/contracts/voting/dao-voting-token-staked/src/contract.rs index c8c0e883e..73e95208e 100644 --- a/contracts/voting/dao-voting-token-staked/src/contract.rs +++ b/contracts/voting/dao-voting-token-staked/src/contract.rs @@ -34,15 +34,15 @@ use dao_voting::{ }, }; -use crate::error::ContractError; use crate::msg::{ ExecuteMsg, GetHooksResponse, InstantiateMsg, ListStakersResponse, MigrateMsg, QueryMsg, - StakerBalanceResponse, TokenInfo, + StakerBalanceResponse, }; use crate::state::{ Config, ACTIVE_THRESHOLD, CLAIMS, CONFIG, DAO, DENOM, HOOKS, MAX_CLAIMS, STAKED_BALANCES, STAKED_TOTAL, TOKEN_INSTANTIATION_INFO, TOKEN_ISSUER_CONTRACT, }; +use crate::{error::ContractError, msg::TokenInfo}; pub(crate) const CONTRACT_NAME: &str = "crates.io:dao-voting-token-staked"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -139,10 +139,10 @@ pub fn instantiate( funds, } => { // Call factory contract. Use only a trusted factory contract, - // as this is a critical security component and valdiation of + // as this is a critical security component and validation of // setup will happen in the factory. Ok(Response::new() - .add_attribute("action", "intantiate") + .add_attribute("action", "instantiate") .add_attribute("token", "custom_factory") .add_submessage(SubMsg::reply_on_success( WasmMsg::Execute { @@ -633,7 +633,8 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result Result TokenVotingContract<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("token_voting"), &[], signer, )? @@ -398,7 +398,7 @@ impl<'a> TokenVotingContract<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("token_voting_contract"), &[], signer, )? diff --git a/packages/cw-curves/Cargo.toml b/packages/cw-curves/Cargo.toml new file mode 100644 index 000000000..1353e7ab1 --- /dev/null +++ b/packages/cw-curves/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "cw-curves" +authors = [ + "Ethan Frey ", + "Jake Hartnell", + "Adair ", + "Gabe ", +] +description = "A package for defining curves to be used in augmented bonding curves." +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +rust_decimal = { workspace = true } +integer-sqrt = { workspace = true } +integer-cbrt = { workspace = true } diff --git a/packages/cw-curves/README.md b/packages/cw-curves/README.md new file mode 100644 index 000000000..9159a1070 --- /dev/null +++ b/packages/cw-curves/README.md @@ -0,0 +1,6 @@ +# CosmWasm Curves + +This package provides the curves to be used for +[cw-abc](../../contracts/external/cw-abc). + +It provides a framework for defining various types of curves, such as constant, linear, and square root curves. The library ensures precision in token operations allowing for the easy implementation of custom curves in CosmWasm-based applications. diff --git a/packages/cw-curves/src/curve.rs b/packages/cw-curves/src/curve.rs new file mode 100644 index 000000000..c89d9eb54 --- /dev/null +++ b/packages/cw-curves/src/curve.rs @@ -0,0 +1,120 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Decimal as StdDecimal, StdError, StdResult, Uint128}; +use rust_decimal::prelude::{FromPrimitive, ToPrimitive}; +use rust_decimal::Decimal; +use std::fmt::Debug; + +/// Defines the interface for bonding curves +pub trait Curve: Debug { + /// Returns the spot price given the supply. + /// + /// This corresponds to `f(x)` in the mathematical representation. + /// + /// # Arguments + /// + /// * `supply` - The current token supply + /// + /// # Returns + /// + /// * `StdResult` - The spot price as a StdDecimal, or an error if the calculation fails + fn spot_price(&self, supply: Uint128) -> StdResult; + + /// Returns the total price paid up to purchase the given supply of tokens. + /// + /// This corresponds to the integral `F(x)` in the mathematical representation. + /// + /// # Arguments + /// + /// * `supply` - The token supply to calculate the reserve for + /// + /// # Returns + /// + /// * `StdResult` - The total reserve amount, or an error if the calculation fails + fn reserve(&self, supply: Uint128) -> StdResult; + + /// Inverse of reserve. Returns how many tokens would be issued for a given reserve amount. + /// + /// This corresponds to `F^-1(x)` in the mathematical representation. + /// + /// # Arguments + /// + /// * `reserve` - The reserve amount to calculate the supply for + /// + /// # Returns + /// + /// * `StdResult` - The token supply, or an error if the calculation fails + fn supply(&self, reserve: Uint128) -> StdResult; +} + +/// DecimalPlaces for normalizing between supply and reserve tokens +#[cw_serde] +#[derive(Copy)] +pub struct DecimalPlaces { + /// Number of decimal places for the supply token + pub supply: u32, + /// Number of decimal places for the reserve token (e.g., 6 for uatom, 9 for nstep, 18 for wei) + pub reserve: u32, +} + +impl DecimalPlaces { + /// Creates a new DecimalPlaces instance + /// + /// # Arguments + /// + /// * `supply` - Number of decimal places for the supply token + /// * `reserve` - Number of decimal places for the reserve token + pub fn new(supply: u8, reserve: u8) -> Self { + DecimalPlaces { + supply: supply as u32, + reserve: reserve as u32, + } + } + + /// Converts a reserve amount from Decimal to Uint128 + pub fn to_reserve(&self, reserve: Decimal) -> StdResult { + let factor = Decimal::from_u128(10u128.pow(self.reserve)) + .ok_or_else(|| StdError::generic_err("Failed to create decimal factor"))?; + reserve + .checked_mul(factor) + .ok_or_else(|| StdError::generic_err("Overflow in reserve calculation"))? + .floor() + .to_u128() + .ok_or_else(|| StdError::generic_err("Overflow in to_reserve conversion")) + .map(Uint128::from) + } + + /// Converts a supply amount from Decimal to Uint128 + pub fn to_supply(&self, supply: Decimal) -> StdResult { + let factor = Decimal::from_u128(10u128.pow(self.supply)) + .ok_or_else(|| StdError::generic_err("Failed to create decimal factor"))?; + supply + .checked_mul(factor) + .ok_or_else(|| StdError::generic_err("Overflow in supply calculation"))? + .floor() + .to_u128() + .ok_or_else(|| StdError::generic_err("Overflow in to_supply conversion")) + .map(Uint128::from) + } + + /// Converts a supply amount from Uint128 to Decimal + pub fn from_supply(&self, supply: Uint128) -> StdResult { + Decimal::from_u128(supply.u128()) + .ok_or_else(|| StdError::generic_err("Failed to convert supply to Decimal"))? + .checked_div( + Decimal::from_u128(10u128.pow(self.supply)) + .ok_or_else(|| StdError::generic_err("Failed to create decimal divisor"))?, + ) + .ok_or_else(|| StdError::generic_err("Division by zero in from_supply")) + } + + /// Converts a reserve amount from Uint128 to Decimal + pub fn from_reserve(&self, reserve: Uint128) -> StdResult { + Decimal::from_u128(reserve.u128()) + .ok_or_else(|| StdError::generic_err("Failed to convert reserve to Decimal"))? + .checked_div( + Decimal::from_u128(10u128.pow(self.reserve)) + .ok_or_else(|| StdError::generic_err("Failed to create decimal divisor"))?, + ) + .ok_or_else(|| StdError::generic_err("Division by zero in from_reserve")) + } +} diff --git a/packages/cw-curves/src/curves/constant.rs b/packages/cw-curves/src/curves/constant.rs new file mode 100644 index 000000000..17a4acc34 --- /dev/null +++ b/packages/cw-curves/src/curves/constant.rs @@ -0,0 +1,86 @@ +use cosmwasm_std::{Decimal as StdDecimal, StdError, StdResult, Uint128}; +use rust_decimal::Decimal; + +use crate::{utils::decimal_to_std, Curve, DecimalPlaces}; + +/// Implements a Constant bonding curve where spot price is always a constant value +#[derive(Debug)] +pub struct Constant { + /// The constant value of the curve + pub value: Decimal, + /// Decimal places for normalization between supply and reserve tokens + pub normalize: DecimalPlaces, +} + +impl Constant { + /// Creates a new Constant curve instance + /// + /// # Arguments + /// + /// * `value` - The constant value of the curve + /// * `normalize` - DecimalPlaces for normalization between supply and reserve tokens + pub fn new(value: Decimal, normalize: DecimalPlaces) -> Self { + Self { value, normalize } + } +} + +impl Curve for Constant { + /// Calculates the spot price, which is always the constant value + /// + /// Note: The value is normalized with the reserve decimal places + /// (e.g., 0.1 value would return 100_000 if reserve was uatom) + /// + /// # Arguments + /// + /// * `_supply` - The current supply (unused in this implementation) + /// + /// # Returns + /// + /// * `StdResult` - The constant spot price as a StdDecimal + fn spot_price(&self, _supply: Uint128) -> StdResult { + // f(x) = self.value + decimal_to_std(self.value) + } + + /// Calculates the total number of reserve tokens needed to purchase a given number of supply tokens + /// + /// Note: Both supply and reserve are normalized internally + /// + /// # Arguments + /// + /// * `supply` - The amount of supply tokens + /// + /// # Returns + /// + /// * `StdResult` - The amount of reserve tokens needed + fn reserve(&self, supply: Uint128) -> StdResult { + // f(x) = supply * self.value + let reserve = self + .normalize + .from_supply(supply)? + .checked_mul(self.value) + .ok_or_else(|| StdError::generic_err("Overflow in reserve calculation"))?; + self.normalize.to_reserve(reserve) + } + + /// Calculates the number of supply tokens that can be purchased with a given amount of reserve tokens + /// + /// # Arguments + /// + /// * `reserve` - The amount of reserve tokens + /// + /// # Returns + /// + /// * `StdResult` - The amount of supply tokens that can be purchased + fn supply(&self, reserve: Uint128) -> StdResult { + // f(x) = reserve / self.value + let supply = self + .normalize + .from_reserve(reserve)? + .checked_div(self.value) + .ok_or_else(|| { + StdError::generic_err("Division by zero or overflow in supply calculation") + })?; + self.normalize.to_supply(supply) + } +} diff --git a/packages/cw-curves/src/curves/linear.rs b/packages/cw-curves/src/curves/linear.rs new file mode 100644 index 000000000..22c6a9780 --- /dev/null +++ b/packages/cw-curves/src/curves/linear.rs @@ -0,0 +1,76 @@ +use cosmwasm_std::{Decimal as StdDecimal, StdError, StdResult, Uint128}; +use rust_decimal::Decimal; + +use crate::{ + utils::{decimal_to_std, square_root}, + Curve, DecimalPlaces, +}; + +/// Implements a Linear bonding curve where spot price is slope * supply +#[derive(Debug)] +pub struct Linear { + /// The slope of the linear curve + pub slope: Decimal, + /// Decimal places for normalization between supply and reserve tokens + pub normalize: DecimalPlaces, +} + +impl Linear { + /// Creates a new Linear curve instance + /// + /// # Arguments + /// + /// * `slope` - The slope of the curve + /// * `normalize` - DecimalPlaces for normalization between supply and reserve tokens + pub fn new(slope: Decimal, normalize: DecimalPlaces) -> Self { + Self { slope, normalize } + } +} + +impl Curve for Linear { + /// Calculates the spot price for a given supply + /// + /// The spot price is calculated as: f(x) = slope * supply + fn spot_price(&self, supply: Uint128) -> StdResult { + let out = self + .normalize + .from_supply(supply)? + .checked_mul(self.slope) + .ok_or_else(|| StdError::generic_err("Overflow in spot price calculation"))?; + decimal_to_std(out) + } + + /// Calculates the reserve for a given supply + /// + /// The reserve is calculated as: f(x) = (slope * supply * supply) / 2 + fn reserve(&self, supply: Uint128) -> StdResult { + let normalized = self.normalize.from_supply(supply)?; + let square = normalized + .checked_mul(normalized) + .ok_or_else(|| StdError::generic_err("Overflow in supply squaring"))?; + // Note: multiplying by 0.5 is much faster than dividing by 2 + let reserve = square + .checked_mul(self.slope) + .and_then(|r| r.checked_mul(Decimal::new(5, 1))) + .ok_or_else(|| StdError::generic_err("Overflow in reserve calculation"))?; + self.normalize.to_reserve(reserve) + } + + /// Calculates the supply for a given reserve + /// + /// The supply is calculated as: f(x) = sqrt(2 * reserve / slope) + fn supply(&self, reserve: Uint128) -> StdResult { + let doubled_reserve = reserve + .checked_add(reserve) + .map_err(|_| StdError::generic_err("Overflow in doubling reserve"))?; + let square = self + .normalize + .from_reserve(doubled_reserve)? + .checked_div(self.slope) + .ok_or_else(|| { + StdError::generic_err("Division by zero or overflow in supply calculation") + })?; + let supply = square_root(square)?; + self.normalize.to_supply(supply) + } +} diff --git a/packages/cw-curves/src/curves/mod.rs b/packages/cw-curves/src/curves/mod.rs new file mode 100644 index 000000000..e25a90429 --- /dev/null +++ b/packages/cw-curves/src/curves/mod.rs @@ -0,0 +1,8 @@ +pub mod constant; +pub use constant::Constant; + +pub mod linear; +pub use linear::Linear; + +pub mod square_root; +pub use square_root::SquareRoot; diff --git a/packages/cw-curves/src/curves/square_root.rs b/packages/cw-curves/src/curves/square_root.rs new file mode 100644 index 000000000..098c9240c --- /dev/null +++ b/packages/cw-curves/src/curves/square_root.rs @@ -0,0 +1,78 @@ +use cosmwasm_std::{Decimal as StdDecimal, StdError, StdResult, Uint128}; +use rust_decimal::Decimal; + +use crate::{ + utils::{cube_root, decimal_to_std, square_root}, + Curve, DecimalPlaces, +}; + +/// Implements a Square Root bonding curve where spot price is slope * (supply)^0.5 +#[derive(Debug)] +pub struct SquareRoot { + /// The slope of the curve + pub slope: Decimal, + /// Decimal places for normalization between supply and reserve tokens + pub normalize: DecimalPlaces, +} + +impl SquareRoot { + /// Creates a new SquareRoot curve instance + /// + /// # Arguments + /// + /// * `slope` - The slope of the curve + /// * `normalize` - DecimalPlaces for normalization between supply and reserve tokens + pub fn new(slope: Decimal, normalize: DecimalPlaces) -> Self { + Self { slope, normalize } + } +} + +impl Curve for SquareRoot { + /// Calculates the spot price for a given supply + /// + /// The spot price is calculated as: f(x) = slope * supply^0.5 + fn spot_price(&self, supply: Uint128) -> StdResult { + let square = self.normalize.from_supply(supply)?; + let root = square_root(square)?; + root.checked_mul(self.slope) + .ok_or_else(|| StdError::generic_err("Overflow in spot price calculation")) + .and_then(decimal_to_std) + } + + /// Calculates the reserve for a given supply + /// + /// The reserve is calculated as: f(x) = (slope * supply * supply^0.5) / 1.5 + fn reserve(&self, supply: Uint128) -> StdResult { + let normalized = self.normalize.from_supply(supply)?; + let root = square_root(normalized)?; + normalized + .checked_mul(root) + .and_then(|r| r.checked_mul(self.slope)) + .and_then(|r| r.checked_div(Decimal::new(15, 1))) + .ok_or_else(|| { + StdError::generic_err("Overflow or division by zero in reserve calculation") + }) + .and_then(|result| self.normalize.to_reserve(result)) + } + + /// Calculates the supply for a given reserve + /// + /// The supply is calculated as: f(x) = (1.5 * reserve / slope) ^ (2/3) + fn supply(&self, reserve: Uint128) -> StdResult { + let base = self + .normalize + .from_reserve(reserve)? + .checked_mul(Decimal::new(15, 1)) + .and_then(|r| r.checked_div(self.slope)) + .ok_or_else(|| { + StdError::generic_err("Overflow or division by zero in supply calculation") + })?; + + let squared = base + .checked_mul(base) + .ok_or_else(|| StdError::generic_err("Overflow in supply calculation"))?; + + let supply = cube_root(squared)?; + self.normalize.to_supply(supply) + } +} diff --git a/packages/cw-curves/src/lib.rs b/packages/cw-curves/src/lib.rs new file mode 100644 index 000000000..a4b6170a5 --- /dev/null +++ b/packages/cw-curves/src/lib.rs @@ -0,0 +1,8 @@ +pub mod curve; +pub mod curves; +pub mod utils; + +#[cfg(test)] +mod tests; + +pub use curve::{Curve, DecimalPlaces}; diff --git a/packages/cw-curves/src/tests.rs b/packages/cw-curves/src/tests.rs new file mode 100644 index 000000000..dd0edec5f --- /dev/null +++ b/packages/cw-curves/src/tests.rs @@ -0,0 +1,111 @@ +use cosmwasm_std::{Decimal as StdDecimal, StdResult, Uint128}; + +use crate::{ + curves::{Constant, Linear, SquareRoot}, + utils::decimal, + Curve, DecimalPlaces, +}; + +#[test] +fn constant_curve() -> StdResult<()> { + // Set up normalization for 9 decimal places input, 6 decimal places output + let normalize = DecimalPlaces::new(9, 6); + // Create a constant curve with a value of 1.5 + let curve = Constant::new(decimal(15u128, 1)?, normalize); + + // Test spot price (should always be 1.5 regardless of supply) + assert_eq!( + StdDecimal::percent(150), + curve.spot_price(Uint128::new(100))? + ); + // Test reserve calculation (30 billion input should yield 45 million output) + assert_eq!( + Uint128::new(45_000_000), + curve.reserve(Uint128::new(30_000_000_000))? + ); + // Test supply calculation (36 million input should yield 24 billion output) + assert_eq!( + Uint128::new(24_000_000_000), + curve.supply(Uint128::new(36_000_000))? + ); + + Ok(()) +} + +#[test] +fn linear_curve() -> StdResult<()> { + // Set up normalization for 2 decimal places input, 8 decimal places output + let normalize = DecimalPlaces::new(2, 8); + // Create a linear curve with a slope of 0.1 + let curve = Linear::new(decimal(1u128, 1)?, normalize); + + // Test spot price (100 input should yield 0.1 output) + assert_eq!( + StdDecimal::permille(100), + curve.spot_price(Uint128::new(100))? + ); + // Test reserve calculation (1000 input should yield 500 million output) + assert_eq!( + Uint128::new(500_000_000), + curve.reserve(Uint128::new(1000))? + ); + // Test supply calculation (125 million input should yield 500 output) + assert_eq!(Uint128::new(500), curve.supply(Uint128::new(125_000_000))?); + + Ok(()) +} + +#[test] +fn sqrt_curve() -> StdResult<()> { + // Set up normalization for 6 decimal places input, 2 decimal places output + let normalize = DecimalPlaces::new(6, 2); + // Create a square root curve with a multiplier of 0.35 + let curve = SquareRoot::new(decimal(35u128, 2)?, normalize); + + // Test spot price (1 million input should yield 0.35 output) + assert_eq!( + StdDecimal::percent(35), + curve.spot_price(Uint128::new(1_000_000))? + ); + // Test reserve calculation (1 million input should yield 23 output) + assert_eq!(Uint128::new(23), curve.reserve(Uint128::new(1_000_000))?); + // Test supply calculation (23 input should yield 990,000 output) + assert_eq!(Uint128::new(990_000), curve.supply(Uint128::new(23))?); + + Ok(()) +} + +#[test] +fn generic_curve_test() -> StdResult<()> { + // Set up normalization for 6 decimal places input and output + let normalize = DecimalPlaces::new(6, 6); + // Create a vector of different curve types + let curves: Vec> = vec![ + Box::new(Constant::new(decimal(1u128, 0)?, normalize)), + Box::new(Linear::new(decimal(1u128, 2)?, normalize)), + Box::new(SquareRoot::new(decimal(1u128, 1)?, normalize)), + ]; + + for curve in curves.iter() { + // Test with a supply of 1 million + let supply = Uint128::new(1_000_000); + // Calculate the reserve for this supply + let reserve = curve.reserve(supply)?; + // Calculate the supply from the reserve (should match original supply) + let calculated_supply = curve.supply(reserve)?; + + // Calculate the percentage difference between original and calculated supply + let diff = + (calculated_supply.u128() as f64 - supply.u128() as f64).abs() / supply.u128() as f64; + // Assert that the difference is within 2% + assert!( + diff <= 0.02, + "Supply mismatch: original={}, calculated={}, difference={:.2}%", + supply, + calculated_supply, + diff * 100.0 + ); + } + + Ok(()) +} diff --git a/packages/cw-curves/src/utils.rs b/packages/cw-curves/src/utils.rs new file mode 100644 index 000000000..ceecfb5b4 --- /dev/null +++ b/packages/cw-curves/src/utils.rs @@ -0,0 +1,95 @@ +use cosmwasm_std::{Decimal as StdDecimal, StdError, StdResult}; +use integer_cbrt::IntegerCubeRoot; +use integer_sqrt::IntegerSquareRoot; +use rust_decimal::prelude::{FromPrimitive, ToPrimitive}; +use rust_decimal::Decimal; +use std::str::FromStr; + +/// Creates a Decimal representation of a number with a specified scale. +/// +/// This function returns a Decimal object equal to num * 10^(-scale). +/// It's used in contract.rs instead of directly calling the crate constructor, +/// allowing for easier swapping of the implementation if needed in the future. +/// +/// # Arguments +/// +/// * `num` - The number to convert to Decimal. +/// * `scale` - The number of decimal places to shift the number. +/// +/// # Returns +/// +/// * `StdResult` - The resulting Decimal on success, or an error if the conversion fails. +pub fn decimal>(num: T, scale: u32) -> StdResult { + Decimal::try_from_i128_with_scale(num.into() as i128, scale) + .map_err(|_| StdError::generic_err("Failed to create Decimal")) +} + +/// Converts a rust_decimal::Decimal to cosmwasm_std::Decimal (StdDecimal). +/// +/// StdDecimal stores values as a u128 with 18 decimal points of precision. +/// This function uses string conversion, which is straightforward but potentially inefficient. +/// +/// # Arguments +/// +/// * `x` - The rust_decimal::Decimal to convert. +/// +/// # Returns +/// +/// * `StdResult` - The resulting StdDecimal on success, or an error if the conversion fails. +/// +/// # Note +/// +/// An alternative approach using mathematical operations is commented out below. +/// This approach attempts to preserve decimal points (up to 9) and might handle rounding differently. +/// Further investigation may be needed to determine the most appropriate method for specific use cases. +pub fn decimal_to_std(x: Decimal) -> StdResult { + StdDecimal::from_str(&x.to_string()) + .map_err(|_| StdError::generic_err("Failed to convert Decimal to StdDecimal")) + + // Alternative approach (commented out): + // + // let digits = min(x.scale(), 9); + // let multiplier = 10u128.pow(digits); + // + // let nominator = (x * decimal(multiplier, 0)?).to_u128() + // .ok_or_else(|| StdError::generic_err("Overflow in conversion to u128"))?; + // StdDecimal::from_ratio(nominator, multiplier) +} + +/// Calculates the square root of a Decimal +pub(crate) fn square_root(square: Decimal) -> StdResult { + const PRECISION_FACTOR: u32 = 12; + let multiplier = Decimal::from_u128(10u128.saturating_pow(PRECISION_FACTOR)) + .ok_or_else(|| StdError::generic_err("Failed to create precision multiplier"))?; + + let scaled_square = square + .checked_mul(multiplier) + .ok_or_else(|| StdError::generic_err("Overflow in square root calculation"))?; + + let integer_square = scaled_square + .floor() + .to_u128() + .ok_or_else(|| StdError::generic_err("Failed to convert to u128"))?; + + let integer_root = integer_square.integer_sqrt(); + decimal(integer_root, PRECISION_FACTOR / 2) +} + +/// Calculates the cube root of a Decimal +pub(crate) fn cube_root(cube: Decimal) -> StdResult { + const PRECISION_FACTOR: u32 = 9; + let multiplier = Decimal::from_u128(10u128.saturating_pow(PRECISION_FACTOR)) + .ok_or_else(|| StdError::generic_err("Failed to create precision multiplier"))?; + + let scaled_cube = cube + .checked_mul(multiplier) + .ok_or_else(|| StdError::generic_err("Overflow in cube root calculation"))?; + + let integer_cube = scaled_cube + .floor() + .to_u128() + .ok_or_else(|| StdError::generic_err("Failed to convert to u128"))?; + + let integer_root = integer_cube.integer_cbrt(); + decimal(integer_root, PRECISION_FACTOR / 3) +} diff --git a/packages/cw-orch/Cargo.toml b/packages/cw-orch/Cargo.toml index f03ecd4e2..2a5f371cb 100644 --- a/packages/cw-orch/Cargo.toml +++ b/packages/cw-orch/Cargo.toml @@ -12,8 +12,11 @@ default = [] wasm_test = [] [dependencies] + +serde.workspace = true btsg-ft-factory.workspace = true cosmwasm-std.workspace = true +cw-abc.workspace = true cw-orch.workspace = true cw20-stake.workspace = true cw20-stake-external-rewards = { path = "../../contracts/staking/cw20-stake-external-rewards" } @@ -46,4 +49,4 @@ dao-voting-cw721-staked.workspace = true dao-voting-token-staked.workspace = true dao-rewards-distributor.workspace = true cw-fund-distributor.workspace = true -serde.workspace = true \ No newline at end of file +serde.workspace = true diff --git a/packages/cw-orch/src/external/cw_abc.rs b/packages/cw-orch/src/external/cw_abc.rs new file mode 100644 index 000000000..31fe9ea4f --- /dev/null +++ b/packages/cw-orch/src/external/cw_abc.rs @@ -0,0 +1,20 @@ +use cw_orch::{interface, prelude::*}; + +use cw_abc::contract::{execute, instantiate, query, reply}; +use cw_abc::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +#[interface(InstantiateMsg, ExecuteMsg, QueryMsg, Empty)] +pub struct DaoExternalCwAbc; + +impl Uploadable for DaoExternalCwAbc { + /// Return the path to the wasm file corresponding to the contract + fn wasm(_chain: &ChainInfoOwned) -> WasmPath { + artifacts_dir_from_workspace!() + .find_wasm_path("cw_abc") + .unwrap() + } + /// Returns a CosmWasm contract wrapper + fn wrapper() -> Box> { + Box::new(ContractWrapper::new_with_empty(execute, instantiate, query).with_reply(reply)) + } +} diff --git a/packages/cw-orch/src/external/mod.rs b/packages/cw-orch/src/external/mod.rs index ee24e4bfd..51c080f0f 100644 --- a/packages/cw-orch/src/external/mod.rs +++ b/packages/cw-orch/src/external/mod.rs @@ -1,6 +1,7 @@ mod admin_factory; mod btsg_ft_factory; mod cw721_roles; +mod cw_abc; mod cw_vesting; mod migrator; mod payroll_factory; @@ -10,6 +11,7 @@ mod tokenfactory_issuer; pub use admin_factory::DaoExternalAdminFactory; pub use btsg_ft_factory::DaoExternalFantokenFactory; pub use cw721_roles::DaoExternalCw721Roles; +pub use cw_abc::DaoExternalCwAbc; pub use cw_vesting::DaoExternalCwVesting; pub use migrator::DaoExternalMigrator; pub use payroll_factory::DaoExternalPayrollFactory; diff --git a/packages/cw-orch/src/tests.rs b/packages/cw-orch/src/tests.rs index c3636e190..5ce142b82 100644 --- a/packages/cw-orch/src/tests.rs +++ b/packages/cw-orch/src/tests.rs @@ -7,10 +7,11 @@ use cw_orch::{ }; use crate::{ - Cw20Stake, Cw20StakeExternalRewards, Cw20StakeRewardDistributor, DaoDaoCore, - DaoPreProposeApprovalSingle, DaoPreProposeApprover, DaoPreProposeMultiple, DaoPreProposeSingle, - DaoProposalCondorcet, DaoProposalHookCounter, DaoProposalMultiple, DaoProposalSingle, - DaoProposalSudo, DaoTestCustomFactory, DaoVotingCw20Balance, DaoVotingCw20Staked, DaoVotingCw4, + DaoDaoCore, DaoExternalCwAbc, DaoExternalTokenfactoryIssuer, DaoPreProposeApprovalSingle, + DaoPreProposeApprover, DaoPreProposeMultiple, DaoPreProposeSingle, DaoProposalCondorcet, + DaoProposalHookCounter, DaoProposalMultiple, DaoProposalSingle, DaoProposalSudo, + DaoStakingCw20, DaoStakingCw20ExternalRewards, DaoStakingCw20RewardDistributor, + DaoTestCustomFactory, DaoVotingCw20Balance, DaoVotingCw20Staked, DaoVotingCw4, DaoVotingCw721Roles, DaoVotingCw721Staked, DaoVotingTokenStaked, }; @@ -44,9 +45,12 @@ fn test_all_wasms_different() { DaoProposalMultiple::::wasm(&DUMMY_CHAIN_INFO.into()), DaoProposalSingle::::wasm(&DUMMY_CHAIN_INFO.into()), // Stake - Cw20Stake::::wasm(&DUMMY_CHAIN_INFO.into()), - Cw20StakeExternalRewards::::wasm(&DUMMY_CHAIN_INFO.into()), - Cw20StakeRewardDistributor::::wasm(&DUMMY_CHAIN_INFO.into()), + DaoStakingCw20::::wasm(&DUMMY_CHAIN_INFO.into()), + DaoStakingCw20ExternalRewards::::wasm(&DUMMY_CHAIN_INFO.into()), + DaoStakingCw20RewardDistributor::::wasm(&DUMMY_CHAIN_INFO.into()), + // External + DaoExternalCwAbc::::wasm(&DUMMY_CHAIN_INFO.into()), + DaoExternalTokenfactoryIssuer::::wasm(&DUMMY_CHAIN_INFO.into()), // Voting DaoVotingCw4::::wasm(&DUMMY_CHAIN_INFO.into()), DaoVotingCw20Staked::::wasm(&DUMMY_CHAIN_INFO.into()), diff --git a/packages/cw-paginate-storage/src/lib.rs b/packages/cw-paginate-storage/src/lib.rs index 61f420f3a..ec1edc410 100644 --- a/packages/cw-paginate-storage/src/lib.rs +++ b/packages/cw-paginate-storage/src/lib.rs @@ -114,7 +114,7 @@ where } /// Same as `paginate_map` but only returns the keys. For use with -/// `SnaphotMap`. +/// `SnapshotMap`. pub fn paginate_snapshot_map_keys<'a, 'b, K, V, R: 'static>( deps: Deps, map: &SnapshotMap<'a, K, V>, diff --git a/packages/cw-tokenfactory-types/src/msg.rs b/packages/cw-tokenfactory-types/src/msg.rs index 8c2b061b9..9f2405944 100644 --- a/packages/cw-tokenfactory-types/src/msg.rs +++ b/packages/cw-tokenfactory-types/src/msg.rs @@ -61,6 +61,8 @@ mod tokenfactory_msg { display: metadata.display, name: metadata.name, symbol: metadata.symbol, + uri: metadata.uri, + uri_hash: metadata.uri_hash, }), } } diff --git a/packages/dao-interface/src/msg.rs b/packages/dao-interface/src/msg.rs index e8027f7c5..d28f1c671 100644 --- a/packages/dao-interface/src/msg.rs +++ b/packages/dao-interface/src/msg.rs @@ -175,7 +175,7 @@ pub enum QueryMsg { /// Gets the address associated with an item key. #[returns(crate::query::GetItemResponse)] GetItem { key: String }, - /// Lists all of the items associted with the contract. For + /// Lists all of the items associated with the contract. For /// example, given the items `{ "group": "foo", "subdao": "bar"}` /// this query would return `[("group", "foo"), ("subdao", /// "bar")]`. diff --git a/packages/dao-testing/Cargo.toml b/packages/dao-testing/Cargo.toml index 9b191be86..84517fc97 100644 --- a/packages/dao-testing/Cargo.toml +++ b/packages/dao-testing/Cargo.toml @@ -1,12 +1,18 @@ [package] name = "dao-testing" -authors = ["ekez ekez@withoutdoing.com", "Jake Hartnell "] +authors = [ + "ekez ekez@withoutdoing.com", + "Jake Hartnell ", +] description = "Testing helper functions and interfaces for testing DAO modules." edition = { workspace = true } license = { workspace = true } repository = { workspace = true } version = { workspace = true } +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin)'] } + [features] # use test tube feature to enable test-tube integration tests, for example # cargo test --features "test-tube" @@ -37,6 +43,7 @@ serde = { workspace = true } serde_json = { workspace = true } cw-admin-factory = { workspace = true } +cw-abc = { workspace = true } cw-core-v1 = { workspace = true, features = ["library"] } cw-hooks = { workspace = true } cw-proposal-single-v1 = { workspace = true } @@ -45,6 +52,7 @@ cw20-stake = { workspace = true } cw721-base = { workspace = true } cw721-roles = { workspace = true } cw-tokenfactory-issuer = { workspace = true } +dao-abc-factory = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } dao-interface = { workspace = true } dao-pre-propose-multiple = { workspace = true } diff --git a/packages/dao-testing/src/lib.rs b/packages/dao-testing/src/lib.rs index eeb38e678..6e49685fe 100644 --- a/packages/dao-testing/src/lib.rs +++ b/packages/dao-testing/src/lib.rs @@ -12,5 +12,9 @@ pub mod contracts; #[cfg(not(target_arch = "wasm32"))] pub use tests::*; +// Integration tests using an actual chain binary, requires +// the "test-tube" feature to be enabled +// cargo test --features test-tube #[cfg(not(target_arch = "wasm32"))] +#[cfg(feature = "test-tube")] pub mod test_tube; diff --git a/packages/dao-testing/src/test_tube/cw4_group.rs b/packages/dao-testing/src/test_tube/cw4_group.rs index a40d407c7..944d3fd58 100644 --- a/packages/dao-testing/src/test_tube/cw4_group.rs +++ b/packages/dao-testing/src/test_tube/cw4_group.rs @@ -36,7 +36,7 @@ impl<'a> Cw4Group<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("cw4_group"), &[], signer, )? diff --git a/packages/dao-testing/src/test_tube/cw721_base.rs b/packages/dao-testing/src/test_tube/cw721_base.rs index 84c80b8fe..f5916c8f4 100644 --- a/packages/dao-testing/src/test_tube/cw721_base.rs +++ b/packages/dao-testing/src/test_tube/cw721_base.rs @@ -36,7 +36,7 @@ impl<'a> Cw721Base<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("cw721_base"), &[], signer, )? diff --git a/packages/dao-testing/src/test_tube/cw_abc.rs b/packages/dao-testing/src/test_tube/cw_abc.rs new file mode 100644 index 000000000..c0b17e29d --- /dev/null +++ b/packages/dao-testing/src/test_tube/cw_abc.rs @@ -0,0 +1,181 @@ +use cosmwasm_std::Coin; +use cw_abc::{ + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, + ContractError, +}; +use osmosis_test_tube::{ + osmosis_std::types::cosmwasm::wasm::v1::{ + MsgExecuteContractResponse, MsgMigrateContract, MsgMigrateContractResponse, + }, + Account, Module, OsmosisTestApp, Runner, RunnerError, RunnerExecuteResult, SigningAccount, + Wasm, +}; +use serde::de::DeserializeOwned; +use std::fmt::Debug; +use std::path::PathBuf; + +#[derive(Debug)] +pub struct CwAbc<'a> { + pub app: &'a OsmosisTestApp, + pub code_id: u64, + pub contract_addr: String, +} + +impl<'a> CwAbc<'a> { + pub fn new( + app: &'a OsmosisTestApp, + instantiate_msg: &InstantiateMsg, + signer: &SigningAccount, + ) -> Result { + let wasm = Wasm::new(app); + let token_creation_fee = Coin::new(10000000, "uosmo"); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + let contract_addr = wasm + .instantiate( + code_id, + &instantiate_msg, + Some(&signer.address()), + None, + &[token_creation_fee], + signer, + )? + .data + .address; + + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + pub fn new_with_values( + app: &'a OsmosisTestApp, + code_id: u64, + contract_addr: String, + ) -> Result { + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + /// uploads contract and returns a code ID + pub fn upload(app: &OsmosisTestApp, signer: &SigningAccount) -> Result { + let wasm = Wasm::new(app); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + Ok(code_id) + } + + pub fn instantiate( + app: &'a OsmosisTestApp, + code_id: u64, + instantiate_msg: &InstantiateMsg, + signer: &SigningAccount, + ) -> Result { + let wasm = Wasm::new(app); + let contract_addr = wasm + .instantiate( + code_id, + &instantiate_msg, + Some(&signer.address()), + None, + &[], + signer, + )? + .data + .address; + + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + // executes + pub fn execute( + &self, + execute_msg: &ExecuteMsg, + funds: &[Coin], + signer: &SigningAccount, + ) -> RunnerExecuteResult { + let wasm = Wasm::new(self.app); + wasm.execute(&self.contract_addr, execute_msg, funds, signer) + } + + // queries + pub fn query(&self, query_msg: &QueryMsg) -> Result + where + T: DeserializeOwned, + { + let wasm = Wasm::new(self.app); + wasm.query(&self.contract_addr, query_msg) + } + + pub fn migrate( + &self, + testdata: &str, + signer: &SigningAccount, + ) -> RunnerExecuteResult { + let wasm = Wasm::new(self.app); + let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let wasm_byte_code = + std::fs::read(manifest_path.join("tests").join("testdata").join(testdata)).unwrap(); + + let code_id = wasm.store_code(&wasm_byte_code, None, signer)?.data.code_id; + self.app.execute( + MsgMigrateContract { + sender: signer.address(), + contract: self.contract_addr.clone(), + code_id, + msg: serde_json::to_vec(&MigrateMsg {}).unwrap(), + }, + "/cosmwasm.wasm.v1.MsgMigrateContract", + signer, + ) + } + + fn get_wasm_byte_code() -> Vec { + let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let byte_code = std::fs::read( + manifest_path + .join("..") + .join("..") + .join("artifacts") + .join("cw_abc.wasm"), + ); + match byte_code { + Ok(byte_code) => byte_code, + // On arm processors, the above path is not found, so we try the following path + Err(_) => std::fs::read( + manifest_path + .join("..") + .join("..") + .join("artifacts") + .join("cw_abc-aarch64.wasm"), + ) + .unwrap(), + } + } + + pub fn execute_error(err: ContractError) -> RunnerError { + RunnerError::ExecuteError { + msg: format!( + "failed to execute message; message index: 0: {}: execute wasm contract failed", + err + ), + } + } +} diff --git a/packages/dao-testing/src/test_tube/cw_admin_factory.rs b/packages/dao-testing/src/test_tube/cw_admin_factory.rs index 17675f5b2..67a96c3ff 100644 --- a/packages/dao-testing/src/test_tube/cw_admin_factory.rs +++ b/packages/dao-testing/src/test_tube/cw_admin_factory.rs @@ -26,6 +26,7 @@ impl<'a> CwAdminFactory<'a> { funds: &[Coin], ) -> Result { let wasm = Wasm::new(app); + let code_id = wasm .store_code(&Self::get_wasm_byte_code(), None, signer)? .data @@ -36,7 +37,7 @@ impl<'a> CwAdminFactory<'a> { code_id, &InstantiateMsg { admin }, Some(&signer.address()), - None, + Some("cw_admin_factory"), funds, signer, )? diff --git a/packages/dao-testing/src/test_tube/cw_tokenfactory_issuer.rs b/packages/dao-testing/src/test_tube/cw_tokenfactory_issuer.rs index 27ed1dcf0..813b3a57c 100644 --- a/packages/dao-testing/src/test_tube/cw_tokenfactory_issuer.rs +++ b/packages/dao-testing/src/test_tube/cw_tokenfactory_issuer.rs @@ -40,7 +40,7 @@ impl<'a> TokenfactoryIssuer<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("cw_tokenfactory_issuer"), &[token_creation_fee], signer, )? diff --git a/packages/dao-testing/src/test_tube/dao_abc_factory.rs b/packages/dao-testing/src/test_tube/dao_abc_factory.rs new file mode 100644 index 000000000..d000548c4 --- /dev/null +++ b/packages/dao-testing/src/test_tube/dao_abc_factory.rs @@ -0,0 +1,129 @@ +use cosmwasm_std::Coin; +use dao_abc_factory::{ + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + ContractError, +}; +use osmosis_test_tube::{ + osmosis_std::types::cosmwasm::wasm::v1::MsgExecuteContractResponse, Account, Module, + OsmosisTestApp, RunnerError, RunnerExecuteResult, SigningAccount, Wasm, +}; +use serde::de::DeserializeOwned; +use std::fmt::Debug; +use std::path::PathBuf; + +#[derive(Debug)] +pub struct AbcFactoryContract<'a> { + pub app: &'a OsmosisTestApp, + pub code_id: u64, + pub contract_addr: String, +} + +impl<'a> AbcFactoryContract<'a> { + pub fn new( + app: &'a OsmosisTestApp, + instantiate_msg: &InstantiateMsg, + signer: &SigningAccount, + ) -> Result { + let wasm = Wasm::new(app); + let token_creation_fee = Coin::new(10000000, "uosmo"); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + let contract_addr = wasm + .instantiate( + code_id, + &instantiate_msg, + Some(&signer.address()), + None, + &[token_creation_fee], + signer, + )? + .data + .address; + + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + pub fn new_with_values( + app: &'a OsmosisTestApp, + code_id: u64, + contract_addr: String, + ) -> Result { + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + /// uploads contract and returns a code ID + pub fn upload(app: &OsmosisTestApp, signer: &SigningAccount) -> Result { + let wasm = Wasm::new(app); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + Ok(code_id) + } + + // executes + pub fn execute( + &self, + execute_msg: &ExecuteMsg, + funds: &[Coin], + signer: &SigningAccount, + ) -> RunnerExecuteResult { + let wasm = Wasm::new(self.app); + wasm.execute(&self.contract_addr, execute_msg, funds, signer) + } + + // queries + pub fn query(&self, query_msg: &QueryMsg) -> Result + where + T: DeserializeOwned, + { + let wasm = Wasm::new(self.app); + wasm.query(&self.contract_addr, query_msg) + } + + fn get_wasm_byte_code() -> Vec { + let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let byte_code = std::fs::read( + manifest_path + .join("..") + .join("..") + .join("artifacts") + .join("dao_abc_factory.wasm"), + ); + match byte_code { + Ok(byte_code) => byte_code, + // On arm processors, the above path is not found, so we try the following path + Err(_) => std::fs::read( + manifest_path + .join("..") + .join("..") + .join("artifacts") + .join("dao_abc_factory-aarch64.wasm"), + ) + .unwrap(), + } + } + + pub fn execute_error(err: ContractError) -> RunnerError { + RunnerError::ExecuteError { + msg: format!( + "failed to execute message; message index: 0: {}: execute wasm contract failed", + err + ), + } + } +} diff --git a/packages/dao-testing/src/test_tube/dao_dao_core.rs b/packages/dao-testing/src/test_tube/dao_dao_core.rs index 3fc9b73e7..06ea9b061 100644 --- a/packages/dao-testing/src/test_tube/dao_dao_core.rs +++ b/packages/dao-testing/src/test_tube/dao_dao_core.rs @@ -34,7 +34,7 @@ impl<'a> DaoCore<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("dao_dao_core"), funds, signer, )? diff --git a/packages/dao-testing/src/test_tube/dao_proposal_single.rs b/packages/dao-testing/src/test_tube/dao_proposal_single.rs index 4f6d51a96..68c40d733 100644 --- a/packages/dao-testing/src/test_tube/dao_proposal_single.rs +++ b/packages/dao-testing/src/test_tube/dao_proposal_single.rs @@ -37,7 +37,7 @@ impl<'a> DaoProposalSingle<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("dao_proposal_single"), &[token_creation_fee], signer, )? diff --git a/packages/dao-testing/src/test_tube/dao_test_custom_factory.rs b/packages/dao-testing/src/test_tube/dao_test_custom_factory.rs index 754374884..33cc5ed76 100644 --- a/packages/dao-testing/src/test_tube/dao_test_custom_factory.rs +++ b/packages/dao-testing/src/test_tube/dao_test_custom_factory.rs @@ -37,7 +37,7 @@ impl<'a> CustomFactoryContract<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("dao_test_custom_factory"), &[token_creation_fee], signer, )? diff --git a/packages/dao-testing/src/test_tube/dao_voting_cw4.rs b/packages/dao-testing/src/test_tube/dao_voting_cw4.rs index ce0fdac33..3589880c0 100644 --- a/packages/dao-testing/src/test_tube/dao_voting_cw4.rs +++ b/packages/dao-testing/src/test_tube/dao_voting_cw4.rs @@ -36,7 +36,7 @@ impl<'a> DaoVotingCw4<'a> { code_id, &instantiate_msg, Some(&signer.address()), - None, + Some("dao_voting_cw4"), funds, signer, )? diff --git a/packages/dao-testing/src/test_tube/dao_voting_token_staked.rs b/packages/dao-testing/src/test_tube/dao_voting_token_staked.rs new file mode 100644 index 000000000..df1f6b7cc --- /dev/null +++ b/packages/dao-testing/src/test_tube/dao_voting_token_staked.rs @@ -0,0 +1,129 @@ +use cosmwasm_std::Coin; +use dao_voting_token_staked::{ + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + ContractError, +}; +use osmosis_test_tube::{ + osmosis_std::types::cosmwasm::wasm::v1::MsgExecuteContractResponse, Account, Module, + OsmosisTestApp, RunnerError, RunnerExecuteResult, SigningAccount, Wasm, +}; +use serde::de::DeserializeOwned; +use std::fmt::Debug; +use std::path::PathBuf; + +#[derive(Debug)] +pub struct TokenVotingContract<'a> { + pub app: &'a OsmosisTestApp, + pub code_id: u64, + pub contract_addr: String, +} + +impl<'a> TokenVotingContract<'a> { + pub fn new( + app: &'a OsmosisTestApp, + instantiate_msg: &InstantiateMsg, + signer: &SigningAccount, + ) -> Result { + let wasm = Wasm::new(app); + let token_creation_fee = Coin::new(10000000, "uosmo"); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + let contract_addr = wasm + .instantiate( + code_id, + &instantiate_msg, + Some(&signer.address()), + None, + &[token_creation_fee], + signer, + )? + .data + .address; + + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + pub fn new_with_values( + app: &'a OsmosisTestApp, + code_id: u64, + contract_addr: String, + ) -> Result { + Ok(Self { + app, + code_id, + contract_addr, + }) + } + + /// uploads contract and returns a code ID + pub fn upload(app: &OsmosisTestApp, signer: &SigningAccount) -> Result { + let wasm = Wasm::new(app); + + let code_id = wasm + .store_code(&Self::get_wasm_byte_code(), None, signer)? + .data + .code_id; + + Ok(code_id) + } + + // executes + pub fn execute( + &self, + execute_msg: &ExecuteMsg, + funds: &[Coin], + signer: &SigningAccount, + ) -> RunnerExecuteResult { + let wasm = Wasm::new(self.app); + wasm.execute(&self.contract_addr, execute_msg, funds, signer) + } + + // queries + pub fn query(&self, query_msg: &QueryMsg) -> Result + where + T: DeserializeOwned, + { + let wasm = Wasm::new(self.app); + wasm.query(&self.contract_addr, query_msg) + } + + fn get_wasm_byte_code() -> Vec { + let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let byte_code = std::fs::read( + manifest_path + .join("..") + .join("..") + .join("artifacts") + .join("dao_voting_token_staked.wasm"), + ); + match byte_code { + Ok(byte_code) => byte_code, + // On arm processors, the above path is not found, so we try the following path + Err(_) => std::fs::read( + manifest_path + .join("..") + .join("..") + .join("artifacts") + .join("dao_voting_token_staked-aarch64.wasm"), + ) + .unwrap(), + } + } + + pub fn execute_error(err: ContractError) -> RunnerError { + RunnerError::ExecuteError { + msg: format!( + "failed to execute message; message index: 0: {}: execute wasm contract failed", + err + ), + } + } +} diff --git a/packages/dao-testing/src/test_tube/mod.rs b/packages/dao-testing/src/test_tube/mod.rs index 107ea403d..25dc322d2 100644 --- a/packages/dao-testing/src/test_tube/mod.rs +++ b/packages/dao-testing/src/test_tube/mod.rs @@ -1,27 +1,15 @@ -// Integrationg tests using an actual chain binary, requires -// the "test-tube" feature to be enabled -// cargo test --features test-tube +// Ignore integration tests for code coverage since there will be problems with dynamic linking libosmosistesttube +// and also, tarpaulin will not be able read coverage out of wasm binary anyway +#![cfg(not(tarpaulin))] -#[cfg(feature = "test-tube")] -pub mod cw_admin_factory; - -#[cfg(feature = "test-tube")] -pub mod cw_tokenfactory_issuer; - -#[cfg(feature = "test-tube")] pub mod cw4_group; - -#[cfg(feature = "test-tube")] pub mod cw721_base; - -#[cfg(feature = "test-tube")] +pub mod cw_abc; +pub mod cw_admin_factory; +pub mod cw_tokenfactory_issuer; +pub mod dao_abc_factory; pub mod dao_dao_core; - -#[cfg(feature = "test-tube")] pub mod dao_proposal_single; - -#[cfg(feature = "test-tube")] pub mod dao_test_custom_factory; - -#[cfg(feature = "test-tube")] pub mod dao_voting_cw4; +pub mod dao_voting_token_staked; diff --git a/packages/dao-voting/src/voting.rs b/packages/dao-voting/src/voting.rs index 2aabafc2e..48be99a49 100644 --- a/packages/dao-voting/src/voting.rs +++ b/packages/dao-voting/src/voting.rs @@ -179,10 +179,10 @@ impl Votes { /// Computes the total number of votes cast. /// - /// NOTE: The total number of votes avaliable from a voting module + /// NOTE: The total number of votes available from a voting module /// is a `Uint128`. As it is not possible to vote twice we know /// that the sum of votes must be <= 2^128 and can safely return a - /// `Uint128` from this function. A missbehaving voting power + /// `Uint128` from this function. A misbehaving voting power /// module may break this invariant. pub fn total(&self) -> Uint128 { self.yes + self.no + self.abstain