From 334874ab279aa7b7ca63b06b9b35e81b7d85daaf Mon Sep 17 00:00:00 2001 From: Connor Barr Date: Wed, 22 Jan 2025 08:22:48 +0000 Subject: [PATCH] feat: Improved macros and execution flow for AMP (#741) Co-authored-by: Joe Monem <66594578+joemonem@users.noreply.github.com> --- CHANGELOG.md | 2 + Cargo.lock | 138 ++++----- Cargo.toml | 4 +- Makefile | 6 +- .../andromeda-fixed-multisig/src/contract.rs | 32 +- .../andromeda-fixed-multisig/src/execute.rs | 39 +-- .../andromeda-app-contract/src/contract.rs | 37 +-- .../app/andromeda-app-contract/src/execute.rs | 5 - .../andromeda-app-contract/src/testing/mod.rs | 8 +- .../data-storage/andromeda-boolean/Cargo.toml | 1 - .../andromeda-boolean/src/contract.rs | 44 ++- .../andromeda-boolean/src/execute.rs | 50 +-- .../andromeda-form/src/contract.rs | 40 +-- .../andromeda-form/src/execute.rs | 56 +--- .../andromeda-primitive/Cargo.toml | 1 - .../andromeda-primitive/src/contract.rs | 41 ++- .../andromeda-primitive/src/execute.rs | 50 +-- .../andromeda-string-storage/Cargo.toml | 1 - .../andromeda-string-storage/src/contract.rs | 44 ++- .../andromeda-string-storage/src/execute.rs | 50 +-- .../ecosystem/andromeda-vault/Cargo.toml | 2 - .../ecosystem/andromeda-vault/src/contract.rs | 41 +-- .../src/contract.rs | 62 +--- .../src/testing/tests.rs | 187 ++++++----- .../src/contract.rs | 30 +- .../src/contract.rs | 73 +---- .../src/testing/tests.rs | 33 +- .../src/contract.rs | 54 +--- .../andromeda-splitter/src/contract.rs | 94 +----- .../andromeda-splitter/src/testing/tests.rs | 32 +- .../andromeda-timelock/src/contract.rs | 36 +-- .../src/testing/mock_querier.rs | 2 +- .../andromeda-timelock/src/testing/tests.rs | 90 ++---- .../src/contract.rs | 57 +--- .../src/testing/mock_querier.rs | 94 +++++- .../src/testing/tests.rs | 12 +- .../finance/andromeda-vesting/src/contract.rs | 66 +--- .../andromeda-vesting/src/testing/tests.rs | 43 ++- .../Cargo.toml | 4 +- .../src/contract.rs | 101 +----- .../src/lib.rs | 3 + .../src/mock.rs | 91 ++++++ .../src/mock_querier.rs | 172 ----------- .../src/testing/tests.rs | 20 +- .../andromeda-cw20-exchange/src/contract.rs | 45 +-- .../andromeda-cw20-staking/Cargo.toml | 1 - .../andromeda-cw20-staking/src/contract.rs | 70 +---- .../src/testing/tests.rs | 69 ++--- .../andromeda-cw20/src/contract.rs | 41 +-- .../andromeda-cw20/src/testing/tests.rs | 7 +- .../andromeda-ics20/src/testing/tests.rs | 38 +-- .../andromeda-lockdrop/Cargo.toml | 1 - .../andromeda-lockdrop/src/contract.rs | 47 +-- .../andromeda-lockdrop/src/testing/tests.rs | 20 +- .../andromeda-merkle-airdrop/Cargo.toml | 1 - .../andromeda-merkle-airdrop/src/contract.rs | 55 +--- .../src/testing/tests.rs | 51 +-- contracts/math/andromeda-counter/Cargo.toml | 1 - .../math/andromeda-counter/src/contract.rs | 59 +--- contracts/math/andromeda-curve/Cargo.toml | 1 - .../math/andromeda-curve/src/contract.rs | 47 +-- .../math/andromeda-date-time/src/contract.rs | 40 +-- .../math/andromeda-distance/src/contract.rs | 40 +-- .../math/andromeda-graph/src/contract.rs | 54 +--- contracts/math/andromeda-matrix/Cargo.toml | 1 - .../math/andromeda-matrix/src/contract.rs | 54 +--- contracts/math/andromeda-point/Cargo.toml | 1 - .../math/andromeda-point/src/contract.rs | 25 +- contracts/math/andromeda-point/src/execute.rs | 40 +-- contracts/math/andromeda-shunting/Cargo.toml | 1 - .../math/andromeda-shunting/src/contract.rs | 35 +-- .../modules/andromeda-address-list/Cargo.toml | 2 +- .../andromeda-address-list/src/contract.rs | 39 +-- .../src/testing/tests.rs | 20 +- .../modules/andromeda-rates/src/contract.rs | 40 +-- .../andromeda-rates/src/testing/tests.rs | 18 +- .../modules/andromeda-schema/src/contract.rs | 23 +- .../modules/andromeda-schema/src/execute.rs | 39 +-- .../andromeda-auction/src/contract.rs | 59 +--- .../andromeda-auction/src/testing/tests.rs | 291 +++--------------- .../andromeda-crowdfund/src/contract.rs | 99 +----- .../andromeda-crowdfund/src/testing/tests.rs | 193 +----------- .../andromeda-cw721/Cargo.toml | 2 +- .../andromeda-cw721/src/contract.rs | 140 +++------ .../andromeda-cw721/src/testing/mod.rs | 30 +- .../andromeda-marketplace/src/contract.rs | 44 +-- .../src/testing/tests.rs | 17 +- .../os/andromeda-ibc-registry/src/contract.rs | 34 +- contracts/os/andromeda-kernel/src/contract.rs | 7 +- contracts/os/andromeda-kernel/src/ibc.rs | 11 +- {tests-integration => e2e-tests}/Cargo.toml | 3 +- {tests-integration => e2e-tests}/src/lib.rs | 0 e2e-tests/tests/amp/access_control.rs | 129 ++++++++ e2e-tests/tests/amp/mod.rs | 1 + {tests-integration => e2e-tests}/tests/app.rs | 0 .../tests/auction_app.rs | 0 .../tests/conditional_splitter.rs | 61 +++- .../tests/crowdfund_app.rs | 22 +- .../tests/curve_app.rs | 0 .../tests/cw20_app.rs | 0 .../tests/cw20_staking.rs | 0 .../tests/fixed_amount_splitter.rs | 0 .../tests/ibc_registry.rs | 0 .../tests/kernel.rs | 0 .../tests/kernel_orch.rs | 47 +++ .../tests/lockdrop.rs | 0 e2e-tests/tests/macro_tests/attrs.rs | 33 ++ e2e-tests/tests/macro_tests/exec_fn.rs | 248 +++++++++++++++ e2e-tests/tests/macro_tests/mod.rs | 2 + .../tests/marketplace_app.rs | 0 {tests-integration => e2e-tests}/tests/mod.rs | 6 + .../tests/primitive.rs | 0 e2e-tests/tests/rates_orch.rs | 221 +++++++++++++ e2e-tests/tests/set_amount_splitter.rs | 255 +++++++++++++++ .../tests/shunting.rs | 0 .../tests/splitter.rs | 0 .../tests/validator_staking.rs | 0 .../tests_old/cw20_staking_app.rs | 0 .../tests_old/cw721.rs | 0 .../tests_old/ics721_app.rs | 0 .../tests_old/kernel_path_bridge.rs | 0 .../tests_old/mod.rs | 0 .../tests_old/wrapped_cw721_app.rs | 0 packages/andromeda-app/src/app.rs | 1 + .../andromeda-data-storage/src/boolean.rs | 10 +- packages/andromeda-data-storage/src/form.rs | 9 +- .../andromeda-data-storage/src/primitive.rs | 10 +- .../src/string_storage.rs | 2 + packages/andromeda-ecosystem/src/vault.rs | 2 + .../src/conditional_splitter.rs | 2 + .../src/fixed_amount_splitter.rs | 16 +- .../src/rate_limiting_withdrawals.rs | 9 +- packages/andromeda-finance/src/splitter.rs | 20 +- .../src/validator_staking.rs | 12 +- packages/andromeda-finance/src/vesting.rs | 3 + .../src/weighted_splitter.rs | 6 + .../andromeda-fungible-tokens/src/airdrop.rs | 3 + .../src/cw20_exchange.rs | 2 + .../src/cw20_staking.rs | 17 +- .../andromeda-fungible-tokens/src/lockdrop.rs | 6 +- packages/andromeda-math/src/counter.rs | 6 + packages/andromeda-math/src/curve.rs | 2 + packages/andromeda-math/src/graph.rs | 16 +- packages/andromeda-math/src/matrix.rs | 2 + packages/andromeda-math/src/point.rs | 10 +- packages/andromeda-math/src/shunting.rs | 1 + .../andromeda-modules/src/address_list.rs | 2 + packages/andromeda-modules/src/rates.rs | 2 + packages/andromeda-modules/src/schema.rs | 1 + .../src/auction.rs | 3 + .../src/crowdfund.rs | 7 + .../src/cw721.rs | 32 +- .../src/marketplace.rs | 3 + packages/deploy/src/adodb.rs | 5 + packages/std/Cargo.toml | 7 +- packages/std/macros/Cargo.toml | 4 +- packages/std/macros/src/attrs/direct.rs | 60 ++++ packages/std/macros/src/attrs/handler.rs | 12 + packages/std/macros/src/attrs/mod.rs | 49 +++ packages/std/macros/src/attrs/payable.rs | 60 ++++ packages/std/macros/src/attrs/restricted.rs | 61 ++++ packages/std/macros/src/attrs/utils.rs | 37 +++ packages/std/macros/src/execute.rs | 106 +++++++ packages/std/macros/src/instantiate.rs | 29 ++ packages/std/macros/src/lib.rs | 197 +++--------- packages/std/macros/src/query.rs | 54 ++++ packages/std/macros/src/utils.rs | 29 ++ packages/std/src/ado_contract/execute.rs | 57 ++++ .../std/src/ado_contract/permissioning.rs | 30 +- packages/std/src/amp/messages.rs | 6 + packages/std/src/common/actions.rs | 20 +- packages/std/src/common/context.rs | 8 +- packages/std/src/common/denom.rs | 2 +- packages/std/src/error.rs | 2 +- packages/std/src/lib.rs | 5 +- packages/std/src/os/aos_querier.rs | 1 - 176 files changed, 2847 insertions(+), 3240 deletions(-) create mode 100644 contracts/finance/andromeda-weighted-distribution-splitter/src/mock.rs delete mode 100644 contracts/finance/andromeda-weighted-distribution-splitter/src/mock_querier.rs rename {tests-integration => e2e-tests}/Cargo.toml (99%) rename {tests-integration => e2e-tests}/src/lib.rs (100%) create mode 100644 e2e-tests/tests/amp/access_control.rs create mode 100644 e2e-tests/tests/amp/mod.rs rename {tests-integration => e2e-tests}/tests/app.rs (100%) rename {tests-integration => e2e-tests}/tests/auction_app.rs (100%) rename {tests-integration => e2e-tests}/tests/conditional_splitter.rs (82%) rename {tests-integration => e2e-tests}/tests/crowdfund_app.rs (96%) rename {tests-integration => e2e-tests}/tests/curve_app.rs (100%) rename {tests-integration => e2e-tests}/tests/cw20_app.rs (100%) rename {tests-integration => e2e-tests}/tests/cw20_staking.rs (100%) rename {tests-integration => e2e-tests}/tests/fixed_amount_splitter.rs (100%) rename {tests-integration => e2e-tests}/tests/ibc_registry.rs (100%) rename {tests-integration => e2e-tests}/tests/kernel.rs (100%) rename {tests-integration => e2e-tests}/tests/kernel_orch.rs (98%) rename {tests-integration => e2e-tests}/tests/lockdrop.rs (100%) create mode 100644 e2e-tests/tests/macro_tests/attrs.rs create mode 100644 e2e-tests/tests/macro_tests/exec_fn.rs create mode 100644 e2e-tests/tests/macro_tests/mod.rs rename {tests-integration => e2e-tests}/tests/marketplace_app.rs (100%) rename {tests-integration => e2e-tests}/tests/mod.rs (87%) rename {tests-integration => e2e-tests}/tests/primitive.rs (100%) create mode 100644 e2e-tests/tests/rates_orch.rs create mode 100644 e2e-tests/tests/set_amount_splitter.rs rename {tests-integration => e2e-tests}/tests/shunting.rs (100%) rename {tests-integration => e2e-tests}/tests/splitter.rs (100%) rename {tests-integration => e2e-tests}/tests/validator_staking.rs (100%) rename {tests-integration => e2e-tests}/tests_old/cw20_staking_app.rs (100%) rename {tests-integration => e2e-tests}/tests_old/cw721.rs (100%) rename {tests-integration => e2e-tests}/tests_old/ics721_app.rs (100%) rename {tests-integration => e2e-tests}/tests_old/kernel_path_bridge.rs (100%) rename {tests-integration => e2e-tests}/tests_old/mod.rs (100%) rename {tests-integration => e2e-tests}/tests_old/wrapped_cw721_app.rs (100%) create mode 100644 packages/std/macros/src/attrs/direct.rs create mode 100644 packages/std/macros/src/attrs/handler.rs create mode 100644 packages/std/macros/src/attrs/mod.rs create mode 100644 packages/std/macros/src/attrs/payable.rs create mode 100644 packages/std/macros/src/attrs/restricted.rs create mode 100644 packages/std/macros/src/attrs/utils.rs create mode 100644 packages/std/macros/src/execute.rs create mode 100644 packages/std/macros/src/instantiate.rs create mode 100644 packages/std/macros/src/query.rs create mode 100644 packages/std/macros/src/utils.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a8b754f3..080b9d489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- feat: Improved macros and execution flow for AMP [(#741)](https://github.com/andromedaprotocol/andromeda-core/pull/741) + ### Fixed ## Release 4 diff --git a/Cargo.lock b/Cargo.lock index 03475c775..b5c0b20a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", ] @@ -209,7 +208,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", ] [[package]] @@ -261,7 +259,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "test-case", ] @@ -315,14 +312,13 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", "cw20-base", ] [[package]] name = "andromeda-cw721" -version = "2.1.0" +version = "2.2.0-b.1" dependencies = [ "andromeda-non-fungible-tokens", "andromeda-std", @@ -661,17 +657,16 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", ] [[package]] name = "andromeda-macros" -version = "1.0.0" +version = "1.1.0-b.1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.96", ] [[package]] @@ -714,7 +709,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", ] @@ -732,7 +726,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", "hex", "serde", @@ -780,7 +773,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", ] [[package]] @@ -795,7 +787,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", ] @@ -865,7 +856,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw2 1.1.2", "serde-cw-value", "simple-shunting", @@ -891,7 +881,7 @@ dependencies = [ [[package]] name = "andromeda-std" -version = "1.5.0" +version = "1.5.1-b.1" dependencies = [ "andromeda-macros", "cosmwasm-schema", @@ -934,7 +924,6 @@ dependencies = [ "cw-multi-test", "cw-orch", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", "cw20", ] @@ -1029,7 +1018,6 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", ] [[package]] @@ -1069,6 +1057,7 @@ dependencies = [ "andromeda-app", "andromeda-finance", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", @@ -2333,6 +2322,61 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "e2e-tests" +version = "1.0.0" +dependencies = [ + "andromeda-address-list", + "andromeda-adodb", + "andromeda-app", + "andromeda-app-contract", + "andromeda-auction", + "andromeda-conditional-splitter", + "andromeda-counter", + "andromeda-crowdfund", + "andromeda-curve", + "andromeda-cw20", + "andromeda-cw20-staking", + "andromeda-cw721", + "andromeda-data-storage", + "andromeda-economics", + "andromeda-ecosystem", + "andromeda-finance", + "andromeda-fixed-amount-splitter", + "andromeda-fungible-tokens", + "andromeda-graph", + "andromeda-ibc-registry", + "andromeda-kernel", + "andromeda-lockdrop", + "andromeda-marketplace", + "andromeda-math", + "andromeda-modules", + "andromeda-non-fungible-tokens", + "andromeda-primitive", + "andromeda-rates", + "andromeda-shunting", + "andromeda-splitter", + "andromeda-std", + "andromeda-testing", + "andromeda-validator-staking", + "andromeda-vault", + "andromeda-vesting", + "andromeda-vfs", + "cosmwasm-schema", + "cosmwasm-std", + "cw-asset", + "cw-multi-test", + "cw-orch", + "cw-orch-interchain", + "cw-utils 1.0.3", + "cw20", + "cw721 0.18.0", + "cw721-base 0.18.0", + "ibc-relayer-types", + "rstest", + "toml 0.8.19", +] + [[package]] name = "ecdsa" version = "0.16.9" @@ -4277,9 +4321,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.8.0", "errno", @@ -5089,60 +5133,6 @@ dependencies = [ "test-case-core", ] -[[package]] -name = "tests-integration" -version = "1.0.0" -dependencies = [ - "andromeda-address-list", - "andromeda-adodb", - "andromeda-app", - "andromeda-app-contract", - "andromeda-auction", - "andromeda-conditional-splitter", - "andromeda-counter", - "andromeda-crowdfund", - "andromeda-curve", - "andromeda-cw20", - "andromeda-cw20-staking", - "andromeda-cw721", - "andromeda-data-storage", - "andromeda-economics", - "andromeda-ecosystem", - "andromeda-finance", - "andromeda-fixed-amount-splitter", - "andromeda-fungible-tokens", - "andromeda-graph", - "andromeda-ibc-registry", - "andromeda-kernel", - "andromeda-lockdrop", - "andromeda-marketplace", - "andromeda-math", - "andromeda-modules", - "andromeda-non-fungible-tokens", - "andromeda-primitive", - "andromeda-rates", - "andromeda-shunting", - "andromeda-splitter", - "andromeda-std", - "andromeda-testing", - "andromeda-validator-staking", - "andromeda-vault", - "andromeda-vesting", - "andromeda-vfs", - "cosmwasm-schema", - "cosmwasm-std", - "cw-asset", - "cw-multi-test", - "cw-orch", - "cw-orch-interchain", - "cw20", - "cw721 0.18.0", - "cw721-base 0.18.0", - "ibc-relayer-types", - "rstest", - "toml 0.8.19", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -5586,9 +5576,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" +checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" [[package]] name = "vcpkg" diff --git a/Cargo.toml b/Cargo.toml index a377406ef..c0a2e2970 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ "contracts/math/*", #Internal - "tests-integration", + "e2e-tests", "ibc-tests", ] resolver = "2" @@ -34,7 +34,7 @@ strip = true andromeda-std = { path = "./packages/std", default-features = false, features = [ "deploy", ] } -andromeda-macros = { path = "./packages/std/macros", default-features = false, version = "1.0.0" } +andromeda-macros = { path = "./packages/std/macros", default-features = false } andromeda-non-fungible-tokens = { path = "./packages/andromeda-non-fungible-tokens", version = "1.0.0" } andromeda-fungible-tokens = { path = "./packages/andromeda-fungible-tokens", version = "1.0.0" } andromeda-finance = { path = "./packages/andromeda-finance", version = "1.0.0" } diff --git a/Makefile b/Makefile index d7e0c5a47..87a75a358 100644 --- a/Makefile +++ b/Makefile @@ -49,13 +49,13 @@ unit-test: @echo "Unit tests complete! \033[0;32m\xE2\x9C\x94\033[0m" # Runs integration tests -integration-test: +e2e-test: @echo "Running integration tests..." - @cargo test -p tests-integration --quiet + @cargo test -p e2e-tests --quiet @echo "Integration tests complete! \033[0;32m\xE2\x9C\x94\033[0m" # Runs all tests -test: unit-test integration-test +test: unit-test e2e-test @echo "All tests complete! \033[0;32m\xE2\x9C\x94\033[0m" # Deploys OS to specified blockchain diff --git a/contracts/accounts/andromeda-fixed-multisig/src/contract.rs b/contracts/accounts/andromeda-fixed-multisig/src/contract.rs index 34e713e21..33aaad1f9 100644 --- a/contracts/accounts/andromeda-fixed-multisig/src/contract.rs +++ b/contracts/accounts/andromeda-fixed-multisig/src/contract.rs @@ -6,12 +6,13 @@ use andromeda_accounts::fixed_multisig::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; use cw2::set_contract_version; -use crate::execute::handle_execute; +use crate::execute::{execute_close, execute_execute, execute_propose, execute_vote}; use crate::query::{ list_proposals, list_voters, list_votes, query_proposal, query_threshold, query_vote, query_voter, reverse_proposals, @@ -87,19 +88,22 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); +// This contains functionality derived from the cw3-fixed-multisig contract. +// Source: https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw3-fixed-multisig +// License: Apache-2.0 +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), + ExecuteMsg::Propose { + title, + description, + msgs, + latest, + } => execute_propose(ctx, title, description, msgs, latest), + ExecuteMsg::Vote { proposal_id, vote } => execute_vote(ctx, proposal_id, vote), + ExecuteMsg::Execute { proposal_id } => execute_execute(ctx, proposal_id), + ExecuteMsg::Close { proposal_id } => execute_close(ctx, proposal_id), + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/accounts/andromeda-fixed-multisig/src/execute.rs b/contracts/accounts/andromeda-fixed-multisig/src/execute.rs index 966768beb..218965b4d 100644 --- a/contracts/accounts/andromeda-fixed-multisig/src/execute.rs +++ b/contracts/accounts/andromeda-fixed-multisig/src/execute.rs @@ -1,9 +1,4 @@ -use andromeda_accounts::fixed_multisig::ExecuteMsg; -use andromeda_std::{ - ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext}, - error::ContractError, -}; +use andromeda_std::{common::context::ExecuteContext, error::ContractError}; use cosmwasm_std::{CosmosMsg, Empty, Response}; use cw3::{Ballot, Proposal, Status, Vote, Votes}; use cw_utils::Expiration; @@ -11,38 +6,6 @@ use std::cmp::Ordering; use crate::state::{next_id, BALLOTS, CONFIG, PROPOSALS, VOTERS}; -// This contains functionality derived from the cw3-fixed-multisig contract. -// Source: https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw3-fixed-multisig -// License: Apache-2.0 - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { - ExecuteMsg::Propose { - title, - description, - msgs, - latest, - } => execute_propose(ctx, title, description, msgs, latest), - ExecuteMsg::Vote { proposal_id, vote } => execute_vote(ctx, proposal_id, vote), - ExecuteMsg::Execute { proposal_id } => execute_execute(ctx, proposal_id), - ExecuteMsg::Close { proposal_id } => execute_close(ctx, proposal_id), - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) -} - pub fn execute_propose( ctx: ExecuteContext, title: String, diff --git a/contracts/app/andromeda-app-contract/src/contract.rs b/contracts/app/andromeda-app-contract/src/contract.rs index 7524e39a8..80c9727e4 100644 --- a/contracts/app/andromeda-app-contract/src/contract.rs +++ b/contracts/app/andromeda-app-contract/src/contract.rs @@ -1,14 +1,16 @@ -use crate::reply::on_component_instantiation; -use crate::state::{add_app_component, create_cross_chain_message, ADO_ADDRESSES, APP_NAME}; +use crate::{ + reply::on_component_instantiation, + state::{add_app_component, create_cross_chain_message, ADO_ADDRESSES, APP_NAME}, +}; use andromeda_app::app::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use andromeda_std::ado_contract::ADOContract; -use andromeda_std::amp::AndrAddr; -use andromeda_std::common::context::ExecuteContext; -use andromeda_std::common::reply::ReplyId; -use andromeda_std::os::vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, ado_base::MigrateMsg, common::encode_binary, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_contract::ADOContract, + amp::AndrAddr, + andr_execute_fn, + common::{encode_binary, reply::ReplyId}, error::ContractError, + os::vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}, }; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; @@ -165,23 +167,8 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::AddAppComponent { component } => { execute::handle_add_app_component(ctx, component) diff --git a/contracts/app/andromeda-app-contract/src/execute.rs b/contracts/app/andromeda-app-contract/src/execute.rs index 02eb31540..bc17b27fc 100644 --- a/contracts/app/andromeda-app-contract/src/execute.rs +++ b/contracts/app/andromeda-app-contract/src/execute.rs @@ -34,11 +34,6 @@ pub fn handle_add_app_component( !matches!(component.component_type, ComponentType::CrossChain(..)), ContractError::CrossChainComponentsCurrentlyDisabled {} ); - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(ctx.deps.storage, sender)?, - ContractError::Unauthorized {} - ); let idx = add_app_component(ctx.deps.storage, &component)?; ensure!(idx < 50, ContractError::TooManyAppComponents {}); diff --git a/contracts/app/andromeda-app-contract/src/testing/mod.rs b/contracts/app/andromeda-app-contract/src/testing/mod.rs index a617531dc..18d4d89e7 100644 --- a/contracts/app/andromeda-app-contract/src/testing/mod.rs +++ b/contracts/app/andromeda-app-contract/src/testing/mod.rs @@ -1,17 +1,11 @@ -use crate::state::{ADO_DESCRIPTORS, ADO_IDX}; - use super::{contract::*, state::ADO_ADDRESSES}; +use crate::state::{ADO_DESCRIPTORS, ADO_IDX}; use andromeda_app::app::{AppComponent, ComponentType, ExecuteMsg, InstantiateMsg}; use andromeda_std::ado_base::ownership::OwnershipMessage; -// use andromeda_std::amp::AndrAddr; -// use andromeda_std::common::reply::ReplyId; -// use andromeda_std::os::vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}; use andromeda_std::testing::mock_querier::{ mock_dependencies_custom, MOCK_ANCHOR_CONTRACT, MOCK_CW20_CONTRACT, MOCK_KERNEL_CONTRACT, }; - use andromeda_std::{ado_base::AndromedaMsg, error::ContractError}; - use cosmwasm_std::{ attr, testing::{mock_env, mock_info}, diff --git a/contracts/data-storage/andromeda-boolean/Cargo.toml b/contracts/data-storage/andromeda-boolean/Cargo.toml index 4fe9894f9..1e9986fb6 100644 --- a/contracts/data-storage/andromeda-boolean/Cargo.toml +++ b/contracts/data-storage/andromeda-boolean/Cargo.toml @@ -27,7 +27,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw20 = { workspace = true } diff --git a/contracts/data-storage/andromeda-boolean/src/contract.rs b/contracts/data-storage/andromeda-boolean/src/contract.rs index c41adb143..0071223e5 100644 --- a/contracts/data-storage/andromeda-boolean/src/contract.rs +++ b/contracts/data-storage/andromeda-boolean/src/contract.rs @@ -1,9 +1,11 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Addr, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; +use cosmwasm_std::{ + ensure, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, +}; use crate::{ - execute::handle_execute, + execute::{delete_value, set_value, update_restriction}, query::{get_data_owner, get_value}, state::RESTRICTION, }; @@ -11,10 +13,12 @@ use andromeda_data_storage::boolean::{BooleanRestriction, ExecuteMsg, Instantiat use andromeda_std::{ ado_base::{ permissioning::{LocalPermission, Permission}, + rates::{Rate, RatesMessage}, InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; @@ -47,7 +51,7 @@ pub fn instantiate( RESTRICTION.save(deps.storage, &msg.restriction)?; if msg.restriction == BooleanRestriction::Private { - ADOContract::default().permission_action(SET_DELETE_VALUE_ACTION, deps.storage)?; + ADOContract::default().permission_action(deps.storage, SET_DELETE_VALUE_ACTION)?; ADOContract::set_permission( deps.storage, @@ -63,19 +67,25 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + match msg.clone() { + ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), + ExecuteMsg::SetValue { value } => set_value(ctx, value, action), + ExecuteMsg::DeleteValue {} => delete_value(ctx), + ExecuteMsg::Rates(rates_message) => match rates_message { + RatesMessage::SetRate { rate, .. } => match rate { + Rate::Local(local_rate) => { + // Percent rates aren't applicable in this case, so we enforce Flat rates + ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); + ADOContract::default().execute(ctx, msg) + } + Rate::Contract(_) => ADOContract::default().execute(ctx, msg), + }, + RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), + }, + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/data-storage/andromeda-boolean/src/execute.rs b/contracts/data-storage/andromeda-boolean/src/execute.rs index fe43e2cc2..40ae6a0fc 100644 --- a/contracts/data-storage/andromeda-boolean/src/execute.rs +++ b/contracts/data-storage/andromeda-boolean/src/execute.rs @@ -1,59 +1,22 @@ -use andromeda_data_storage::boolean::{BooleanRestriction, ExecuteMsg}; +use crate::{ + contract::SET_DELETE_VALUE_ACTION, + state::{DATA, DATA_OWNER, RESTRICTION}, +}; +use andromeda_data_storage::boolean::BooleanRestriction; use andromeda_std::{ - ado_base::rates::{Rate, RatesMessage}, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, rates::get_tax_amount, Funds}, + common::{context::ExecuteContext, rates::get_tax_amount, Funds}, error::ContractError, }; use cosmwasm_std::{ coin, ensure, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, Response, SubMsg, Uint128, }; -use cw_utils::nonpayable; - -use crate::{ - contract::SET_DELETE_VALUE_ACTION, - state::{DATA, DATA_OWNER, RESTRICTION}, -}; - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action = msg.as_ref().to_string(); - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - match msg.clone() { - ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), - ExecuteMsg::SetValue { value } => set_value(ctx, value, action), - ExecuteMsg::DeleteValue {} => delete_value(ctx), - ExecuteMsg::Rates(rates_message) => match rates_message { - RatesMessage::SetRate { rate, .. } => match rate { - Rate::Local(local_rate) => { - // Percent rates aren't applicable in this case, so we enforce Flat rates - ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); - ADOContract::default().execute(ctx, msg) - } - Rate::Contract(_) => ADOContract::default().execute(ctx, msg), - }, - RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), - }, - _ => ADOContract::default().execute(ctx, msg), - } -} pub fn update_restriction( ctx: ExecuteContext, restriction: BooleanRestriction, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); RESTRICTION.save(ctx.deps.storage, &restriction)?; Ok(Response::new() .add_attribute("method", "update_restriction") @@ -112,7 +75,6 @@ pub fn set_value( } pub fn delete_value(mut ctx: ExecuteContext) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender.clone(); let restriction = RESTRICTION.load(ctx.deps.storage)?; if restriction == BooleanRestriction::Private { diff --git a/contracts/data-storage/andromeda-form/src/contract.rs b/contracts/data-storage/andromeda-form/src/contract.rs index a8327f44d..19101fd5d 100644 --- a/contracts/data-storage/andromeda-form/src/contract.rs +++ b/contracts/data-storage/andromeda-form/src/contract.rs @@ -11,14 +11,15 @@ use andromeda_std::{ InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, ado_contract::ADOContract, - common::{ - context::ExecuteContext, encode_binary, expiration::get_and_validate_start_time, - Milliseconds, - }, + andr_execute_fn, + common::{encode_binary, expiration::get_and_validate_start_time, Milliseconds}, error::ContractError, }; -use crate::execute::{handle_execute, milliseconds_from_expiration}; +use crate::execute::{ + execute_close_form, execute_delete_submission, execute_edit_submission, execute_open_form, + execute_submit_form, milliseconds_from_expiration, +}; use crate::query::{ get_all_submissions, get_form_status, get_schema, get_submission, get_submission_ids, }; @@ -103,7 +104,7 @@ pub fn instantiate( if let Some(authorized_addresses_for_submission) = msg.authorized_addresses_for_submission { if !authorized_addresses_for_submission.is_empty() { - ADOContract::default().permission_action(SUBMIT_FORM_ACTION, deps.storage)?; + ADOContract::default().permission_action(deps.storage, SUBMIT_FORM_ACTION)?; } for address in authorized_addresses_for_submission { @@ -130,19 +131,22 @@ pub fn instantiate( Ok(response) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), + ExecuteMsg::SubmitForm { data } => execute_submit_form(ctx, data), + ExecuteMsg::DeleteSubmission { + submission_id, + wallet_address, + } => execute_delete_submission(ctx, submission_id, wallet_address), + ExecuteMsg::EditSubmission { + submission_id, + wallet_address, + data, + } => execute_edit_submission(ctx, submission_id, wallet_address, data), + ExecuteMsg::OpenForm {} => execute_open_form(ctx), + ExecuteMsg::CloseForm {} => execute_close_form(ctx), + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/data-storage/andromeda-form/src/execute.rs b/contracts/data-storage/andromeda-form/src/execute.rs index 8fd7d1055..07b6b5b6f 100644 --- a/contracts/data-storage/andromeda-form/src/execute.rs +++ b/contracts/data-storage/andromeda-form/src/execute.rs @@ -1,13 +1,13 @@ -use andromeda_data_storage::form::{ExecuteMsg, SubmissionInfo}; +use andromeda_data_storage::form::SubmissionInfo; use andromeda_modules::schema::{QueryMsg as SchemaQueryMsg, ValidateDataResponse}; use andromeda_std::{ ado_contract::ADOContract, amp::AndrAddr, - common::{actions::call_action, context::ExecuteContext, encode_binary, Milliseconds}, + common::{context::ExecuteContext, encode_binary, Milliseconds}, error::ContractError, }; use cosmwasm_std::{ensure, Env, QueryRequest, Response, Uint64, WasmQuery}; -use cw_utils::{nonpayable, Expiration}; +use cw_utils::Expiration; use crate::{ contract::SUBMIT_FORM_ACTION, @@ -16,42 +16,10 @@ use crate::{ const MAX_LIMIT: u64 = 100u64; -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { - ExecuteMsg::SubmitForm { data } => execute_submit_form(ctx, data), - ExecuteMsg::DeleteSubmission { - submission_id, - wallet_address, - } => execute_delete_submission(ctx, submission_id, wallet_address), - ExecuteMsg::EditSubmission { - submission_id, - wallet_address, - data, - } => execute_edit_submission(ctx, submission_id, wallet_address, data), - ExecuteMsg::OpenForm {} => execute_open_form(ctx), - ExecuteMsg::CloseForm {} => execute_close_form(ctx), - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) -} - pub fn execute_submit_form( mut ctx: ExecuteContext, data: String, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; ADOContract::default().is_permissioned( ctx.deps.branch(), @@ -141,13 +109,7 @@ pub fn execute_delete_submission( submission_id: u64, wallet_address: AndrAddr, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - let address = wallet_address.get_raw_address(&ctx.deps.as_ref())?; submissions() .load(ctx.deps.storage, &(submission_id, address.clone())) @@ -173,7 +135,6 @@ pub fn execute_edit_submission( wallet_address: AndrAddr, data: String, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; let config = CONFIG.load(ctx.deps.storage)?; @@ -246,13 +207,7 @@ pub fn execute_edit_submission( } pub fn execute_open_form(ctx: ExecuteContext) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - let mut config = CONFIG.load(ctx.deps.storage)?; let current_time = Milliseconds::from_nanos(ctx.env.block.time.nanos()); @@ -323,12 +278,7 @@ pub fn execute_open_form(ctx: ExecuteContext) -> Result } pub fn execute_close_form(ctx: ExecuteContext) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); let current_time = Milliseconds::from_nanos(ctx.env.block.time.nanos()); let end_time = current_time.plus_milliseconds(Milliseconds(1)); diff --git a/contracts/data-storage/andromeda-primitive/Cargo.toml b/contracts/data-storage/andromeda-primitive/Cargo.toml index e1a67b285..797a87bc4 100644 --- a/contracts/data-storage/andromeda-primitive/Cargo.toml +++ b/contracts/data-storage/andromeda-primitive/Cargo.toml @@ -30,7 +30,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw20 = { workspace = true } andromeda-std = { workspace = true, features = ["rates"] } diff --git a/contracts/data-storage/andromeda-primitive/src/contract.rs b/contracts/data-storage/andromeda-primitive/src/contract.rs index ab2bd55ef..3e25f6a95 100644 --- a/contracts/data-storage/andromeda-primitive/src/contract.rs +++ b/contracts/data-storage/andromeda-primitive/src/contract.rs @@ -1,17 +1,20 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; +use cosmwasm_std::{ensure, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; +use crate::execute::update_restriction; use andromeda_data_storage::primitive::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::ado_base::rates::{Rate, RatesMessage}; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; use crate::{ - execute::handle_execute, + execute::{delete_value, set_value}, query::{all_keys, get_type, get_value, owner_keys}, state::RESTRICTION, }; @@ -44,19 +47,25 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + match msg.clone() { + ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), + ExecuteMsg::SetValue { key, value } => set_value(ctx, key, value, action), + ExecuteMsg::DeleteValue { key } => delete_value(ctx, key), + ExecuteMsg::Rates(rates_message) => match rates_message { + RatesMessage::SetRate { rate, .. } => match rate { + Rate::Local(local_rate) => { + // Percent rates aren't applicable in this case, so we enforce Flat rates + ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); + ADOContract::default().execute(ctx, msg) + } + Rate::Contract(_) => ADOContract::default().execute(ctx, msg), + }, + RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), + }, + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/data-storage/andromeda-primitive/src/execute.rs b/contracts/data-storage/andromeda-primitive/src/execute.rs index 7cf61a6c6..f63ebda7e 100644 --- a/contracts/data-storage/andromeda-primitive/src/execute.rs +++ b/contracts/data-storage/andromeda-primitive/src/execute.rs @@ -1,59 +1,22 @@ -use andromeda_data_storage::primitive::{ExecuteMsg, Primitive, PrimitiveRestriction}; +use crate::{ + query::{get_key_or_default, has_key_permission}, + state::{DATA, KEY_OWNER, RESTRICTION}, +}; +use andromeda_data_storage::primitive::{Primitive, PrimitiveRestriction}; use andromeda_std::{ - ado_base::rates::{Rate, RatesMessage}, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, rates::get_tax_amount, Funds}, + common::{context::ExecuteContext, rates::get_tax_amount, Funds}, error::ContractError, }; use cosmwasm_std::{ coin, ensure, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, Response, StdError, SubMsg, Uint128, }; -use cw_utils::nonpayable; - -use crate::{ - query::{get_key_or_default, has_key_permission}, - state::{DATA, KEY_OWNER, RESTRICTION}, -}; - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action = msg.as_ref().to_string(); - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - match msg.clone() { - ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), - ExecuteMsg::SetValue { key, value } => set_value(ctx, key, value, action), - ExecuteMsg::DeleteValue { key } => delete_value(ctx, key), - ExecuteMsg::Rates(rates_message) => match rates_message { - RatesMessage::SetRate { rate, .. } => match rate { - Rate::Local(local_rate) => { - // Percent rates aren't applicable in this case, so we enforce Flat rates - ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); - ADOContract::default().execute(ctx, msg) - } - Rate::Contract(_) => ADOContract::default().execute(ctx, msg), - }, - RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), - }, - _ => ADOContract::default().execute(ctx, msg), - } -} pub fn update_restriction( ctx: ExecuteContext, restriction: PrimitiveRestriction, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); RESTRICTION.save(ctx.deps.storage, &restriction)?; Ok(Response::new() .add_attribute("method", "update_restriction") @@ -108,7 +71,6 @@ pub fn set_value( } pub fn delete_value(ctx: ExecuteContext, key: Option) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; let key = get_key_or_default(&key); diff --git a/contracts/data-storage/andromeda-string-storage/Cargo.toml b/contracts/data-storage/andromeda-string-storage/Cargo.toml index cdccd7209..cf58cca8e 100644 --- a/contracts/data-storage/andromeda-string-storage/Cargo.toml +++ b/contracts/data-storage/andromeda-string-storage/Cargo.toml @@ -27,7 +27,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw20 = { workspace = true } diff --git a/contracts/data-storage/andromeda-string-storage/src/contract.rs b/contracts/data-storage/andromeda-string-storage/src/contract.rs index eedafa00d..08bb453d5 100644 --- a/contracts/data-storage/andromeda-string-storage/src/contract.rs +++ b/contracts/data-storage/andromeda-string-storage/src/contract.rs @@ -1,17 +1,21 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; +use cosmwasm_std::{ensure, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; use crate::{ - execute::handle_execute, + execute::{delete_value, set_value, update_restriction}, query::{get_data_owner, get_value}, state::RESTRICTION, }; use andromeda_data_storage::string_storage::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ - ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_base::{ + rates::{Rate, RatesMessage}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, + }, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; @@ -43,19 +47,25 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + match msg.clone() { + ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), + ExecuteMsg::SetValue { value } => set_value(ctx, value, action), + ExecuteMsg::DeleteValue {} => delete_value(ctx), + ExecuteMsg::Rates(rates_message) => match rates_message { + RatesMessage::SetRate { rate, .. } => match rate { + Rate::Local(local_rate) => { + // Percent rates aren't applicable in this case, so we enforce Flat rates + ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); + ADOContract::default().execute(ctx, msg) + } + Rate::Contract(_) => ADOContract::default().execute(ctx, msg), + }, + RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), + }, + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/data-storage/andromeda-string-storage/src/execute.rs b/contracts/data-storage/andromeda-string-storage/src/execute.rs index 70120fbdd..ee56d23f3 100644 --- a/contracts/data-storage/andromeda-string-storage/src/execute.rs +++ b/contracts/data-storage/andromeda-string-storage/src/execute.rs @@ -1,59 +1,22 @@ -use andromeda_data_storage::string_storage::{ExecuteMsg, StringStorage, StringStorageRestriction}; +use crate::{ + query::has_permission, + state::{DATA, DATA_OWNER, RESTRICTION}, +}; +use andromeda_data_storage::string_storage::{StringStorage, StringStorageRestriction}; use andromeda_std::{ - ado_base::rates::{Rate, RatesMessage}, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, rates::get_tax_amount, Funds}, + common::{context::ExecuteContext, rates::get_tax_amount, Funds}, error::ContractError, }; use cosmwasm_std::{ coin, ensure, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, Response, SubMsg, Uint128, }; -use cw_utils::nonpayable; - -use crate::{ - query::has_permission, - state::{DATA, DATA_OWNER, RESTRICTION}, -}; - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action = msg.as_ref().to_string(); - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - match msg.clone() { - ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), - ExecuteMsg::SetValue { value } => set_value(ctx, value, action), - ExecuteMsg::DeleteValue {} => delete_value(ctx), - ExecuteMsg::Rates(rates_message) => match rates_message { - RatesMessage::SetRate { rate, .. } => match rate { - Rate::Local(local_rate) => { - // Percent rates aren't applicable in this case, so we enforce Flat rates - ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); - ADOContract::default().execute(ctx, msg) - } - Rate::Contract(_) => ADOContract::default().execute(ctx, msg), - }, - RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), - }, - _ => ADOContract::default().execute(ctx, msg), - } -} pub fn update_restriction( ctx: ExecuteContext, restriction: StringStorageRestriction, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); RESTRICTION.save(ctx.deps.storage, &restriction)?; Ok(Response::new() .add_attribute("method", "update_restriction") @@ -98,7 +61,6 @@ pub fn set_value( } pub fn delete_value(ctx: ExecuteContext) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; ensure!( has_permission(ctx.deps.storage, &sender)?, diff --git a/contracts/ecosystem/andromeda-vault/Cargo.toml b/contracts/ecosystem/andromeda-vault/Cargo.toml index 58aaf479b..a7a4313b1 100644 --- a/contracts/ecosystem/andromeda-vault/Cargo.toml +++ b/contracts/ecosystem/andromeda-vault/Cargo.toml @@ -15,8 +15,6 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } - andromeda-ecosystem = { workspace = true } andromeda-std = { workspace = true } diff --git a/contracts/ecosystem/andromeda-vault/src/contract.rs b/contracts/ecosystem/andromeda-vault/src/contract.rs index ac6231987..1874e58c2 100644 --- a/contracts/ecosystem/andromeda-vault/src/contract.rs +++ b/contracts/ecosystem/andromeda-vault/src/contract.rs @@ -5,7 +5,7 @@ use andromeda_ecosystem::vault::{ use andromeda_std::ado_base::ownership::ContractOwnerResponse; use andromeda_std::ado_contract::ADOContract; use andromeda_std::amp::{AndrAddr, Recipient}; -use andromeda_std::common::actions::call_action; +use andromeda_std::andr_execute_fn; use andromeda_std::common::context::ExecuteContext; use andromeda_std::common::encode_binary; use andromeda_std::{ @@ -19,8 +19,6 @@ use cosmwasm_std::{ ContractResult, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, QueryRequest, Reply, ReplyOn, Response, StdError, SubMsg, SystemResult, Uint128, WasmMsg, WasmQuery, }; -use cw_utils::nonpayable; - // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-vault"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -58,31 +56,8 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::Deposit { recipient, msg } => execute_deposit(ctx, recipient, msg), ExecuteMsg::WithdrawVault { @@ -216,8 +191,6 @@ pub fn execute_withdraw( strategy: Option, ) -> Result { let ExecuteContext { info, deps, .. } = ctx; - nonpayable(&info)?; - ensure!( !withdrawals.is_empty(), ContractError::InvalidTokensToWithdraw { @@ -339,13 +312,7 @@ fn execute_update_strategy( strategy: StrategyType, address: AndrAddr, ) -> Result { - let ExecuteContext { - deps, env, info, .. - } = ctx; - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_ref())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let strategy_addr = address.get_raw_address(&deps.as_ref())?; //The vault contract must be an operator for the given contract in order to enable withdrawals diff --git a/contracts/finance/andromeda-conditional-splitter/src/contract.rs b/contracts/finance/andromeda-conditional-splitter/src/contract.rs index f0a2d1a16..3f9ff21ba 100644 --- a/contracts/finance/andromeda-conditional-splitter/src/contract.rs +++ b/contracts/finance/andromeda-conditional-splitter/src/contract.rs @@ -8,10 +8,8 @@ use std::vec; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::messages::AMPPkt, - common::{ - actions::call_action, encode_binary, expiration::Expiry, Milliseconds, - MillisecondsExpiration, - }, + andr_execute_fn, + common::{encode_binary, expiration::Expiry, Milliseconds, MillisecondsExpiration}, error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; @@ -19,7 +17,6 @@ use cosmwasm_std::{ attr, ensure, entry_point, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, SubMsg, Uint128, }; -use cw_utils::nonpayable; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-conditional-splitter"; @@ -94,41 +91,14 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - let res = match msg { ExecuteMsg::UpdateThresholds { thresholds } => execute_update_thresholds(ctx, thresholds), ExecuteMsg::UpdateLock { lock_time } => execute_update_lock(ctx, lock_time), ExecuteMsg::Send {} => execute_send(ctx), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn execute_send(ctx: ExecuteContext) -> Result { @@ -213,16 +183,7 @@ fn execute_update_thresholds( ctx: ExecuteContext, thresholds: Vec, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let conditional_splitter = CONDITIONAL_SPLITTER.load(deps.storage)?; @@ -245,16 +206,7 @@ fn execute_update_thresholds( } fn execute_update_lock(ctx: ExecuteContext, lock_time: Expiry) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut conditional_splitter = CONDITIONAL_SPLITTER.load(deps.storage)?; diff --git a/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs b/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs index c78af5df3..eb1a25aea 100644 --- a/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs +++ b/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs @@ -6,7 +6,6 @@ use andromeda_std::{ common::{expiration::Expiry, Milliseconds}, error::ContractError, }; -use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ attr, from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, @@ -198,12 +197,10 @@ fn test_execute_update_lock() { let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); assert_eq!( - Response::default() - .add_attributes(vec![ - attr("action", "update_lock"), - attr("locked", lock_time.get_time(&env.block).to_string()) - ]) - .add_submessage(generate_economics_message(OWNER, "UpdateLock")), + Response::default().add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", lock_time.get_time(&env.block).to_string()) + ]), res ); @@ -317,9 +314,7 @@ fn test_execute_update_thresholds() { let info = mock_info(OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::default() - .add_attributes(vec![attr("action", "update_thresholds")]) - .add_submessage(generate_economics_message(OWNER, "UpdateThresholds")), + Response::default().add_attributes(vec![attr("action", "update_thresholds")]), res ); @@ -437,8 +432,7 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -479,8 +473,7 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -513,8 +506,7 @@ fn test_execute_send() { let expected_res = Response::new() // No refund for the sender since the percentages add up to 100 .add_submessage(amp_msg) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); } @@ -580,84 +572,81 @@ fn test_execute_send_threshold_not_found() { } ); } +#[test] +fn test_execute_send_ado_recipient() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 10000u128; + let info = mock_info(OWNER, &[Coin::new(sender_funds_amount, "uluna")]); + + let recip_address1 = "address1".to_string(); + let recip_address2 = "address2".to_string(); + + let recip1 = Recipient::from_string(recip_address1); + let recip2 = Recipient::from_string(recip_address2); + + let msg = ExecuteMsg::Send {}; + + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1000, "uluna")])) + .unwrap(); + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(2000, "uluna")])) + .unwrap(); + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg_1, amp_msg_2], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(vec![Coin::new(1000, "uluna"), Coin::new(2000, "uluna")]), + 1, + ) + .unwrap(); -// #[test] -// fn test_execute_send_ado_recipient() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let _res: Response = init(deps.as_mut()); - -// let sender_funds_amount = 10000u128; -// let info = mock_info(OWNER, &[Coin::new(sender_funds_amount, "uluna")]); - -// let recip_address1 = "address1".to_string(); -// let recip_percent1 = 10; // 10% - -// let recip_address2 = "address2".to_string(); -// let recip_percent2 = 20; // 20% - -// let recip1 = Recipient::from_string(recip_address1); -// let recip2 = Recipient::from_string(recip_address2); - -// let recipient = vec![ -// AddressFunds { -// recipient: recip1.clone(), -// percent: Decimal::percent(recip_percent1), -// }, -// AddressFunds { -// recipient: recip2.clone(), -// percent: Decimal::percent(recip_percent2), -// }, -// ]; -// let msg = ExecuteMsg::Send {}; - -// let amp_msg_1 = recip1 -// .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1000, "uluna")])) -// .unwrap(); -// let amp_msg_2 = recip2 -// .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(2000, "uluna")])) -// .unwrap(); -// let amp_pkt = AMPPkt::new( -// MOCK_CONTRACT_ADDR.to_string(), -// MOCK_CONTRACT_ADDR.to_string(), -// vec![amp_msg_1, amp_msg_2], -// ); -// let amp_msg = amp_pkt -// .to_sub_msg( -// MOCK_KERNEL_CONTRACT, -// Some(vec![Coin::new(1000, "uluna"), Coin::new(2000, "uluna")]), -// 1, -// ) -// .unwrap(); - -// let splitter = ConditionalSplitter { -// recipients: recipient, -// lock: Milliseconds::default(), -// }; - -// CONDITIONAL_SPLITTER -// .save(deps.as_mut().storage, &splitter) -// .unwrap(); - -// let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); - -// let expected_res = Response::new() -// .add_submessages(vec![ -// SubMsg::new( -// // refunds remainder to sender -// CosmosMsg::Bank(BankMsg::Send { -// to_address: info.sender.to_string(), -// amount: vec![Coin::new(7000, "uluna")], // 10000 * 0.7 remainder -// }), -// ), -// amp_msg, -// ]) -// .add_attribute("action", "send") -// .add_attribute("sender", "creator") -// .add_submessage(generate_economics_message(OWNER, "Send")); - -// assert_eq!(res, expected_res); -// } + let splitter = ConditionalSplitter { + thresholds: vec![Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + recip1.clone(), // 10% + Decimal::from_ratio(Uint128::one(), Uint128::new(10)), + ), + AddressPercent::new( + recip2.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + ], + )], + lock_time: Milliseconds::default(), + }; + + CONDITIONAL_SPLITTER + .save(deps.as_mut().storage, &splitter) + .unwrap(); + + let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); + + let expected_res = Response::new() + .add_submessages(vec![ + SubMsg::new( + // refunds remainder to sender + CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![Coin::new(7000, "uluna")], // 10000 * 0.7 remainder + }), + ), + amp_msg, + ]) + .add_attribute("action", "send") + .add_attribute("sender", "creator"); + + assert_eq!(res, expected_res); +} #[test] fn test_handle_packet_exit_with_error_true() { @@ -804,8 +793,7 @@ fn test_update_app_contract() { assert_eq!( Response::new() .add_attribute("action", "update_app_contract") - .add_attribute("address", "app_contract") - .add_submessage(generate_economics_message(OWNER, "UpdateAppContract")), + .add_attribute("address", "app_contract"), res ); } @@ -911,8 +899,7 @@ fn test_execute_send_with_multiple_thresholds() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -953,8 +940,7 @@ fn test_execute_send_with_multiple_thresholds() { })), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -995,8 +981,7 @@ fn test_execute_send_with_multiple_thresholds() { })), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); } diff --git a/contracts/finance/andromeda-cross-chain-swap/src/contract.rs b/contracts/finance/andromeda-cross-chain-swap/src/contract.rs index 327841421..5ad248429 100644 --- a/contracts/finance/andromeda-cross-chain-swap/src/contract.rs +++ b/contracts/finance/andromeda-cross-chain-swap/src/contract.rs @@ -1,7 +1,7 @@ use andromeda_finance::cross_chain_swap::{ ExecuteMsg, InstantiateMsg, OsmosisSwapResponse, QueryMsg, }; -use andromeda_std::common::actions::call_action; +use andromeda_std::andr_execute_fn; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::{ @@ -118,32 +118,8 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let _contract = ADOContract::default(); - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::SwapAndForward { dex, diff --git a/contracts/finance/andromeda-fixed-amount-splitter/src/contract.rs b/contracts/finance/andromeda-fixed-amount-splitter/src/contract.rs index 9c47cb1d8..649144704 100644 --- a/contracts/finance/andromeda-fixed-amount-splitter/src/contract.rs +++ b/contracts/finance/andromeda-fixed-amount-splitter/src/contract.rs @@ -11,7 +11,8 @@ use andromeda_finance::{ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::{messages::AMPPkt, Recipient}, - common::{actions::call_action, encode_binary, expiration::Expiry, Milliseconds}, + andr_execute_fn, + common::{encode_binary, expiration::Expiry, Milliseconds}, error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; @@ -20,7 +21,6 @@ use cosmwasm_std::{ MessageInfo, Reply, Response, StdError, SubMsg, Uint128, }; use cw20::{Cw20Coin, Cw20ReceiveMsg}; -use cw_utils::nonpayable; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-fixed-amount-splitter"; @@ -84,32 +84,9 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - let res = match msg { ExecuteMsg::UpdateRecipients { recipients } => execute_update_recipients(ctx, recipients), ExecuteMsg::UpdateLock { lock_time } => execute_update_lock(ctx, lock_time), ExecuteMsg::UpdateDefaultRecipient { recipient } => { @@ -118,11 +95,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result handle_receive_cw20(ctx, receive_msg), ExecuteMsg::Send { config } => execute_send(ctx, config), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } pub fn handle_receive_cw20( @@ -130,8 +103,6 @@ pub fn handle_receive_cw20( receive_msg: Cw20ReceiveMsg, ) -> Result { let ExecuteContext { ref info, .. } = ctx; - nonpayable(info)?; - let asset_sent = info.sender.clone().into_string(); let amount_sent = receive_msg.amount; let sender = receive_msg.sender; @@ -231,17 +202,7 @@ fn execute_update_default_recipient( ctx: ExecuteContext, recipient: Option, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; // Can't call this function while the lock isn't expired @@ -378,16 +339,7 @@ fn execute_update_recipients( ctx: ExecuteContext, recipients: Vec, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; validate_recipient_list(deps.as_ref(), recipients.clone())?; @@ -411,16 +363,7 @@ fn execute_update_recipients( } fn execute_update_lock(ctx: ExecuteContext, lock_time: Expiry) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; diff --git a/contracts/finance/andromeda-fixed-amount-splitter/src/testing/tests.rs b/contracts/finance/andromeda-fixed-amount-splitter/src/testing/tests.rs index b27828125..59c8cf036 100644 --- a/contracts/finance/andromeda-fixed-amount-splitter/src/testing/tests.rs +++ b/contracts/finance/andromeda-fixed-amount-splitter/src/testing/tests.rs @@ -6,7 +6,6 @@ use andromeda_std::{ common::{expiration::Expiry, Milliseconds}, error::ContractError, }; -use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ attr, coin, coins, from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, @@ -79,12 +78,10 @@ fn test_execute_update_lock() { .plus_seconds(current_time) .plus_milliseconds(Milliseconds(879)); assert_eq!( - Response::default() - .add_attributes(vec![ - attr("action", "update_lock"), - attr("locked", new_lock.to_string()) - ]) - .add_submessage(generate_economics_message(OWNER, "UpdateLock")), + Response::default().add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", new_lock.to_string()) + ]), res ); @@ -148,9 +145,7 @@ fn test_execute_update_recipients() { let info = mock_info(OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::default() - .add_attributes(vec![attr("action", "update_recipients")]) - .add_submessage(generate_economics_message(OWNER, "UpdateRecipients")), + Response::default().add_attributes(vec![attr("action", "update_recipients")]), res ); @@ -253,8 +248,7 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -302,8 +296,7 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!(res, expected_res); @@ -378,8 +371,7 @@ fn test_execute_send_ado_recipient() { amp_msg, ]) .add_attribute("action", "send") - .add_attribute("sender", "creator") - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attribute("sender", "creator"); assert_eq!(res, expected_res); } @@ -532,8 +524,7 @@ fn test_update_app_contract() { assert_eq!( Response::new() .add_attribute("action", "update_app_contract") - .add_attribute("address", "app_contract") - .add_submessage(generate_economics_message(OWNER, "UpdateAppContract")), + .add_attribute("address", "app_contract"), res ); } @@ -646,7 +637,7 @@ fn test_send_with_config_unlocked(unlocked_splitter: (DepsMut<'static>, Splitter let res = execute(deps, mock_env(), info, msg).unwrap(); // Verify response contains expected submessages and refund - assert_eq!(3, res.messages.len()); // 1 for refund, 1 for transfer, 1 for economics + assert_eq!(2, res.messages.len()); // 1 for refund, 1 for transfer assert!(res.attributes.contains(&attr("action", "send"))); } @@ -660,7 +651,7 @@ fn test_send_without_config_locked(locked_splitter: (DepsMut<'static>, Splitter) let res = execute(deps, mock_env(), info, msg).unwrap(); // Verify response contains expected submessages and refund - assert_eq!(3, res.messages.len()); // 1 for refund, 1 for transfers, 1 for economics + assert_eq!(2, res.messages.len()); // 1 for refund, 1 for transfers assert!(res.attributes.contains(&attr("action", "send"))); } @@ -674,6 +665,6 @@ fn test_send_without_config_unlocked(unlocked_splitter: (DepsMut<'static>, Split let res = execute(deps, mock_env(), info, msg).unwrap(); // Verify response contains expected submessages and refund - assert_eq!(3, res.messages.len()); // 1 for refund, 1 for transfers, 1 for economics + assert_eq!(2, res.messages.len()); // 1 for refund, 1 for transfers assert!(res.attributes.contains(&attr("action", "send"))); } diff --git a/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs b/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs index f1fe17217..2f34c1b39 100644 --- a/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs +++ b/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs @@ -2,20 +2,18 @@ use crate::state::{ACCOUNTS, ALLOWED_COIN}; use andromeda_finance::rate_limiting_withdrawals::{ AccountDetails, CoinAllowance, ExecuteMsg, InstantiateMsg, MinimumFrequency, QueryMsg, }; - -use andromeda_std::ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}; -use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::actions::call_action; -use andromeda_std::common::context::ExecuteContext; -use andromeda_std::common::Milliseconds; -use andromeda_std::{common::encode_binary, error::ContractError}; - +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_contract::ADOContract, + andr_execute_fn, + common::{context::ExecuteContext, encode_binary, Milliseconds}, + error::ContractError, +}; use cosmwasm_std::{ ensure, entry_point, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, Uint128, }; - -use cw_utils::{nonpayable, one_coin}; +use cw_utils::one_coin; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-rate-limiting-withdrawals"; @@ -70,41 +68,13 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { ExecuteMsg::Deposit { recipient } => execute_deposit(ctx, recipient), ExecuteMsg::Withdraw { amount } => execute_withdraw(ctx, amount), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn execute_deposit( @@ -169,8 +139,6 @@ fn execute_withdraw(ctx: ExecuteContext, amount: Uint128) -> Result Result Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let res = match msg { ExecuteMsg::UpdateRecipients { recipients } => execute_update_recipients(ctx, recipients), ExecuteMsg::UpdateLock { lock_time } => execute_update_lock(ctx, lock_time), @@ -107,36 +84,16 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result handle_receive_cw20(ctx, receive_msg), _ => ADOContract::default().execute(ctx, msg), }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + + Ok(res) } pub fn handle_receive_cw20( ctx: ExecuteContext, receive_msg: Cw20ReceiveMsg, ) -> Result { - // let is_valid_cw20 = ADOContract::default() - // .is_permissioned( - // ctx.deps.branch(), - // ctx.env.clone(), - // SEND_CW20_ACTION, - // ctx.info.sender.clone(), - // ) - // .is_ok(); - - // ensure!( - // is_valid_cw20, - // ContractError::InvalidAsset { - // asset: ctx.info.sender.into_string() - // } - // ); - - let ExecuteContext { ref info, .. } = ctx; - nonpayable(info)?; - - let asset_sent = info.sender.clone().into_string(); + let ExecuteContext { ref raw_info, .. } = ctx; + let asset_sent = raw_info.sender.clone().into_string(); let amount_sent = receive_msg.amount; let sender = receive_msg.sender; @@ -236,7 +193,7 @@ fn execute_send( remainder_recipient.generate_direct_msg(&deps.as_ref(), remainder_funds)?; msgs.push(native_msg); } - let kernel_address = ADOContract::default().get_kernel_address(deps.as_ref().storage)?; + let kernel_address = ctx.contract.get_kernel_address(deps.as_ref().storage)?; if !pkt.messages.is_empty() { let distro_msg = pkt.to_sub_msg(kernel_address, Some(amp_funds), 1)?; @@ -323,16 +280,7 @@ fn execute_update_recipients( ctx: ExecuteContext, recipients: Vec, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; validate_recipient_list(deps.as_ref(), recipients.clone())?; @@ -356,16 +304,7 @@ fn execute_update_recipients( } fn execute_update_lock(ctx: ExecuteContext, lock_time: Expiry) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; @@ -391,16 +330,7 @@ fn execute_update_default_recipient( ctx: ExecuteContext, recipient: Option, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; diff --git a/contracts/finance/andromeda-splitter/src/testing/tests.rs b/contracts/finance/andromeda-splitter/src/testing/tests.rs index e8db72dba..cd88466a0 100644 --- a/contracts/finance/andromeda-splitter/src/testing/tests.rs +++ b/contracts/finance/andromeda-splitter/src/testing/tests.rs @@ -6,7 +6,6 @@ use andromeda_std::{ common::{expiration::Expiry, Milliseconds}, error::ContractError, }; -use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ attr, from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, @@ -184,12 +183,10 @@ fn test_execute_update_lock() { .plus_seconds(current_time) .plus_milliseconds(Milliseconds(879)); assert_eq!( - Response::default() - .add_attributes(vec![ - attr("action", "update_lock"), - attr("locked", "1571970219879".to_string()) - ]) - .add_submessage(generate_economics_message(OWNER, "UpdateLock")), + Response::default().add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", "1571970219879".to_string()) + ]), res ); @@ -253,9 +250,7 @@ fn test_execute_update_recipients() { let info = mock_info(OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::default() - .add_attributes(vec![attr("action", "update_recipients")]) - .add_submessage(generate_economics_message(OWNER, "UpdateRecipients")), + Response::default().add_attributes(vec![attr("action", "update_recipients")]), res ); @@ -344,8 +339,7 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -381,8 +375,7 @@ fn test_execute_send() { ), amp_msg.clone(), ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); @@ -430,8 +423,7 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); assert_eq!(res, expected_res); } @@ -507,8 +499,7 @@ fn test_execute_send_ado_recipient() { amp_msg, ]) .add_attribute("action", "send") - .add_attribute("sender", "creator") - .add_submessage(generate_economics_message(OWNER, "Send")); + .add_attribute("sender", "creator"); assert_eq!(res, expected_res); } @@ -655,8 +646,7 @@ fn test_update_app_contract() { assert_eq!( Response::new() .add_attribute("action", "update_app_contract") - .add_attribute("address", "app_contract") - .add_submessage(generate_economics_message(OWNER, "UpdateAppContract")), + .add_attribute("address", "app_contract"), res ); } @@ -769,7 +759,7 @@ fn test_send_with_config_unlocked(unlocked_splitter: (DepsMut<'static>, Splitter let res = execute(deps, mock_env(), info, msg).unwrap(); // Verify response contains expected submessages - assert_eq!(2, res.messages.len()); + assert_eq!(1, res.messages.len()); assert!(res.attributes.contains(&attr("action", "send"))); } diff --git a/contracts/finance/andromeda-timelock/src/contract.rs b/contracts/finance/andromeda-timelock/src/contract.rs index 0d5abecb3..1c8276d7c 100644 --- a/contracts/finance/andromeda-timelock/src/contract.rs +++ b/contracts/finance/andromeda-timelock/src/contract.rs @@ -5,7 +5,8 @@ use andromeda_finance::timelock::{ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::Recipient, - common::{actions::call_action, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; @@ -45,32 +46,9 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - let res = match msg { ExecuteMsg::HoldFunds { condition, recipient, @@ -86,11 +64,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_release_specific_funds(ctx, owner, recipient_addr), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn execute_hold_funds( diff --git a/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs b/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs index d250753a4..e04c1bb82 100644 --- a/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs +++ b/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs @@ -19,7 +19,7 @@ pub fn mock_dependencies_custom( let custom_querier: WasmMockQuerier = WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); let storage = MockStorage::default(); - let mut deps = OwnedDeps { + let mut deps: OwnedDeps = OwnedDeps { storage, api: MockApi::default(), querier: custom_querier, diff --git a/contracts/finance/andromeda-timelock/src/testing/tests.rs b/contracts/finance/andromeda-timelock/src/testing/tests.rs index bf6ad24f3..19dccb2b0 100644 --- a/contracts/finance/andromeda-timelock/src/testing/tests.rs +++ b/contracts/finance/andromeda-timelock/src/testing/tests.rs @@ -10,7 +10,6 @@ use andromeda_std::{ common::{expiration::Expiry, Milliseconds}, error::ContractError, }; -use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ attr, coin, coins, from_json, testing::{mock_env, mock_info}, @@ -34,17 +33,15 @@ fn test_execute_hold_funds() { }; let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - let expected = Response::default() - .add_attributes(vec![ - attr("action", "hold_funds"), - attr("sender", info.sender.to_string()), - attr( - "recipient", - format!("{:?}", Recipient::from_string(info.sender.to_string())), - ), - attr("condition", format!("{:?}", Some(condition.clone()))), - ]) - .add_submessage(generate_economics_message("owner", "HoldFunds")); + let expected = Response::default().add_attributes(vec![ + attr("action", "hold_funds"), + attr("sender", info.sender.to_string()), + attr( + "recipient", + format!("{:?}", Recipient::from_string(info.sender.to_string())), + ), + attr("condition", format!("{:?}", Some(condition.clone()))), + ]); assert_eq!(expected, res); let query_msg = QueryMsg::GetLockedFunds { @@ -140,13 +137,10 @@ fn test_execute_release_funds_no_condition() { amount: info.funds, }; assert_eq!( - Response::new() - .add_message(bank_msg) - .add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]) - .add_submessage(generate_economics_message(owner, "ReleaseFunds")), + Response::new().add_message(bank_msg).add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]), res ); } @@ -189,8 +183,7 @@ fn test_execute_release_multiple_escrows() { .add_attributes(vec![ attr("action", "release_funds"), attr("recipient_addr", "recipient"), - ]) - .add_submessage(generate_economics_message("sender2", "ReleaseFunds")), + ]), res ); } @@ -224,13 +217,10 @@ fn test_execute_release_funds_time_condition() { amount: info.funds, }; assert_eq!( - Response::new() - .add_message(bank_msg) - .add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]) - .add_submessage(generate_economics_message(owner, "ReleaseFunds")), + Response::new().add_message(bank_msg).add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]), res ); } @@ -308,13 +298,10 @@ fn test_execute_release_funds_min_funds_condition() { amount: vec![coin(210, "uusd"), coin(120, "uluna")], }; assert_eq!( - Response::new() - .add_message(bank_msg) - .add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]) - .add_submessage(generate_economics_message(owner, "ReleaseFunds")), + Response::new().add_message(bank_msg).add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]), res ); } @@ -357,13 +344,10 @@ fn test_execute_release_specific_funds_no_condition() { amount: info.funds, }; assert_eq!( - Response::new() - .add_message(bank_msg) - .add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]) - .add_submessage(generate_economics_message(owner, "ReleaseSpecificFunds")), + Response::new().add_message(bank_msg).add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]), res ); } @@ -396,13 +380,10 @@ fn test_execute_release_specific_funds_time_condition() { amount: info.funds, }; assert_eq!( - Response::new() - .add_message(bank_msg) - .add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]) - .add_submessage(generate_economics_message(owner, "ReleaseSpecificFunds")), + Response::new().add_message(bank_msg).add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]), res ); } @@ -452,13 +433,10 @@ fn test_execute_release_specific_funds_min_funds_condition() { amount: vec![coin(210, "uusd"), coin(120, "uluna")], }; assert_eq!( - Response::new() - .add_message(bank_msg) - .add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]) - .add_submessage(generate_economics_message(owner, "ReleaseSpecificFunds")), + Response::new().add_message(bank_msg).add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]), res ); } diff --git a/contracts/finance/andromeda-validator-staking/src/contract.rs b/contracts/finance/andromeda-validator-staking/src/contract.rs index bc31cc291..bfcb76c84 100644 --- a/contracts/finance/andromeda-validator-staking/src/contract.rs +++ b/contracts/finance/andromeda-validator-staking/src/contract.rs @@ -17,6 +17,7 @@ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::AndrAddr, + andr_execute_fn, common::{context::ExecuteContext, distribution::MsgWithdrawDelegatorReward, encode_binary}, error::ContractError, os::aos_querier::AOSQuerier, @@ -63,24 +64,8 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::Stake { validator } => execute_stake(ctx, validator), ExecuteMsg::Unstake { validator, amount } => execute_unstake(ctx, validator, amount), @@ -160,15 +145,7 @@ fn execute_redelegate( dst_validator: Addr, amount: Option, ) -> Result { - let ExecuteContext { - deps, env, info, .. - } = ctx; - - // Ensure sender is the contract owner - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let src_validator = match src_validator { Some(addr) => { @@ -231,12 +208,6 @@ fn execute_unstake( } = ctx; let delegator = env.contract.address; - // Ensure sender is the contract owner - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let default_validator = DEFAULT_VALIDATOR.load(deps.storage)?; let validator = validator.unwrap_or(default_validator); @@ -386,12 +357,6 @@ fn execute_withdraw_fund( deps, info, env, .. } = ctx; - // Ensure sender is the contract owner - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let recipient = recipient.map_or(Ok(info.sender), |r| r.get_raw_address(&deps.as_ref()))?; let funds = denom.map_or( deps.querier @@ -432,12 +397,7 @@ fn execute_update_default_validator( ctx: ExecuteContext, validator: Addr, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, .. } = ctx; // Check if the validator is valid before setting to default validator is_validator(&deps, &validator)?; @@ -533,15 +493,14 @@ fn on_restake_reward(deps: DepsMut, env: Env, msg: Reply) -> Result OwnedDeps { +pub fn mock_dependencies_custom( + contract_balance: &[Coin], +) -> OwnedDeps { let default_validator = Validator { address: String::from(DEFAULT_VALIDATOR), commission: Decimal::percent(1), @@ -18,14 +32,80 @@ pub fn mock_dependencies_custom() -> OwnedDeps QuerierResult { + // MockQuerier doesn't support Custom, so we ignore it completely here + let request: QueryRequest = match from_json(bin_request) { + Ok(v) => v, + Err(e) => { + return SystemResult::Err(SystemError::InvalidRequest { + error: format!("Parsing query request: {e}"), + request: bin_request.into(), + }) + } + }; + self.handle_query(&request) + } +} + +impl WasmMockQuerier { + pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { + match &request { + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) + } + _ => MockAndromedaQuerier::default().handle_query(&self.base, request), + } + } + + pub fn new(base: MockQuerier) -> Self { + WasmMockQuerier { + base, + contract_address: mock_env().contract.address.to_string(), + tokens_left_to_burn: 2, + } } } diff --git a/contracts/finance/andromeda-validator-staking/src/testing/tests.rs b/contracts/finance/andromeda-validator-staking/src/testing/tests.rs index 3af016064..d48b59178 100644 --- a/contracts/finance/andromeda-validator-staking/src/testing/tests.rs +++ b/contracts/finance/andromeda-validator-staking/src/testing/tests.rs @@ -27,7 +27,7 @@ fn init(deps: DepsMut, default_validator: Addr) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::CreateBatch { lockup_duration, @@ -111,10 +83,6 @@ fn execute_create_batch( let ExecuteContext { deps, info, env, .. } = ctx; - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); let config = CONFIG.load(deps.storage)?; let current_time = Milliseconds::from_seconds(env.block.time.seconds()); @@ -200,15 +168,7 @@ fn execute_claim( number_of_claims: Option, batch_id: u64, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - let contract = ADOContract::default(); - // Should this be owner or recipient? - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let config = CONFIG.load(deps.storage)?; @@ -243,17 +203,7 @@ fn execute_claim_all( limit: Option, up_to_time: Option, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - - let contract = ADOContract::default(); - - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let config = CONFIG.load(deps.storage)?; diff --git a/contracts/finance/andromeda-vesting/src/testing/tests.rs b/contracts/finance/andromeda-vesting/src/testing/tests.rs index 8bc2aed2f..7691f6f63 100644 --- a/contracts/finance/andromeda-vesting/src/testing/tests.rs +++ b/contracts/finance/andromeda-vesting/src/testing/tests.rs @@ -348,7 +348,7 @@ fn test_claim_batch_still_locked() { batch_id: 1, }; - let res = execute(deps.as_mut(), mock_env(), info, msg); + let res = execute(deps.as_mut(), mock_env(), mock_info("owner", &[]), msg); assert_eq!(ContractError::FundsAreLocked {}, res.unwrap_err()); } @@ -374,7 +374,7 @@ fn test_claim_batch_no_funds_available() { batch_id: 1, }; - let res = execute(deps.as_mut(), mock_env(), info, msg); + let res = execute(deps.as_mut(), mock_env(), mock_info("owner", &[]), msg); // This is because, the first payment becomes available after 10 seconds. assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); @@ -432,7 +432,7 @@ fn test_claim_batch_single_claim() { batch_id: 1, }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() @@ -493,7 +493,7 @@ fn test_claim_batch_not_nice_numbers_single_release() { batch_id: 1, }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() @@ -557,7 +557,13 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { batch_id: 1, }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); + let res = execute( + deps.as_mut(), + env.clone(), + mock_info("owner", &[]), + msg.clone(), + ) + .unwrap(); assert_eq!( Response::new() @@ -587,7 +593,7 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { env.block.time = env.block.time.plus_seconds(duration); - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() .add_message(BankMsg::Send { @@ -645,13 +651,18 @@ fn test_claim_batch_middle_of_interval() { // Only halfway to first release. env.block.time = env.block.time.plus_seconds(release_duration.seconds() / 2); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); + let res = execute( + deps.as_mut(), + env.clone(), + mock_info("owner", &[]), + msg.clone(), + ); assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); // First release available and halfway to second -> result is rounding down. env.block.time = env.block.time.plus_seconds(release_duration.seconds()); - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() @@ -711,7 +722,7 @@ fn test_claim_batch_multiple_claims() { number_of_claims: Some(1), batch_id: 1, }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + let res = execute(deps.as_mut(), env.clone(), mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() @@ -744,7 +755,7 @@ fn test_claim_batch_multiple_claims() { number_of_claims: None, batch_id: 1, }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() @@ -805,7 +816,13 @@ fn test_claim_batch_all_releases() { number_of_claims: None, batch_id: 1, }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); + let res = execute( + deps.as_mut(), + env.clone(), + mock_info("owner", &[]), + msg.clone(), + ) + .unwrap(); assert_eq!( Response::new() @@ -834,7 +851,7 @@ fn test_claim_batch_all_releases() { ); // Try to claim again. - let res = execute(deps.as_mut(), env, info, msg); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg); assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); } @@ -870,7 +887,7 @@ fn test_claim_batch_too_high_of_claim() { batch_id: 1, }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env, mock_info("owner", &[]), msg).unwrap(); assert_eq!( Response::new() diff --git a/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml b/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml index 220731a90..22b32c31d 100644 --- a/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml +++ b/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -27,6 +27,8 @@ andromeda-finance = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } cw-orch = { workspace = true } +andromeda-testing = { workspace = true, optional = true } + [dev-dependencies] andromeda-app = { workspace = true } diff --git a/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs b/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs index 548ea764c..d7ff3cf9d 100644 --- a/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs +++ b/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs @@ -10,14 +10,14 @@ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::{AndrAddr, Recipient}, - common::{actions::call_action, context::ExecuteContext, encode_binary, expiration::Expiry}, + andr_execute_fn, + common::{context::ExecuteContext, encode_binary, expiration::Expiry}, error::ContractError, }; use cosmwasm_std::{ attr, ensure, entry_point, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, SubMsg, Uint128, }; -use cw_utils::nonpayable; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-weighted-distribution-splitter"; @@ -67,31 +67,8 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::UpdateRecipients { recipients } => execute_update_recipients(ctx, recipients), ExecuteMsg::UpdateRecipientWeight { recipient } => { @@ -113,15 +90,7 @@ pub fn execute_update_recipient_weight( ctx: ExecuteContext, recipient: AddressWeight, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - // Only the contract's owner can update a recipient's weight - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; // Can't set weight to 0 ensure!( @@ -138,7 +107,6 @@ pub fn execute_update_recipient_weight( ); // Recipients are stored in a vector, we search for the desired recipient's index in the vector - let user_index = splitter .recipients .clone() @@ -160,16 +128,7 @@ fn execute_update_default_recipient( ctx: ExecuteContext, recipient: Option, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; @@ -203,23 +162,11 @@ pub fn execute_add_recipient( ctx: ExecuteContext, recipient: AddressWeight, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - - // Only the contract's owner can add a recipient - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - // No need to send funds + let ExecuteContext { deps, env, .. } = ctx; - // Check if splitter is locked let mut splitter = SPLITTER.load(deps.storage)?; // Can't add recipients while the lock isn't expired - ensure!( splitter.lock.is_expired(&env.block), ContractError::ContractLocked { msg: None } @@ -363,17 +310,7 @@ fn execute_update_recipients( ctx: ExecuteContext, recipients: Vec, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - - // Only the owner can use this function - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - // No need to send funds + let ExecuteContext { deps, env, .. } = ctx; // Recipient list can't be empty ensure!( @@ -410,15 +347,7 @@ fn execute_remove_recipient( ctx: ExecuteContext, recipient: AndrAddr, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; @@ -444,21 +373,11 @@ fn execute_remove_recipient( } fn execute_update_lock(ctx: ExecuteContext, lock_time: Expiry) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut splitter = SPLITTER.load(deps.storage)?; // Can't call this function while the lock isn't expired - ensure!( splitter.lock.is_expired(&env.block), ContractError::ContractLocked { msg: None } diff --git a/contracts/finance/andromeda-weighted-distribution-splitter/src/lib.rs b/contracts/finance/andromeda-weighted-distribution-splitter/src/lib.rs index 1a3944968..8a891cda8 100644 --- a/contracts/finance/andromeda-weighted-distribution-splitter/src/lib.rs +++ b/contracts/finance/andromeda-weighted-distribution-splitter/src/lib.rs @@ -1,6 +1,9 @@ pub mod contract; pub mod state; +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; + #[cfg(test)] mod testing; diff --git a/contracts/finance/andromeda-weighted-distribution-splitter/src/mock.rs b/contracts/finance/andromeda-weighted-distribution-splitter/src/mock.rs new file mode 100644 index 000000000..5fa188503 --- /dev/null +++ b/contracts/finance/andromeda-weighted-distribution-splitter/src/mock.rs @@ -0,0 +1,91 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] + +use crate::contract::{execute, instantiate, query, reply}; +use andromeda_finance::weighted_splitter::{AddressWeight, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::{amp::Recipient, common::expiration::Expiry}; +use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockWeightedDistributionSplitter(Addr); +mock_ado!(MockWeightedDistributionSplitter, ExecuteMsg, QueryMsg); + +impl MockWeightedDistributionSplitter { + #[allow(clippy::too_many_arguments)] + pub fn instantiate( + app: &mut MockApp, + code_id: u64, + sender: Addr, + recipients: Vec, + kernel_address: impl Into, + lock_time: Option, + owner: Option, + default_recipient: Option, + ) -> Self { + let msg = mock_splitter_instantiate_msg( + recipients, + kernel_address, + lock_time, + owner, + default_recipient, + ); + let res = app.instantiate_contract(code_id, sender, &msg, &[], "Andromeda Splitter", None); + + Self(res.unwrap()) + } + + pub fn execute_send( + &self, + app: &mut MockApp, + sender: Addr, + funds: &[Coin], + config: Option>, + ) -> ExecuteResult { + let msg = mock_splitter_send_msg(config); + + self.execute(app, &msg, sender, funds) + } + + pub fn execute_update_recipients( + &self, + app: &mut MockApp, + sender: Addr, + funds: &[Coin], + recipients: Vec, + ) -> ExecuteResult { + let msg = mock_splitter_update_recipients_msg(recipients); + + self.execute(app, &msg, sender, funds) + } +} + +pub fn mock_andromeda_splitter() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query).with_reply(reply); + Box::new(contract) +} + +pub fn mock_splitter_instantiate_msg( + recipients: Vec, + kernel_address: impl Into, + lock_time: Option, + owner: Option, + default_recipient: Option, +) -> InstantiateMsg { + InstantiateMsg { + recipients, + lock_time, + kernel_address: kernel_address.into(), + owner, + default_recipient, + } +} + +pub fn mock_splitter_send_msg(config: Option>) -> ExecuteMsg { + ExecuteMsg::Send { config } +} + +pub fn mock_splitter_update_recipients_msg(recipients: Vec) -> ExecuteMsg { + ExecuteMsg::UpdateRecipients { recipients } +} diff --git a/contracts/finance/andromeda-weighted-distribution-splitter/src/mock_querier.rs b/contracts/finance/andromeda-weighted-distribution-splitter/src/mock_querier.rs deleted file mode 100644 index 1c4bd2ef8..000000000 --- a/contracts/finance/andromeda-weighted-distribution-splitter/src/mock_querier.rs +++ /dev/null @@ -1,172 +0,0 @@ -use andromeda_app::app::QueryMsg as AppQueryMsg; -use common::{ado_base::hooks::RatesResponse, Funds}; -use cosmwasm_std::{ - from_json, - testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, BankMsg, Binary, Coin, ContractResult, CosmosMsg, OwnedDeps, Querier, - QuerierResult, QueryRequest, Response, SubMsg, SystemError, SystemResult, Uint128, WasmQuery, -}; - -pub const MOCK_TOKEN_CONTRACT: &str = "token_contract"; -pub const MOCK_RATES_CONTRACT: &str = "rates_contract"; -pub const MOCK_WEIGHTED_DISTRIBUTION_SPLITTER_CONTRACT: &str = - "weighted_distribution_splitter_contract"; -pub const MOCK_APP_CONTRACT: &str = "app_contract"; -pub const MOCK_ADDRESSLIST_CONTRACT: &str = "addresslist_contract"; -pub const MOCK_RECIPIENT1: &str = "mock_recipient1"; -pub const MOCK_RECIPIENT2: &str = "mock_recipient2"; - -pub const MOCK_TOKEN_ADDR: &str = "token0001"; -pub const MOCK_TOKEN_OWNER: &str = "owner"; -pub const MOCK_UNCLAIMED_TOKEN: &str = "unclaimed_token"; -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; -pub const MOCK_TOKENS_FOR_SALE: &[&str] = &[ - "token1", "token2", "token3", "token4", "token5", "token6", "token7", -]; - -pub const MOCK_CONDITIONS_MET_CONTRACT: &str = "conditions_met"; -pub const MOCK_CONDITIONS_NOT_MET_CONTRACT: &str = "conditions_not_met"; - -pub fn mock_dependencies_custom( - contract_balance: &[Coin], -) -> OwnedDeps { - let custom_querier: WasmMockQuerier = - WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); - - OwnedDeps { - storage: MockStorage::default(), - api: MockApi::default(), - querier: custom_querier, - custom_query_type: std::marker::PhantomData, - } -} - -pub struct WasmMockQuerier { - base: MockQuerier, - pub contract_address: String, - pub tokens_left_to_burn: usize, -} - -impl Querier for WasmMockQuerier { - fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_json(bin_request) { - Ok(v) => v, - Err(e) => { - return SystemResult::Err(SystemError::InvalidRequest { - error: format!("Parsing query request: {e}"), - request: bin_request.into(), - }) - } - }; - self.handle_query(&request) - } -} - -impl WasmMockQuerier { - pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { - match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_WEIGHTED_DISTRIBUTION_SPLITTER_CONTRACT => todo!(), - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_APP_CONTRACT => self.handle_app_query(msg), - MOCK_ADDRESSLIST_CONTRACT => self.handle_addresslist_query(msg), - _ => panic!("Unknown Contract Address {}", contract_addr), - } - } - _ => self.base.handle_query(request), - } - } - - fn handle_app_query(&self, msg: &Binary) -> QuerierResult { - let valid_identifiers = ["e", "b"]; - match from_json(msg).unwrap() { - AppQueryMsg::ComponentExists { name } => { - let value = valid_identifiers.contains(&name.as_str()); - SystemResult::Ok(ContractResult::Ok(to_json_binary(&value).unwrap())) - } - _ => panic!("Unsupported Query: {}", msg), - } - } - - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )) - } - }; - let response = RatesResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Err("UnsupportedOperation".to_string())), - }, - } - } - - pub fn new(base: MockQuerier) -> Self { - WasmMockQuerier { - base, - contract_address: mock_env().contract.address.to_string(), - tokens_left_to_burn: 2, - } - } -} diff --git a/contracts/finance/andromeda-weighted-distribution-splitter/src/testing/tests.rs b/contracts/finance/andromeda-weighted-distribution-splitter/src/testing/tests.rs index 78c24e991..021628754 100644 --- a/contracts/finance/andromeda-weighted-distribution-splitter/src/testing/tests.rs +++ b/contracts/finance/andromeda-weighted-distribution-splitter/src/testing/tests.rs @@ -1,24 +1,22 @@ -use andromeda_std::amp::AndrAddr; -use andromeda_std::common::expiration::Expiry; -use andromeda_std::common::Milliseconds; -use andromeda_std::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}; +use andromeda_finance::weighted_splitter::{AddressWeight, ExecuteMsg, InstantiateMsg, Splitter}; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, ado_contract::ADOContract, - amp::recipient::Recipient, error::ContractError, + ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_contract::ADOContract, + amp::{recipient::Recipient, AndrAddr}, + common::{expiration::Expiry, Milliseconds}, + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}, }; use cosmwasm_std::{ attr, - testing::{mock_env, mock_info}, - Response, Uint128, + testing::{mock_dependencies, mock_env, mock_info}, + BankMsg, Coin, CosmosMsg, DepsMut, QuerierWrapper, Response, SubMsg, Uint128, }; -use cosmwasm_std::{BankMsg, Coin, CosmosMsg, DepsMut, QuerierWrapper, SubMsg}; use crate::{ contract::{execute, instantiate}, state::SPLITTER, }; -use andromeda_finance::weighted_splitter::{AddressWeight, ExecuteMsg, InstantiateMsg, Splitter}; -use cosmwasm_std::testing::mock_dependencies; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); const MOCK_RECIPIENT1: &str = "recipient1"; const MOCK_RECIPIENT2: &str = "recipient2"; diff --git a/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs b/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs index 574376ec7..ca2190612 100644 --- a/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs +++ b/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs @@ -5,8 +5,8 @@ use andromeda_fungible_tokens::cw20_exchange::{ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, + andr_execute_fn, common::{ - actions::call_action, context::ExecuteContext, expiration::{expiration_from_milliseconds, get_and_validate_start_time, Expiry}, Milliseconds, MillisecondsDuration, @@ -20,7 +20,7 @@ use cosmwasm_std::{ use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use cw_asset::AssetInfo; use cw_storage_plus::Bound; -use cw_utils::{nonpayable, one_coin, Expiration}; +use cw_utils::{one_coin, Expiration}; use crate::state::{SALE, TOKEN_ADDRESS}; @@ -73,41 +73,14 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - let res = match msg { ExecuteMsg::CancelSale { asset } => execute_cancel_sale(ctx, asset), ExecuteMsg::Purchase { recipient } => execute_purchase_native(ctx, recipient), ExecuteMsg::Receive(cw20_msg) => execute_receive(ctx, cw20_msg), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } pub fn execute_receive( @@ -115,8 +88,6 @@ pub fn execute_receive( receive_msg: Cw20ReceiveMsg, ) -> Result { let ExecuteContext { ref info, .. } = ctx; - nonpayable(info)?; - let asset_sent = AssetInfo::Cw20(info.sender.clone()); let amount_sent = receive_msg.amount; let sender = receive_msg.sender; @@ -383,12 +354,6 @@ pub fn execute_cancel_sale( ) -> Result { let ExecuteContext { deps, info, .. } = ctx; - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let Some(sale) = SALE.may_load(deps.storage, &asset.to_string())? else { return Err(ContractError::NoOngoingSale {}); }; diff --git a/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml b/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml index 447bee7fa..7d6830f39 100644 --- a/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml +++ b/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml @@ -19,7 +19,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw20 = { workspace = true } cw20-base = { workspace = true } cw-asset = { workspace = true } diff --git a/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs b/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs index e506d0de4..8a7bf9649 100644 --- a/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs +++ b/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs @@ -3,7 +3,8 @@ use std::{ops::Mul, str::FromStr}; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, encode_binary, Milliseconds}, + andr_execute_fn, + common::{context::ExecuteContext, encode_binary, Milliseconds}, error::ContractError, }; use cosmwasm_std::{ @@ -30,8 +31,6 @@ use andromeda_fungible_tokens::cw20_staking::{ RewardType, StakerResponse, State, }; -use cw_utils::nonpayable; - // Version info, for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-cw20-staking"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -105,33 +104,9 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let _contract = ADOContract::default(); - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - let res = match msg { ExecuteMsg::Receive(msg) => receive_cw20(ctx, msg), ExecuteMsg::AddRewardToken { reward_token } => execute_add_reward_token(ctx, reward_token), ExecuteMsg::RemoveRewardToken { reward_token } => { @@ -168,11 +143,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_unstake_tokens(ctx, amount), ExecuteMsg::ClaimRewards {} => execute_claim_rewards(ctx), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn receive_cw20(ctx: ExecuteContext, msg: Cw20ReceiveMsg) -> Result { @@ -205,14 +176,7 @@ fn execute_add_reward_token( ctx: ExecuteContext, reward_token: RewardTokenUnchecked, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - let contract = ADOContract::default(); - ensure!( - contract.is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let mut config = CONFIG.load(deps.storage)?; let new_number = config.number_of_reward_tokens.checked_add(1); @@ -270,15 +234,7 @@ fn execute_remove_reward_token( ctx: ExecuteContext, reward_token_string: String, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - let contract = ADOContract::default(); - ensure!( - contract.is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - + let ExecuteContext { deps, env, .. } = ctx; // Set reward token as inactive match REWARD_TOKENS.load(deps.storage, &reward_token_string) { Ok(mut reward_token) if reward_token.is_active => { @@ -322,16 +278,7 @@ fn execute_replace_reward_token( origin_reward_token_string: String, reward_token: RewardTokenUnchecked, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - let contract = ADOContract::default(); - - // Only owner can replace reward token - ensure!( - contract.is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; let config = CONFIG.load(deps.storage)?; // Validate token to be replaced @@ -473,7 +420,6 @@ fn execute_unstake_tokens( let ExecuteContext { deps, info, env, .. } = ctx; - nonpayable(&info)?; let sender = info.sender.as_str(); let staking_token = get_staking_token(deps.as_ref())?; diff --git a/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs b/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs index db400829e..430e9ca9a 100644 --- a/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs +++ b/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs @@ -27,7 +27,6 @@ use andromeda_fungible_tokens::cw20_staking::{ AllocationConfig, AllocationState, Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, RewardToken, RewardTokenUnchecked, RewardType, StakerResponse, State, }; -use andromeda_testing::economics_msg::generate_economics_message; use cw_asset::{AssetInfo, AssetInfoUnchecked}; const MOCK_STAKING_TOKEN: &str = "staking_token"; @@ -353,8 +352,7 @@ fn test_stake_unstake_tokens() { .add_attribute("action", "stake_tokens") .add_attribute("sender", "sender") .add_attribute("share", "100") - .add_attribute("amount", "100") - .add_submessage(generate_economics_message(MOCK_STAKING_TOKEN, "Receive")), + .add_attribute("amount", "100"), res ); @@ -392,8 +390,7 @@ fn test_stake_unstake_tokens() { .add_attribute("action", "stake_tokens") .add_attribute("sender", "other_sender") .add_attribute("share", "50") - .add_attribute("amount", "100") - .add_submessage(generate_economics_message(MOCK_STAKING_TOKEN, "Receive")), + .add_attribute("amount", "100"), res ); @@ -445,8 +442,7 @@ fn test_stake_unstake_tokens() { amount: Uint128::new(200) }) .unwrap() - }) - .add_submessage(generate_economics_message("sender", "UnstakeTokens")), + }), res ); @@ -489,8 +485,7 @@ fn test_stake_unstake_tokens() { amount: Uint128::new(100) }) .unwrap() - }) - .add_submessage(generate_economics_message("other_sender", "UnstakeTokens")), + }), res ); @@ -587,8 +582,7 @@ fn test_update_global_indexes() { .add_attribute("action", "update_global_indexes") .add_attribute("cw20:incentive_token", "0.2") .add_attribute("native:uandr", "0") - .add_attribute("native:uusd", "0.4") - .add_submessage(generate_economics_message("owner", "UpdateGlobalIndexes")), + .add_attribute("native:uusd", "0.4"), res ); @@ -648,8 +642,7 @@ fn test_update_global_indexes() { .add_attribute("action", "update_global_indexes") .add_attribute("cw20:incentive_token", "0.2") .add_attribute("native:uandr", "0.4") - .add_attribute("native:uusd", "0.4") - .add_submessage(generate_economics_message("owner", "UpdateGlobalIndexes")), + .add_attribute("native:uusd", "0.4"), res ); @@ -720,8 +713,7 @@ fn test_update_global_indexes_selective() { assert_eq!( Response::new() .add_attribute("action", "update_global_indexes") - .add_attribute("native:uusd", "0.4") - .add_submessage(generate_economics_message("owner", "UpdateGlobalIndexes")), + .add_attribute("native:uusd", "0.4"), res ); @@ -854,8 +846,7 @@ fn test_update_global_indexes_cw20_deposit() { assert_eq!( Response::new() .add_attribute("action", "update_global_indexes") - .add_attribute("cw20:incentive_token", "0.2") - .add_submessage(generate_economics_message(MOCK_INCENTIVE_TOKEN, "Receive")), + .add_attribute("cw20:incentive_token", "0.2"), res ); @@ -1007,7 +998,7 @@ fn test_claim_rewards() { let info = mock_info("user1", &[]); let msg = ExecuteMsg::ClaimRewards {}; - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + let res = execute(deps.as_mut(), mock_env(), info, msg); assert_eq!( StakerRewardInfo { @@ -1040,9 +1031,8 @@ fn test_claim_rewards() { .add_message(BankMsg::Send { to_address: "user1".to_string(), amount: coins(66, "uusd") - }) - .add_submessage(generate_economics_message("user1", "ClaimRewards")), - res + }), + res.unwrap() ); deps.querier @@ -1051,7 +1041,7 @@ fn test_claim_rewards() { let info = mock_info("user2", &[]); let msg = ExecuteMsg::ClaimRewards {}; - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + let res = execute(deps.as_mut(), mock_env(), info, msg); assert_eq!( Response::new() @@ -1059,9 +1049,8 @@ fn test_claim_rewards() { .add_message(BankMsg::Send { to_address: "user2".to_string(), amount: coins(33, "uusd") - }) - .add_submessage(generate_economics_message("user2", "ClaimRewards")), - res + }), + res.unwrap() ); assert_eq!( @@ -1227,8 +1216,7 @@ fn test_claim_rewards_allocated() { amount: Uint128::new(25) }) .unwrap(), - }) - .add_submessage(generate_economics_message("user1", "ClaimRewards")), + }), res ); @@ -1284,8 +1272,7 @@ fn test_claim_rewards_allocated() { amount: Uint128::new(25) }) .unwrap(), - }) - .add_submessage(generate_economics_message("user2", "ClaimRewards")), + }), res ); @@ -1406,8 +1393,7 @@ fn test_claim_rewards_allocated_init_timestamp_in_future() { amount: Uint128::new(25) }) .unwrap(), - }) - .add_submessage(generate_economics_message("user1", "ClaimRewards")), + }), res ); @@ -1462,8 +1448,7 @@ fn test_claim_rewards_allocated_init_timestamp_in_future() { amount: Uint128::new(25) }) .unwrap(), - }) - .add_submessage(generate_economics_message("user2", "ClaimRewards")), + }), res ); @@ -1857,8 +1842,7 @@ fn test_add_reward_token() { assert_eq!( Response::new() .add_attribute("action", "add_reward_token") - .add_attribute("added_token", "cw20:incentive_token") - .add_submessage(generate_economics_message("owner", "AddRewardToken")), + .add_attribute("added_token", "cw20:incentive_token"), res ); @@ -2013,8 +1997,7 @@ fn test_remove_reward_token() { Response::new() .add_attribute("action", "remove_reward_token") .add_attribute("number_of_reward_tokens", "0") - .add_attribute("removed_token", "native:uusd") - .add_submessage(generate_economics_message("owner", "RemoveRewardToken")), + .add_attribute("removed_token", "native:uusd"), res ); @@ -2204,8 +2187,7 @@ fn test_claim_rewards_after_remove() { .add_message(BankMsg::Send { to_address: "user1".to_string(), amount: coins(66, "uusd") - }) - .add_submessage(generate_economics_message("user1", "ClaimRewards")), + }), res ); @@ -2229,8 +2211,7 @@ fn test_claim_rewards_after_remove() { .add_message(BankMsg::Send { to_address: "user2".to_string(), amount: coins(33, "uusd") - }) - .add_submessage(generate_economics_message("user2", "ClaimRewards")), + }), res ); @@ -2362,8 +2343,7 @@ fn test_claim_rewards_allocated_after_remove() { amount: Uint128::new(25) }) .unwrap(), - }) - .add_submessage(generate_economics_message("user", "ClaimRewards")), + }), res ); @@ -2433,8 +2413,7 @@ fn test_replace_reward_token() { Response::new() .add_attribute("action", "replace_reward_token") .add_attribute("origin_reward_token", "native:uusd") - .add_attribute("new_reward_token", format!("cw20:{MOCK_INCENTIVE_TOKEN}")) - .add_submessage(generate_economics_message("owner", "ReplaceRewardToken")), + .add_attribute("new_reward_token", format!("cw20:{MOCK_INCENTIVE_TOKEN}")), res ); diff --git a/contracts/fungible-tokens/andromeda-cw20/src/contract.rs b/contracts/fungible-tokens/andromeda-cw20/src/contract.rs index 83c13b3de..308abe378 100644 --- a/contracts/fungible-tokens/andromeda-cw20/src/contract.rs +++ b/contracts/fungible-tokens/andromeda-cw20/src/contract.rs @@ -3,7 +3,8 @@ use andromeda_std::{ ado_base::{AndromedaMsg, AndromedaQuery, InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::AndrAddr, - common::{actions::call_action, context::ExecuteContext, encode_binary, Funds}, + andr_execute_fn, + common::{context::ExecuteContext, encode_binary, Funds}, error::ContractError, }; use cosmwasm_std::{entry_point, Reply, StdError}; @@ -50,36 +51,10 @@ pub fn instantiate( .add_attributes(cw20_resp.attributes)) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let action = msg.as_ref().to_string(); - - let _contract = ADOContract::default(); - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { + match msg { ExecuteMsg::Transfer { recipient, amount } => { execute_transfer(ctx, recipient, amount, action) } @@ -108,11 +83,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result Ok(execute_cw20(ctx.deps, ctx.env, ctx.info, msg.into())?), } } - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn execute_transfer( diff --git a/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs b/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs index 8f88b50f8..fb2a6bcef 100644 --- a/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs +++ b/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs @@ -8,7 +8,6 @@ use andromeda_std::amp::{AndrAddr, Recipient}; use andromeda_std::common::context::ExecuteContext; use andromeda_std::{error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT}; -use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{attr, Decimal, Event}; use cosmwasm_std::{ testing::{mock_env, mock_info}, @@ -140,8 +139,7 @@ fn test_transfer() { .add_attribute("action", "transfer") .add_attribute("from", "sender") .add_attribute("to", "other") - .add_attribute("amount", "90") - .add_submessage(generate_economics_message("sender", "Transfer")), + .add_attribute("amount", "90"), res ); @@ -236,8 +234,7 @@ fn test_send() { .into_cosmos_msg("contract") .unwrap(), ) - .add_event(expected_event) - .add_submessage(generate_economics_message("sender", "Send")), + .add_event(expected_event), res ); diff --git a/contracts/fungible-tokens/andromeda-ics20/src/testing/tests.rs b/contracts/fungible-tokens/andromeda-ics20/src/testing/tests.rs index b67b6b71c..715709929 100644 --- a/contracts/fungible-tokens/andromeda-ics20/src/testing/tests.rs +++ b/contracts/fungible-tokens/andromeda-ics20/src/testing/tests.rs @@ -1,25 +1,27 @@ -use crate::contract::{execute, instantiate, query}; -use crate::testing::mock_querier::mock_dependencies_custom; +use crate::{ + contract::{execute, instantiate, query}, + testing::mock_querier::{mock_dependencies_custom, MOCK_CW20_CONTRACT}, +}; use andromeda_fungible_tokens::cw20::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use andromeda_std::ado_base::permissioning::Permission; -use andromeda_std::ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}; -use andromeda_std::ado_contract::ADOContract; -use andromeda_std::amp::{AndrAddr, Recipient}; -use andromeda_std::common::context::ExecuteContext; - -use andromeda_std::{error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT}; -use andromeda_testing::economics_msg::generate_economics_message; -use cosmwasm_std::{attr, Decimal, Event}; +use andromeda_std::{ + ado_base::{ + permissioning::Permission, + rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}, + }, + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, + common::context::ExecuteContext, + error::ContractError, + testing::mock_querier::MOCK_KERNEL_CONTRACT, +}; use cosmwasm_std::{ + attr, testing::{mock_env, mock_info}, - to_json_binary, Addr, DepsMut, Response, Uint128, + to_json_binary, Addr, Decimal, DepsMut, Event, Response, Uint128, }; - use cw20::{Cw20Coin, Cw20ReceiveMsg}; use cw20_base::state::BALANCES; -use super::mock_querier::MOCK_CW20_CONTRACT; - fn init(deps: DepsMut) -> Response { let msg = InstantiateMsg { name: MOCK_CW20_CONTRACT.into(), @@ -140,8 +142,7 @@ fn test_transfer() { .add_attribute("action", "transfer") .add_attribute("from", "sender") .add_attribute("to", "other") - .add_attribute("amount", "90") - .add_submessage(generate_economics_message("sender", "Transfer")), + .add_attribute("amount", "90"), res ); @@ -236,8 +237,7 @@ fn test_send() { .into_cosmos_msg("contract") .unwrap(), ) - .add_event(expected_event) - .add_submessage(generate_economics_message("sender", "Send")), + .add_event(expected_event), res ); diff --git a/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml b/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml index b40f5c529..27f2ece16 100644 --- a/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml +++ b/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml @@ -19,7 +19,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw-asset = { workspace = true } cw20 = { workspace = true } diff --git a/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs b/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs index 4fcd22dbc..fcc4a70a6 100644 --- a/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs +++ b/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs @@ -8,9 +8,10 @@ use andromeda_fungible_tokens::lockdrop::{ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, + andr_execute_fn, common::{ - actions::call_action, context::ExecuteContext, encode_binary, - expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, Milliseconds, MillisecondsExpiration, + context::ExecuteContext, encode_binary, expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, + Milliseconds, MillisecondsExpiration, }, error::ContractError, }; @@ -23,8 +24,6 @@ use cw_asset::Asset; use crate::state::{Config, State, CONFIG, STATE, USER_INFO}; use cw20::Cw20ReceiveMsg; -use cw_utils::nonpayable; - // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-lockdrop"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -89,34 +88,9 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let _contract = ADOContract::default(); - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { ExecuteMsg::Receive(msg) => receive_cw20(ctx, msg), ExecuteMsg::DepositNative {} => execute_deposit_native(ctx), ExecuteMsg::WithdrawNative { amount } => execute_withdraw_native(ctx, amount), @@ -124,11 +98,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_claim_rewards(ctx), // ExecuteMsg::WithdrawProceeds { recipient } => execute_withdraw_proceeds(ctx, recipient), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } #[cfg_attr(not(feature = "library"), entry_point)] @@ -343,10 +313,7 @@ pub fn execute_withdraw_native( /// Called along-with Bootstrap contract's LP Pool provide liquidity tx. If it is not /// specified then anyone can execute this when the phase has ended. pub fn execute_enable_claims(ctx: ExecuteContext) -> Result { - let ExecuteContext { - deps, env, info, .. - } = ctx; - nonpayable(&info)?; + let ExecuteContext { deps, env, .. } = ctx; // let contract = ADOContract::default(); let config = CONFIG.load(deps.storage)?; diff --git a/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs b/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs index 96e658de2..07cf25d20 100644 --- a/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs +++ b/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs @@ -15,7 +15,6 @@ use andromeda_std::{ error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT, }; -use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ coin, coins, from_json, testing::{mock_env, mock_info}, @@ -203,8 +202,7 @@ fn test_increase_incentives() { assert_eq!( Response::new() .add_attribute("action", "incentives_increased") - .add_attribute("amount", "100") - .add_submessage(generate_economics_message(MOCK_INCENTIVE_TOKEN, "Receive")), + .add_attribute("amount", "100"), res ); @@ -301,8 +299,7 @@ fn test_deposit_native() { Response::new() .add_attribute("action", "lock_native") .add_attribute("user", "sender") - .add_attribute("ust_deposited", "100") - .add_submessage(generate_economics_message("sender", "DepositNative")), + .add_attribute("ust_deposited", "100"), res ); @@ -419,8 +416,7 @@ fn test_withdraw_native() { }) .add_attribute("action", "withdraw_native") .add_attribute("user", "sender") - .add_attribute("amount", "100") - .add_submessage(generate_economics_message("sender", "WithdrawNative")), + .add_attribute("amount", "100"), res ); @@ -701,9 +697,7 @@ fn test_enable_claims_no_bootstrap_specified() { let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); assert_eq!( - Response::new() - .add_attribute("action", "enable_claims") - .add_submessage(generate_economics_message("sender", "EnableClaims")), + Response::new().add_attribute("action", "enable_claims"), res ); @@ -858,8 +852,7 @@ fn test_claim_rewards() { amount: Uint128::new(75) }) .unwrap() - }) - .add_submessage(generate_economics_message("user1", "ClaimRewards")), + }), res ); @@ -897,8 +890,7 @@ fn test_claim_rewards() { amount: Uint128::new(25) }) .unwrap() - }) - .add_submessage(generate_economics_message("user2", "ClaimRewards")), + }), res ); diff --git a/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml b/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml index 9762cb47b..a62a37704 100644 --- a/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml +++ b/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml @@ -19,7 +19,6 @@ testing = ["cw-multi-test"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw20 = { workspace = true } cw-asset = { workspace = true } sha2 = "0.10.6" diff --git a/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs b/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs index 06f41a115..9662d6dbd 100644 --- a/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs +++ b/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs @@ -6,7 +6,6 @@ use cosmwasm_std::{ attr, ensure, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, Uint128, }; -use cw_utils::nonpayable; use sha2::Digest; use std::convert::TryInto; @@ -24,8 +23,8 @@ use andromeda_std::{ InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, ado_contract::ADOContract, + andr_execute_fn, common::{ - actions::call_action, context::ExecuteContext, denom::{Asset, SEND_CW20_ACTION}, encode_binary, @@ -64,7 +63,7 @@ pub fn instantiate( // Unless Cw20 is not identified as verified asset if let Asset::Cw20Token(addr) = msg.asset_info.clone() { let addr = addr.get_raw_address(&deps.as_ref())?; - ADOContract::default().permission_action(SEND_CW20_ACTION, deps.storage)?; + ADOContract::default().permission_action(deps.storage, SEND_CW20_ACTION)?; ADOContract::set_permission( deps.storage, SEND_CW20_ACTION, @@ -88,32 +87,9 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - let res = match msg { ExecuteMsg::RegisterMerkleRoot { merkle_root, expiration, @@ -126,11 +102,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_claim(ctx, stage, amount, proof), ExecuteMsg::Burn { stage } => execute_burn(ctx, stage), _ => ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } pub fn execute_register_merkle_root( @@ -139,15 +111,7 @@ pub fn execute_register_merkle_root( expiration: Option, total_amount: Option, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; // check merkle root length let mut root_buf: [u8; 32] = [0; 32]; @@ -187,8 +151,6 @@ pub fn execute_claim( let ExecuteContext { deps, info, env, .. } = ctx; - nonpayable(&info)?; - // Ensure that the stage expiration (if it exists) isn't expired let expiration_milliseconds = STAGE_EXPIRATION.load(deps.storage, stage)?; if let Some(expiration_milliseconds) = expiration_milliseconds { @@ -256,11 +218,6 @@ pub fn execute_burn(ctx: ExecuteContext, stage: u8) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let action = msg.as_ref().to_string(); - - // let action_response = call_action( - // &mut ctx.deps, - // &ctx.info, - // &ctx.env, - // &ctx.amp_ctx, - // msg.as_ref(), - // )?; - - let res = match msg { + match msg { ExecuteMsg::Increment {} => execute_increment(ctx, action), ExecuteMsg::Decrement {} => execute_decrement(ctx, action), ExecuteMsg::Reset {} => execute_reset(ctx, action), @@ -113,18 +89,10 @@ fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result ADOContract::default().execute(ctx, msg), - }?; - - Ok( - res, // .add_submessages(action_response.messages) - // .add_attributes(action_response.attributes) - // .add_events(action_response.events)) - ) + } } pub fn execute_increment(ctx: ExecuteContext, action: String) -> Result { - nonpayable(&ctx.info)?; - let sender = ctx.info.sender.clone(); ensure!( has_permission(ctx.deps.storage, &sender)?, @@ -147,8 +115,6 @@ pub fn execute_increment(ctx: ExecuteContext, action: String) -> Result Result { - nonpayable(&ctx.info)?; - let sender = ctx.info.sender.clone(); ensure!( has_permission(ctx.deps.storage, &sender)?, @@ -191,12 +157,7 @@ pub fn execute_update_restriction( restriction: CounterRestriction, action: String, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); RESTRICTION.save(ctx.deps.storage, &restriction)?; Ok(Response::new().add_attributes(vec![attr("action", action), attr("sender", sender)])) @@ -208,11 +169,6 @@ pub fn execute_set_increase_amount( action: String, ) -> Result { let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - INCREASE_AMOUNT.save(ctx.deps.storage, &increase_amount)?; Ok(Response::new().add_attributes(vec![ @@ -228,11 +184,6 @@ pub fn execute_set_decrease_amount( action: String, ) -> Result { let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - DECREASE_AMOUNT.save(ctx.deps.storage, &decrease_amount)?; Ok(Response::new().add_attributes(vec![ diff --git a/contracts/math/andromeda-curve/Cargo.toml b/contracts/math/andromeda-curve/Cargo.toml index f0e96cf1e..e79abdd2a 100644 --- a/contracts/math/andromeda-curve/Cargo.toml +++ b/contracts/math/andromeda-curve/Cargo.toml @@ -19,7 +19,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } test-case = { workspace = true } andromeda-std = { workspace = true, features = [] } diff --git a/contracts/math/andromeda-curve/src/contract.rs b/contracts/math/andromeda-curve/src/contract.rs index 53c4a1aca..b5f7749fd 100644 --- a/contracts/math/andromeda-curve/src/contract.rs +++ b/contracts/math/andromeda-curve/src/contract.rs @@ -10,7 +10,8 @@ use andromeda_std::{ InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::{context::ExecuteContext, encode_binary}, error::ContractError, }; @@ -19,8 +20,6 @@ use cosmwasm_std::{ Storage, }; -use cw_utils::nonpayable; - // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-curve"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -51,8 +50,8 @@ pub fn instantiate( if let Some(authorized_operator_addresses) = msg.authorized_operator_addresses { if !authorized_operator_addresses.is_empty() { - ADOContract::default().permission_action(UPDATE_CURVE_CONFIG_ACTION, deps.storage)?; - ADOContract::default().permission_action(RESET_ACTION, deps.storage)?; + ADOContract::default().permission_action(deps.storage, UPDATE_CURVE_CONFIG_ACTION)?; + ADOContract::default().permission_action(deps.storage, RESET_ACTION)?; } for address in authorized_operator_addresses { @@ -78,50 +77,21 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg.clone() { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + match msg.clone() { ExecuteMsg::UpdateCurveConfig { curve_config } => { execute_update_curve_config(ctx, curve_config) } ExecuteMsg::Reset {} => execute_reset(ctx), _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } pub fn execute_update_curve_config( mut ctx: ExecuteContext, curve_config: CurveConfig, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender.clone(); ADOContract::default().is_permissioned( ctx.deps.branch(), @@ -139,7 +109,6 @@ pub fn execute_update_curve_config( } pub fn execute_reset(mut ctx: ExecuteContext) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender.clone(); ADOContract::default().is_permissioned( ctx.deps.branch(), diff --git a/contracts/math/andromeda-date-time/src/contract.rs b/contracts/math/andromeda-date-time/src/contract.rs index d2346afcb..dfa225cf4 100644 --- a/contracts/math/andromeda-date-time/src/contract.rs +++ b/contracts/math/andromeda-date-time/src/contract.rs @@ -1,3 +1,4 @@ +use andromeda_std::andr_execute_fn; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; @@ -7,7 +8,7 @@ use andromeda_math::date_time::{ExecuteMsg, InstantiateMsg, QueryMsg, Timezone}; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, encode_binary}, + common::encode_binary, error::ContractError, }; use chrono::{DateTime, Datelike, Timelike, Weekday}; @@ -40,40 +41,9 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -#[allow(clippy::match_single_binding)] -fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + ADOContract::default().execute(ctx, msg) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/math/andromeda-distance/src/contract.rs b/contracts/math/andromeda-distance/src/contract.rs index 2471a8c39..ca35bdebd 100644 --- a/contracts/math/andromeda-distance/src/contract.rs +++ b/contracts/math/andromeda-distance/src/contract.rs @@ -8,7 +8,8 @@ use andromeda_math::distance::{Coordinate, DistanceType, ExecuteMsg, Instantiate use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; @@ -40,40 +41,9 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -#[allow(clippy::match_single_binding)] -fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + ADOContract::default().execute(ctx, msg) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/math/andromeda-graph/src/contract.rs b/contracts/math/andromeda-graph/src/contract.rs index 8cc5c7b30..c9f93f76c 100644 --- a/contracts/math/andromeda-graph/src/contract.rs +++ b/contracts/math/andromeda-graph/src/contract.rs @@ -1,3 +1,4 @@ +use andromeda_std::andr_execute_fn; use std::str::FromStr; #[cfg(not(feature = "library"))] @@ -16,7 +17,7 @@ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::AndrAddr, - common::{actions::call_action, context::ExecuteContext, encode_binary}, + common::{context::ExecuteContext, encode_binary}, error::ContractError, os::aos_querier::AOSQuerier, }; @@ -54,32 +55,9 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { ExecuteMsg::UpdateMap { map_info } => execute_update_map(ctx, map_info), ExecuteMsg::StoreCoordinate { coordinate, @@ -90,12 +68,7 @@ fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_store_user_coordinate(ctx, user_location_paths), ExecuteMsg::DeleteUserCoordinate { user } => execute_delete_user_coordinate(ctx, user), _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } pub fn execute_update_map( @@ -103,10 +76,6 @@ pub fn execute_update_map( map_info: MapInfo, ) -> Result { let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); let map = MAP_INFO .load(ctx.deps.storage) @@ -140,11 +109,6 @@ pub fn execute_store_coordinate( is_timestamp_allowed: bool, ) -> Result { let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - let map = MAP_INFO .load(ctx.deps.storage) .map_err(|_| ContractError::InvalidParameter { @@ -345,10 +309,6 @@ pub fn execute_store_user_coordinate( user_location_paths: Vec, ) -> Result { let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); for user_location_path in user_location_paths { let address = user_location_path.get_raw_address(&ctx.deps.as_ref())?; let contract_info = ctx.deps.querier.query_wasm_contract_info(address.clone()); @@ -398,10 +358,6 @@ pub fn execute_delete_user_coordinate( user: AndrAddr, ) -> Result { let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); let user_addr = user.get_raw_address(&ctx.deps.as_ref())?; USER_COORDINATE.remove(ctx.deps.storage, user_addr); diff --git a/contracts/math/andromeda-matrix/Cargo.toml b/contracts/math/andromeda-matrix/Cargo.toml index 70d1133a4..2eb22672d 100644 --- a/contracts/math/andromeda-matrix/Cargo.toml +++ b/contracts/math/andromeda-matrix/Cargo.toml @@ -26,7 +26,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw20 = { workspace = true } diff --git a/contracts/math/andromeda-matrix/src/contract.rs b/contracts/math/andromeda-matrix/src/contract.rs index 17f2a5469..a748c9abc 100644 --- a/contracts/math/andromeda-matrix/src/contract.rs +++ b/contracts/math/andromeda-matrix/src/contract.rs @@ -1,7 +1,9 @@ +use andromeda_std::andr_execute_fn; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, Storage}; +use crate::state::{DEFAULT_KEY, KEY_OWNER, MATRIX}; use andromeda_math::matrix::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_math::matrix::{GetMatrixResponse, Matrix}; use andromeda_std::{ @@ -11,14 +13,10 @@ use andromeda_std::{ }, ado_contract::ADOContract, amp::AndrAddr, - common::{actions::call_action, context::ExecuteContext, encode_binary}, + common::{context::ExecuteContext, encode_binary}, error::ContractError, }; -use cw_utils::nonpayable; - -use crate::state::{DEFAULT_KEY, KEY_OWNER, MATRIX}; - // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-matrix"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -49,8 +47,8 @@ pub fn instantiate( if let Some(authorized_operator_addresses) = msg.authorized_operator_addresses { if !authorized_operator_addresses.is_empty() { - ADOContract::default().permission_action(STORE_MATRIX_ACTION, deps.storage)?; - ADOContract::default().permission_action(DELETE_MATRIX_ACTION, deps.storage)?; + ADOContract::default().permission_action(deps.storage, STORE_MATRIX_ACTION)?; + ADOContract::default().permission_action(deps.storage, DELETE_MATRIX_ACTION)?; } for address in authorized_operator_addresses { @@ -73,19 +71,12 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + match msg.clone() { + ExecuteMsg::StoreMatrix { key, data } => store_matrix(ctx, key, data), + ExecuteMsg::DeleteMatrix { key } => delete_matrix(ctx, key), + _ => ADOContract::default().execute(ctx, msg), } } @@ -104,34 +95,12 @@ pub fn migrate(deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg.clone() { - ExecuteMsg::StoreMatrix { key, data } => store_matrix(ctx, key, data), - ExecuteMsg::DeleteMatrix { key } => delete_matrix(ctx, key), - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) -} - /// ============================== Execution Functions ============================== /// pub fn store_matrix( mut ctx: ExecuteContext, key: Option, data: Matrix, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender.clone(); ADOContract::default().is_permissioned( @@ -169,7 +138,6 @@ pub fn delete_matrix( mut ctx: ExecuteContext, key: Option, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; ADOContract::default().is_permissioned( diff --git a/contracts/math/andromeda-point/Cargo.toml b/contracts/math/andromeda-point/Cargo.toml index 286c84d11..387f6b4f8 100644 --- a/contracts/math/andromeda-point/Cargo.toml +++ b/contracts/math/andromeda-point/Cargo.toml @@ -27,7 +27,6 @@ testing = ["cw-multi-test", "andromeda-testing"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } andromeda-std = { workspace = true } andromeda-math = { workspace = true } diff --git a/contracts/math/andromeda-point/src/contract.rs b/contracts/math/andromeda-point/src/contract.rs index 3272c859d..7b35483e2 100644 --- a/contracts/math/andromeda-point/src/contract.rs +++ b/contracts/math/andromeda-point/src/contract.rs @@ -3,7 +3,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError}; use crate::{ - execute::handle_execute, + execute::{delete_point, set_point, update_restriction}, query::{get_data_owner, get_point}, state::RESTRICTION, }; @@ -11,7 +11,8 @@ use andromeda_math::point::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; @@ -43,19 +44,13 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + match msg.clone() { + ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), + ExecuteMsg::SetPoint { point } => set_point(ctx, point), + ExecuteMsg::DeletePoint {} => delete_point(ctx), + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/math/andromeda-point/src/execute.rs b/contracts/math/andromeda-point/src/execute.rs index 0e067fae1..40ef13fd8 100644 --- a/contracts/math/andromeda-point/src/execute.rs +++ b/contracts/math/andromeda-point/src/execute.rs @@ -1,49 +1,16 @@ -use andromeda_math::point::{ExecuteMsg, PointCoordinate, PointRestriction}; -use andromeda_std::{ - ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext}, - error::ContractError, -}; -use cosmwasm_std::{ensure, Response}; -use cw_utils::nonpayable; - use crate::{ query::has_permission, state::{DATA, DATA_OWNER, RESTRICTION}, }; - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg.clone() { - ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), - ExecuteMsg::SetPoint { point } => set_point(ctx, point), - ExecuteMsg::DeletePoint {} => delete_point(ctx), - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) -} +use andromeda_math::point::{PointCoordinate, PointRestriction}; +use andromeda_std::{common::context::ExecuteContext, error::ContractError}; +use cosmwasm_std::{ensure, Response}; pub fn update_restriction( ctx: ExecuteContext, restriction: PointRestriction, ) -> Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); RESTRICTION.save(ctx.deps.storage, &restriction)?; Ok(Response::new() .add_attribute("method", "update_restriction") @@ -69,7 +36,6 @@ pub fn set_point(ctx: ExecuteContext, point: PointCoordinate) -> Result Result { - nonpayable(&ctx.info)?; let sender = ctx.info.sender; ensure!( has_permission(ctx.deps.storage, &sender)?, diff --git a/contracts/math/andromeda-shunting/Cargo.toml b/contracts/math/andromeda-shunting/Cargo.toml index 7caf14ffe..0e10df248 100644 --- a/contracts/math/andromeda-shunting/Cargo.toml +++ b/contracts/math/andromeda-shunting/Cargo.toml @@ -16,7 +16,6 @@ testing = ["cw-multi-test"] [dependencies] cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } cw2 = { workspace = true } cosmwasm-schema = { workspace = true } andromeda-std = { workspace = true, features = [] } diff --git a/contracts/math/andromeda-shunting/src/contract.rs b/contracts/math/andromeda-shunting/src/contract.rs index 3b8d07056..972de6445 100644 --- a/contracts/math/andromeda-shunting/src/contract.rs +++ b/contracts/math/andromeda-shunting/src/contract.rs @@ -6,16 +6,15 @@ use andromeda_math::shunting::{ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, + andr_execute_fn, common::{context::ExecuteContext, encode_binary}, error::ContractError, }; use cosmwasm_std::{ - attr, ensure, entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, + attr, entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, WasmQuery, }; use cw2::set_contract_version; -use cw_utils::nonpayable; - use serde_cw_value::Value; use crate::state::EXPRESSIONS; @@ -52,25 +51,8 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let _contract = ADOContract::default(); - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::UpdateExpressions { expressions } => { execute_update_expression(ctx, expressions) @@ -83,14 +65,7 @@ fn execute_update_expression( ctx: ExecuteContext, expressions: Vec, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; - - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - + let ExecuteContext { deps, .. } = ctx; EXPRESSIONS.save(deps.storage, &expressions)?; Ok(Response::new().add_attributes(vec![attr("action", "update_expression")])) diff --git a/contracts/modules/andromeda-address-list/Cargo.toml b/contracts/modules/andromeda-address-list/Cargo.toml index d0bb28dd6..4e716fb64 100644 --- a/contracts/modules/andromeda-address-list/Cargo.toml +++ b/contracts/modules/andromeda-address-list/Cargo.toml @@ -25,8 +25,8 @@ andromeda-std = { workspace = true, features = [] } andromeda-modules = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -cw-multi-test = { workspace = true, optional = true } andromeda-testing = { workspace = true, optional = true } +cw-multi-test = { workspace = true, optional = true } cw-orch = { workspace = true } [dev-dependencies] diff --git a/contracts/modules/andromeda-address-list/src/contract.rs b/contracts/modules/andromeda-address-list/src/contract.rs index 12473f5f6..d82a47563 100644 --- a/contracts/modules/andromeda-address-list/src/contract.rs +++ b/contracts/modules/andromeda-address-list/src/contract.rs @@ -5,6 +5,7 @@ use andromeda_std::{ ado_base::{permissioning::LocalPermission, InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::AndrAddr, + andr_execute_fn, common::{context::ExecuteContext, encode_binary}, error::ContractError, }; @@ -13,7 +14,6 @@ use cosmwasm_std::{ attr, ensure, entry_point, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, }; -use cw_utils::nonpayable; use crate::state::{add_actors_permission, includes_actor, PERMISSIONS}; // version info for migration info @@ -62,25 +62,8 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let _contract = ADOContract::default(); - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::PermissionActors { actors, permission } => { execute_permission_actors(ctx, actors, permission) @@ -95,14 +78,7 @@ fn execute_permission_actors( actors: Vec, permission: LocalPermission, ) -> Result { - let ExecuteContext { - deps, env, info, .. - } = ctx; - nonpayable(&info)?; - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; if let LocalPermission::Limited { .. } = permission { return Err(ContractError::InvalidPermission { msg: "Limited permission is not supported in address list contract".to_string(), @@ -130,12 +106,7 @@ fn execute_remove_permissions( ctx: ExecuteContext, actors: Vec, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, .. } = ctx; ensure!(!actors.is_empty(), ContractError::NoActorsProvided {}); for actor in actors.clone() { diff --git a/contracts/modules/andromeda-address-list/src/testing/tests.rs b/contracts/modules/andromeda-address-list/src/testing/tests.rs index 9ba2b2233..00fec50a3 100644 --- a/contracts/modules/andromeda-address-list/src/testing/tests.rs +++ b/contracts/modules/andromeda-address-list/src/testing/tests.rs @@ -1,19 +1,19 @@ -use crate::contract::{execute, instantiate, query}; -use crate::state::PERMISSIONS; -use crate::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}; +use crate::{ + contract::{execute, instantiate, query}, + state::PERMISSIONS, + testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}, +}; use andromeda_modules::address_list::{ ActorPermission, ActorPermissionResponse, ExecuteMsg, IncludesActorResponse, InstantiateMsg, QueryMsg, }; -use andromeda_std::ado_base::permissioning::LocalPermission; - -use andromeda_std::amp::AndrAddr; -use andromeda_std::error::ContractError; - -use cosmwasm_std::{attr, from_json, Addr, DepsMut, MessageInfo}; +use andromeda_std::{ + ado_base::permissioning::LocalPermission, amp::AndrAddr, error::ContractError, +}; use cosmwasm_std::{ + attr, from_json, testing::{mock_env, mock_info}, - Response, + Addr, DepsMut, MessageInfo, Response, }; fn init(deps: DepsMut, info: MessageInfo) { diff --git a/contracts/modules/andromeda-rates/src/contract.rs b/contracts/modules/andromeda-rates/src/contract.rs index 4bad10940..a2efc8786 100644 --- a/contracts/modules/andromeda-rates/src/contract.rs +++ b/contracts/modules/andromeda-rates/src/contract.rs @@ -7,17 +7,17 @@ use andromeda_std::{ InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, ado_contract::ADOContract, + andr_execute_fn, common::{context::ExecuteContext, deduct_funds, encode_binary, Funds}, error::ContractError, }; use cosmwasm_std::{ - attr, coin, ensure, Binary, Coin, Deps, DepsMut, Env, Event, MessageInfo, Reply, Response, - StdError, SubMsg, + attr, coin, Binary, Coin, Deps, DepsMut, Env, Event, MessageInfo, Reply, Response, StdError, + SubMsg, }; use cosmwasm_std::{entry_point, from_json}; use cw20::Cw20Coin; -use cw_utils::nonpayable; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-rates"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -52,24 +52,8 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::SetRate { action, rate } => execute_set_rate(ctx, action, rate), ExecuteMsg::RemoveRate { action } => execute_remove_rate(ctx, action), @@ -82,13 +66,8 @@ fn execute_set_rate( action: String, rate: LocalRate, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; + let ExecuteContext { deps, .. } = ctx; - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); rate.validate(deps.as_ref())?; RATES.save(deps.storage, &action, &rate)?; @@ -97,13 +76,8 @@ fn execute_set_rate( } fn execute_remove_rate(ctx: ExecuteContext, action: String) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; + let ExecuteContext { deps, .. } = ctx; - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); if RATES.has(deps.storage, &action) { RATES.remove(deps.storage, &action); Ok(Response::new().add_attributes(vec![attr("action", "remove_rates")])) diff --git a/contracts/modules/andromeda-rates/src/testing/tests.rs b/contracts/modules/andromeda-rates/src/testing/tests.rs index cb3b6b4a0..82fec5888 100644 --- a/contracts/modules/andromeda-rates/src/testing/tests.rs +++ b/contracts/modules/andromeda-rates/src/testing/tests.rs @@ -3,18 +3,16 @@ use crate::testing::mock_querier::{ mock_dependencies_custom, MOCK_KERNEL_CONTRACT, MOCK_OWNER, MOCK_RECIPIENT1, }; use andromeda_modules::rates::{ExecuteMsg, InstantiateMsg, QueryMsg, RateResponse}; - -use andromeda_std::ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, RatesResponse}; -use andromeda_std::amp::AndrAddr; -use andromeda_std::common::Funds; -use andromeda_std::testing::mock_querier::{MOCK_CW20_CONTRACT, MOCK_UANDR}; -use andromeda_std::{amp::recipient::Recipient, common::encode_binary}; - -use cosmwasm_std::{attr, Event}; +use andromeda_std::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, RatesResponse}, + amp::{recipient::Recipient, AndrAddr}, + common::{encode_binary, Funds}, + testing::mock_querier::{MOCK_CW20_CONTRACT, MOCK_UANDR}, +}; use cosmwasm_std::{ - coin, coins, + attr, coin, coins, testing::{mock_env, mock_info}, - BankMsg, CosmosMsg, Response, SubMsg, WasmMsg, + BankMsg, CosmosMsg, Event, Response, SubMsg, WasmMsg, }; use cw20::{Cw20Coin, Cw20ExecuteMsg}; diff --git a/contracts/modules/andromeda-schema/src/contract.rs b/contracts/modules/andromeda-schema/src/contract.rs index b53d0901d..46196becc 100644 --- a/contracts/modules/andromeda-schema/src/contract.rs +++ b/contracts/modules/andromeda-schema/src/contract.rs @@ -8,14 +8,15 @@ use andromeda_modules::schema::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, + andr_execute_fn, + common::encode_binary, error::ContractError, }; use cw_json::JSON; use serde_json::{from_str, Value}; use crate::{ - execute::handle_execute, + execute::execute_update_schema, query::{get_schema, validate_data}, state::SCHEMA, }; @@ -58,19 +59,13 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), + ExecuteMsg::UpdateSchema { + new_schema_json_string, + } => execute_update_schema(ctx, new_schema_json_string), + _ => ADOContract::default().execute(ctx, msg), } } diff --git a/contracts/modules/andromeda-schema/src/execute.rs b/contracts/modules/andromeda-schema/src/execute.rs index ee1361a2d..e19f34abc 100644 --- a/contracts/modules/andromeda-schema/src/execute.rs +++ b/contracts/modules/andromeda-schema/src/execute.rs @@ -1,48 +1,15 @@ -use andromeda_modules::schema::ExecuteMsg; -use andromeda_std::{ - ado_contract::ADOContract, - common::{actions::call_action, context::ExecuteContext}, - error::ContractError, -}; -use cosmwasm_std::{ensure, Response}; +use andromeda_std::{common::context::ExecuteContext, error::ContractError}; +use cosmwasm_std::Response; use cw_json::JSON; use serde_json::{from_str, Value}; use crate::state::SCHEMA; -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { - ExecuteMsg::UpdateSchema { - new_schema_json_string, - } => execute_update_schema(ctx, new_schema_json_string), - _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) -} - -fn execute_update_schema( +pub fn execute_update_schema( ctx: ExecuteContext, new_schema_json: String, ) -> Result { let sender: cosmwasm_std::Addr = ctx.info.sender; - - ensure!( - ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, - ContractError::Unauthorized {} - ); - let new_schema_json_value: Value = from_str(new_schema_json.as_str()).map_err(|_| ContractError::CustomError { msg: "Invalid JSON Schema".to_string(), diff --git a/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs b/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs index 8c0894b54..60ffb91dd 100644 --- a/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs +++ b/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs @@ -12,8 +12,8 @@ use andromeda_std::{ InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, amp::Recipient, + andr_execute_fn, common::{ - actions::call_action, denom::{ authorize_addresses, execute_authorize_contract, execute_deauthorize_contract, validate_native_denom, Asset, AuthorizedAddressesResponse, PermissionAction, @@ -34,7 +34,6 @@ use cosmwasm_std::{ }; use cw20::{Cw20Coin, Cw20ExecuteMsg, Cw20ReceiveMsg}; use cw721::{Cw721ExecuteMsg, Cw721QueryMsg, Cw721ReceiveMsg, OwnerOfResponse}; -use cw_utils::nonpayable; const CONTRACT_NAME: &str = "crates.io:andromeda-auction"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -75,35 +74,10 @@ pub fn instantiate( Ok(resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let action = msg.as_ref().to_string(); - - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { + match msg { ExecuteMsg::ReceiveNft(msg) => handle_receive_cw721(ctx, msg), ExecuteMsg::Receive(msg) => handle_receive_cw20(ctx, msg), ExecuteMsg::UpdateAuction { @@ -155,11 +129,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn handle_receive_cw721( @@ -219,7 +189,6 @@ pub fn handle_receive_cw20( ); let ExecuteContext { ref info, .. } = ctx; - nonpayable(info)?; let asset_sent = info.sender.clone().into_string(); let amount_sent = receive_msg.amount; @@ -308,7 +277,7 @@ fn execute_start_auction( BIDS.save(deps.storage, auction_id.u128(), &vec![])?; if let Some(ref whitelist) = whitelist { - ADOContract::default().permission_action(auction_id.to_string(), deps.storage)?; + ADOContract::default().permission_action(deps.storage, auction_id.to_string())?; for whitelisted_address in whitelist { ADOContract::set_permission( @@ -375,7 +344,6 @@ fn execute_update_auction( env, .. } = ctx; - nonpayable(&info)?; let (coin_denom, uses_cw20) = coin_denom.get_verified_asset(deps.branch(), env.clone())?; if uses_cw20 { @@ -431,7 +399,7 @@ fn execute_update_auction( if let Some(ref whitelist) = whitelist { ADOContract::default() - .permission_action(token_auction_state.auction_id.to_string(), deps.storage)?; + .permission_action(deps.storage, token_auction_state.auction_id.to_string())?; for whitelisted_address in whitelist { ADOContract::set_permission( @@ -589,10 +557,7 @@ fn execute_buy_now( action: String, ) -> Result { let ExecuteContext { - mut deps, - info, - env, - .. + deps, info, env, .. } = ctx; let mut token_auction_state = get_existing_token_auction_state(deps.storage, &token_id, &token_address)?; @@ -602,13 +567,6 @@ fn execute_buy_now( .buy_now_price .map_or_else(|| Err(ContractError::NoBuyNowOption {}), Ok)?; - ADOContract::default().is_permissioned( - deps.branch(), - env.clone(), - token_auction_state.auction_id, - info.sender.clone(), - )?; - validate_auction(token_auction_state.clone(), info.clone(), &env.block)?; ensure!( @@ -956,7 +914,6 @@ fn execute_cancel( let ExecuteContext { deps, info, env, .. } = ctx; - nonpayable(&info)?; let mut token_auction_state = get_existing_token_auction_state(deps.storage, &token_id, &token_address)?; diff --git a/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs b/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs index ec4f11d21..1937ab603 100644 --- a/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs +++ b/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs @@ -24,19 +24,16 @@ use andromeda_std::{ denom::Asset, encode_binary, expiration::{Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, - reply::ReplyId, Milliseconds, }, error::ContractError, - os::economics::ExecuteMsg as EconomicsExecuteMsg, testing::mock_querier::MOCK_KERNEL_CONTRACT, }; use andromeda_std::{amp::Recipient, testing::mock_querier::MOCK_CW20_CONTRACT}; use cosmwasm_std::{ attr, coin, coins, from_json, testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, Deps, DepsMut, Env, Response, SubMsg, - Timestamp, Uint128, WasmMsg, + Addr, BankMsg, CosmosMsg, Decimal, Deps, DepsMut, Env, Response, Timestamp, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use cw721::Cw721ReceiveMsg; @@ -450,7 +447,7 @@ fn execute_place_bid_whitelist_cw20() { }); let invalid_asset = "invalid_asset"; - let info = mock_info(invalid_asset, &coins(100, "uusd".to_string())); + let info = mock_info(invalid_asset, &[]); env.block.time = env.block.time.plus_seconds(1); let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert_eq!( @@ -579,26 +576,12 @@ fn execute_place_bid_multiple_bids() { let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); assert_eq!( - Response::new() - .add_attributes(vec![ - attr("action", "bid"), - attr("token_id", MOCK_UNCLAIMED_TOKEN), - attr("bidder", info.sender), - attr("amount", "100"), - ]) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("sender"), - action: "PlaceBid".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + Response::new().add_attributes(vec![ + attr("action", "bid"), + attr("token_id", MOCK_UNCLAIMED_TOKEN), + attr("bidder", info.sender), + attr("amount", "100"), + ]), res ); let mut expected_response = AuctionStateResponse { @@ -634,20 +617,7 @@ fn execute_place_bid_multiple_bids() { attr("token_id", MOCK_UNCLAIMED_TOKEN), attr("bidder", info.sender), attr("amount", "200"), - ]) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("other"), - action: "PlaceBid".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + ]), res ); @@ -671,20 +641,7 @@ fn execute_place_bid_multiple_bids() { attr("token_id", MOCK_UNCLAIMED_TOKEN), attr("bidder", info.sender), attr("amount", "250"), - ]) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("sender"), - action: "PlaceBid".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + ]), res ); @@ -1160,27 +1117,14 @@ fn execute_start_auction_after_previous_finished() { let info = mock_info(MOCK_TOKEN_ADDR, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::new() - .add_attributes(vec![ - attr("action", "start_auction"), - attr("start_time", "expiration time: 1571801019.880000000"), - attr("end_time", "expiration time: 1571817419.879000000"), - attr("coin_denom", "uusd"), - attr("auction_id", "2"), - attr("whitelist", "None"), - ]) // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked(MOCK_TOKEN_ADDR), - action: "ReceiveNft".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + Response::new().add_attributes(vec![ + attr("action", "start_auction"), + attr("start_time", "expiration time: 1571801019.880000000"), + attr("end_time", "expiration time: 1571817419.879000000"), + attr("coin_denom", "uusd"), + attr("auction_id", "2"), + attr("whitelist", "None"), + ]), res ); } @@ -1219,20 +1163,7 @@ fn execute_claim_no_bids() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", MOCK_TOKEN_OWNER) .add_attribute("winning_bid_amount", Uint128::zero()) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("any_user"), - action: "Claim".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); } @@ -1271,20 +1202,7 @@ fn execute_claim_no_bids_cw20() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", MOCK_TOKEN_OWNER) .add_attribute("winning_bid_amount", Uint128::zero()) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("any_user"), - action: "Claim".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); } @@ -1358,20 +1276,7 @@ fn execute_claim_with_tax() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", "sender") .add_attribute("winning_bid_amount", Uint128::from(100u128)) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("any_user"), - action: "Claim".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); } @@ -1434,20 +1339,7 @@ fn execute_buy_now() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", "sender_2") .add_attribute("bought_at", Uint128::from(500u128)) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("sender_2"), - action: "BuyNow".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); @@ -1535,20 +1427,7 @@ fn execute_claim_with_royalty() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", "sender") .add_attribute("winning_bid_amount", Uint128::from(100u128)) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("any_user"), - action: "Claim".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); } @@ -1611,20 +1490,7 @@ fn execute_claim_cw20() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", "sender") .add_attribute("winning_bid_amount", Uint128::from(100u128)) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("any_user"), - action: "Claim".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); } @@ -1714,20 +1580,7 @@ fn execute_claim_cw20_with_tax() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", "sender") .add_attribute("winning_bid_amount", Uint128::from(100u128)) - .add_attribute("auction_id", "1") - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("any_user"), - action: "Claim".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + .add_attribute("auction_id", "1"), res ); } @@ -1817,29 +1670,15 @@ fn execute_cancel_no_bids() { let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::new() - .add_message(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_ADDR.to_owned(), - msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), - token_id: MOCK_UNCLAIMED_TOKEN.to_owned() - }) - .unwrap(), - funds: vec![], - })) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("owner"), - action: "CancelAuction".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_owned(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned() + }) + .unwrap(), + funds: vec![], + })), res ); @@ -1868,29 +1707,15 @@ fn execute_cancel_no_bids_cw20() { let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::new() - .add_message(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_ADDR.to_owned(), - msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), - token_id: MOCK_UNCLAIMED_TOKEN.to_owned() - }) - .unwrap(), - funds: vec![], - })) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("owner"), - action: "CancelAuction".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_owned(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned() + }) + .unwrap(), + funds: vec![], + })), res ); @@ -1942,20 +1767,7 @@ fn execute_cancel_with_bids() { .add_message(CosmosMsg::Bank(BankMsg::Send { to_address: "bidder".to_string(), amount: coins(100, "uusd") - })) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("owner"), - action: "CancelAuction".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + })), res ); @@ -2022,20 +1834,7 @@ fn execute_cancel_with_bids_cw20() { }) .unwrap(), funds: vec![] - })) - // Economics message - .add_submessage(SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("owner"), - action: "CancelAuction".to_string() - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - )), + })), res ); diff --git a/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs b/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs index ec0ea9e95..75189cc66 100644 --- a/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs +++ b/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs @@ -13,8 +13,8 @@ use andromeda_std::{ }, ado_contract::ADOContract, amp::{messages::AMPPkt, AndrAddr, Recipient}, + andr_execute_fn, common::{ - actions::call_action, context::ExecuteContext, denom::{Asset, SEND_CW20_ACTION}, encode_binary, @@ -70,7 +70,7 @@ pub fn instantiate( let tiers: Vec = msg.tiers.into_iter().collect(); if let Asset::Cw20Token(addr) = campaign_config.denom.clone() { let addr = addr.get_raw_address(&deps.as_ref())?; - ADOContract::default().permission_action(SEND_CW20_ACTION, deps.storage)?; + ADOContract::default().permission_action(deps.storage, SEND_CW20_ACTION)?; ADOContract::set_permission( deps.storage, SEND_CW20_ACTION, @@ -104,33 +104,9 @@ pub fn migrate(deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result Result { - let ctx = ExecuteContext::new(deps, info, env); - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { ExecuteMsg::AddTier { tier } => execute_add_tier(ctx, tier), ExecuteMsg::UpdateTier { tier } => execute_update_tier(ctx, tier), ExecuteMsg::RemoveTier { level } => execute_remove_tier(ctx, level), @@ -145,22 +121,11 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_discard_campaign(ctx), ExecuteMsg::Claim {} => execute_claim(ctx), _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn execute_add_tier(ctx: ExecuteContext, tier: Tier) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, .. } = ctx; tier.validate()?; @@ -189,13 +154,7 @@ fn execute_add_tier(ctx: ExecuteContext, tier: Tier) -> Result Result { - let ExecuteContext { deps, info, .. } = ctx; - - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, .. } = ctx; tier.validate()?; @@ -224,13 +183,7 @@ fn execute_update_tier(ctx: ExecuteContext, tier: Tier) -> Result Result { - let ExecuteContext { deps, info, .. } = ctx; - - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, .. } = ctx; let curr_stage = get_current_stage(deps.storage); ensure!( @@ -256,16 +209,7 @@ fn execute_start_campaign( end_time: Expiry, presale: Option>, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - - // Only owner can start the campaign - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { deps, env, .. } = ctx; ensure!(is_valid_tiers(deps.storage), ContractError::InvalidTiers {}); @@ -373,18 +317,7 @@ fn handle_receive_cw20( fn execute_discard_campaign(mut ctx: ExecuteContext) -> Result { nonpayable(&ctx.info)?; - let ExecuteContext { - ref mut deps, - ref info, - .. - } = ctx; - - // Only owner can discard the campaign - let contract = ADOContract::default(); - ensure!( - contract.is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); + let ExecuteContext { ref mut deps, .. } = ctx; let curr_stage = get_current_stage(deps.storage); // Ensure that the campaign is in ONGOING, or READY stage @@ -409,18 +342,10 @@ fn execute_end_campaign(mut ctx: ExecuteContext) -> Result"] edition = "2021" rust-version = "1.75.0" diff --git a/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs b/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs index e743ee267..0f4ddae00 100644 --- a/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs +++ b/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs @@ -1,3 +1,4 @@ +use andromeda_std::andr_execute_fn; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -12,10 +13,10 @@ use andromeda_non_fungible_tokens::cw721::{ }; use andromeda_std::common::rates::get_tax_amount; use andromeda_std::{ - ado_base::{AndromedaMsg, AndromedaQuery}, - ado_contract::{permissioning::is_context_permissioned_strict, ADOContract}, + ado_base::AndromedaQuery, + ado_contract::{permissioning::is_context_permissioned, ADOContract}, amp::AndrAddr, - common::{actions::call_action, context::ExecuteContext}, + common::context::ExecuteContext, }; use andromeda_std::{ @@ -29,6 +30,7 @@ use cw721_base::{state::TokenInfo, Cw721Contract, ExecuteMsg as Cw721ExecuteMsg} pub type AndrCW721Contract<'a> = Cw721Contract<'a, TokenExtension, Empty, ExecuteMsg, QueryMsg>; const CONTRACT_NAME: &str = "crates.io:andromeda-cw721"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +const MINT_ACTION: &str = "Mint"; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -51,6 +53,8 @@ pub fn instantiate( let contract = ADOContract::default(); ANDR_MINTER.save(deps.storage, &msg.minter)?; + contract.permission_action(deps.storage, MINT_ACTION)?; + let resp = contract.instantiate( deps.storage, env, @@ -68,37 +72,8 @@ pub fn instantiate( Ok(resp.add_attributes(vec![attr("minter", msg.minter)])) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - if let ExecuteMsg::AMPReceive(pkt) = msg { - ADOContract::default().execute_amp_receive( - ExecuteContext::new(deps, info, env), - pkt, - handle_execute, - ) - } else { - let ctx = ExecuteContext::new(deps, info, env); - handle_execute(ctx, msg) - } -} - -fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let contract = ADOContract::default(); - let action = msg.as_ref().to_string(); - - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { if let ExecuteMsg::Approve { token_id, .. } = &msg { ensure!( !is_archived(ctx.deps.storage, token_id)?.is_archived, @@ -112,12 +87,12 @@ fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_mint(ctx, token_id, token_uri, owner, extension, action), - ExecuteMsg::BatchMint { tokens } => execute_batch_mint(ctx, tokens, action), + } => execute_mint(ctx, token_id, token_uri, owner, extension), + ExecuteMsg::BatchMint { tokens } => execute_batch_mint(ctx, tokens), ExecuteMsg::TransferNft { recipient, token_id, - } => execute_transfer(ctx, recipient, token_id, &action), + } => execute_transfer(ctx, recipient, token_id), ExecuteMsg::TransferAgreement { token_id, agreement, @@ -129,19 +104,14 @@ fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_send_nft(ctx, token_id, contract, msg), - _ => { - let serialized = to_json_binary(&msg)?; - - match from_json::(&serialized) { - Ok(msg) => contract.execute(ctx, msg), - Err(_) => execute_cw721(ctx, msg.into()), - } - } + // Attempt to match the message as a cw721 message first, if it fails, fallback to the + // default ADO execute function. + _ => match msg.clone().try_into() { + Ok(cw721_msg) => execute_cw721(ctx, cw721_msg), + Err(_) => ADOContract::default().execute(ctx, msg), + }, }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + Ok(res) } fn execute_cw721( @@ -152,28 +122,36 @@ fn execute_cw721( Ok(contract.execute(ctx.deps, ctx.env, ctx.info, msg)?) } +macro_rules! ensure_can_mint { + ($ctx:expr) => { + let minter = ANDR_MINTER + .load($ctx.deps.storage)? + .get_raw_address(&$ctx.deps.as_ref())?; + + let is_minter = $ctx.info.sender == minter.as_str(); + // We check if the sender is the minter before checking if they have the mint permission + // to prevent consuming unnecessary limited permission usage. + let has_mint_permission = is_minter + || is_context_permissioned( + &mut $ctx.deps, + &$ctx.info, + &$ctx.env, + &$ctx.amp_ctx, + MINT_ACTION, + )?; + + ensure!(has_mint_permission, ContractError::Unauthorized {}); + }; +} + fn execute_mint( mut ctx: ExecuteContext, token_id: String, token_uri: Option, owner: String, extension: TokenExtension, - action: String, ) -> Result { - let minter = ANDR_MINTER - .load(ctx.deps.storage)? - .get_raw_address(&ctx.deps.as_ref())?; - ensure!( - ctx.contains_sender(minter.as_str()) - | is_context_permissioned_strict( - ctx.deps.branch(), - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - action - )?, - ContractError::Unauthorized {} - ); + ensure_can_mint!(ctx); mint(ctx, token_id, token_uri, owner, extension) } @@ -211,23 +189,9 @@ fn mint( fn execute_batch_mint( mut ctx: ExecuteContext, tokens_to_mint: Vec, - action: String, ) -> Result { let mut resp = Response::default(); - let minter = ANDR_MINTER - .load(ctx.deps.storage)? - .get_raw_address(&ctx.deps.as_ref())?; - ensure!( - ctx.contains_sender(minter.as_str()) - | is_context_permissioned_strict( - ctx.deps.branch(), - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - action - )?, - ContractError::Unauthorized {} - ); + ensure_can_mint!(ctx); ensure!( !tokens_to_mint.is_empty(), ContractError::Std(cosmwasm_std::StdError::GenericErr { @@ -235,12 +199,8 @@ fn execute_batch_mint( }) ); for msg in tokens_to_mint { - let ctx = ExecuteContext { - deps: ctx.deps.branch(), - info: ctx.info.clone(), - env: ctx.env.clone(), - amp_ctx: ctx.amp_ctx.clone(), - }; + let mut ctx = ExecuteContext::new(ctx.deps.branch(), ctx.info.clone(), ctx.env.clone()); + ctx.amp_ctx = ctx.amp_ctx.clone(); let mint_resp = mint(ctx, msg.token_id, msg.token_uri, msg.owner, msg.extension)?; resp = resp .add_attributes(mint_resp.attributes) @@ -254,12 +214,14 @@ fn execute_transfer( ctx: ExecuteContext, recipient: AndrAddr, token_id: String, - action: &str, ) -> Result { let ExecuteContext { - deps, info, env, .. + deps, + info, + env, + contract: base_contract, + .. } = ctx; - let base_contract = ADOContract::default(); // Reduce all responses into one. let mut resp = Response::new(); let recipient_address = recipient.get_raw_address(&deps.as_ref())?.into_string(); @@ -276,7 +238,7 @@ fn execute_transfer( let agreement_amount = get_transfer_agreement_amount(deps.api, &deps.querier, agreement)?; let transfer_response = base_contract.query_deducted_funds( deps.as_ref(), - action, + "Transfer", Funds::Native(agreement_amount.clone()), )?; diff --git a/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs b/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs index 17b576146..f81649dab 100644 --- a/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs +++ b/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs @@ -3,10 +3,11 @@ use andromeda_non_fungible_tokens::cw721::{ ExecuteMsg, InstantiateMsg, IsArchivedResponse, MintMsg, QueryMsg, TokenExtension, TransferAgreement, }; -use andromeda_std::error::ContractError; -use andromeda_std::testing::mock_querier::FAKE_VFS_PATH; -use andromeda_std::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}; -use andromeda_std::{ado_contract::ADOContract, amp::addresses::AndrAddr}; +use andromeda_std::{ + amp::addresses::AndrAddr, + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, FAKE_VFS_PATH, MOCK_KERNEL_CONTRACT}, +}; use cosmwasm_std::{ attr, coin, from_json, testing::{mock_env, mock_info}, @@ -289,23 +290,12 @@ fn test_burn() { let info = mock_info(creator.as_str(), &[]); let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); - let fee_message = ADOContract::default() - .pay_fee( - deps.as_ref().storage, - &deps.as_ref().querier, - "Burn".to_string(), - Addr::unchecked("creator".to_string()), - ) - .unwrap(); - assert_eq!( - Response::default() - .add_submessage(fee_message) - .add_attributes(vec![ - attr("action", "burn"), - attr("token_id", &token_id), - attr("sender", info.sender.to_string()), - ]), + Response::default().add_attributes(vec![ + attr("action", "burn"), + attr("token_id", &token_id), + attr("sender", info.sender.to_string()), + ]), res ); diff --git a/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs b/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs index acd8414bd..8a1bfed92 100644 --- a/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs +++ b/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs @@ -11,8 +11,8 @@ use andromeda_std::{ ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::Recipient, + andr_execute_fn, common::{ - actions::call_action, context::ExecuteContext, denom::{ authorize_addresses, execute_authorize_contract, execute_deauthorize_contract, Asset, @@ -37,7 +37,7 @@ use cosmwasm_std::{ WasmQuery, }; -use cw_utils::{nonpayable, Expiration}; +use cw_utils::Expiration; const CONTRACT_NAME: &str = "crates.io:andromeda-marketplace"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -75,35 +75,10 @@ pub fn instantiate( Ok(inst_resp) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - let ctx = ExecuteContext::new(deps, info, env); - - match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +#[andr_execute_fn] +pub fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let action = msg.as_ref().to_string(); - - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { + match msg { ExecuteMsg::ReceiveNft(msg) => handle_receive_cw721(ctx, msg), ExecuteMsg::Receive(msg) => handle_receive_cw20(ctx, msg), ExecuteMsg::UpdateSale { @@ -132,11 +107,7 @@ pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result ADOContract::default().execute(ctx, msg), - }?; - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } fn handle_receive_cw721( @@ -183,7 +154,6 @@ pub fn handle_receive_cw20( ctx.info.sender.clone(), )?; let ExecuteContext { ref info, .. } = ctx; - nonpayable(info)?; let asset_sent = info.sender.clone(); let amount_sent = receive_msg.amount; @@ -296,7 +266,6 @@ fn execute_update_sale( .. } = ctx; let (coin_denom, uses_cw20) = coin_denom.get_verified_asset(deps.branch(), env)?; - nonpayable(&info)?; let mut token_sale_state = get_existing_token_sale_state(deps.storage, &token_id, &token_address)?; @@ -611,7 +580,6 @@ fn execute_cancel( token_address: String, ) -> Result { let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; let mut token_sale_state = get_existing_token_sale_state(deps.storage, &token_id, &token_address)?; diff --git a/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs b/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs index e53e0149a..46b6fa22e 100644 --- a/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs +++ b/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs @@ -14,18 +14,15 @@ use andromeda_std::{ }, encode_binary, expiration::{expiration_from_milliseconds, Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, - reply::ReplyId, Milliseconds, }, error::ContractError, - os::economics::ExecuteMsg as EconomicsExecuteMsg, testing::mock_querier::MOCK_CW20_CONTRACT, }; use cosmwasm_std::{ attr, coin, coins, from_json, testing::{mock_env, mock_info}, - to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, Deps, DepsMut, Env, Response, SubMsg, - Uint128, WasmMsg, + BankMsg, CosmosMsg, Decimal, Deps, DepsMut, Env, Response, SubMsg, Uint128, WasmMsg, }; use cw20::Cw20ReceiveMsg; use cw721::{Cw721ExecuteMsg, Cw721ReceiveMsg}; @@ -962,18 +959,6 @@ fn test_execute_buy_with_tax_and_royalty_works() { to_address: "owner".to_string(), amount: vec![coin(100, "uusd")], })), - SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "economics_contract".to_string(), - msg: to_json_binary(&EconomicsExecuteMsg::PayFee { - payee: Addr::unchecked("someone"), - action: "Buy".to_string(), - }) - .unwrap(), - funds: vec![], - }), - ReplyId::PayFee.repr(), - ), ]; assert_eq!(res.messages, expected) } diff --git a/contracts/os/andromeda-ibc-registry/src/contract.rs b/contracts/os/andromeda-ibc-registry/src/contract.rs index 23c168a4a..289ee686d 100644 --- a/contracts/os/andromeda-ibc-registry/src/contract.rs +++ b/contracts/os/andromeda-ibc-registry/src/contract.rs @@ -1,6 +1,5 @@ use crate::state::REGISTRY; use andromeda_std::ado_base::permissioning::{LocalPermission, Permission}; -use andromeda_std::common::actions::call_action; use andromeda_std::os::ibc_registry::{ verify_denom, AllDenomInfoResponse, DenomInfo, DenomInfoResponse, ExecuteMsg, IBCDenomInfo, InstantiateMsg, QueryMsg, @@ -52,7 +51,7 @@ pub fn instantiate( .get_raw_address(&deps.as_ref())? .into_string(); - ADOContract::default().permission_action(STORE_DENOM_INFO, deps.storage)?; + ADOContract::default().permission_action(deps.storage, STORE_DENOM_INFO)?; ADOContract::set_permission( deps.storage, STORE_DENOM_INFO, @@ -72,40 +71,15 @@ pub fn execute( ) -> Result { let ctx = ExecuteContext::new(deps, info, env); match msg { - ExecuteMsg::AMPReceive(pkt) => { - ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) - } - _ => handle_execute(ctx, msg), - } -} - -fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let action = msg.as_ref().to_string(); - - let action_response = call_action( - &mut ctx.deps, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref(), - )?; - - let res = match msg { ExecuteMsg::StoreDenomInfo { ibc_denom_info } => { - execute_store_denom_info(ctx, action, ibc_denom_info) + execute_store_denom_info(ctx, ibc_denom_info) } _ => ADOContract::default().execute(ctx, msg), - }?; - - Ok(res - .add_submessages(action_response.messages) - .add_attributes(action_response.attributes) - .add_events(action_response.events)) + } } pub fn execute_store_denom_info( mut ctx: ExecuteContext, - action: String, ibc_denom_info: Vec, ) -> Result { let sender = ctx.info.sender.clone(); @@ -113,7 +87,7 @@ pub fn execute_store_denom_info( ADOContract::default().is_permissioned_strict( ctx.deps.branch(), ctx.env.clone(), - action, + "StoreDenomInfo", sender.clone(), )?; diff --git a/contracts/os/andromeda-kernel/src/contract.rs b/contracts/os/andromeda-kernel/src/contract.rs index 0cae443b7..a97e1cf2e 100644 --- a/contracts/os/andromeda-kernel/src/contract.rs +++ b/contracts/os/andromeda-kernel/src/contract.rs @@ -82,12 +82,7 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - let mut execute_env = ExecuteContext { - deps, - env, - info, - amp_ctx: None, - }; + let mut execute_env = ExecuteContext::new(deps, info, env); match msg { ExecuteMsg::AMPReceive(packet) => execute::amp_receive( diff --git a/contracts/os/andromeda-kernel/src/ibc.rs b/contracts/os/andromeda-kernel/src/ibc.rs index b133eb8f7..e7745361e 100644 --- a/contracts/os/andromeda-kernel/src/ibc.rs +++ b/contracts/os/andromeda-kernel/src/ibc.rs @@ -135,15 +135,14 @@ pub fn do_ibc_packet_receive( .ok_or(ContractError::Unauthorized {})?; let packet_msg: IbcExecuteMsg = from_json(&msg.packet.data)?; - let mut execute_env = ExecuteContext { - env: env.clone(), - deps: deps.branch(), - info: MessageInfo { + let mut execute_env = ExecuteContext::new( + deps.branch(), + MessageInfo { funds: vec![], sender: Addr::unchecked("foreign_kernel"), }, - amp_ctx: None, - }; + env.clone(), + ); match packet_msg { IbcExecuteMsg::SendMessage { amp_packet } => { execute_env.amp_ctx = Some(amp_packet.clone()); diff --git a/tests-integration/Cargo.toml b/e2e-tests/Cargo.toml similarity index 99% rename from tests-integration/Cargo.toml rename to e2e-tests/Cargo.toml index a1bdd5f60..d004b0181 100644 --- a/tests-integration/Cargo.toml +++ b/e2e-tests/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "tests-integration" +name = "e2e-tests" version = "1.0.0" edition = "2021" rust-version = "1.75.0" @@ -134,6 +134,7 @@ cw721-base = { workspace = true } cw721 = { workspace = true } cw20 = { workspace = true } cw-asset = { workspace = true } +cw-utils = { workspace = true } toml = "0.8" cw-orch = { workspace = true } cw-orch-interchain = "=0.3.0" diff --git a/tests-integration/src/lib.rs b/e2e-tests/src/lib.rs similarity index 100% rename from tests-integration/src/lib.rs rename to e2e-tests/src/lib.rs diff --git a/e2e-tests/tests/amp/access_control.rs b/e2e-tests/tests/amp/access_control.rs new file mode 100644 index 000000000..1b52c861c --- /dev/null +++ b/e2e-tests/tests/amp/access_control.rs @@ -0,0 +1,129 @@ +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; +use andromeda_cw721::mock::{ + mock_andromeda_cw721, mock_cw721_instantiate_msg, mock_quick_mint_msg, MockCW721, +}; +use andromeda_non_fungible_tokens::cw721::ExecuteMsg; +use andromeda_std::{ + ado_base::permissioning::{LocalPermission, Permission, PermissioningMessage}, + amp::AndrAddr, +}; +use andromeda_testing::{ + mock::mock_app, mock_builder::MockAndromedaBuilder, MockAndromeda, MockContract, +}; +use cosmwasm_std::{coin, to_json_binary}; +use cw_multi_test::{App, BankKeeper, MockApiBech32}; +use rstest::*; + +const FALSE_USER: &str = "false_user"; + +const CW721_OWNER: &str = "owner"; +const CW721_USER: &str = "user1"; +const CW721_APP_NAME: &str = "app"; +const CW721_COMPONENT_NAME: &str = "cw721"; +const CW721_MINT_ACTION: &str = "Mint"; + +#[fixture] +fn setup_cw721() -> (App, MockAndromeda, MockCW721) { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + (CW721_OWNER, vec![coin(1000, "uandr")]), + (CW721_USER, vec![]), + (FALSE_USER, vec![]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("app-contract", mock_andromeda_app()), + ]) + .build(&mut router); + + // Set up wallets + let owner = andr.get_wallet(CW721_OWNER); + let user = andr.get_wallet(CW721_USER); + + // Create the CW721 App + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + CW721_COMPONENT_NAME.to_string(), + CW721_COMPONENT_NAME.to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + CW721_APP_NAME.to_string(), + vec![cw721_component.clone()], + andr.kernel.addr(), + None, + ); + + let components = app.query_components(&router); + assert_eq!(components, vec![cw721_component]); + + let cw721 = app.query_ado_by_component_name::(&router, CW721_COMPONENT_NAME); + + // Set up permissioning for the mint action + let permission_msg = ExecuteMsg::Permissioning(PermissioningMessage::SetPermission { + actors: vec![AndrAddr::from_string(user)], + action: CW721_MINT_ACTION.to_string(), + permission: Permission::Local(LocalPermission::whitelisted(None, None)), + }); + cw721 + .execute(&mut router, &permission_msg, owner.clone(), &[]) + .unwrap(); + + (router, andr, cw721) +} + +// Tests permission-based access control for NFT minting operations via the Kernel using AMP +// Tests three scenarios: +// 1. Owner attempts to mint (should succeed) +// 2. Whitelisted user attempts to mint (should succeed) +// 3. Non-whitelisted user attempts to mint (should fail) +#[rstest] +#[case::owner(CW721_OWNER, true)] +#[case::user(CW721_USER, true)] +#[case::false_user(FALSE_USER, false)] +fn test_mint_permission( + setup_cw721: (App, MockAndromeda, MockCW721), + #[case] sender: &str, // The address attempting to mint + #[case] expected_success: bool, // Whether the mint operation should succeed +) { + let (mut router, andr, cw721) = setup_cw721; + + // Attempt to mint token #1 to the sender's address + let mint_msg = mock_quick_mint_msg(1, andr.get_wallet(sender).to_string()); + let cw721_path = format!( + "/home/{}/{}/{}", + andr.get_wallet(CW721_OWNER), + CW721_APP_NAME, + CW721_COMPONENT_NAME, + ); + let res = andr.kernel.execute_send( + &mut router, + andr.get_wallet(sender).clone(), + cw721_path, + mint_msg, + vec![], + None, + ); + + // Verify the operation succeeded/failed as expected + assert_eq!(res.is_ok(), expected_success); + + // If the mint was expected to succeed, verify ownership + if expected_success { + let owner = cw721.query_owner_of(&router, "0"); + assert_eq!(owner, andr.get_wallet(sender).to_string()); + } +} diff --git a/e2e-tests/tests/amp/mod.rs b/e2e-tests/tests/amp/mod.rs new file mode 100644 index 000000000..18e237199 --- /dev/null +++ b/e2e-tests/tests/amp/mod.rs @@ -0,0 +1 @@ +pub mod access_control; diff --git a/tests-integration/tests/app.rs b/e2e-tests/tests/app.rs similarity index 100% rename from tests-integration/tests/app.rs rename to e2e-tests/tests/app.rs diff --git a/tests-integration/tests/auction_app.rs b/e2e-tests/tests/auction_app.rs similarity index 100% rename from tests-integration/tests/auction_app.rs rename to e2e-tests/tests/auction_app.rs diff --git a/tests-integration/tests/conditional_splitter.rs b/e2e-tests/tests/conditional_splitter.rs similarity index 82% rename from tests-integration/tests/conditional_splitter.rs rename to e2e-tests/tests/conditional_splitter.rs index f733ace16..b52a13cb2 100644 --- a/tests-integration/tests/conditional_splitter.rs +++ b/e2e-tests/tests/conditional_splitter.rs @@ -3,8 +3,8 @@ use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; -use andromeda_std::amp::Recipient; -use cosmwasm_std::{coin, Decimal, Uint128}; +use andromeda_std::{amp::Recipient, os::adodb::ActionFee}; +use cosmwasm_std::{attr, coin, Decimal, Uint128}; use andromeda_conditional_splitter::mock::{ mock_andromeda_conditional_splitter, mock_conditional_splitter_instantiate_msg, @@ -23,6 +23,7 @@ fn test_conditional_splitter() { ("recipient1", vec![]), ("recipient2", vec![]), ("recipient3", vec![]), + ("recipient4", vec![coin(100000000, "uandr")]), ]) .with_contracts(vec![ ("app-contract", mock_andromeda_app()), @@ -124,7 +125,7 @@ fn test_conditional_splitter() { // Third batch let token2 = coin(50_000, "uandr"); splitter - .execute_send(&mut router, owner.clone(), &[token2]) + .execute_send(&mut router, owner.clone(), &[token2.clone()]) .unwrap(); let balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); @@ -173,6 +174,60 @@ fn test_conditional_splitter() { assert_eq!(uusd_balance_1.amount, Uint128::from(20u128)); assert_eq!(uusd_balance_2.amount, Uint128::from(80u128)); + + // Economics Msg + andr.adodb + .execute( + &mut router, + &andromeda_std::os::adodb::ExecuteMsg::UpdateActionFees { + ado_type: "conditional-splitter".to_string(), + action_fees: vec![ActionFee { + action: "UpdateThresholds".to_string(), + asset: "native:uandr".to_string(), + amount: Uint128::from(10u128), + receiver: Some(owner.clone()), + }], + }, + andr.get_wallet("admin").clone(), + &[], + ) + .unwrap(); + + andr.economics + .execute( + &mut router, + &andromeda_std::os::economics::ExecuteMsg::Deposit { address: None }, + owner.clone(), + &[coin(500, "uandr")], + ) + .unwrap(); + + let res = splitter + .execute( + &mut router, + &andromeda_finance::conditional_splitter::ExecuteMsg::UpdateThresholds { + thresholds: vec![Threshold::new( + Uint128::new(20), + vec![ + AddressPercent::new( + Recipient::from_string(recipient_2.to_string()), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + AddressPercent::new( + Recipient::from_string(recipient_3.to_string()), // 10% + Decimal::from_ratio(Uint128::one(), Uint128::new(10)), + ), + ], + )], + }, + owner.clone(), + &[], + ) + .unwrap(); + assert!(res + .events + .iter() + .any(|e| e.attributes.contains(&attr("paid_fee", "10native:uandr")))); } #[test] diff --git a/tests-integration/tests/crowdfund_app.rs b/e2e-tests/tests/crowdfund_app.rs similarity index 96% rename from tests-integration/tests/crowdfund_app.rs rename to e2e-tests/tests/crowdfund_app.rs index 05d697e86..8ecbd4d0e 100644 --- a/tests-integration/tests/crowdfund_app.rs +++ b/e2e-tests/tests/crowdfund_app.rs @@ -10,12 +10,13 @@ use andromeda_cw721::mock::{mock_andromeda_cw721, mock_cw721_instantiate_msg, Mo use andromeda_finance::splitter::AddressPercent; use andromeda_non_fungible_tokens::{ crowdfund::{CampaignConfig, CampaignStage, PresaleTierOrder, SimpleTierOrder, TierMetaData}, - cw721::TokenExtension, + cw721::{ExecuteMsg, TokenExtension}, }; use andromeda_splitter::mock::{ mock_andromeda_splitter, mock_splitter_instantiate_msg, mock_splitter_send_msg, }; use andromeda_std::{ + ado_base::permissioning::{LocalPermission, Permission, PermissioningMessage}, amp::{AndrAddr, Recipient}, common::{denom::Asset, encode_binary, expiration::Expiry, Milliseconds}, }; @@ -108,7 +109,7 @@ fn setup( let cw721_init_msg = mock_cw721_instantiate_msg( "Campaign Tier".to_string(), "CT".to_string(), - "./crowdfund".to_string(), + owner.to_string(), andr.kernel.addr().to_string(), None, ); @@ -237,6 +238,23 @@ fn setup( orderer: buyer_one.clone(), }]; + let permission_action_msg = ExecuteMsg::Permissioning(PermissioningMessage::PermissionAction { + action: "Mint".to_string(), + }); + cw721 + .execute(&mut router, &permission_action_msg, owner.clone(), &[]) + .unwrap(); + + let permission_msg = ExecuteMsg::Permissioning(PermissioningMessage::SetPermission { + actors: vec![AndrAddr::from_string(crowdfund.addr().to_string())], + action: "Mint".to_string(), + permission: Permission::Local(LocalPermission::whitelisted(None, None)), + }); + + cw721 + .execute(&mut router, &permission_msg, owner.clone(), &[]) + .unwrap(); + TestCase { router, andr, diff --git a/tests-integration/tests/curve_app.rs b/e2e-tests/tests/curve_app.rs similarity index 100% rename from tests-integration/tests/curve_app.rs rename to e2e-tests/tests/curve_app.rs diff --git a/tests-integration/tests/cw20_app.rs b/e2e-tests/tests/cw20_app.rs similarity index 100% rename from tests-integration/tests/cw20_app.rs rename to e2e-tests/tests/cw20_app.rs diff --git a/tests-integration/tests/cw20_staking.rs b/e2e-tests/tests/cw20_staking.rs similarity index 100% rename from tests-integration/tests/cw20_staking.rs rename to e2e-tests/tests/cw20_staking.rs diff --git a/tests-integration/tests/fixed_amount_splitter.rs b/e2e-tests/tests/fixed_amount_splitter.rs similarity index 100% rename from tests-integration/tests/fixed_amount_splitter.rs rename to e2e-tests/tests/fixed_amount_splitter.rs diff --git a/tests-integration/tests/ibc_registry.rs b/e2e-tests/tests/ibc_registry.rs similarity index 100% rename from tests-integration/tests/ibc_registry.rs rename to e2e-tests/tests/ibc_registry.rs diff --git a/tests-integration/tests/kernel.rs b/e2e-tests/tests/kernel.rs similarity index 100% rename from tests-integration/tests/kernel.rs rename to e2e-tests/tests/kernel.rs diff --git a/tests-integration/tests/kernel_orch.rs b/e2e-tests/tests/kernel_orch.rs similarity index 98% rename from tests-integration/tests/kernel_orch.rs rename to e2e-tests/tests/kernel_orch.rs index d658d604e..d00a3fdfc 100644 --- a/tests-integration/tests/kernel_orch.rs +++ b/e2e-tests/tests/kernel_orch.rs @@ -51,13 +51,16 @@ fn test_kernel_ibc_execute_only() { let counter_osmosis = CounterContract::new(osmosis.clone()); let vfs_osmosis = VFSContract::new(osmosis.clone()); let adodb_osmosis = ADODBContract::new(osmosis.clone()); + let economics_osmosis = EconomicsContract::new(osmosis.clone()); kernel_juno.upload().unwrap(); vfs_juno.upload().unwrap(); + kernel_osmosis.upload().unwrap(); counter_osmosis.upload().unwrap(); vfs_osmosis.upload().unwrap(); adodb_osmosis.upload().unwrap(); + economics_osmosis.upload().unwrap(); let init_msg_juno = &InstantiateMsg { owner: None, @@ -132,6 +135,17 @@ fn test_kernel_ibc_execute_only() { ) .unwrap(); + economics_osmosis + .instantiate( + &os::economics::InstantiateMsg { + kernel_address: kernel_osmosis.address().unwrap().into_string(), + owner: None, + }, + None, + None, + ) + .unwrap(); + kernel_juno .execute( &ExecuteMsg::UpsertKeyAddress { @@ -162,6 +176,16 @@ fn test_kernel_ibc_execute_only() { ) .unwrap(); + kernel_osmosis + .execute( + &ExecuteMsg::UpsertKeyAddress { + key: "economics".to_string(), + value: economics_osmosis.address().unwrap().into_string(), + }, + None, + ) + .unwrap(); + kernel_juno .execute( &ExecuteMsg::AssignChannels { @@ -425,11 +449,13 @@ fn test_kernel_ibc_execute_only_multi_hop() { let counter_andromeda = CounterContract::new(andromeda.clone()); let vfs_andromeda = VFSContract::new(andromeda.clone()); let adodb_andromeda = ADODBContract::new(andromeda.clone()); + let economics_andromeda = EconomicsContract::new(andromeda.clone()); kernel_andromeda.upload().unwrap(); counter_andromeda.upload().unwrap(); vfs_andromeda.upload().unwrap(); adodb_andromeda.upload().unwrap(); + economics_andromeda.upload().unwrap(); let init_msg_andromeda = &InstantiateMsg { owner: None, @@ -462,6 +488,17 @@ fn test_kernel_ibc_execute_only_multi_hop() { ) .unwrap(); + economics_andromeda + .instantiate( + &os::economics::InstantiateMsg { + kernel_address: kernel_andromeda.address().unwrap().into_string(), + owner: None, + }, + None, + None, + ) + .unwrap(); + adodb_andromeda .execute( &os::adodb::ExecuteMsg::Publish { @@ -485,6 +522,16 @@ fn test_kernel_ibc_execute_only_multi_hop() { ) .unwrap(); + kernel_andromeda + .execute( + &ExecuteMsg::UpsertKeyAddress { + key: "economics".to_string(), + value: economics_andromeda.address().unwrap().into_string(), + }, + None, + ) + .unwrap(); + // Set up channel from osmosis to andromeda let channel_receipt_2 = interchain .create_contract_channel(&kernel_osmosis, &kernel_andromeda, "andr-kernel-1", None) diff --git a/tests-integration/tests/lockdrop.rs b/e2e-tests/tests/lockdrop.rs similarity index 100% rename from tests-integration/tests/lockdrop.rs rename to e2e-tests/tests/lockdrop.rs diff --git a/e2e-tests/tests/macro_tests/attrs.rs b/e2e-tests/tests/macro_tests/attrs.rs new file mode 100644 index 000000000..cc6fca47d --- /dev/null +++ b/e2e-tests/tests/macro_tests/attrs.rs @@ -0,0 +1,33 @@ +use cosmwasm_schema::cw_serde; +use rstest::*; + +use andromeda_std::andr_exec; + +#[andr_exec] +#[cw_serde] +pub enum TestEnum { + #[attrs(restricted, nonpayable, direct)] + AllAttrs, + #[attrs(restricted)] + Restricted, + #[attrs(nonpayable)] + NonPayable, + #[attrs(direct)] + Direct, +} + +#[rstest] +#[case(TestEnum::AllAttrs, true, false, true)] +#[case(TestEnum::Restricted, true, true, false)] +#[case(TestEnum::NonPayable, false, false, false)] +#[case(TestEnum::Direct, false, true, true)] +fn test_attrs( + #[case] test: TestEnum, + #[case] restricted: bool, + #[case] payable: bool, + #[case] direct: bool, +) { + assert_eq!(test.is_restricted(), restricted); + assert_eq!(test.is_payable(), payable); + assert_eq!(test.must_be_direct(), direct); +} diff --git a/e2e-tests/tests/macro_tests/exec_fn.rs b/e2e-tests/tests/macro_tests/exec_fn.rs new file mode 100644 index 000000000..eb346fa60 --- /dev/null +++ b/e2e-tests/tests/macro_tests/exec_fn.rs @@ -0,0 +1,248 @@ +use andromeda_std::{ + ado_base::InstantiateMsg, + ado_contract::ADOContract, + amp::messages::{AMPMsg, AMPPkt}, + andr_exec, andr_execute_fn, + common::context::ExecuteContext, + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, WasmMockQuerier, MOCK_KERNEL_CONTRACT}, + unwrap_amp_msg, +}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ + coin, + testing::{mock_env, mock_info, MockApi, MockStorage}, + to_json_binary, Env, MessageInfo, OwnedDeps, QuerierWrapper, Response, +}; +use cw_utils::PaymentError; +use rstest::*; + +const OWNER: &str = "sender"; +const ATTACKER: &str = "attacker"; + +#[andr_exec] +#[cw_serde] +enum ExecuteMsg { + #[attrs(restricted, nonpayable, direct)] + AllAttrs, + #[attrs(restricted, nonpayable)] + RestrictedNonPayable, + #[attrs(restricted, direct)] + RestrictedDirect, + #[attrs(nonpayable, direct)] + NonPayableDirect, + #[attrs(restricted)] + Restricted, +} + +#[andr_execute_fn] +fn execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + Ok(Response::new()) +} + +#[fixture] +fn setup() -> (OwnedDeps, Env) { + let mut deps = mock_dependencies_custom(&[]); + let querier = QuerierWrapper::new(&deps.querier); + let env = mock_env(); + let info = mock_info(OWNER, &[]); + + ADOContract::default() + .instantiate( + &mut deps.storage, + env.clone(), + &deps.api, + &querier, + info.clone(), + InstantiateMsg { + ado_type: "andromeda-test".to_string(), + ado_version: "0.1.0".to_string(), + owner: Some("sender".to_string()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + }, + ) + .unwrap(); + (deps, env) +} + +/// Tests calling the execute entry point directly on each enum variant +/// The first test case is without funds, the second is with funds +#[rstest] +fn test_exec_fn_direct( + setup: (OwnedDeps, Env), + #[values( + // AllAttrs (restricted, nonpayable, direct) + (ExecuteMsg::AllAttrs, OWNER, None, Some(ContractError::Payment(PaymentError::NonPayable {}))), + (ExecuteMsg::AllAttrs, ATTACKER, Some(ContractError::Unauthorized {}), Some(ContractError::Unauthorized {})), + + // RestrictedNonPayable (restricted, nonpayable) + (ExecuteMsg::RestrictedNonPayable, OWNER, None, Some(ContractError::Payment(PaymentError::NonPayable {}))), + (ExecuteMsg::RestrictedNonPayable, ATTACKER, Some(ContractError::Unauthorized {}), Some(ContractError::Unauthorized {})), + + // RestrictedDirect (restricted, direct) + (ExecuteMsg::RestrictedDirect, OWNER, None, None), + (ExecuteMsg::RestrictedDirect, ATTACKER, Some(ContractError::Unauthorized {}), Some(ContractError::Unauthorized {})), + + // NonPayableDirect (nonpayable, direct) + (ExecuteMsg::NonPayableDirect, OWNER, None, Some(ContractError::Payment(PaymentError::NonPayable {}))), + (ExecuteMsg::NonPayableDirect, ATTACKER, None, Some(ContractError::Payment(PaymentError::NonPayable {}))) + )] + case: ( + ExecuteMsg, + &str, + Option, + Option, + ), +) { + let (mut deps, env) = setup; + + // Test case with no funds + let send_info_no_funds = mock_info(case.1, &[]); + let res_no_funds = execute( + deps.as_mut(), + env.clone(), + send_info_no_funds, + case.0.clone(), + ); + + match case.2 { + Some(expected) => assert_eq!(res_no_funds, Err(expected)), + None => assert!(res_no_funds.is_ok()), + } + + // Test case with funds + let send_info_with_funds = mock_info(case.1, &[coin(100, "uatom")]); + let res_with_funds = execute(deps.as_mut(), env, send_info_with_funds, case.0); + + match case.3 { + Some(expected) => assert_eq!(res_with_funds, Err(expected)), + None => assert!(res_with_funds.is_ok()), + } +} + +fn direct_msg_error(msg: &str) -> Option { + Some(ContractError::InvalidPacket { + error: Some(format!("{} cannot be received via AMP packet", msg)), + }) +} + +/// Tests calling the execute entry point via AMP packet on each enum variant +/// The first test case is without funds, the second is with funds +#[rstest] +fn test_exec_fn_amp_receive( + setup: (OwnedDeps, Env), + #[values( + // AllAttrs (restricted, nonpayable, direct) + (ExecuteMsg::AllAttrs, OWNER, direct_msg_error("AllAttrs"), direct_msg_error("AllAttrs")), + (ExecuteMsg::AllAttrs, ATTACKER, direct_msg_error("AllAttrs"), direct_msg_error("AllAttrs")), + + // RestrictedNonPayable (restricted, nonpayable) + (ExecuteMsg::RestrictedNonPayable, OWNER, None, Some(ContractError::Payment(PaymentError::NonPayable {}))), + (ExecuteMsg::RestrictedNonPayable, ATTACKER, Some(ContractError::Unauthorized {}), Some(ContractError::Unauthorized {})), + + // RestrictedDirect (restricted, direct) + (ExecuteMsg::RestrictedDirect, OWNER, direct_msg_error("RestrictedDirect"), direct_msg_error("RestrictedDirect")), + (ExecuteMsg::RestrictedDirect, ATTACKER, direct_msg_error("RestrictedDirect"), direct_msg_error("RestrictedDirect")), + + // NonPayableDirect (nonpayable, direct) + (ExecuteMsg::NonPayableDirect, OWNER, direct_msg_error("NonPayableDirect"), direct_msg_error("NonPayableDirect")), + (ExecuteMsg::NonPayableDirect, ATTACKER, direct_msg_error("NonPayableDirect"), direct_msg_error("NonPayableDirect")) + )] + case: ( + ExecuteMsg, + &str, + Option, + Option, + ), +) { + let (mut deps, env) = setup; + + // Test case with no funds + let send_info_no_funds = mock_info(case.1, &[]); + let amp_msg_no_funds = AMPMsg::new( + env.contract.address.clone(), + to_json_binary(&case.0.clone()).unwrap(), + None, + ); + let amp_pkt_no_funds = AMPPkt::new( + case.1.to_string(), + case.1.to_string(), + vec![amp_msg_no_funds], + ); + let res_no_funds = execute( + deps.as_mut(), + env.clone(), + send_info_no_funds, + ExecuteMsg::AMPReceive(amp_pkt_no_funds), + ); + + match case.2 { + Some(expected) => assert_eq!(res_no_funds, Err(expected)), + None => assert!(res_no_funds.is_ok()), + } + + // Test case with funds + let send_info_with_funds = mock_info(case.1, &[coin(100, "uatom")]); + let amp_msg_with_funds = AMPMsg::new( + env.contract.address.clone(), + to_json_binary(&case.0.clone()).unwrap(), + Some(vec![coin(100, "uatom")]), + ); + let amp_pkt_with_funds = AMPPkt::new( + case.1.to_string(), + case.1.to_string(), + vec![amp_msg_with_funds], + ); + let res_with_funds = execute( + deps.as_mut(), + env, + send_info_with_funds, + ExecuteMsg::AMPReceive(amp_pkt_with_funds), + ); + + match case.3 { + Some(expected) => assert_eq!(res_with_funds, Err(expected)), + None => assert!(res_with_funds.is_ok()), + } +} + +#[test] +fn test_unwrap_amp_msg() { + let (mut deps, env) = setup(); + let info: MessageInfo = mock_info(MOCK_KERNEL_CONTRACT, &[]); + + let sent_msg = ExecuteMsg::Restricted; + let amp_msg = AMPMsg::new( + "sender".to_string(), + to_json_binary(&sent_msg).unwrap(), + None, + ); + let amp_pkt = AMPPkt::new("sender".to_string(), "sender".to_string(), vec![amp_msg]); + let msg = ExecuteMsg::AMPReceive(amp_pkt); + + let (ctx, msg, _) = (|| -> Result<(ExecuteContext, ExecuteMsg, Response), ContractError> { + let (ctx, msg, resp) = unwrap_amp_msg!(deps.as_mut(), info.clone(), env.clone(), msg); + Ok((ctx, msg, resp)) + })() + .unwrap(); + + assert_eq!(ctx.info.sender, "sender"); + assert_eq!(ctx.raw_info.sender, MOCK_KERNEL_CONTRACT); + assert_eq!(msg, sent_msg); + + let empty_amp_pkt = AMPPkt::new("sender".to_string(), "sender".to_string(), vec![]); + let msg = ExecuteMsg::AMPReceive(empty_amp_pkt); + + let err = (|| -> Result<(), ContractError> { + let _ = unwrap_amp_msg!(deps.as_mut(), info, env, msg); + Ok(()) + })() + .unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidPacket { + error: Some("AMP Packet received with no messages".to_string()) + } + ); +} diff --git a/e2e-tests/tests/macro_tests/mod.rs b/e2e-tests/tests/macro_tests/mod.rs new file mode 100644 index 000000000..3270e821e --- /dev/null +++ b/e2e-tests/tests/macro_tests/mod.rs @@ -0,0 +1,2 @@ +mod attrs; +mod exec_fn; diff --git a/tests-integration/tests/marketplace_app.rs b/e2e-tests/tests/marketplace_app.rs similarity index 100% rename from tests-integration/tests/marketplace_app.rs rename to e2e-tests/tests/marketplace_app.rs diff --git a/tests-integration/tests/mod.rs b/e2e-tests/tests/mod.rs similarity index 87% rename from tests-integration/tests/mod.rs rename to e2e-tests/tests/mod.rs index 48a69db1c..f71a4cbb4 100644 --- a/tests-integration/tests/mod.rs +++ b/e2e-tests/tests/mod.rs @@ -31,5 +31,11 @@ mod fixed_amount_splitter; #[cfg(test)] mod shunting; +#[cfg(test)] +mod amp; + +#[cfg(test)] +mod macro_tests; + #[cfg(test)] mod curve_app; diff --git a/tests-integration/tests/primitive.rs b/e2e-tests/tests/primitive.rs similarity index 100% rename from tests-integration/tests/primitive.rs rename to e2e-tests/tests/primitive.rs diff --git a/e2e-tests/tests/rates_orch.rs b/e2e-tests/tests/rates_orch.rs new file mode 100644 index 000000000..7046bb181 --- /dev/null +++ b/e2e-tests/tests/rates_orch.rs @@ -0,0 +1,221 @@ +use andromeda_adodb::ADODBContract; +use andromeda_economics::EconomicsContract; +use andromeda_kernel::KernelContract; +use andromeda_marketplace::MarketplaceContract; +use andromeda_modules::rates::InstantiateMsg as RatesInstantiateMsg; +use andromeda_non_fungible_tokens::marketplace::{ + ExecuteMsg, InstantiateMsg as MarketplaceInstantiateMsg, QueryMsg, +}; +use andromeda_rates::RatesContract; +use andromeda_std::{ + ado_base::{ + rates::{AllRatesResponse, LocalRate, LocalRateType, PercentRate}, + MigrateMsg, + }, + amp::{AndrAddr, Recipient}, + os::{ + self, + kernel::{ExecuteMsg as KernelExecuteMsg, InstantiateMsg as KernelInstantiateMsg}, + }, +}; +use andromeda_vfs::VFSContract; +use cosmwasm_std::{Addr, Decimal}; +use cw_orch::prelude::*; +use cw_orch_interchain::prelude::*; + +#[test] +fn test_marketplace_migration() { + // Here `juno-1` is the chain-id and `juno` is the address prefix for this chain + let sender = Addr::unchecked("sender_for_all_chains"); + let interchain = MockInterchainEnv::new(vec![("juno", &sender.clone().into_string())]); + let juno = interchain.get_chain("juno").unwrap(); + + juno.set_balance( + sender.clone().into_string().clone(), + vec![Coin::new(100000000000000, "juno")], + ) + .unwrap(); + + let marketplace_juno = MarketplaceContract::new(juno.clone()); + let kernel_juno = KernelContract::new(juno.clone()); + let rates_juno = RatesContract::new(juno.clone()); + let vfs_juno = VFSContract::new(juno.clone()); + let adodb_juno = ADODBContract::new(juno.clone()); + let economics_juno = EconomicsContract::new(juno.clone()); + + marketplace_juno.upload().unwrap(); + kernel_juno.upload().unwrap(); + rates_juno.upload().unwrap(); + vfs_juno.upload().unwrap(); + adodb_juno.upload().unwrap(); + economics_juno.upload().unwrap(); + + let kernel_init_msg = &KernelInstantiateMsg { + owner: None, + chain_name: "juno".to_string(), + }; + kernel_juno + .instantiate(kernel_init_msg, None, None) + .unwrap(); + + vfs_juno + .instantiate( + &os::vfs::InstantiateMsg { + kernel_address: kernel_juno.address().unwrap().into_string(), + owner: None, + }, + None, + None, + ) + .unwrap(); + + kernel_juno + .execute( + &KernelExecuteMsg::UpsertKeyAddress { + key: "vfs".to_string(), + value: vfs_juno.address().unwrap().into_string(), + }, + None, + ) + .unwrap(); + + adodb_juno + .instantiate( + &os::adodb::InstantiateMsg { + kernel_address: kernel_juno.address().unwrap().into_string(), + owner: None, + }, + None, + None, + ) + .unwrap(); + + kernel_juno + .execute( + &KernelExecuteMsg::UpsertKeyAddress { + key: "adodb".to_string(), + value: adodb_juno.address().unwrap().into_string(), + }, + None, + ) + .unwrap(); + + adodb_juno + .execute( + &os::adodb::ExecuteMsg::Publish { + code_id: 3, + ado_type: "rates".to_string(), + action_fees: None, + version: "2.0.3".to_string(), + publisher: None, + }, + None, + ) + .unwrap(); + + let rates_init_msg = &RatesInstantiateMsg { + action: "Claim".to_string(), + rate: LocalRate { + rate_type: LocalRateType::Additive, + recipient: Recipient::from_string("recipient".to_string()), + value: andromeda_std::ado_base::rates::LocalRateValue::Percent(PercentRate { + percent: Decimal::one(), + }), + description: None, + }, + kernel_address: kernel_juno.address().unwrap().into_string(), + owner: Some(sender.clone().into_string().clone()), + }; + rates_juno.instantiate(rates_init_msg, None, None).unwrap(); + + kernel_juno + .execute( + &KernelExecuteMsg::UpsertKeyAddress { + key: "rates".to_string(), + value: rates_juno.address().unwrap().into_string(), + }, + None, + ) + .unwrap(); + + let marketplace_init_msg = &MarketplaceInstantiateMsg { + authorized_cw20_addresses: None, + authorized_token_addresses: None, + kernel_address: kernel_juno.address().unwrap().into_string(), + owner: Some(sender.clone().into_string().clone()), + }; + + marketplace_juno + .instantiate(marketplace_init_msg, Some(&sender), None) + .unwrap(); + + adodb_juno + .execute( + &os::adodb::ExecuteMsg::Publish { + code_id: 6, + ado_type: "economics".to_string(), + action_fees: None, + version: "1.1.1".to_string(), + publisher: None, + }, + None, + ) + .unwrap(); + + economics_juno + .instantiate( + &os::economics::InstantiateMsg { + kernel_address: kernel_juno.address().unwrap().into_string(), + owner: None, + }, + None, + None, + ) + .unwrap(); + + kernel_juno + .execute( + &KernelExecuteMsg::UpsertKeyAddress { + key: "economics".to_string(), + value: economics_juno.address().unwrap().into_string(), + }, + None, + ) + .unwrap(); + + marketplace_juno + .execute( + &ExecuteMsg::Rates(andromeda_std::ado_base::rates::RatesMessage::SetRate { + action: "Claim".to_string(), + rate: andromeda_std::ado_base::rates::Rate::Contract(AndrAddr::from_string( + rates_juno.address().unwrap().into_string(), + )), + }), + None, + ) + .unwrap(); + + marketplace_juno.upload().unwrap(); + + // Query marketplace rates + let rates_query: AllRatesResponse = marketplace_juno.query(&QueryMsg::AllRates {}).unwrap(); + assert_eq!(rates_query.all_rates.len(), 1); + + marketplace_juno.migrate(&MigrateMsg {}, 7).unwrap(); + + // Adjusting the migrate function for testing purposes will show that the code works as expected. + // Let the code in the migrate function to expect Recipient instead of Vec and the below rates query will return 0 + let rates_query: AllRatesResponse = marketplace_juno.query(&QueryMsg::AllRates {}).unwrap(); + assert_eq!(rates_query.all_rates.len(), 1); + + // vfs_juno + // .instantiate( + // &os::vfs::InstantiateMsg { + // kernel_address: kernel_juno.address().unwrap().into_string(), + // owner: None, + // }, + // None, + // None, + // ) + // .unwrap(); +} diff --git a/e2e-tests/tests/set_amount_splitter.rs b/e2e-tests/tests/set_amount_splitter.rs new file mode 100644 index 000000000..54e908946 --- /dev/null +++ b/e2e-tests/tests/set_amount_splitter.rs @@ -0,0 +1,255 @@ +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; + +use andromeda_cw20::mock::{mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_minter, MockCW20}; +use andromeda_testing::{ + mock::{mock_app, MockApp}, + mock_builder::MockAndromedaBuilder, + MockAndromeda, MockContract, +}; + +use andromeda_std::amp::Recipient; +use cosmwasm_std::{coin, coins, to_json_binary, Coin, Empty, Uint128}; + +use andromeda_finance::fixed_amount_splitter::{AddressAmount, Cw20HookMsg}; +use andromeda_fixed_amount_splitter::mock::{ + mock_andromeda_fixed_amount_splitter, mock_fixed_amount_splitter_instantiate_msg, + MockFixedAmountSplitter, +}; +use cw20::Cw20Coin; +use cw_multi_test::Contract; +use rstest::{fixture, rstest}; + +struct TestCase { + router: MockApp, + andr: MockAndromeda, + splitter: MockFixedAmountSplitter, + cw20: MockCW20, +} + +#[fixture] +fn wallets() -> Vec<(&'static str, Vec)> { + vec![ + ("owner", vec![coin(1000000, "uandr")]), + ("recipient1", vec![]), + ("recipient2", vec![]), + ] +} + +#[fixture] +fn contracts() -> Vec<(&'static str, Box>)> { + vec![ + ("cw20", mock_andromeda_cw20()), + ( + "fixed-amount-splitter", + mock_andromeda_fixed_amount_splitter(), + ), + ("app-contract", mock_andromeda_app()), + ] +} + +#[fixture] +fn setup( + #[default(true)] use_native_token: bool, + wallets: Vec<(&'static str, Vec)>, + contracts: Vec<(&'static str, Box>)>, +) -> TestCase { + let mut router = mock_app(None); + + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(wallets) + .with_contracts(contracts) + .build(&mut router); + + let owner = andr.get_wallet("owner"); + + // Prepare Splitter component which can be used as a withdrawal address for some test cases + let recipient_1 = andr.get_wallet("recipient1"); + let recipient_2 = andr.get_wallet("recipient2"); + + let splitter_recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(recipient_1.to_string()), + coins: coins(100, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(recipient_2.to_string()), + coins: coins(100, "uandr"), + }, + ]; + let splitter_init_msg = mock_fixed_amount_splitter_instantiate_msg( + splitter_recipients, + andr.kernel.addr().clone(), + None, + None, + None, + ); + let splitter_component = AppComponent::new( + "fixed-amount-splitter".to_string(), + "fixed-amount-splitter".to_string(), + to_json_binary(&splitter_init_msg).unwrap(), + ); + + let mut app_components = vec![splitter_component.clone()]; + + // Add cw20 components for test cases using cw20 + let cw20_component: AppComponent = { + let initial_balances = vec![Cw20Coin { + address: owner.to_string(), + amount: Uint128::from(1_000_000u128), + }]; + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + app_components.push(cw20_component.clone()); + cw20_component + }; + + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Set Amount Splitter App", + app_components.clone(), + andr.kernel.addr(), + Some(owner.to_string()), + ); + + let splitter: MockFixedAmountSplitter = + app.query_ado_by_component_name(&router, splitter_component.name); + + let cw20: MockCW20 = app.query_ado_by_component_name(&router, cw20_component.name); + + // Update splitter recipients to use cw20 if applicable + if !use_native_token { + let cw20_addr = cw20.addr(); + let splitter_recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(recipient_1.to_string()), + coins: coins(100, cw20_addr.clone()), + }, + AddressAmount { + recipient: Recipient::from_string(recipient_2.to_string()), + coins: coins(100, cw20_addr.clone()), + }, + ]; + + splitter + .execute_update_recipients(&mut router, owner.clone(), &[], splitter_recipients) + .unwrap(); + } + TestCase { + router, + andr, + splitter, + cw20, + } +} + +#[rstest] +fn test_successful_fixed_amount_splitter_native(setup: TestCase) { + let TestCase { + mut router, + andr, + splitter, + .. + } = setup; + + let owner = andr.get_wallet("owner"); + + splitter + .execute_send(&mut router, owner.clone(), &[coin(1000, "uandr")], None) + .unwrap(); + + assert_eq!( + router + .wrap() + .query_balance(andr.get_wallet("recipient1"), "uandr") + .unwrap() + .amount, + Uint128::from(100u128) + ); + assert_eq!( + router + .wrap() + .query_balance(andr.get_wallet("recipient2"), "uandr") + .unwrap() + .amount, + Uint128::from(100u128) + ); +} + +#[rstest] +fn test_successful_fixed_amount_splitter_cw20_with_remainder(#[with(false)] setup: TestCase) { + let TestCase { + mut router, + andr, + splitter, + cw20, + } = setup; + + let owner = andr.get_wallet("owner"); + + let hook_msg = Cw20HookMsg::Send { config: None }; + + cw20.execute_send( + &mut router, + owner.clone(), + splitter.addr(), + Uint128::new(1000), + &hook_msg, + ) + .unwrap(); + + let cw20_balance = cw20.query_balance(&router, andr.get_wallet("recipient1")); + assert_eq!(cw20_balance, Uint128::from(100u128)); + let cw20_balance = cw20.query_balance(&router, andr.get_wallet("recipient2")); + assert_eq!(cw20_balance, Uint128::from(100u128)); + let cw20_balance = cw20.query_balance(&router, owner); + assert_eq!(cw20_balance, Uint128::from(1_000_000u128 - 200u128)); +} + +#[rstest] +fn test_successful_fixed_amount_splitter_cw20_without_remainder(#[with(false)] setup: TestCase) { + let TestCase { + mut router, + andr, + splitter, + cw20, + } = setup; + + let owner = andr.get_wallet("owner"); + + let hook_msg = Cw20HookMsg::Send { config: None }; + + cw20.execute_send( + &mut router, + owner.clone(), + splitter.addr(), + Uint128::new(200), + &hook_msg, + ) + .unwrap(); + + let cw20_balance = cw20.query_balance(&router, andr.get_wallet("recipient1")); + assert_eq!(cw20_balance, Uint128::from(100u128)); + let cw20_balance = cw20.query_balance(&router, andr.get_wallet("recipient2")); + assert_eq!(cw20_balance, Uint128::from(100u128)); + let cw20_balance = cw20.query_balance(&router, owner); + assert_eq!(cw20_balance, Uint128::from(1_000_000u128 - 200u128)); +} diff --git a/tests-integration/tests/shunting.rs b/e2e-tests/tests/shunting.rs similarity index 100% rename from tests-integration/tests/shunting.rs rename to e2e-tests/tests/shunting.rs diff --git a/tests-integration/tests/splitter.rs b/e2e-tests/tests/splitter.rs similarity index 100% rename from tests-integration/tests/splitter.rs rename to e2e-tests/tests/splitter.rs diff --git a/tests-integration/tests/validator_staking.rs b/e2e-tests/tests/validator_staking.rs similarity index 100% rename from tests-integration/tests/validator_staking.rs rename to e2e-tests/tests/validator_staking.rs diff --git a/tests-integration/tests_old/cw20_staking_app.rs b/e2e-tests/tests_old/cw20_staking_app.rs similarity index 100% rename from tests-integration/tests_old/cw20_staking_app.rs rename to e2e-tests/tests_old/cw20_staking_app.rs diff --git a/tests-integration/tests_old/cw721.rs b/e2e-tests/tests_old/cw721.rs similarity index 100% rename from tests-integration/tests_old/cw721.rs rename to e2e-tests/tests_old/cw721.rs diff --git a/tests-integration/tests_old/ics721_app.rs b/e2e-tests/tests_old/ics721_app.rs similarity index 100% rename from tests-integration/tests_old/ics721_app.rs rename to e2e-tests/tests_old/ics721_app.rs diff --git a/tests-integration/tests_old/kernel_path_bridge.rs b/e2e-tests/tests_old/kernel_path_bridge.rs similarity index 100% rename from tests-integration/tests_old/kernel_path_bridge.rs rename to e2e-tests/tests_old/kernel_path_bridge.rs diff --git a/tests-integration/tests_old/mod.rs b/e2e-tests/tests_old/mod.rs similarity index 100% rename from tests-integration/tests_old/mod.rs rename to e2e-tests/tests_old/mod.rs diff --git a/tests-integration/tests_old/wrapped_cw721_app.rs b/e2e-tests/tests_old/wrapped_cw721_app.rs similarity index 100% rename from tests-integration/tests_old/wrapped_cw721_app.rs rename to e2e-tests/tests_old/wrapped_cw721_app.rs diff --git a/packages/andromeda-app/src/app.rs b/packages/andromeda-app/src/app.rs index 9ee9372e3..0dcc0e890 100644 --- a/packages/andromeda-app/src/app.rs +++ b/packages/andromeda-app/src/app.rs @@ -311,6 +311,7 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(restricted)] AddAppComponent { component: AppComponent, }, diff --git a/packages/andromeda-data-storage/src/boolean.rs b/packages/andromeda-data-storage/src/boolean.rs index 11bb0a9da..a6c294faa 100644 --- a/packages/andromeda-data-storage/src/boolean.rs +++ b/packages/andromeda-data-storage/src/boolean.rs @@ -10,9 +10,15 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - SetValue { value: bool }, + SetValue { + value: bool, + }, + #[attrs(nonpayable)] DeleteValue {}, - UpdateRestriction { restriction: BooleanRestriction }, + #[attrs(nonpayable, restricted)] + UpdateRestriction { + restriction: BooleanRestriction, + }, } #[andr_query] diff --git a/packages/andromeda-data-storage/src/form.rs b/packages/andromeda-data-storage/src/form.rs index b86c3519c..139507b8f 100644 --- a/packages/andromeda-data-storage/src/form.rs +++ b/packages/andromeda-data-storage/src/form.rs @@ -23,19 +23,22 @@ pub struct FormConfig { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - SubmitForm { - data: String, - }, + #[attrs(nonpayable)] + SubmitForm { data: String }, + #[attrs(nonpayable, restricted)] DeleteSubmission { submission_id: u64, wallet_address: AndrAddr, }, + #[attrs(nonpayable)] EditSubmission { submission_id: u64, wallet_address: AndrAddr, data: String, }, + #[attrs(nonpayable, restricted)] OpenForm {}, + #[attrs(nonpayable, restricted)] CloseForm {}, } diff --git a/packages/andromeda-data-storage/src/primitive.rs b/packages/andromeda-data-storage/src/primitive.rs index e5100f6e5..de98cec53 100644 --- a/packages/andromeda-data-storage/src/primitive.rs +++ b/packages/andromeda-data-storage/src/primitive.rs @@ -18,12 +18,10 @@ pub enum ExecuteMsg { value: Primitive, }, /// If key is not specified the default key will be used. - DeleteValue { - key: Option, - }, - UpdateRestriction { - restriction: PrimitiveRestriction, - }, + #[attrs(nonpayable)] + DeleteValue { key: Option }, + #[attrs(restricted, nonpayable)] + UpdateRestriction { restriction: PrimitiveRestriction }, } #[andr_query] diff --git a/packages/andromeda-data-storage/src/string_storage.rs b/packages/andromeda-data-storage/src/string_storage.rs index 64eec7dfb..f0a77a0c1 100644 --- a/packages/andromeda-data-storage/src/string_storage.rs +++ b/packages/andromeda-data-storage/src/string_storage.rs @@ -14,7 +14,9 @@ pub enum ExecuteMsg { SetValue { value: StringStorage, }, + #[attrs(nonpayable)] DeleteValue {}, + #[attrs(nonpayable, restricted)] UpdateRestriction { restriction: StringStorageRestriction, }, diff --git a/packages/andromeda-ecosystem/src/vault.rs b/packages/andromeda-ecosystem/src/vault.rs index 360195634..063fa2948 100644 --- a/packages/andromeda-ecosystem/src/vault.rs +++ b/packages/andromeda-ecosystem/src/vault.rs @@ -101,11 +101,13 @@ pub struct InstantiateMsg {} #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable)] WithdrawVault { recipient: Option, withdrawals: Vec, strategy: Option, }, + #[attrs(restriced)] UpdateStrategy { strategy: StrategyType, address: AndrAddr, diff --git a/packages/andromeda-finance/src/conditional_splitter.rs b/packages/andromeda-finance/src/conditional_splitter.rs index 1a7fabce6..57cea3516 100644 --- a/packages/andromeda-finance/src/conditional_splitter.rs +++ b/packages/andromeda-finance/src/conditional_splitter.rs @@ -75,8 +75,10 @@ pub struct InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { /// Update the thresholds. Only executable by the contract owner when the contract is not locked. + #[attrs(restricted, nonpayable, direct)] UpdateThresholds { thresholds: Vec }, /// Used to lock/unlock the contract allowing the config to be updated. + #[attrs(restricted, nonpayable, direct)] UpdateLock { lock_time: Expiry }, /// Divides any attached funds to the message amongst the recipients list. Send {}, diff --git a/packages/andromeda-finance/src/fixed_amount_splitter.rs b/packages/andromeda-finance/src/fixed_amount_splitter.rs index 915561e05..404ac315e 100644 --- a/packages/andromeda-finance/src/fixed_amount_splitter.rs +++ b/packages/andromeda-finance/src/fixed_amount_splitter.rs @@ -59,23 +59,21 @@ pub enum Cw20HookMsg { #[cw_serde] pub enum ExecuteMsg { /// Update the recipients list. Only executable by the contract owner when the contract is not locked. - UpdateRecipients { - recipients: Vec, - }, + #[attrs(restricted, nonpayable, direct)] + UpdateRecipients { recipients: Vec }, /// Used to lock/unlock the contract allowing the config to be updated. + #[attrs(restricted, nonpayable, direct)] UpdateLock { // Milliseconds from current time lock_time: Expiry, }, /// Update the default recipient. Only executable by the contract owner when the contract is not locked. - UpdateDefaultRecipient { - recipient: Option, - }, + #[attrs(restricted, nonpayable, direct)] + UpdateDefaultRecipient { recipient: Option }, + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// Divides any attached funds to the message amongst the recipients list. - Send { - config: Option>, - }, + Send { config: Option> }, } #[andr_query] diff --git a/packages/andromeda-finance/src/rate_limiting_withdrawals.rs b/packages/andromeda-finance/src/rate_limiting_withdrawals.rs index 6ef43b3ae..893ddeb06 100644 --- a/packages/andromeda-finance/src/rate_limiting_withdrawals.rs +++ b/packages/andromeda-finance/src/rate_limiting_withdrawals.rs @@ -49,8 +49,13 @@ pub enum MinimumFrequency { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - Deposit { recipient: Option }, - Withdraw { amount: Uint128 }, + Deposit { + recipient: Option, + }, + #[attrs(nonpayable)] + Withdraw { + amount: Uint128, + }, } #[andr_query] diff --git a/packages/andromeda-finance/src/splitter.rs b/packages/andromeda-finance/src/splitter.rs index 2acb108c4..3583a7e1e 100644 --- a/packages/andromeda-finance/src/splitter.rs +++ b/packages/andromeda-finance/src/splitter.rs @@ -58,22 +58,18 @@ pub enum Cw20HookMsg { #[cw_serde] pub enum ExecuteMsg { /// Update the recipients list. Only executable by the contract owner when the contract is not locked. - UpdateRecipients { - recipients: Vec, - }, + #[attrs(restricted, nonpayable, direct)] + UpdateRecipients { recipients: Vec }, /// Used to lock/unlock the contract allowing the config to be updated. - UpdateLock { - lock_time: Expiry, - }, + #[attrs(restricted, nonpayable, direct)] + UpdateLock { lock_time: Expiry }, /// Update the default recipient. Only executable by the contract owner when the contract is not locked. - UpdateDefaultRecipient { - recipient: Option, - }, + #[attrs(restricted, nonpayable, direct)] + UpdateDefaultRecipient { recipient: Option }, + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// Divides any attached funds to the message amongst the recipients list. - Send { - config: Option>, - }, + Send { config: Option> }, } #[andr_query] diff --git a/packages/andromeda-finance/src/validator_staking.rs b/packages/andromeda-finance/src/validator_staking.rs index dbd79c2b9..9e7eac50c 100644 --- a/packages/andromeda-finance/src/validator_staking.rs +++ b/packages/andromeda-finance/src/validator_staking.rs @@ -17,13 +17,13 @@ pub struct InstantiateMsg { #[cfg_attr(not(target_arch = "wasm32"), derive(cw_orch::ExecuteFns))] pub enum ExecuteMsg { #[cfg_attr(not(target_arch = "wasm32"), cw_orch(payable))] - Stake { - validator: Option, - }, + Stake { validator: Option }, + #[attrs(restricted)] Unstake { validator: Option, amount: Option, }, + #[attrs(restricted)] Redelegate { src_validator: Option, dst_validator: Addr, @@ -34,13 +34,13 @@ pub enum ExecuteMsg { /// Defaults to false restake: Option, }, + #[attrs(restricted)] WithdrawFunds { denom: Option, recipient: Option, }, - UpdateDefaultValidator { - validator: Addr, - }, + #[attrs(restricted)] + UpdateDefaultValidator { validator: Addr }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] diff --git a/packages/andromeda-finance/src/vesting.rs b/packages/andromeda-finance/src/vesting.rs index 4b40c95a5..a7a603b0b 100644 --- a/packages/andromeda-finance/src/vesting.rs +++ b/packages/andromeda-finance/src/vesting.rs @@ -21,6 +21,7 @@ pub struct InstantiateMsg { pub enum ExecuteMsg { /// Claim the number of batches specified starting from the beginning. If not /// specified then the max will be claimed. + #[attrs(restricted, nonpayable)] Claim { number_of_claims: Option, batch_id: u64, @@ -28,11 +29,13 @@ pub enum ExecuteMsg { /// Claims tokens from all batches using a paginated approach. If `up_to_time` /// is specified then it will only claim up to a specific time, otherwise it /// it will claim to the most recent release. + #[attrs(restricted, nonpayable)] ClaimAll { up_to_time: Option, limit: Option, }, /// Creates a new batch + #[attrs(restricted)] CreateBatch { /// Specifying None would mean no lock up period and funds start vesting right away. lockup_duration: Option, diff --git a/packages/andromeda-finance/src/weighted_splitter.rs b/packages/andromeda-finance/src/weighted_splitter.rs index 7dbba120c..b55e4d7c0 100644 --- a/packages/andromeda-finance/src/weighted_splitter.rs +++ b/packages/andromeda-finance/src/weighted_splitter.rs @@ -37,16 +37,22 @@ pub struct InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { /// Update the recipients list. Only executable by the contract owner when the contract is not locked. + #[attrs(restricted, nonpayable, direct)] UpdateRecipients { recipients: Vec }, /// Update a specific recipient's weight. Only executable by the contract owner when the contract is not locked. + #[attrs(restricted, nonpayable, direct)] UpdateRecipientWeight { recipient: AddressWeight }, /// Update the default recipient. Only executable by the contract owner when the contract is not locked. + #[attrs(restricted, nonpayable, direct)] UpdateDefaultRecipient { recipient: Option }, /// Add a single recipient to the recipient list. Only executable by the contract owner when the contract is not locked. + #[attrs(restricted, nonpayable, direct)] AddRecipient { recipient: AddressWeight }, /// Remove a single recipient from the recipient list. Only executable by the contract owner when the contract is not locked. + #[attrs(restricted, nonpayable, direct)] RemoveRecipient { recipient: AndrAddr }, /// Used to lock/unlock the contract allowing the config to be updated. + #[attrs(restricted, nonpayable, direct)] UpdateLock { lock_time: Expiry }, /// Divides any attached funds to the message amongst the recipients list. Send { config: Option> }, diff --git a/packages/andromeda-fungible-tokens/src/airdrop.rs b/packages/andromeda-fungible-tokens/src/airdrop.rs index 76db7df26..e1c7f5363 100644 --- a/packages/andromeda-fungible-tokens/src/airdrop.rs +++ b/packages/andromeda-fungible-tokens/src/airdrop.rs @@ -14,6 +14,7 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(restricted, nonpayable)] RegisterMerkleRoot { /// MerkleRoot is hex-encoded merkle root. merkle_root: String, @@ -21,6 +22,7 @@ pub enum ExecuteMsg { total_amount: Option, }, /// Claim does not check if contract has enough funds, owner must ensure it. + #[attrs(nonpayable)] Claim { stage: u8, amount: Uint128, @@ -28,6 +30,7 @@ pub enum ExecuteMsg { proof: Vec, }, /// Burn the remaining tokens after expire time (only owner) + #[attrs(restricted)] Burn { stage: u8 }, } diff --git a/packages/andromeda-fungible-tokens/src/cw20_exchange.rs b/packages/andromeda-fungible-tokens/src/cw20_exchange.rs index a1ed81d17..c6c234160 100644 --- a/packages/andromeda-fungible-tokens/src/cw20_exchange.rs +++ b/packages/andromeda-fungible-tokens/src/cw20_exchange.rs @@ -20,10 +20,12 @@ pub struct InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { /// Cancels an ongoing sale + #[attrs(restricted)] CancelSale { asset: AssetInfo }, /// Purchases tokens with native funds Purchase { recipient: Option }, /// Receive for CW20 tokens, used for purchasing and starting sales + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), } diff --git a/packages/andromeda-fungible-tokens/src/cw20_staking.rs b/packages/andromeda-fungible-tokens/src/cw20_staking.rs index e9c6330a5..21bb8ebec 100644 --- a/packages/andromeda-fungible-tokens/src/cw20_staking.rs +++ b/packages/andromeda-fungible-tokens/src/cw20_staking.rs @@ -21,16 +21,16 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// Add `reward_token` as another reward token. Owner only. - AddRewardToken { - reward_token: RewardTokenUnchecked, - }, + #[attrs(restricted)] + AddRewardToken { reward_token: RewardTokenUnchecked }, /// Remove `reward_token`. Owner only. - RemoveRewardToken { - reward_token: String, - }, + #[attrs(restricted)] + RemoveRewardToken { reward_token: String }, /// Replace `reward_token` as another reward token. Owner only. + #[attrs(restricted)] ReplaceRewardToken { origin_reward_token: String, reward_token: RewardTokenUnchecked, @@ -38,9 +38,8 @@ pub enum ExecuteMsg { /// Unstakes the specified amount of assets, or all if not specified. The user's pending /// rewards and indexes are updated for each additional reward token. - UnstakeTokens { - amount: Option, - }, + #[attrs(nonpayable)] + UnstakeTokens { amount: Option }, /// Claims any outstanding rewards from the addtional reward tokens. ClaimRewards {}, /// Updates the global reward index for the specified reward tokens or all of the specified ones if diff --git a/packages/andromeda-fungible-tokens/src/lockdrop.rs b/packages/andromeda-fungible-tokens/src/lockdrop.rs index 490dd02d9..937eb22c3 100644 --- a/packages/andromeda-fungible-tokens/src/lockdrop.rs +++ b/packages/andromeda-fungible-tokens/src/lockdrop.rs @@ -26,17 +26,17 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// Function to deposit native fund in the contract in exchange for recieving a proportion of the /// TOKEN. DepositNative {}, /// Function to withdraw native fund from the lockup position. - WithdrawNative { - amount: Option, - }, + WithdrawNative { amount: Option }, /// Facilitates reward claim after claims are enabled. ClaimRewards {}, /// Called by the bootstrap contract when liquidity is added to the TOKEN-NATIVE Pool to enable TOKEN withdrawals by users. + #[attrs(nonpayable)] EnableClaims {}, // Called by the owner after the phase is over to withdraw all of the NATIVE token to the // given recipient, or themselves if not specified. diff --git a/packages/andromeda-math/src/counter.rs b/packages/andromeda-math/src/counter.rs index fbcb993a6..b769bbb7b 100644 --- a/packages/andromeda-math/src/counter.rs +++ b/packages/andromeda-math/src/counter.rs @@ -18,11 +18,17 @@ pub struct State { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable)] Increment {}, + #[attrs(nonpayable)] Decrement {}, + #[attrs(nonpayable)] Reset {}, + #[attrs(nonpayable, restricted)] UpdateRestriction { restriction: CounterRestriction }, + #[attrs(nonpayable, restricted)] SetIncreaseAmount { increase_amount: u64 }, + #[attrs(nonpayable, restricted)] SetDecreaseAmount { decrease_amount: u64 }, } diff --git a/packages/andromeda-math/src/curve.rs b/packages/andromeda-math/src/curve.rs index f1d44eb9f..21f01ffec 100644 --- a/packages/andromeda-math/src/curve.rs +++ b/packages/andromeda-math/src/curve.rs @@ -49,7 +49,9 @@ impl CurveConfig { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable)] UpdateCurveConfig { curve_config: CurveConfig }, + #[attrs(nonpayable)] Reset {}, } diff --git a/packages/andromeda-math/src/graph.rs b/packages/andromeda-math/src/graph.rs index 949e34a79..a17c21ac3 100644 --- a/packages/andromeda-math/src/graph.rs +++ b/packages/andromeda-math/src/graph.rs @@ -26,19 +26,17 @@ pub struct MapSize { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - UpdateMap { - map_info: MapInfo, - }, + #[attrs(restricted)] + UpdateMap { map_info: MapInfo }, + #[attrs(restricted)] StoreCoordinate { coordinate: Coordinate, is_timestamp_allowed: bool, }, - StoreUserCoordinate { - user_location_paths: Vec, - }, - DeleteUserCoordinate { - user: AndrAddr, - }, + #[attrs(restricted)] + StoreUserCoordinate { user_location_paths: Vec }, + #[attrs(restricted)] + DeleteUserCoordinate { user: AndrAddr }, } #[cw_serde] diff --git a/packages/andromeda-math/src/matrix.rs b/packages/andromeda-math/src/matrix.rs index 977a41569..4f98a6038 100644 --- a/packages/andromeda-math/src/matrix.rs +++ b/packages/andromeda-math/src/matrix.rs @@ -10,7 +10,9 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable)] StoreMatrix { key: Option, data: Matrix }, + #[attrs(nonpayable)] DeleteMatrix { key: Option }, } diff --git a/packages/andromeda-math/src/point.rs b/packages/andromeda-math/src/point.rs index ad8525d32..e74bc5a44 100644 --- a/packages/andromeda-math/src/point.rs +++ b/packages/andromeda-math/src/point.rs @@ -11,9 +11,15 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - SetPoint { point: PointCoordinate }, + SetPoint { + point: PointCoordinate, + }, + #[attrs(nonpayable)] DeletePoint {}, - UpdateRestriction { restriction: PointRestriction }, + #[attrs(restricted, nonpayable)] + UpdateRestriction { + restriction: PointRestriction, + }, } #[cw_serde] diff --git a/packages/andromeda-math/src/shunting.rs b/packages/andromeda-math/src/shunting.rs index 1040c4775..1a1b35ea3 100644 --- a/packages/andromeda-math/src/shunting.rs +++ b/packages/andromeda-math/src/shunting.rs @@ -11,6 +11,7 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(nonpayable, restricted)] UpdateExpressions { expressions: Vec }, } diff --git a/packages/andromeda-modules/src/address_list.rs b/packages/andromeda-modules/src/address_list.rs index 864d4d7fc..ff191e7ee 100644 --- a/packages/andromeda-modules/src/address_list.rs +++ b/packages/andromeda-modules/src/address_list.rs @@ -21,11 +21,13 @@ pub struct ActorPermission { #[cw_serde] pub enum ExecuteMsg { /// Adds an actor key and a permission value + #[attrs(restricted, nonpayable)] PermissionActors { actors: Vec, permission: LocalPermission, }, /// Removes actor alongisde his permission + #[attrs(restricted, nonpayable)] RemovePermissions { actors: Vec }, } diff --git a/packages/andromeda-modules/src/rates.rs b/packages/andromeda-modules/src/rates.rs index 2406d087e..40d90b4f6 100644 --- a/packages/andromeda-modules/src/rates.rs +++ b/packages/andromeda-modules/src/rates.rs @@ -11,7 +11,9 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(restricted, nonpayable)] SetRate { action: String, rate: LocalRate }, + #[attrs(restricted, nonpayable)] RemoveRate { action: String }, } diff --git a/packages/andromeda-modules/src/schema.rs b/packages/andromeda-modules/src/schema.rs index 8636a66ee..d869e8d3d 100644 --- a/packages/andromeda-modules/src/schema.rs +++ b/packages/andromeda-modules/src/schema.rs @@ -10,6 +10,7 @@ pub struct InstantiateMsg { #[andr_exec] #[cw_serde] pub enum ExecuteMsg { + #[attrs(restricted)] UpdateSchema { new_schema_json_string: String }, } diff --git a/packages/andromeda-non-fungible-tokens/src/auction.rs b/packages/andromeda-non-fungible-tokens/src/auction.rs index 40dcad458..bd2a5e1cc 100644 --- a/packages/andromeda-non-fungible-tokens/src/auction.rs +++ b/packages/andromeda-non-fungible-tokens/src/auction.rs @@ -22,6 +22,7 @@ pub struct InstantiateMsg { pub enum ExecuteMsg { ReceiveNft(Cw721ReceiveMsg), // for cw20 + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// Places a bid on the current auction for the given token_id. The previous largest bid gets /// automatically sent back to the bidder when they are outbid. @@ -38,6 +39,7 @@ pub enum ExecuteMsg { token_id: String, token_address: String, }, + #[attrs(nonpayable)] UpdateAuction { token_id: String, token_address: String, @@ -50,6 +52,7 @@ pub enum ExecuteMsg { buy_now_price: Option, recipient: Option, }, + #[attrs(nonpayable)] CancelAuction { token_id: String, token_address: String, diff --git a/packages/andromeda-non-fungible-tokens/src/crowdfund.rs b/packages/andromeda-non-fungible-tokens/src/crowdfund.rs index fda382d34..44aeb7115 100644 --- a/packages/andromeda-non-fungible-tokens/src/crowdfund.rs +++ b/packages/andromeda-non-fungible-tokens/src/crowdfund.rs @@ -25,12 +25,16 @@ pub struct InstantiateMsg { #[cfg_attr(not(target_arch = "wasm32"), derive(cw_orch::ExecuteFns))] pub enum ExecuteMsg { /// Add a tier + #[attrs(restricted, nonpayable)] AddTier { tier: Tier }, /// Update an existing tier + #[attrs(restricted, nonpayable)] UpdateTier { tier: Tier }, /// Remove a tier + #[attrs(restricted, nonpayable)] RemoveTier { level: Uint64 }, /// Start the campaign + #[attrs(restricted)] StartCampaign { start_time: Option, end_time: Expiry, @@ -40,12 +44,15 @@ pub enum ExecuteMsg { #[cfg_attr(not(target_arch = "wasm32"), cw_orch(payable))] PurchaseTiers { orders: Vec }, /// Purchase tiers with cw20 + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// End the campaign + #[attrs(restricted, nonpayable)] EndCampaign {}, /// Claim tiers or get refunded based on the campaign result Claim {}, /// Discard the campaign + #[attrs(restricted, nonpayable)] DiscardCampaign {}, } diff --git a/packages/andromeda-non-fungible-tokens/src/cw721.rs b/packages/andromeda-non-fungible-tokens/src/cw721.rs index 90d0f4d73..f3512807d 100644 --- a/packages/andromeda-non-fungible-tokens/src/cw721.rs +++ b/packages/andromeda-non-fungible-tokens/src/cw721.rs @@ -120,54 +120,56 @@ pub enum ExecuteMsg { BatchMint { tokens: Vec }, } -impl From for Cw721ExecuteMsg { - fn from(msg: ExecuteMsg) -> Self { +impl TryFrom for Cw721ExecuteMsg { + type Error = String; + + fn try_from(msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::TransferNft { recipient, token_id, - } => Cw721ExecuteMsg::TransferNft { + } => Ok(Cw721ExecuteMsg::TransferNft { recipient: recipient.to_string(), token_id, - }, + }), ExecuteMsg::SendNft { contract, token_id, msg, - } => Cw721ExecuteMsg::SendNft { + } => Ok(Cw721ExecuteMsg::SendNft { contract: contract.to_string(), token_id, msg, - }, + }), ExecuteMsg::Approve { spender, token_id, expires, - } => Cw721ExecuteMsg::Approve { + } => Ok(Cw721ExecuteMsg::Approve { spender, token_id, expires, - }, + }), ExecuteMsg::Revoke { spender, token_id } => { - Cw721ExecuteMsg::Revoke { spender, token_id } + Ok(Cw721ExecuteMsg::Revoke { spender, token_id }) } ExecuteMsg::ApproveAll { operator, expires } => { - Cw721ExecuteMsg::ApproveAll { operator, expires } + Ok(Cw721ExecuteMsg::ApproveAll { operator, expires }) } - ExecuteMsg::RevokeAll { operator } => Cw721ExecuteMsg::RevokeAll { operator }, + ExecuteMsg::RevokeAll { operator } => Ok(Cw721ExecuteMsg::RevokeAll { operator }), ExecuteMsg::Mint { extension, token_id, token_uri, owner, - } => Cw721ExecuteMsg::Mint { + } => Ok(Cw721ExecuteMsg::Mint { extension, token_id, token_uri, owner, - }, - ExecuteMsg::Burn { token_id } => Cw721ExecuteMsg::Burn { token_id }, - _ => panic!("Unsupported message"), + }), + ExecuteMsg::Burn { token_id } => Ok(Cw721ExecuteMsg::Burn { token_id }), + _ => Err("Unsupported message".to_string()), } } } diff --git a/packages/andromeda-non-fungible-tokens/src/marketplace.rs b/packages/andromeda-non-fungible-tokens/src/marketplace.rs index e188e0791..324c4ce33 100644 --- a/packages/andromeda-non-fungible-tokens/src/marketplace.rs +++ b/packages/andromeda-non-fungible-tokens/src/marketplace.rs @@ -25,6 +25,7 @@ pub struct InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { ReceiveNft(Cw721ReceiveMsg), + #[attrs(nonpayable)] Receive(Cw20ReceiveMsg), /// Transfers NFT to buyer and sends funds to seller Buy { @@ -32,6 +33,7 @@ pub enum ExecuteMsg { token_address: String, }, /// Updates the sale's price, demomination, and whitelist + #[attrs(nonpayable)] UpdateSale { token_id: String, token_address: String, @@ -39,6 +41,7 @@ pub enum ExecuteMsg { coin_denom: Asset, recipient: Option, }, + #[attrs(nonpayable)] CancelSale { token_id: String, token_address: String, diff --git a/packages/deploy/src/adodb.rs b/packages/deploy/src/adodb.rs index 0e1eea5c1..89f2b7450 100644 --- a/packages/deploy/src/adodb.rs +++ b/packages/deploy/src/adodb.rs @@ -75,6 +75,11 @@ pub fn deploy( continue; } + if version.contains("-a.") { + log::info!("Skipping {} {} - alpha version", name, version); + continue; + } + log::info!("Deploying {} {}", name, version); let code_id = upload(&daemon)?; let res = adodb.publish(name.clone(), code_id, version.clone(), None, None); diff --git a/packages/std/Cargo.toml b/packages/std/Cargo.toml index 154d0912a..3be6e0e64 100644 --- a/packages/std/Cargo.toml +++ b/packages/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-std" -version = "1.5.0" +version = "1.5.1-b.1" edition = "2021" rust-version = "1.75.0" description = "The standard library for creating an Andromeda Digital Object" @@ -44,9 +44,8 @@ prost = { version = "0.11.2", default-features = false, features = [ "prost-derive", ], optional = true } -[dev-dependencies] -cw-multi-test = { workspace = true } -rstest = "0.24.0" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true } +rstest = "0.24.0" cw-orch = { workspace = true } diff --git a/packages/std/macros/Cargo.toml b/packages/std/macros/Cargo.toml index 78b431d07..ba528d56d 100644 --- a/packages/std/macros/Cargo.toml +++ b/packages/std/macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-macros" -version = "1.0.0" +version = "1.1.0-b.1" edition = "2021" rust-version = "1.75.0" description = "Macros for Andromeda Digital Objects" @@ -14,6 +14,6 @@ withdraw = [] rates = [] [dependencies] -syn = { version = "1.0.0", features = ["derive"] } +syn = { version = "2.0.91", features = ["derive", "full"] } proc-macro2 = "1.0" quote = "1.0" diff --git a/packages/std/macros/src/attrs/direct.rs b/packages/std/macros/src/attrs/direct.rs new file mode 100644 index 000000000..b0b966a1d --- /dev/null +++ b/packages/std/macros/src/attrs/direct.rs @@ -0,0 +1,60 @@ +use super::{handler::AttributeHandler, utils::generate_match_pattern}; +use quote::quote; + +const ATTR_KEY: &str = "direct"; +/** + * DirectAttribute is used to indicate that a message cannot be received via an AMP packet. + * + * Example usage: + * ```rust + * #[andr_exec] + * enum ExecuteMsg { + * #[attrs(direct)] + * MyMessage{..}, + * } + * ``` + */ +pub struct DirectAttribute; + +impl AttributeHandler for DirectAttribute { + fn check_attribute(&self, attr: &syn::Attribute) -> bool { + if attr.path().is_ident("attrs") { + let mut is_direct = false; + attr.parse_args_with(|input: syn::parse::ParseStream| { + while !input.is_empty() { + let ident: syn::Ident = input.parse()?; + if ident == ATTR_KEY { + is_direct = true; + } + if !input.is_empty() { + input.parse::()?; + } + } + Ok(()) + }) + .unwrap_or(()); + return is_direct; + } + false + } + + fn generate_impl( + &self, + data_enum: &syn::DataEnum, + variants: &[(syn::Ident, bool)], + ) -> proc_macro2::TokenStream { + let match_arms = variants.iter().map(|(variant_name, is_direct)| { + let pattern = generate_match_pattern(data_enum, variant_name); + quote! { #pattern => #is_direct } + }); + + quote! { + #[inline] + pub fn must_be_direct(&self) -> bool { + match self { + #(#match_arms,)* + } + } + } + } +} diff --git a/packages/std/macros/src/attrs/handler.rs b/packages/std/macros/src/attrs/handler.rs new file mode 100644 index 000000000..96b2ca7c5 --- /dev/null +++ b/packages/std/macros/src/attrs/handler.rs @@ -0,0 +1,12 @@ +// Trait for attribute handlers +pub trait AttributeHandler { + /// Checks if the attribute is present + fn check_attribute(&self, attr: &syn::Attribute) -> bool; + + /// Generates the implementation for the attribute + fn generate_impl( + &self, + data_enum: &syn::DataEnum, + variants: &[(syn::Ident, bool)], + ) -> proc_macro2::TokenStream; +} diff --git a/packages/std/macros/src/attrs/mod.rs b/packages/std/macros/src/attrs/mod.rs new file mode 100644 index 000000000..bd5673ef1 --- /dev/null +++ b/packages/std/macros/src/attrs/mod.rs @@ -0,0 +1,49 @@ +mod direct; +mod handler; +mod payable; +mod restricted; +mod utils; + +use direct::DirectAttribute; +use handler::AttributeHandler; +use payable::NonPayableAttribute; +use proc_macro::TokenStream; +use quote::quote; +use restricted::RestrictedAttribute; +use syn::{parse_macro_input, DeriveInput}; +use utils::process_variants_dynamic; + +pub fn derive_execute_attrs(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + match &input.data { + syn::Data::Enum(data_enum) => { + let name = &input.ident; + + // Define handlers + let handlers: Vec> = vec![ + Box::new(NonPayableAttribute), + Box::new(RestrictedAttribute), + Box::new(DirectAttribute), + ]; + + // Process variants and generate implementations for each handler + let implementations = handlers + .iter() + .map(|handler| { + let variants = process_variants_dynamic(data_enum, handler.as_ref()); + handler.generate_impl(data_enum, &variants) + }) + .collect::>(); + + let expanded = quote! { + impl #name { + #(#implementations)* + } + }; + + TokenStream::from(expanded) + } + _ => panic!("Attrs can only be derived for enums"), + } +} diff --git a/packages/std/macros/src/attrs/payable.rs b/packages/std/macros/src/attrs/payable.rs new file mode 100644 index 000000000..4ced79b9d --- /dev/null +++ b/packages/std/macros/src/attrs/payable.rs @@ -0,0 +1,60 @@ +use super::{handler::AttributeHandler, utils::generate_match_pattern}; +use quote::quote; + +const ATTR_KEY: &str = "nonpayable"; +/** + * NonPayableAttribute is used to indicate that a message can receive funds. + * + * Example usage: + * ```rust + * #[andr_exec] + * enum ExecuteMsg { + * #[attrs(nonpayable)] + * MyMessage{..}, + * } + * ``` + */ +pub struct NonPayableAttribute; + +impl AttributeHandler for NonPayableAttribute { + fn check_attribute(&self, attr: &syn::Attribute) -> bool { + if attr.path().is_ident("attrs") { + let mut is_nonpayable = false; + attr.parse_args_with(|input: syn::parse::ParseStream| { + while !input.is_empty() { + let ident: syn::Ident = input.parse()?; + if ident == ATTR_KEY { + is_nonpayable = true; + } + if !input.is_empty() { + input.parse::()?; + } + } + Ok(()) + }) + .unwrap_or(()); + return is_nonpayable; + } + false + } + + fn generate_impl( + &self, + data_enum: &syn::DataEnum, + variants: &[(syn::Ident, bool)], + ) -> proc_macro2::TokenStream { + let match_arms = variants.iter().map(|(variant_name, is_nonpayable)| { + let pattern = generate_match_pattern(data_enum, variant_name); + quote! { #pattern => !#is_nonpayable } + }); + + quote! { + #[inline] + pub fn is_payable(&self) -> bool { + match self { + #(#match_arms,)* + } + } + } + } +} diff --git a/packages/std/macros/src/attrs/restricted.rs b/packages/std/macros/src/attrs/restricted.rs new file mode 100644 index 000000000..aa858d2aa --- /dev/null +++ b/packages/std/macros/src/attrs/restricted.rs @@ -0,0 +1,61 @@ +use super::{handler::AttributeHandler, utils::generate_match_pattern}; +use quote::quote; + +const ATTR_KEY: &str = "restricted"; + +/** + * RestrictedAttribute is used to indicate that a message can only be executed by the owner **unless the message is permissioned**. + * + * Example usage: + * ```rust + * #[andr_exec] + * enum ExecuteMsg { + * #[attrs(restricted)] + * MyMessage{..}, + * } + * ``` + */ +pub struct RestrictedAttribute; + +impl AttributeHandler for RestrictedAttribute { + fn check_attribute(&self, attr: &syn::Attribute) -> bool { + if attr.path().is_ident("attrs") { + let mut is_restricted = false; + attr.parse_args_with(|input: syn::parse::ParseStream| { + while !input.is_empty() { + let ident: syn::Ident = input.parse()?; + if ident == ATTR_KEY { + is_restricted = true; + } + if !input.is_empty() { + input.parse::()?; + } + } + Ok(()) + }) + .unwrap_or(()); + return is_restricted; + } + false + } + + fn generate_impl( + &self, + data_enum: &syn::DataEnum, + variants: &[(syn::Ident, bool)], + ) -> proc_macro2::TokenStream { + let match_arms = variants.iter().map(|(variant_name, is_restricted)| { + let pattern = generate_match_pattern(data_enum, variant_name); + quote! { #pattern => #is_restricted } + }); + + quote! { + #[inline] + pub fn is_restricted(&self) -> bool { + match self { + #(#match_arms,)* + } + } + } + } +} diff --git a/packages/std/macros/src/attrs/utils.rs b/packages/std/macros/src/attrs/utils.rs new file mode 100644 index 000000000..caf41ffc0 --- /dev/null +++ b/packages/std/macros/src/attrs/utils.rs @@ -0,0 +1,37 @@ +use quote::quote; + +use super::handler::AttributeHandler; + +pub(crate) fn generate_match_pattern( + data_enum: &syn::DataEnum, + variant_name: &syn::Ident, +) -> proc_macro2::TokenStream { + let variant = data_enum + .variants + .iter() + .find(|v| v.ident == *variant_name) + .expect("Variant not found. Make sure the variant name matches the enum definition."); + + match &variant.fields { + syn::Fields::Named(_) => quote! { Self::#variant_name { .. } }, + syn::Fields::Unnamed(_) => quote! { Self::#variant_name(..) }, + syn::Fields::Unit => quote! { Self::#variant_name }, + } +} + +pub(crate) fn process_variants_dynamic( + data_enum: &syn::DataEnum, + handler: &dyn AttributeHandler, +) -> Vec<(syn::Ident, bool)> { + data_enum + .variants + .iter() + .map(|variant| { + let has_attr = variant + .attrs + .iter() + .any(|attr| handler.check_attribute(attr)); + (variant.ident.clone(), has_attr) + }) + .collect() +} diff --git a/packages/std/macros/src/execute.rs b/packages/std/macros/src/execute.rs new file mode 100644 index 000000000..c86545996 --- /dev/null +++ b/packages/std/macros/src/execute.rs @@ -0,0 +1,106 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, parse_quote, DeriveInput, ItemFn}; + +use crate::utils::merge_variants; + +pub fn enum_implementation(_args: TokenStream, input: TokenStream) -> TokenStream { + #[allow(unused_mut)] + let mut merged = merge_variants( + input, + quote! { + enum Right { + #[serde(rename="amp_receive")] + AMPReceive(::andromeda_std::amp::messages::AMPPkt), + Ownership(::andromeda_std::ado_base::ownership::OwnershipMessage), + UpdateKernelAddress { + address: ::cosmwasm_std::Addr, + }, + UpdateAppContract { + address: String, + }, + Permissioning(::andromeda_std::ado_base::permissioning::PermissioningMessage), + } + } + .into(), + ); + + #[cfg(feature = "rates")] + { + merged = merge_variants( + merged, + quote! { + enum Right { + Rates(::andromeda_std::ado_base::rates::RatesMessage) + } + } + .into(), + ) + } + + let input = parse_macro_input!(merged as DeriveInput); + let output = andr_exec_derive(input); + + quote! { + #output + } + .into() +} + +fn andr_exec_derive(input: DeriveInput) -> proc_macro2::TokenStream { + match &input.data { + syn::Data::Enum(_) => { + parse_quote! { + #[derive(::andromeda_std::AsRefStr, ::andromeda_std::ExecuteAttrs)] + #input + } + } + _ => panic!("unions are not supported"), + } +} + +pub(crate) fn fn_implementation(_attr: TokenStream, item: TokenStream) -> TokenStream { + let input = parse_macro_input!(item as ItemFn); + let vis = &input.vis; + let body = &input.block; + + let expanded = quote! { + #[cfg_attr(not(feature = "library"), ::cosmwasm_std::entry_point)] + pub fn execute( + deps: ::cosmwasm_std::DepsMut, + env: ::cosmwasm_std::Env, + info: ::cosmwasm_std::MessageInfo, + msg: ExecuteMsg, + ) -> Result<::cosmwasm_std::Response, ContractError> { + let (ctx, msg, resp) = ::andromeda_std::unwrap_amp_msg!(deps, info.clone(), env, msg); + + // Check if the message is restricted to the owner + if msg.is_restricted() { + let is_owner = ctx.contract.is_contract_owner(ctx.deps.storage, info.sender.as_str())?; + ::cosmwasm_std::ensure!( + is_owner, + ContractError::Unauthorized {} + ); + } + + // Check if the message is payable + if !msg.is_payable() { + ::cosmwasm_std::ensure!(info.funds.is_empty(), ContractError::Payment(andromeda_std::error::PaymentError::NonPayable {})); + } + + + let res = execute_inner(ctx, msg)?; + + Ok(res + .add_submessages(resp.messages) + .add_attributes(resp.attributes) + .add_events(resp.events)) + } + + #vis fn execute_inner(ctx: ::andromeda_std::common::context::ExecuteContext, msg: ExecuteMsg) -> Result<::cosmwasm_std::Response, ContractError> { + #body + } + }; + + TokenStream::from(expanded) +} diff --git a/packages/std/macros/src/instantiate.rs b/packages/std/macros/src/instantiate.rs new file mode 100644 index 000000000..f3c15ab93 --- /dev/null +++ b/packages/std/macros/src/instantiate.rs @@ -0,0 +1,29 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse::Parser, parse_macro_input, DeriveInput}; + +pub(crate) fn enum_implementation(_args: TokenStream, input: TokenStream) -> TokenStream { + let mut ast = parse_macro_input!(input as DeriveInput); + match &mut ast.data { + syn::Data::Struct(ref mut struct_data) => { + if let syn::Fields::Named(fields) = &mut struct_data.fields { + fields.named.push( + syn::Field::parse_named + .parse2(quote! { pub kernel_address: String }) + .unwrap(), + ); + fields.named.push( + syn::Field::parse_named + .parse2(quote! { pub owner: Option }) + .unwrap(), + ); + } + + quote! { + #ast + } + .into() + } + _ => panic!("Macro only works with structs"), + } +} diff --git a/packages/std/macros/src/lib.rs b/packages/std/macros/src/lib.rs index 72a0374cd..32a6ef92a 100644 --- a/packages/std/macros/src/lib.rs +++ b/packages/std/macros/src/lib.rs @@ -1,32 +1,10 @@ -use proc_macro::TokenStream; -use quote::{quote, ToTokens}; -use syn::{parse::Parser, parse_macro_input, DeriveInput}; - -/// Taken from: https://github.com/DA0-DA0/dao-contracts/blob/74bd3881fdd86829e5e8b132b9952dd64f2d0737/packages/dao-macros/src/lib.rs#L9 -/// Used to merge two enums together. -fn merge_variants(left: TokenStream, right: TokenStream) -> TokenStream { - use syn::Data::Enum; - use syn::DataEnum; - - let mut left: DeriveInput = parse_macro_input!(left); - let right: DeriveInput = parse_macro_input!(right); - - if let ( - Enum(DataEnum { variants, .. }), - Enum(DataEnum { - variants: to_add, .. - }), - ) = (&mut left.data, right.data) - { - variants.extend(to_add); +mod attrs; +mod execute; +mod instantiate; +mod query; +mod utils; - quote! { #left }.into() - } else { - syn::Error::new(left.ident.span(), "variants may only be added for enums") - .to_compile_error() - .into() - } -} +use proc_macro::TokenStream; #[proc_macro_attribute] /// Attaches all relevant ADO messages to a set of Execute messages for a given contract. @@ -36,54 +14,27 @@ fn merge_variants(left: TokenStream, right: TokenStream) -> TokenStream { /// e.g. `ExecuteMsg::MyMessage{..}.as_ref_str()` will return `"MyMessage"` /// /// **Must be placed before `#[cw_serde]`** -pub fn andr_exec(_args: TokenStream, input: TokenStream) -> TokenStream { - #[allow(unused_mut)] - let mut merged = merge_variants( - input, - quote! { - enum Right { - #[serde(rename="amp_receive")] - AMPReceive(::andromeda_std::amp::messages::AMPPkt), - Ownership(::andromeda_std::ado_base::ownership::OwnershipMessage), - UpdateKernelAddress { - address: ::cosmwasm_std::Addr, - }, - UpdateAppContract { - address: String, - }, - Permissioning(::andromeda_std::ado_base::permissioning::PermissioningMessage), - } - } - .into(), - ); - - #[cfg(feature = "rates")] - { - merged = merge_variants( - merged, - quote! { - enum Right { - Rates(::andromeda_std::ado_base::rates::RatesMessage) - } - } - .into(), - ) - } - let input = parse_macro_input!(merged); - TokenStream::from(andr_exec_derive(input).into_token_stream()) +pub fn andr_exec(args: TokenStream, input: TokenStream) -> TokenStream { + execute::enum_implementation(args, input) } -/// Derives the `AsRefStr` trait for a given enum allowing the use of `as_ref_str` to get the string representation of the enum. -fn andr_exec_derive(input: DeriveInput) -> DeriveInput { - use syn::parse_quote; - - match input.data { - syn::Data::Enum(_) => parse_quote! { - #[derive(::andromeda_std::AsRefStr)] - #input - }, - _ => panic!("unions are not supported"), - } +/// Modifies the execute entrypoint to unwrap AMP messages if they are received. +/// +/// It also constructs the `ExecuteCtx` and passes it to the function. +/// +/// **Please note that this will replace `ctx.info.sender` with the `origin` of an AMP packet if it is received. If you wish to use +/// the original `info.sender` use `ctx.raw_info.sender`.** +/// +/// Example usage: +/// ```rust +/// #[andr_execute_fn] +/// pub fn execute(ctx: ExecuteCtx, msg: ExecuteMsg) -> Result { +/// // ... +/// } +/// ``` +#[proc_macro_attribute] +pub fn andr_execute_fn(_attr: TokenStream, item: TokenStream) -> TokenStream { + execute::fn_implementation(_attr, item) } /// Adjusted from https://users.rust-lang.org/t/solved-derive-and-proc-macro-add-field-to-an-existing-struct/52307/3 @@ -93,30 +44,8 @@ fn andr_exec_derive(input: DeriveInput) -> DeriveInput { /// 1. Kernel Address for interacting with aOS /// 2. Owner of the ADO (optional, assumed to be sender otherwise) #[proc_macro_attribute] -pub fn andr_instantiate(_args: TokenStream, input: TokenStream) -> TokenStream { - let mut ast = parse_macro_input!(input as DeriveInput); - match &mut ast.data { - syn::Data::Struct(ref mut struct_data) => { - if let syn::Fields::Named(fields) = &mut struct_data.fields { - fields.named.push( - syn::Field::parse_named - .parse2(quote! { pub kernel_address: String }) - .unwrap(), - ); - fields.named.push( - syn::Field::parse_named - .parse2(quote! { pub owner: Option }) - .unwrap(), - ); - } - - quote! { - #ast - } - .into() - } - _ => panic!("Macro only works with structs"), - } +pub fn andr_instantiate(args: TokenStream, input: TokenStream) -> TokenStream { + instantiate::enum_implementation(args, input) } #[proc_macro_attribute] @@ -124,52 +53,28 @@ pub fn andr_instantiate(_args: TokenStream, input: TokenStream) -> TokenStream { /// /// **Must be placed before `#[cw_serde]`** pub fn andr_query(_metadata: TokenStream, input: TokenStream) -> TokenStream { - #[allow(unused_mut)] - let mut merged = merge_variants( - input, - quote! { - enum Right { - #[returns(andromeda_std::ado_base::ownership::ContractOwnerResponse)] - Owner {}, - #[returns(andromeda_std::ado_base::ownership::ContractPotentialOwnerResponse)] - OwnershipRequest {}, - #[returns(andromeda_std::ado_base::ado_type::TypeResponse)] - Type {}, - #[returns(andromeda_std::ado_base::kernel_address::KernelAddressResponse)] - KernelAddress {}, - #[returns(andromeda_std::ado_base::app_contract::AppContractResponse)] - AppContract {}, - #[returns(andromeda_std::ado_base::ownership::PublisherResponse)] - OriginalPublisher {}, - #[returns(andromeda_std::ado_base::block_height::BlockHeightResponse)] - BlockHeightUponCreation {}, - #[returns(andromeda_std::ado_base::version::VersionResponse)] - Version {}, - #[returns(andromeda_std::ado_base::version::ADOBaseVersionResponse)] - #[schemars(example = "andromeda_std::ado_base::version::base_crate_version")] - ADOBaseVersion {}, - #[returns(Vec<::andromeda_std::ado_base::permissioning::PermissionInfo>)] - Permissions { actor: String, limit: Option, start_after: Option }, - #[returns(Vec)] - PermissionedActions { }, - } - } - .into(), - ); - #[cfg(feature = "rates")] - { - merged = merge_variants( - merged, - quote! { - enum Right { - #[returns(Option<::andromeda_std::ado_base::rates::Rate>)] - Rates {action: String}, - #[returns(::andromeda_std::ado_base::rates::AllRatesResponse)] - AllRates {} - } - } - .into(), - ) - } - merged + query::enum_implementation(_metadata, input) +} + +/** + * Derives the `ExecuteAttrs` trait for a given enum. + * + * This trait is used to allow attributes to be attached to the enum variants. + * The following variants are supported: + * - `nonpayable` - The message cannot receive funds + * - `restricted` - The message can only be executed by the owner **unless the message is permissioned** + * - `direct` - The message cannot be received via an AMP packet + * + * Example usage: + * ```rust + * #[andr_exec] + * enum ExecuteMsg { + * #[attrs(nonpayable, restricted)] + * MyMessage{..}, + * } + * ``` + */ +#[proc_macro_derive(ExecuteAttrs, attributes(attrs))] +pub fn derive_execute_attrs(input: TokenStream) -> TokenStream { + attrs::derive_execute_attrs(input) } diff --git a/packages/std/macros/src/query.rs b/packages/std/macros/src/query.rs new file mode 100644 index 000000000..593133f01 --- /dev/null +++ b/packages/std/macros/src/query.rs @@ -0,0 +1,54 @@ +use crate::utils::merge_variants; +use proc_macro::TokenStream; +use quote::quote; + +pub fn enum_implementation(_metadata: TokenStream, input: TokenStream) -> TokenStream { + #[allow(unused_mut)] + let mut merged = merge_variants( + input, + quote! { + enum Right { + #[returns(andromeda_std::ado_base::ownership::ContractOwnerResponse)] + Owner {}, + #[returns(andromeda_std::ado_base::ownership::ContractPotentialOwnerResponse)] + OwnershipRequest {}, + #[returns(andromeda_std::ado_base::ado_type::TypeResponse)] + Type {}, + #[returns(andromeda_std::ado_base::kernel_address::KernelAddressResponse)] + KernelAddress {}, + #[returns(andromeda_std::ado_base::app_contract::AppContractResponse)] + AppContract {}, + #[returns(andromeda_std::ado_base::ownership::PublisherResponse)] + OriginalPublisher {}, + #[returns(andromeda_std::ado_base::block_height::BlockHeightResponse)] + BlockHeightUponCreation {}, + #[returns(andromeda_std::ado_base::version::VersionResponse)] + Version {}, + #[returns(andromeda_std::ado_base::version::ADOBaseVersionResponse)] + #[schemars(example = "andromeda_std::ado_base::version::base_crate_version")] + ADOBaseVersion {}, + #[returns(Vec<::andromeda_std::ado_base::permissioning::PermissionInfo>)] + Permissions { actor: String, limit: Option, start_after: Option }, + #[returns(Vec)] + PermissionedActions { }, + } + } + .into(), + ); + #[cfg(feature = "rates")] + { + merged = merge_variants( + merged, + quote! { + enum Right { + #[returns(Option<::andromeda_std::ado_base::rates::Rate>)] + Rates {action: String}, + #[returns(::andromeda_std::ado_base::rates::AllRatesResponse)] + AllRates {} + } + } + .into(), + ) + } + merged +} diff --git a/packages/std/macros/src/utils.rs b/packages/std/macros/src/utils.rs new file mode 100644 index 000000000..600efb75e --- /dev/null +++ b/packages/std/macros/src/utils.rs @@ -0,0 +1,29 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +/// Taken from: https://github.com/DA0-DA0/dao-contracts/blob/74bd3881fdd86829e5e8b132b9952dd64f2d0737/packages/dao-macros/src/lib.rs#L9 +/// Used to merge two enums together. +pub(crate) fn merge_variants(left: TokenStream, right: TokenStream) -> TokenStream { + use syn::Data::Enum; + use syn::DataEnum; + + let mut left: DeriveInput = parse_macro_input!(left); + let right: DeriveInput = parse_macro_input!(right); + + if let ( + Enum(DataEnum { variants, .. }), + Enum(DataEnum { + variants: to_add, .. + }), + ) = (&mut left.data, right.data) + { + variants.extend(to_add); + + quote! { #left }.into() + } else { + syn::Error::new(left.ident.span(), "variants may only be added for enums") + .to_compile_error() + .into() + } +} diff --git a/packages/std/src/ado_contract/execute.rs b/packages/std/src/ado_contract/execute.rs index 8ab5da096..93d4b7d02 100644 --- a/packages/std/src/ado_contract/execute.rs +++ b/packages/std/src/ado_contract/execute.rs @@ -425,6 +425,63 @@ impl ADOContract<'_> { } } +#[macro_export] +macro_rules! unwrap_amp_msg { + ($deps:expr, $info:expr, $env:expr, $msg:expr) => {{ + let mut ctx = ::andromeda_std::common::context::ExecuteContext::new($deps, $info, $env); + let mut msg = $msg; + + if let ExecuteMsg::AMPReceive(mut pkt) = msg { + ctx.deps.api.debug("Unwrapping AMP Packet"); + ctx.info = MessageInfo { + sender: ctx.deps.api.addr_validate( + pkt.get_verified_origin(&ctx.info.clone(), &ctx.deps.as_ref()) + .unwrap() + .as_str(), + )?, + funds: ctx.info.funds, + }; + + ctx.deps + .api + .debug(&format!("Set new sender: {}", ctx.info.sender)); + let maybe_amp_msg = pkt.messages.pop(); + + ::cosmwasm_std::ensure!( + maybe_amp_msg.is_some(), + ContractError::InvalidPacket { + error: Some("AMP Packet received with no messages".to_string()), + } + ); + let amp_msg = maybe_amp_msg.unwrap(); + msg = ::cosmwasm_std::from_json(&_msg.message)?; + ::cosmwasm_std::ensure!( + !msg.must_be_direct(), + ContractError::InvalidPacket { + error: Some(format!( + "{} cannot be received via AMP packet", + msg.as_ref() + )), + } + ); + ctx.deps + .api + .debug(&format!("Unwrapped msg: {:?}", msg.as_ref())); + ctx.amp_ctx = Some(pkt); + } + + let action_response = andromeda_std::common::actions::call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + (ctx, msg, action_response) + }}; +} + #[cfg(test)] mod tests { use super::*; diff --git a/packages/std/src/ado_contract/permissioning.rs b/packages/std/src/ado_contract/permissioning.rs index 9978bb87e..1b68e3dcf 100644 --- a/packages/std/src/ado_contract/permissioning.rs +++ b/packages/std/src/ado_contract/permissioning.rs @@ -361,8 +361,8 @@ impl ADOContract<'_> { /// Enables permissioning for a given action pub fn permission_action( &self, - action: impl Into, store: &mut dyn Storage, + action: impl Into, ) -> Result<(), ContractError> { self.permissioned_actions .save(store, action.into(), &true)?; @@ -384,7 +384,7 @@ impl ADOContract<'_> { Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, ContractError::Unauthorized {} ); - self.permission_action(action_string.clone(), ctx.deps.storage)?; + self.permission_action(ctx.deps.storage, action_string.clone())?; Ok(Response::default().add_attributes(vec![ ("action", "permission_action"), ("action", action_string.as_str()), @@ -585,7 +585,7 @@ mod tests { .unwrap(); ADOContract::default() - .permission_action(action, deps.as_mut().storage) + .permission_action(deps.as_mut().storage, action) .unwrap(); // Test Whitelisting @@ -632,7 +632,7 @@ mod tests { ADOContract::remove_permission(deps.as_mut().storage, action, actor).unwrap(); ADOContract::default() - .permission_action(action, deps.as_mut().storage) + .permission_action(deps.as_mut().storage, action) .unwrap(); // Test Blacklisted let permission = Permission::Local(LocalPermission::Blacklisted { @@ -659,7 +659,7 @@ mod tests { .unwrap(); ADOContract::default() - .permission_action(action, deps.as_mut().storage) + .permission_action(deps.as_mut().storage, action) .unwrap(); // Test Blacklisted @@ -818,7 +818,7 @@ mod tests { .unwrap(); ADOContract::default() - .permission_action(action, deps.as_mut().storage) + .permission_action(deps.as_mut().storage, action) .unwrap(); let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); @@ -903,7 +903,7 @@ mod tests { .unwrap(); ADOContract::default() - .permission_action(action, deps.as_mut().storage) + .permission_action(deps.as_mut().storage, action) .unwrap(); let permission = if is_whitelisted { @@ -972,7 +972,7 @@ mod tests { let mut context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()); ADOContract::default() - .permission_action(action, context.deps.storage) + .permission_action(context.deps.storage, action) .unwrap(); assert!(!is_context_permissioned( @@ -1264,12 +1264,7 @@ mod tests { let mut deps = mock_dependencies(); let env = mock_env(); let info = mock_info("owner", &[]); - let ctx = ExecuteContext { - deps: deps.as_mut(), - env, - info: info.clone(), - amp_ctx: None, - }; + let ctx = ExecuteContext::new(deps.as_mut(), info.clone(), env); let contract = ADOContract::default(); @@ -1298,12 +1293,7 @@ mod tests { let mut deps = mock_dependencies(); let env = mock_env(); let info = mock_info("owner", &[]); - let ctx = ExecuteContext { - deps: deps.as_mut(), - env, - info: info.clone(), - amp_ctx: None, - }; + let ctx = ExecuteContext::new(deps.as_mut(), info.clone(), env); let contract = ADOContract::default(); diff --git a/packages/std/src/amp/messages.rs b/packages/std/src/amp/messages.rs index 16f54dcf8..d5bc29dba 100644 --- a/packages/std/src/amp/messages.rs +++ b/packages/std/src/amp/messages.rs @@ -264,6 +264,12 @@ impl AMPPkt { } } + pub fn with_origin(&self, origin: impl Into) -> AMPPkt { + let mut pkt = self.clone(); + pkt.ctx.origin = origin.into(); + pkt + } + /// Adds a message to the current AMP Packet pub fn add_message(mut self, message: AMPMsg) -> Self { self.messages.push(message); diff --git a/packages/std/src/common/actions.rs b/packages/std/src/common/actions.rs index 04f4284b1..74814532e 100644 --- a/packages/std/src/common/actions.rs +++ b/packages/std/src/common/actions.rs @@ -2,6 +2,7 @@ use crate::{ ado_contract::{permissioning::is_context_permissioned, ADOContract}, amp::messages::AMPPkt, error::ContractError, + os::aos_querier::AOSQuerier, }; use cosmwasm_std::{ensure, DepsMut, Env, MessageInfo, Response}; @@ -23,8 +24,21 @@ pub fn call_action( info.sender.clone() }; - let fee_msg = - ADOContract::default().pay_fee(deps.storage, &deps.querier, action.to_owned(), payee)?; + let adodb_addr = ADOContract::default().get_adodb_address(deps.storage, &deps.querier)?; + let code_id = deps + .querier + .query_wasm_contract_info(env.contract.address.clone())? + .code_id; - Ok(Response::default().add_submessage(fee_msg)) + // Check ADO type and fees in one chain + match AOSQuerier::ado_type_getter(&deps.querier, &adodb_addr, code_id)? + .and_then(|ado_type| { + AOSQuerier::action_fee_getter(&deps.querier, &adodb_addr, &ado_type, action).ok() + }) + .map(|_| { + ADOContract::default().pay_fee(deps.storage, &deps.querier, action.to_owned(), payee) + }) { + Some(fee_msg) => Ok(Response::default().add_submessage(fee_msg?)), + None => Ok(Response::default()), + } } diff --git a/packages/std/src/common/context.rs b/packages/std/src/common/context.rs index 7fab8aaca..cd0f26d88 100644 --- a/packages/std/src/common/context.rs +++ b/packages/std/src/common/context.rs @@ -1,4 +1,4 @@ -use crate::amp::messages::AMPPkt; +use crate::{ado_contract::ADOContract, amp::messages::AMPPkt}; use cosmwasm_std::{DepsMut, Env, MessageInfo}; pub struct ExecuteContext<'a> { @@ -6,6 +6,8 @@ pub struct ExecuteContext<'a> { pub info: MessageInfo, pub env: Env, pub amp_ctx: Option, + pub contract: ADOContract<'a>, + pub raw_info: MessageInfo, } impl ExecuteContext<'_> { @@ -13,9 +15,11 @@ impl ExecuteContext<'_> { pub fn new(deps: DepsMut, info: MessageInfo, env: Env) -> ExecuteContext { ExecuteContext { deps, - info, + info: info.clone(), env, amp_ctx: None, + contract: ADOContract::default(), + raw_info: info, } } diff --git a/packages/std/src/common/denom.rs b/packages/std/src/common/denom.rs index cd8b89536..8f370018e 100644 --- a/packages/std/src/common/denom.rs +++ b/packages/std/src/common/denom.rs @@ -130,7 +130,7 @@ pub fn authorize_addresses( addresses: Vec, ) -> Result<(), ContractError> { if !addresses.is_empty() { - ADOContract::default().permission_action(action, deps.storage)?; + ADOContract::default().permission_action(deps.storage, action)?; } for address in addresses { diff --git a/packages/std/src/error.rs b/packages/std/src/error.rs index 85a6594c8..47027cb8e 100644 --- a/packages/std/src/error.rs +++ b/packages/std/src/error.rs @@ -2,7 +2,7 @@ use cosmwasm_std::{Addr, OverflowError, StdError}; use cw20_base::ContractError as Cw20ContractError; use cw721_base::ContractError as Cw721ContractError; use cw_asset::AssetError; -use cw_utils::{ParseReplyError, PaymentError, ThresholdError}; +pub use cw_utils::{ParseReplyError, PaymentError, ThresholdError}; use hex::FromHexError; use std::convert::From; use std::str::{ParseBoolError, Utf8Error}; diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs index 036761f81..b291d9069 100644 --- a/packages/std/src/lib.rs +++ b/packages/std/src/lib.rs @@ -5,7 +5,7 @@ pub mod common; pub mod error; pub mod os; -pub use andromeda_macros::{andr_exec, andr_instantiate, andr_query}; +pub use andromeda_macros::{andr_exec, andr_execute_fn, andr_instantiate, andr_query}; pub use cw_utils::Expiration; pub use strum_macros::AsRefStr; @@ -14,3 +14,6 @@ pub mod testing; #[cfg(feature = "deploy")] pub mod deploy; + +// Re-export the derive macro from the macros crate +pub use andromeda_macros::ExecuteAttrs; diff --git a/packages/std/src/os/aos_querier.rs b/packages/std/src/os/aos_querier.rs index 0ab695402..c05b45e1d 100644 --- a/packages/std/src/os/aos_querier.rs +++ b/packages/std/src/os/aos_querier.rs @@ -182,7 +182,6 @@ impl AOSQuerier { &[ado_type.as_bytes(), action.as_bytes()], )?; let fee: Option = AOSQuerier::query_storage(querier, adodb_addr, &key)?; - Ok(fee) }