diff --git a/.rusty-hook.toml b/.rusty-hook.toml new file mode 100644 index 00000000..6b5b6d2b --- /dev/null +++ b/.rusty-hook.toml @@ -0,0 +1,6 @@ +[hooks] +pre-commit = "just lint test" +pre-push = "just all" + +[logging] +verbose = true diff --git a/Cargo.lock b/Cargo.lock index 6db54a58..1231ff6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -296,6 +296,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ci_info" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24f638c70e8c5753795cc9a8c07c44da91554a09e4cf11a7326e8161b0a3c45e" +dependencies = [ + "envmnt", +] + [[package]] name = "cipher" version = "0.3.0" @@ -477,7 +486,7 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde-json-wasm 0.4.1", "thiserror", "uint", ] @@ -669,6 +678,7 @@ dependencies = [ "cwd-voting-cw20-staked", "generic-query", "hex", + "rusty-hook", "schemars", "serde", "sha2 0.10.6", @@ -691,10 +701,11 @@ dependencies = [ "cw20-base", "generic-query", "hex", + "rusty-hook", "schemars", "serde", "serde-cw-value", - "serde-json-wasm 0.4.1 (git+https://github.com/CyberHoward/serde-json-wasm?rev=cdc78130b25d65981b74a5e4a10a9f8667292d36)", + "serde-json-wasm 0.5.0", "sha2 0.10.6", "thiserror", ] @@ -801,10 +812,11 @@ dependencies = [ "cwd-voting", "cwd-voting-cw20-staked", "generic-query", + "rusty-hook", "schemars", "serde", "serde-cw-value", - "serde-json-wasm 0.4.1 (git+https://github.com/CyberHoward/serde-json-wasm?rev=cdc78130b25d65981b74a5e4a10a9f8667292d36)", + "serde-json-wasm 0.5.0", "serde_json", "smart-query", "thiserror", @@ -818,6 +830,7 @@ dependencies = [ "cosmwasm-std", "cw20", "generic-query", + "rusty-hook", "schemars", "serde", "serde-cw-value", @@ -1517,6 +1530,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "envmnt" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059" +dependencies = [ + "fsio", + "indexmap", +] + [[package]] name = "eyre" version = "0.6.8" @@ -1577,6 +1600,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" +[[package]] +name = "fsio" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fd087255f739f4f1aeea69f11b72f8080e9c2e7645cd06955dad4a178a49e3" + [[package]] name = "futures" version = "0.3.25" @@ -1719,6 +1748,15 @@ dependencies = [ "serde-cw-value", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -2198,6 +2236,12 @@ dependencies = [ "socket2", ] +[[package]] +name = "nias" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0" + [[package]] name = "nix" version = "0.22.3" @@ -2783,6 +2827,18 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rusty-hook" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96cee9be61be7e1cbadd851e58ed7449c29c620f00b23df937cb9cbc04ac21a3" +dependencies = [ + "ci_info", + "getopts", + "nias", + "toml", +] + [[package]] name = "ryu" version = "1.0.11" @@ -2946,8 +3002,9 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" -source = "git+https://github.com/CyberHoward/serde-json-wasm?rev=cdc78130b25d65981b74a5e4a10a9f8667292d36#cdc78130b25d65981b74a5e4a10a9f8667292d36" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] diff --git a/checksum b/checksum index 3f8e09ff..d38aed15 100644 --- a/checksum +++ b/checksum @@ -1,2 +1,2 @@ -f0064d55912d6ca72a1d2fdd9b7414a6e9698a7f87728807690c93a70f0d888e cw_croncat.wasm -de2d1a0c648e41760020dd261f818da085c358240059acf85128f60eb0e05db2 cw_rules.wasm +c678d3d62965d9ba4982766fbd4bafcb8d7c0df2bdc089da0f975f3d78c84c0d cw_croncat.wasm +348ce203ce7a18c2e28f001139c1f7a215f7a569c735825dc819dc79692aaffb cw_rules.wasm diff --git a/ci/gas-benchmark/src/helpers.rs b/ci/gas-benchmark/src/helpers.rs index f93b3804..e4a38891 100644 --- a/ci/gas-benchmark/src/helpers.rs +++ b/ci/gas-benchmark/src/helpers.rs @@ -13,12 +13,15 @@ use cosm_orc::{ }; use cosmwasm_std::Binary; use cw20::Cw20Coin; -use cw_croncat::contract::{GAS_ACTION_FEE_JUNO, GAS_BASE_FEE_JUNO, GAS_DENOMINATOR_DEFAULT_JUNO}; +use cw_croncat::contract::{ + GAS_ACTION_FEE, GAS_BASE_FEE, GAS_DENOMINATOR, GAS_NUMERATOR_DEFAULT, GAS_QUERY_FEE, + GAS_WASM_QUERY_FEE, +}; use cw_croncat_core::{ msg::{TaskRequest, TaskResponse, TaskWithQueriesResponse}, types::Action, }; -use cw_rules_core::msg::QueryResponse; +use cw_rules_core::{msg::QueryResponse, types::CroncatQuery}; const fn add_agent_fee(num: u64) -> u64 { num + (num * 5 / 100) @@ -26,10 +29,23 @@ const fn add_agent_fee(num: u64) -> u64 { fn min_gas_for_actions(actions: &[Action]) -> u64 { actions.iter().fold(0, |acc, action| { - acc + action.gas_limit.unwrap_or(GAS_ACTION_FEE_JUNO) + acc + action.gas_limit.unwrap_or(GAS_ACTION_FEE) }) } +fn min_gas_for_queries(queries: Option<&Vec>) -> u64 { + if let Some(queries) = queries { + queries.iter().fold(GAS_WASM_QUERY_FEE, |acc, query| { + acc + match query { + CroncatQuery::HasBalanceGte(_) => GAS_QUERY_FEE, + _ => GAS_WASM_QUERY_FEE, + } + }) + } else { + 0 + } +} + pub(crate) fn init_contracts( orc: &mut CosmOrc, key: &SigningKey, @@ -71,6 +87,8 @@ pub(crate) fn init_contracts( cw_rules_addr: rules_res.address, owner_id: Some(admin_addr.to_owned()), gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: None, gas_base_fee: None, @@ -175,8 +193,11 @@ where .map(|(_, _, prefix)| (*prefix).to_owned()) .collect(); for (task, extra_funds, prefix) in tasks { - let gas_for_task = GAS_BASE_FEE_JUNO + min_gas_for_actions(&task.actions); - let gas_to_attached_deposit = add_agent_fee(gas_for_task) / GAS_DENOMINATOR_DEFAULT_JUNO; + let gas_for_task = GAS_BASE_FEE + + min_gas_for_actions(&task.actions) + + min_gas_for_queries(task.queries.as_ref()); + let gas_to_attached_deposit = + add_agent_fee(gas_for_task) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; let amount = (gas_to_attached_deposit + extra_funds) * 3; create_task(task, orc, user_key, prefix, &denom, amount)?; } diff --git a/ci/gas-benchmark/src/main.rs b/ci/gas-benchmark/src/main.rs index a77ff9bb..61f9f683 100644 --- a/ci/gas-benchmark/src/main.rs +++ b/ci/gas-benchmark/src/main.rs @@ -201,6 +201,8 @@ fn main() -> Result<()> { agent_fee: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, proxy_callback_gas: None, min_tasks_per_agent: None, diff --git a/ci/local_config.yaml b/ci/local_config.yaml index 71630659..ec4dc483 100644 --- a/ci/local_config.yaml +++ b/ci/local_config.yaml @@ -4,5 +4,5 @@ chain_cfg: chain_id: "testing" rpc_endpoint: "http://localhost:26657/" grpc_endpoint: "http://localhost:9090/" - gas_prices: 0.1 - gas_adjustment: 1.2 + gas_prices: 0.04 + gas_adjustment: 1.5 diff --git a/contracts/cw-croncat/Cargo.toml b/contracts/cw-croncat/Cargo.toml index ee797ee1..00d58288 100644 --- a/contracts/cw-croncat/Cargo.toml +++ b/contracts/cw-croncat/Cargo.toml @@ -60,3 +60,4 @@ cwd-core = { version = "0.2.0", git = "https://github.com/DA0-DA0/dao-contracts" cwd-interface = { version = "0.2.0", git = "https://github.com/DA0-DA0/dao-contracts" } cwd-proposal-single = { version = "0.2.0", git = "https://github.com/DA0-DA0/dao-contracts" } cwd-voting = { version = "0.2.0", git = "https://github.com/DA0-DA0/dao-contracts.git" } +rusty-hook = "0.11.2" diff --git a/contracts/cw-croncat/src/contract.rs b/contracts/cw-croncat/src/contract.rs index 62efb809..8e086875 100644 --- a/contracts/cw-croncat/src/contract.rs +++ b/contracts/cw-croncat/src/contract.rs @@ -16,12 +16,18 @@ const DEFAULT_NOMINATION_DURATION: u16 = 360; /// default for juno /// This based on non-wasm operations, wasm ops seem impossible to predict -pub const GAS_BASE_FEE_JUNO: u64 = 300_000; -/// Gas cost per single action -pub const GAS_ACTION_FEE_JUNO: u64 = 130_000; +pub const GAS_BASE_FEE: u64 = 300_000; +/// Gas needed for single action +pub const GAS_ACTION_FEE: u64 = 130_000; +/// Gas needed for single non-wasm query +pub const GAS_QUERY_FEE: u64 = 5_000; +/// Gas needed for single wasm query +pub const GAS_WASM_QUERY_FEE: u64 = 60_000; /// We can't store gas_price as floats inside cosmwasm -/// so insted of something like 0.1 we use GasFraction{1/10} -pub const GAS_DENOMINATOR_DEFAULT_JUNO: u64 = 9; +/// so insted of having 0.04 we use GasFraction{4/100} +/// and multiply numerator by `gas_adjustment` (1.5) +pub const GAS_NUMERATOR_DEFAULT: u64 = 6; +pub const GAS_DENOMINATOR: u64 = 100; // #[cfg(not(feature = "library"))] impl<'a> CwCroncat<'a> { @@ -44,18 +50,6 @@ impl<'a> CwCroncat<'a> { info.sender }; - let gas_action_fee = if let Some(action_fee) = msg.gas_action_fee { - action_fee.u64() - } else { - GAS_ACTION_FEE_JUNO - }; - - let gas_base_fee = if let Some(base_fee) = msg.gas_base_fee { - base_fee.u64() - } else { - GAS_BASE_FEE_JUNO - }; - let config = Config { paused: false, owner_id, @@ -66,13 +60,18 @@ impl<'a> CwCroncat<'a> { available_balance, staked_balance: GenericBalance::default(), agent_fee: 5, - gas_fraction: GasFraction { - numerator: 1, - denominator: GAS_DENOMINATOR_DEFAULT_JUNO, - }, + gas_fraction: msg.gas_fraction.unwrap_or(GasFraction { + numerator: GAS_NUMERATOR_DEFAULT, + denominator: GAS_DENOMINATOR, + }), proxy_callback_gas: 3, - gas_base_fee, - gas_action_fee, + gas_base_fee: msg.gas_base_fee.map(Into::into).unwrap_or(GAS_BASE_FEE), + gas_action_fee: msg.gas_action_fee.map(Into::into).unwrap_or(GAS_ACTION_FEE), + gas_query_fee: msg.gas_query_fee.map(Into::into).unwrap_or(GAS_QUERY_FEE), + gas_wasm_query_fee: msg + .gas_wasm_query_fee + .map(Into::into) + .unwrap_or(GAS_WASM_QUERY_FEE), slot_granularity_time: 10_000_000_000, // 10 seconds native_denom: msg.denom, cw20_whitelist: vec![], @@ -209,9 +208,7 @@ impl<'a> CwCroncat<'a> { QueryMsg::GetWalletBalances { wallet } => { to_binary(&self.query_wallet_balances(deps, wallet)?) } - QueryMsg::GetState { from_index, limit } => { - to_binary(&self.get_state(deps, env, from_index, limit)?) - } + QueryMsg::GetTaskHash { task } => to_binary(&self.query_get_task_hash(*task)?), } } diff --git a/contracts/cw-croncat/src/helpers.rs b/contracts/cw-croncat/src/helpers.rs index 1e6d91df..c81ed94e 100644 --- a/contracts/cw-croncat/src/helpers.rs +++ b/contracts/cw-croncat/src/helpers.rs @@ -228,8 +228,13 @@ pub(crate) fn proxy_call_submsgs_price( cfg: Config, next_idx: u64, ) -> Result<(Vec, Coin), ContractError> { - let (sub_msgs, gas_total) = - task.get_submsgs_with_total_gas(cfg.gas_base_fee, cfg.gas_action_fee, next_idx)?; + let (sub_msgs, gas_total) = task.get_submsgs_with_total_gas( + cfg.gas_base_fee, + cfg.gas_action_fee, + cfg.gas_query_fee, + cfg.gas_wasm_query_fee, + next_idx, + )?; let gas_amount = calculate_required_amount(gas_total, cfg.agent_fee)?; let price_amount = cfg.gas_fraction.calculate(gas_amount, 1)?; let price = coin(price_amount, cfg.native_denom); diff --git a/contracts/cw-croncat/src/owner.rs b/contracts/cw-croncat/src/owner.rs index fef6ff55..7a72f4e1 100644 --- a/contracts/cw-croncat/src/owner.rs +++ b/contracts/cw-croncat/src/owner.rs @@ -1,16 +1,13 @@ -use crate::balancer::BalancerMode; use crate::error::ContractError; use crate::helpers::has_cw_coins; use crate::state::{Config, CwCroncat}; use cosmwasm_std::{ - has_coins, to_binary, BankMsg, Coin, Deps, DepsMut, Env, MessageInfo, Order, Response, - StdResult, SubMsg, Uint64, WasmMsg, + has_coins, to_binary, BankMsg, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdResult, + SubMsg, WasmMsg, }; use cw20::{Balance, Cw20ExecuteMsg}; use cw_croncat_core::msg::{ - BalancesResponse, CwCroncatResponse, ExecuteMsg, GetBalancesResponse, GetConfigResponse, - GetWalletBalancesResponse, RoundRobinBalancerModeResponse, SlotResponse, - SlotWithQueriesResponse, + ExecuteMsg, GetBalancesResponse, GetConfigResponse, GetWalletBalancesResponse, }; use cw_croncat_core::traits::FindAndMutate; @@ -85,53 +82,60 @@ impl<'a> CwCroncat<'a> { agent_fee, gas_base_fee, gas_action_fee, + gas_query_fee, + gas_wasm_query_fee, gas_fraction, proxy_callback_gas, min_tasks_per_agent, agents_eject_threshold, // treasury_id, } => { + let owner_id = if let Some(addr) = owner_id { + Some(api.addr_validate(&addr)?) + } else { + None + }; self.config - .update(deps.storage, |mut config| -> Result<_, ContractError> { - if info.sender != config.owner_id { + .update(deps.storage, |old_config| -> Result<_, ContractError> { + if info.sender != old_config.owner_id { return Err(ContractError::Unauthorized {}); } - if let Some(owner_id) = owner_id { - let owner_id = api.addr_validate(&owner_id)?; - config.owner_id = owner_id; - } - // if let Some(treasury_id) = treasury_id { - // config.treasury_id = Some(treasury_id); - // } - if let Some(slot_granularity_time) = slot_granularity_time { - config.slot_granularity_time = slot_granularity_time; - } - if let Some(paused) = paused { - config.paused = paused; - } - if let Some(gas_base_fee) = gas_base_fee { - config.gas_base_fee = gas_base_fee.u64(); - } - if let Some(gas_action_fee) = gas_action_fee { - config.gas_action_fee = gas_action_fee.u64(); - } - if let Some(gas_fraction) = gas_fraction { - config.gas_fraction = gas_fraction; - } - if let Some(proxy_callback_gas) = proxy_callback_gas { - config.proxy_callback_gas = proxy_callback_gas; - } - if let Some(agent_fee) = agent_fee { - config.agent_fee = agent_fee; - } - if let Some(min_tasks_per_agent) = min_tasks_per_agent { - config.min_tasks_per_agent = min_tasks_per_agent; - } - if let Some(agents_eject_threshold) = agents_eject_threshold { - config.agents_eject_threshold = agents_eject_threshold; - } - Ok(config) + let new_config = Config { + paused: paused.unwrap_or(old_config.paused), + owner_id: owner_id.unwrap_or(old_config.owner_id), + min_tasks_per_agent: min_tasks_per_agent + .unwrap_or(old_config.min_tasks_per_agent), + agent_active_indices: old_config.agent_active_indices, + agents_eject_threshold: agents_eject_threshold + .unwrap_or(old_config.agents_eject_threshold), + agent_nomination_duration: old_config.agent_nomination_duration, + cw_rules_addr: old_config.cw_rules_addr, + agent_fee: agent_fee.unwrap_or(old_config.agent_fee), + gas_fraction: gas_fraction.unwrap_or(old_config.gas_fraction), + gas_base_fee: gas_base_fee + .map(Into::into) + .unwrap_or(old_config.gas_base_fee), + gas_action_fee: gas_action_fee + .map(Into::into) + .unwrap_or(old_config.gas_action_fee), + gas_query_fee: gas_query_fee + .map(Into::into) + .unwrap_or(old_config.gas_query_fee), + gas_wasm_query_fee: gas_wasm_query_fee + .map(Into::into) + .unwrap_or(old_config.gas_wasm_query_fee), + proxy_callback_gas: proxy_callback_gas + .unwrap_or(old_config.proxy_callback_gas), + slot_granularity_time: slot_granularity_time + .unwrap_or(old_config.slot_granularity_time), + cw20_whitelist: old_config.cw20_whitelist, + native_denom: old_config.native_denom, + available_balance: old_config.available_balance, + staked_balance: old_config.staked_balance, + limit: old_config.limit, + }; + Ok(new_config) })?; } _ => unreachable!(), @@ -275,134 +279,4 @@ impl<'a> CwCroncat<'a> { .add_attribute("account_id", account_id.to_string()) .add_submessages(messages?)) } - - pub(crate) fn get_state( - &self, - deps: Deps, - env: Env, - from_index: Option, - limit: Option, - ) -> StdResult { - let default_limit = self.config.load(deps.storage)?.limit; - let size: u64 = self.task_total.load(deps.storage)?.min(default_limit); - let from_index_unwrap = from_index.unwrap_or_default(); - let limit_unwrap = limit.unwrap_or(default_limit).min(size) as usize; - - let mut agents = Vec::with_capacity(limit_unwrap); - for agent in self - .agents - .keys(deps.storage, None, None, Order::Ascending) - .skip(from_index_unwrap as usize) - .take(limit_unwrap) - { - let agent_info = self.query_get_agent(deps, env.clone(), agent?.to_string())?; - agents.push(agent_info.unwrap()); - } - - let time_slots: Vec = self - .time_slots - .range(deps.storage, None, None, Order::Ascending) - .skip(from_index_unwrap as usize) - .take(limit_unwrap as usize) - .map(|res| { - let res = res.unwrap(); - SlotResponse { - slot: res.0.into(), - tasks: res.1, - } - }) - .collect(); - - let block_slots: Vec = self - .block_slots - .range(deps.storage, None, None, Order::Ascending) - .skip(from_index_unwrap as usize) - .take(limit_unwrap as usize) - .map(|res| { - let res = res.unwrap(); - SlotResponse { - slot: res.0.into(), - tasks: res.1, - } - }) - .collect(); - - let balances: Vec = self - .balances - .range(deps.storage, None, None, Order::Ascending) - .skip(from_index_unwrap as usize) - .take(limit_unwrap as usize) - .map(|res| { - let res = res.unwrap(); - BalancesResponse { - address: res.0, - balances: res.1, - } - }) - .collect(); - - let balancer_mode = match self.balancer.mode { - BalancerMode::ActivationOrder => RoundRobinBalancerModeResponse::ActivationOrder, - BalancerMode::Equalizer => RoundRobinBalancerModeResponse::Equalizer, - }; - - let time_slots_queries: Vec = self - .time_map_queries - .range(deps.storage, None, None, Order::Ascending) - .skip(from_index_unwrap as usize) - .take(limit_unwrap as usize) - .map(|res| { - let res = res.unwrap(); - SlotWithQueriesResponse { - task_hash: res.0, - slot: res.1.into(), - } - }) - .collect(); - - let block_slots_queries: Vec = self - .block_map_queries - .range(deps.storage, None, None, Order::Ascending) - .skip(from_index_unwrap as usize) - .take(limit_unwrap as usize) - .map(|res| { - let res = res.unwrap(); - SlotWithQueriesResponse { - task_hash: res.0, - slot: res.1.into(), - } - }) - .collect(); - - Ok(CwCroncatResponse { - config: self.query_config(deps)?, - - agent_active_queue: self.agent_active_queue.load(deps.storage)?, - agent_pending_queue: self - .agent_pending_queue - .iter(deps.storage)? - .take(50) - .collect::>>()?, - agents, - - tasks: self.query_get_tasks(deps, None, None)?, - task_total: Uint64::from(self.task_total.load(deps.storage)?), - - time_slots, - block_slots, - - tasks_with_queries: self.query_get_tasks_with_queries(deps, from_index, limit)?, - tasks_with_queries_total: Uint64::from( - self.tasks_with_queries_total.load(deps.storage)?, - ), - time_slots_queries, - block_slots_queries, - - reply_index: Uint64::from(self.reply_index.load(deps.storage)?), - agent_nomination_begin_time: self.agent_nomination_begin_time.load(deps.storage)?, - - balances, - balancer_mode, - }) - } } diff --git a/contracts/cw-croncat/src/state.rs b/contracts/cw-croncat/src/state.rs index 745b7bfa..124ede04 100644 --- a/contracts/cw-croncat/src/state.rs +++ b/contracts/cw-croncat/src/state.rs @@ -41,6 +41,8 @@ pub struct Config { pub gas_fraction: GasFraction, pub gas_base_fee: u64, pub gas_action_fee: u64, + pub gas_query_fee: u64, + pub gas_wasm_query_fee: u64, pub proxy_callback_gas: u32, pub slot_granularity_time: u64, diff --git a/contracts/cw-croncat/src/tasks.rs b/contracts/cw-croncat/src/tasks.rs index e8227896..a3dd0b97 100644 --- a/contracts/cw-croncat/src/tasks.rs +++ b/contracts/cw-croncat/src/tasks.rs @@ -262,6 +262,8 @@ impl<'a> CwCroncat<'a> { &cfg.owner_id, cfg.gas_base_fee, cfg.gas_action_fee, + cfg.gas_query_fee, + cfg.gas_wasm_query_fee, )?; let gas_price = calculate_required_amount(gas_amount, cfg.agent_fee)?; let price = cfg.gas_fraction.calculate(gas_price, 1)?; diff --git a/contracts/cw-croncat/src/tests/agent.rs b/contracts/cw-croncat/src/tests/agent.rs index 1eb02125..135bd124 100644 --- a/contracts/cw-croncat/src/tests/agent.rs +++ b/contracts/cw-croncat/src/tests/agent.rs @@ -256,6 +256,8 @@ fn test_instantiate_sets_balance() { cw_rules_addr: "grapestem".to_string(), owner_id: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: None, gas_base_fee: None, @@ -313,6 +315,8 @@ fn register_agent_fail_cases() { proxy_callback_gas: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, slot_granularity_time: None, }; app.execute_contract( @@ -349,6 +353,8 @@ fn register_agent_fail_cases() { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }; app.execute_contract( Addr::unchecked(ADMIN), @@ -751,6 +757,8 @@ fn test_get_agent_status() { denom: NATIVE_DENOM.to_string(), owner_id: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: Some(360), cw_rules_addr: "todo".to_string(), diff --git a/contracts/cw-croncat/src/tests/balance.rs b/contracts/cw-croncat/src/tests/balance.rs index 12796102..751bf9e9 100644 --- a/contracts/cw-croncat/src/tests/balance.rs +++ b/contracts/cw-croncat/src/tests/balance.rs @@ -1,5 +1,8 @@ use crate::balancer::{Balancer, BalancerMode, RoundRobinBalancer}; -use crate::contract::{GAS_ACTION_FEE_JUNO, GAS_BASE_FEE_JUNO, GAS_DENOMINATOR_DEFAULT_JUNO}; +use crate::contract::{ + GAS_ACTION_FEE, GAS_BASE_FEE, GAS_DENOMINATOR, GAS_NUMERATOR_DEFAULT, GAS_QUERY_FEE, + GAS_WASM_QUERY_FEE, +}; use crate::state::{Config, TaskInfo}; use crate::tests::helpers::{default_task, AGENT0, AGENT1, AGENT2, AGENT3, AGENT4}; use cosmwasm_std::testing::{mock_dependencies_with_balance, mock_env}; @@ -22,10 +25,12 @@ fn mock_config() -> Config { staked_balance: GenericBalance::default(), agent_fee: 5, gas_fraction: GasFraction { - numerator: 1, - denominator: GAS_DENOMINATOR_DEFAULT_JUNO, + numerator: GAS_NUMERATOR_DEFAULT, + denominator: GAS_DENOMINATOR, }, - gas_action_fee: GAS_ACTION_FEE_JUNO, + gas_action_fee: GAS_ACTION_FEE, + gas_query_fee: GAS_QUERY_FEE, + gas_wasm_query_fee: GAS_WASM_QUERY_FEE, proxy_callback_gas: 3, slot_granularity_time: 60_000_000_000, native_denom: NATIVE_DENOM.to_owned(), @@ -33,7 +38,7 @@ fn mock_config() -> Config { agent_nomination_duration: 9, limit: 100, cw_rules_addr: Addr::unchecked("todo"), - gas_base_fee: GAS_BASE_FEE_JUNO, + gas_base_fee: GAS_BASE_FEE, } } #[test] diff --git a/contracts/cw-croncat/src/tests/contract.rs b/contracts/cw-croncat/src/tests/contract.rs index d64c4ae8..6784dd27 100644 --- a/contracts/cw-croncat/src/tests/contract.rs +++ b/contracts/cw-croncat/src/tests/contract.rs @@ -1,4 +1,5 @@ -use crate::contract::GAS_DENOMINATOR_DEFAULT_JUNO; +use crate::contract::GAS_DENOMINATOR; +use crate::contract::GAS_NUMERATOR_DEFAULT; use crate::state::QueueItem; use crate::tests::helpers::mock_init; use crate::tests::helpers::AGENT0; @@ -23,6 +24,8 @@ fn configure() { denom: NATIVE_DENOM.to_string(), owner_id: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: Some(360), cw_rules_addr: "todo".to_string(), @@ -54,8 +57,8 @@ fn configure() { assert_eq!(5, value.agent_fee); assert_eq!( GasFraction { - numerator: 1, - denominator: GAS_DENOMINATOR_DEFAULT_JUNO + numerator: GAS_NUMERATOR_DEFAULT, + denominator: GAS_DENOMINATOR }, value.gas_fraction ); diff --git a/contracts/cw-croncat/src/tests/helpers.rs b/contracts/cw-croncat/src/tests/helpers.rs index 19b2430f..002234e3 100644 --- a/contracts/cw-croncat/src/tests/helpers.rs +++ b/contracts/cw-croncat/src/tests/helpers.rs @@ -38,6 +38,8 @@ pub fn mock_init(store: &CwCroncat, deps: DepsMut) -> Result (App, CwTemplateContract, Addr) { owner_id: Some(owner_addr.to_string()), gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: None, }; diff --git a/contracts/cw-croncat/src/tests/manager.rs b/contracts/cw-croncat/src/tests/manager.rs index b63faf31..0eec9d72 100644 --- a/contracts/cw-croncat/src/tests/manager.rs +++ b/contracts/cw-croncat/src/tests/manager.rs @@ -1,4 +1,7 @@ -use crate::contract::{GAS_ACTION_FEE_JUNO, GAS_BASE_FEE_JUNO, GAS_DENOMINATOR_DEFAULT_JUNO}; +use crate::contract::{ + GAS_ACTION_FEE, GAS_BASE_FEE, GAS_DENOMINATOR, GAS_NUMERATOR_DEFAULT, GAS_QUERY_FEE, + GAS_WASM_QUERY_FEE, +}; use crate::tests::helpers::{ add_1000_blocks, add_little_time, add_one_duration_of_time, cw4_template, proper_instantiate, AGENT1, AGENT2, AGENT3, @@ -8,6 +11,7 @@ use cosmwasm_std::{ coin, coins, to_binary, Addr, BankMsg, Coin, CosmosMsg, StakingMsg, StdResult, Uint128, WasmMsg, }; use cw20::Cw20Coin; +use cw_croncat_core::error::CoreError; use cw_croncat_core::msg::{ AgentResponse, AgentTaskResponse, ExecuteMsg, GetAgentIdsResponse, QueryMsg, TaskRequest, TaskResponse, TaskWithQueriesResponse, @@ -101,6 +105,8 @@ fn proxy_call_fail_cases() -> StdResult<()> { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }; app.execute_contract( Addr::unchecked(ADMIN), @@ -167,6 +173,8 @@ fn proxy_call_fail_cases() -> StdResult<()> { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }, &vec![], ) @@ -428,8 +436,8 @@ fn proxy_call_no_task_and_withdraw() -> StdResult<()> { cw20_coins: vec![], }, }; - let gas_for_one = GAS_BASE_FEE_JUNO + gas_limit; - let amount_for_one_task = gas_for_one / GAS_DENOMINATOR_DEFAULT_JUNO; + let gas_for_one = GAS_BASE_FEE + gas_limit; + let amount_for_one_task = gas_for_one * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; let agent_fee = amount_for_one_task * 5 / 100; let amount_with_fee = gas_limit + agent_fee + 1000; // create a task @@ -596,7 +604,7 @@ fn proxy_callback_fail_cases() -> StdResult<()> { attr_key = Some(a.clone().key); attr_value = Some(a.clone().value); } - if e.ty == "transfer" && a.clone().key == "amount" && a.clone().value == "64172atom" + if e.ty == "transfer" && a.clone().key == "amount" && a.clone().value == "93688atom" // task didn't pay for the failed execution { has_submsg_method = true; @@ -694,7 +702,7 @@ fn proxy_callback_fail_cases() -> StdResult<()> { } if e.ty == "transfer" && a.clone().key == "amount" - && a.clone().value == "460840atom" + && a.clone().value == "490356atom" // task didn't pay for the failed execution { has_submsg_method = true; @@ -1296,7 +1304,7 @@ fn test_multi_action() { cw20_coins: vec![], }, }; - let gas_limit = GAS_ACTION_FEE_JUNO; + let gas_limit = GAS_ACTION_FEE; let agent_fee = gas_limit.checked_mul(5).unwrap().checked_div(100).unwrap(); let amount_for_one_task = (gas_limit * 2) + agent_fee * 2 + 3 + 4; // + 3 + 4 atoms sent @@ -1368,11 +1376,11 @@ fn test_balance_changes() { cw20_coins: vec![], }, }; - let gas_for_one = GAS_BASE_FEE_JUNO + (GAS_ACTION_FEE_JUNO * 2); + let gas_for_one = GAS_BASE_FEE + (GAS_ACTION_FEE * 2); let agent_fee = gas_for_one * 5 / 100; let extra = 50; // extra for checking refunds at task removal let amount_for_one_task = - (gas_for_one + agent_fee) / GAS_DENOMINATOR_DEFAULT_JUNO + 3 + 4 + extra; // + 3 + 4 atoms sent + (gas_for_one + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR + 3 + 4 + extra; // + 3 + 4 atoms sent // create a task app.execute_contract( @@ -1502,10 +1510,11 @@ fn test_no_reschedule_if_lack_balance() { }, }; - let gas_for_one = GAS_BASE_FEE_JUNO + GAS_ACTION_FEE_JUNO; + let gas_for_one = GAS_BASE_FEE + GAS_ACTION_FEE; let agent_fee = gas_for_one * 5 / 100; let extra = 50; // extra for checking nonzero task balance - let amount_for_one_task = (gas_for_one + agent_fee) / GAS_DENOMINATOR_DEFAULT_JUNO + 3; // + 3 atoms sent + let amount_for_one_task = + (gas_for_one + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR + 3; // + 3 atoms sent // create a task let resp = app @@ -1560,7 +1569,7 @@ fn test_no_reschedule_if_lack_balance() { .unwrap(); assert_eq!( task.unwrap().total_deposit[0].amount, - Uint128::from((gas_for_one + agent_fee) / GAS_DENOMINATOR_DEFAULT_JUNO + extra) + Uint128::from((gas_for_one + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR + extra) ); app.update_block(add_little_time); @@ -1585,7 +1594,7 @@ fn test_no_reschedule_if_lack_balance() { .query_wasm_smart( contract_addr.clone(), &QueryMsg::GetTask { - task_hash: "65237042c224447b7d6d7cdfd6515af3e76cb3270ce6d5ed989a6babc12f1026" + task_hash: "8fad55a869f129ba363786bd7f0ec698f1a59e2553ba7fdec408f1cd82326cd3" .to_string(), }, ) @@ -1882,6 +1891,8 @@ fn tick() { min_tasks_per_agent: None, agents_eject_threshold: Some(1000), // allow to miss 1000 slots gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, proxy_callback_gas: None, slot_granularity_time: None, gas_base_fee: None, @@ -2077,6 +2088,8 @@ fn tick_task() -> StdResult<()> { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, }; app.execute_contract( @@ -2264,8 +2277,9 @@ fn testing_fee_works() { cw20_coins: vec![], }, }; - let total_gas = GAS_BASE_FEE_JUNO + GAS_ACTION_FEE_JUNO; - let attach_per_action = (total_gas + (total_gas * 5 / 100)) / GAS_DENOMINATOR_DEFAULT_JUNO; + let total_gas = GAS_BASE_FEE + GAS_ACTION_FEE; + let attach_per_action = + (total_gas + (total_gas * 5 / 100)) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; let extra = 100; let amount_for_three = (attach_per_action * 3) as u128 + extra; @@ -3048,3 +3062,423 @@ fn test_error_in_reply() { } assert!(without_failure); } + +#[test] +fn queries_fees() { + let (mut app, cw_template_contract, _) = proper_instantiate(); + let contract_addr = cw_template_contract.addr(); + + // quick agent register + let msg = ExecuteMsg::RegisterAgent { + payable_account_id: Some(AGENT_BENEFICIARY.to_string()), + }; + app.execute_contract(Addr::unchecked(AGENT0), contract_addr.clone(), &msg, &[]) + .unwrap(); + + app.update_block(add_little_time); + + // Non-wasm query + let query = CroncatQuery::HasBalanceGte(HasBalanceGte { + address: contract_addr.to_string(), + required_balance: coins(1, NATIVE_DENOM).into(), + }); + + let transfer_to_bob = BankMsg::Send { + to_address: "bob".to_string(), + amount: coins(1, NATIVE_DENOM), + }; + + let create_task_msg = ExecuteMsg::CreateTask { + task: TaskRequest { + interval: Interval::Once, + boundary: None, + stop_on_fail: false, + actions: vec![Action { + msg: transfer_to_bob.clone().into(), + gas_limit: None, + }], + queries: Some(vec![query]), + transforms: None, + cw20_coins: vec![], + }, + }; + + // Base + action + calling rules + non-wasm query + let gas_needed = GAS_BASE_FEE + GAS_ACTION_FEE + GAS_WASM_QUERY_FEE + GAS_QUERY_FEE; + let agent_fee = gas_needed * 5 / 100; + let gas_to_amount = (gas_needed + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; + let attached_balance = (gas_to_amount + 1) as u128; + + let task_hash_binary = app + .execute_contract( + Addr::unchecked(ADMIN), + contract_addr.clone(), + &create_task_msg, + &coins(attached_balance, NATIVE_DENOM), + ) + .unwrap() + .data + .unwrap(); + let task_hash: String = String::from_utf8(task_hash_binary.to_vec()).unwrap(); + app.update_block(add_little_time); + + let task: TaskResponse = app + .wrap() + .query_wasm_smart( + contract_addr.clone(), + &QueryMsg::GetTask { + task_hash: task_hash.clone(), + }, + ) + .unwrap(); + assert_eq!( + task.amount_for_one_task_native, + coins(attached_balance, NATIVE_DENOM) + ); + + // execute proxy_call + let proxy_call_msg = ExecuteMsg::ProxyCall { + task_hash: Some(task_hash), + }; + let res = app + .execute_contract( + Addr::unchecked(AGENT0), + contract_addr.clone(), + &proxy_call_msg, + &vec![], + ) + .unwrap(); + print!("{:#?}", res); + + assert!(res.events.iter().any(|ev| ev + .attributes + .iter() + .any(|attr| attr.key == "method" && attr.value == "remove_task"))); + + // Wasm query + let wasm_query = CroncatQuery::Query { + contract_addr: contract_addr.to_string(), + msg: to_binary(&QueryMsg::GetAgent { + account_id: AGENT0.to_string(), + }) + .unwrap(), + }; + + let transfer_to_bob = BankMsg::Send { + to_address: "bob".to_string(), + amount: coins(1, NATIVE_DENOM), + }; + + let create_task_msg = ExecuteMsg::CreateTask { + task: TaskRequest { + interval: Interval::Once, + boundary: None, + stop_on_fail: false, + actions: vec![Action { + msg: transfer_to_bob.clone().into(), + gas_limit: None, + }], + queries: Some(vec![wasm_query.clone()]), + transforms: None, + cw20_coins: vec![], + }, + }; + + // Base + action + calling rules + wasm query + let gas_needed = GAS_BASE_FEE + GAS_ACTION_FEE + GAS_WASM_QUERY_FEE + GAS_WASM_QUERY_FEE; + let agent_fee = gas_needed * 5 / 100; + let gas_to_amount = (gas_needed + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; + let attached_balance = (gas_to_amount + 1) as u128; + + let task_hash_binary = app + .execute_contract( + Addr::unchecked(ADMIN), + contract_addr.clone(), + &create_task_msg, + &coins(attached_balance, NATIVE_DENOM), + ) + .unwrap() + .data + .unwrap(); + let task_hash: String = String::from_utf8(task_hash_binary.to_vec()).unwrap(); + app.update_block(add_little_time); + + let task: TaskResponse = app + .wrap() + .query_wasm_smart( + contract_addr.clone(), + &QueryMsg::GetTask { + task_hash: task_hash.clone(), + }, + ) + .unwrap(); + assert_eq!( + task.amount_for_one_task_native, + coins(attached_balance, NATIVE_DENOM) + ); + + // execute proxy_call + let proxy_call_msg = ExecuteMsg::ProxyCall { + task_hash: Some(task_hash), + }; + let res = app + .execute_contract( + Addr::unchecked(AGENT0), + contract_addr.clone(), + &proxy_call_msg, + &vec![], + ) + .unwrap(); + print!("{:#?}", res); + + assert!(res.events.iter().any(|ev| ev + .attributes + .iter() + .any(|attr| attr.key == "method" && attr.value == "remove_task"))); + + // With reschedule to check balance changes + + let create_task_msg = ExecuteMsg::CreateTask { + task: TaskRequest { + interval: Interval::Immediate, + boundary: None, + stop_on_fail: false, + actions: vec![Action { + msg: transfer_to_bob.clone().into(), + gas_limit: None, + }], + queries: Some(vec![wasm_query]), + transforms: None, + cw20_coins: vec![], + }, + }; + + let gas_needed = GAS_BASE_FEE + GAS_ACTION_FEE + GAS_WASM_QUERY_FEE + GAS_WASM_QUERY_FEE; + let agent_fee = gas_needed * 5 / 100; + let gas_to_amount = (gas_needed + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; + let one_proxy_call_amount = (gas_to_amount + 1) as u128; + + let task_hash_binary = app + .execute_contract( + Addr::unchecked(ADMIN), + contract_addr.clone(), + &create_task_msg, + &coins(one_proxy_call_amount * 3, NATIVE_DENOM), + ) + .unwrap() + .data + .unwrap(); + let task_hash: String = String::from_utf8(task_hash_binary.to_vec()).unwrap(); + app.update_block(add_little_time); + + // Initial balance for 3 proxy calls + let task: TaskResponse = app + .wrap() + .query_wasm_smart( + contract_addr.clone(), + &QueryMsg::GetTask { + task_hash: task_hash.clone(), + }, + ) + .unwrap(); + assert_eq!( + task.amount_for_one_task_native, + coins(one_proxy_call_amount, NATIVE_DENOM) + ); + assert_eq!( + task.total_deposit, + coins(one_proxy_call_amount * 3, NATIVE_DENOM) + ); + + // execute proxy_call + let proxy_call_msg = ExecuteMsg::ProxyCall { + task_hash: Some(task_hash.clone()), + }; + app.execute_contract( + Addr::unchecked(AGENT0), + contract_addr.clone(), + &proxy_call_msg, + &vec![], + ) + .unwrap(); + + // for 2 proxies should have left + let task: TaskResponse = app + .wrap() + .query_wasm_smart( + contract_addr.clone(), + &QueryMsg::GetTask { + task_hash: task_hash.to_string(), + }, + ) + .unwrap(); + assert_eq!( + task.total_deposit, + coins(one_proxy_call_amount * 2, NATIVE_DENOM) + ); + + // execute proxy_call + let proxy_call_msg = ExecuteMsg::ProxyCall { + task_hash: Some(task_hash.clone()), + }; + app.execute_contract( + Addr::unchecked(AGENT0), + contract_addr.clone(), + &proxy_call_msg, + &vec![], + ) + .unwrap(); + + // for 2 proxies should have left + let task: TaskResponse = app + .wrap() + .query_wasm_smart( + contract_addr.clone(), + &QueryMsg::GetTask { + task_hash: task_hash.to_string(), + }, + ) + .unwrap(); + assert_eq!( + task.total_deposit, + coins(one_proxy_call_amount, NATIVE_DENOM) + ); + + // execute proxy_call + let proxy_call_msg = ExecuteMsg::ProxyCall { + task_hash: Some(task_hash.clone()), + }; + let res = app + .execute_contract( + Addr::unchecked(AGENT0), + contract_addr.clone(), + &proxy_call_msg, + &vec![], + ) + .unwrap(); + + assert!(res.events.iter().any(|ev| ev + .attributes + .iter() + .any(|attr| attr.key == "method" && attr.value == "remove_task"))); +} + +#[test] +fn queries_fees_negative() { + let (mut app, cw_template_contract, _) = proper_instantiate(); + let contract_addr = cw_template_contract.addr(); + + // quick agent register + let msg = ExecuteMsg::RegisterAgent { + payable_account_id: Some(AGENT_BENEFICIARY.to_string()), + }; + app.execute_contract(Addr::unchecked(AGENT0), contract_addr.clone(), &msg, &[]) + .unwrap(); + + app.update_block(add_little_time); + + // Non-wasm query + let query = CroncatQuery::HasBalanceGte(HasBalanceGte { + address: contract_addr.to_string(), + required_balance: coins(1, NATIVE_DENOM).into(), + }); + + let transfer_to_bob = BankMsg::Send { + to_address: "bob".to_string(), + amount: coins(1, NATIVE_DENOM), + }; + + let create_task_msg = ExecuteMsg::CreateTask { + task: TaskRequest { + interval: Interval::Once, + boundary: None, + stop_on_fail: false, + actions: vec![Action { + msg: transfer_to_bob.clone().into(), + gas_limit: None, + }], + queries: Some(vec![query]), + transforms: None, + cw20_coins: vec![], + }, + }; + + // Base + action + calling rules + non-wasm query + let gas_needed = GAS_BASE_FEE + GAS_ACTION_FEE + GAS_WASM_QUERY_FEE + GAS_QUERY_FEE; + let agent_fee = gas_needed * 5 / 100; + let gas_to_amount = (gas_needed + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; + let attached_balance = (gas_to_amount + 1 - 1) as u128; // missing 1 amount + + let err: ContractError = app + .execute_contract( + Addr::unchecked(ADMIN), + contract_addr.clone(), + &create_task_msg, + &coins(attached_balance, NATIVE_DENOM), + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!( + err, + ContractError::CoreError(CoreError::NotEnoughNative { + denom: NATIVE_DENOM.to_string(), + lack: Uint128::new(1), + }) + ); + + // Wasm query + let wasm_query = CroncatQuery::Query { + contract_addr: contract_addr.to_string(), + msg: to_binary(&QueryMsg::GetAgent { + account_id: AGENT0.to_string(), + }) + .unwrap(), + }; + + let transfer_to_bob = BankMsg::Send { + to_address: "bob".to_string(), + amount: coins(1, NATIVE_DENOM), + }; + + let create_task_msg = ExecuteMsg::CreateTask { + task: TaskRequest { + interval: Interval::Once, + boundary: None, + stop_on_fail: false, + actions: vec![Action { + msg: transfer_to_bob.clone().into(), + gas_limit: None, + }], + queries: Some(vec![wasm_query]), + transforms: None, + cw20_coins: vec![], + }, + }; + + // Base + action + calling rules + wasm query + let gas_needed = GAS_BASE_FEE + GAS_ACTION_FEE + GAS_WASM_QUERY_FEE + GAS_WASM_QUERY_FEE; + let agent_fee = gas_needed * 5 / 100; + let gas_to_amount = (gas_needed + agent_fee) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR; + let attached_balance = (gas_to_amount + 1 - 1) as u128; + + let err: ContractError = app + .execute_contract( + Addr::unchecked(ADMIN), + contract_addr.clone(), + &create_task_msg, + &coins(attached_balance, NATIVE_DENOM), + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!( + err, + ContractError::CoreError(CoreError::NotEnoughNative { + denom: NATIVE_DENOM.to_string(), + lack: Uint128::new(1), + }) + ); +} diff --git a/contracts/cw-croncat/src/tests/owner.rs b/contracts/cw-croncat/src/tests/owner.rs index 89294852..7d124e42 100644 --- a/contracts/cw-croncat/src/tests/owner.rs +++ b/contracts/cw-croncat/src/tests/owner.rs @@ -1,19 +1,12 @@ use crate::error::ContractError; use crate::state::CwCroncat; -use crate::tests::helpers::{ - add_little_time, proper_instantiate, ADMIN, AGENT0, AGENT_BENEFICIARY, ANYONE, NATIVE_DENOM, -}; +use crate::tests::helpers::NATIVE_DENOM; use cosmwasm_std::testing::{mock_dependencies_with_balance, mock_env, mock_info}; -use cosmwasm_std::{ - coin, coins, from_binary, to_binary, Addr, CosmosMsg, MessageInfo, StdResult, Uint64, WasmMsg, -}; +use cosmwasm_std::{coin, coins, from_binary, Addr, MessageInfo}; use cw20::Balance; use cw_croncat_core::msg::{ - CwCroncatResponse, ExecuteMsg, GetBalancesResponse, GetConfigResponse, InstantiateMsg, - QueryMsg, RoundRobinBalancerModeResponse, TaskRequest, + ExecuteMsg, GetBalancesResponse, GetConfigResponse, InstantiateMsg, QueryMsg, }; -use cw_croncat_core::types::{Action, Boundary, Interval}; -use cw_multi_test::Executor; #[test] fn update_settings() { @@ -26,6 +19,8 @@ fn update_settings() { owner_id: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: Some(360), }; @@ -51,6 +46,8 @@ fn update_settings() { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }; // non-owner fails @@ -106,6 +103,8 @@ fn move_balances_auth_checks() { denom: NATIVE_DENOM.to_string(), owner_id: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: Some(360), cw_rules_addr: "todo".to_string(), @@ -128,6 +127,8 @@ fn move_balances_auth_checks() { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }; let info_setting = mock_info("owner_id", &coins(0, "meow")); let res_exec = store @@ -175,6 +176,8 @@ fn move_balances_native() { denom: NATIVE_DENOM.to_string(), owner_id: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, gas_fraction: None, agent_nomination_duration: Some(360), cw_rules_addr: "todo".to_string(), @@ -197,6 +200,8 @@ fn move_balances_native() { slot_granularity_time: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }; let info_settings = mock_info("owner_id", &coins(0, "meow")); let res_exec = store @@ -286,121 +291,3 @@ fn move_balances_native() { // // assert_eq!(info.sender, value.owner_id); // } -#[test] -fn test_get_state() { - let (mut app, cw_template_contract, _) = proper_instantiate(); - let contract_addr = cw_template_contract.addr(); - - let state: StdResult = app.wrap().query_wasm_smart( - &contract_addr.clone(), - &QueryMsg::GetState { - from_index: None, - limit: None, - }, - ); - assert!(state.is_ok()); - let state = state.unwrap(); - - assert_eq!(state.config.paused, false); - assert_eq!(state.config.owner_id.as_str(), ADMIN); - assert_eq!(state.config.agent_fee, 5); - assert_eq!(state.config.gas_base_fee, 300_000); - assert_eq!(state.config.gas_action_fee, 130_000); - assert_eq!(state.config.proxy_callback_gas, 3); - assert!(state.agent_active_queue.is_empty()); - assert!(state.agent_pending_queue.is_empty()); - assert!(state.agents.is_empty()); - assert!(state.tasks.is_empty()); - assert_eq!(state.task_total, Uint64::zero()); - assert!(state.time_slots.is_empty()); - assert!(state.block_slots.is_empty()); - assert!(state.tasks_with_queries.is_empty()); - assert_eq!(state.tasks_with_queries_total, Uint64::zero()); - assert!(state.time_slots_queries.is_empty()); - assert!(state.block_slots_queries.is_empty()); - assert_eq!(state.reply_index, Uint64::zero()); - assert_eq!(state.agent_nomination_begin_time, None); - assert_eq!( - state.balancer_mode, - RoundRobinBalancerModeResponse::ActivationOrder - ); - assert!(state.balances.is_empty()); - - // Create a task - let msg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.to_string(), - msg: to_binary(&ExecuteMsg::WithdrawReward {}).unwrap(), - funds: coins(1, NATIVE_DENOM), - }); - - let create_task_msg = ExecuteMsg::CreateTask { - task: TaskRequest { - interval: Interval::Immediate, - boundary: Some(Boundary::Height { - start: None, - end: None, - }), - stop_on_fail: false, - actions: vec![Action { - msg, - gas_limit: Some(250_000), - }], - queries: None, - transforms: None, - cw20_coins: vec![], - }, - }; - - // create a task - app.execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &create_task_msg, - &coins(525000, NATIVE_DENOM), - ) - .unwrap(); - - // quick agent register - let msg = ExecuteMsg::RegisterAgent { - payable_account_id: Some(AGENT_BENEFICIARY.to_string()), - }; - app.execute_contract(Addr::unchecked(AGENT0), contract_addr.clone(), &msg, &[]) - .unwrap(); - // in pending queue - app.execute_contract(Addr::unchecked(ANYONE), contract_addr.clone(), &msg, &[]) - .unwrap(); - - // might need block advancement - app.update_block(add_little_time); - - let state: StdResult = app.wrap().query_wasm_smart( - &contract_addr.clone(), - &QueryMsg::GetState { - from_index: None, - limit: None, - }, - ); - assert!(state.is_ok()); - let state = state.unwrap(); - - let task_id_str = - "25753e42d62dc9a1ac3cf6b3fcfd773f6dc802cf0a0fea9f56e4dca7272882e8".to_string(); - - assert_eq!(state.agent_active_queue.len(), 1); - assert_eq!(state.agent_active_queue[0].as_str(), AGENT0); - assert_eq!(state.agent_pending_queue.len(), 1); - assert_eq!(state.agent_pending_queue[0].as_str(), ANYONE); - assert_eq!(state.agents.len(), 1); - assert_eq!(state.tasks.len(), 1); - assert_eq!(state.tasks[0].task_hash, task_id_str); - assert_eq!(state.task_total, Uint64::from(1u64)); - assert!(state.time_slots.is_empty()); - assert_eq!(state.block_slots.len(), 1); - assert!(state.tasks_with_queries.is_empty()); - assert_eq!(state.tasks_with_queries_total, Uint64::zero()); - assert!(state.time_slots_queries.is_empty()); - assert!(state.block_slots_queries.is_empty()); - assert_eq!(state.reply_index, Uint64::zero()); - assert!(state.agent_nomination_begin_time.is_some()); - assert!(state.balances.is_empty()); -} diff --git a/contracts/cw-croncat/src/tests/tasks.rs b/contracts/cw-croncat/src/tests/tasks.rs index 81e81813..805593f3 100644 --- a/contracts/cw-croncat/src/tests/tasks.rs +++ b/contracts/cw-croncat/src/tests/tasks.rs @@ -1,5 +1,5 @@ use super::helpers::{ADMIN, ANYONE, NATIVE_DENOM, VERY_RICH}; -use crate::contract::{GAS_ACTION_FEE_JUNO, GAS_BASE_FEE_JUNO, GAS_DENOMINATOR_DEFAULT_JUNO}; +use crate::contract::{GAS_ACTION_FEE, GAS_BASE_FEE, GAS_DENOMINATOR, GAS_NUMERATOR_DEFAULT}; use crate::tests::helpers::proper_instantiate; use crate::ContractError; use cosmwasm_std::{ @@ -363,6 +363,8 @@ fn check_task_create_fail_cases() -> StdResult<()> { min_tasks_per_agent: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }; app.execute_contract( Addr::unchecked(ADMIN), @@ -401,6 +403,8 @@ fn check_task_create_fail_cases() -> StdResult<()> { min_tasks_per_agent: None, gas_base_fee: None, gas_action_fee: None, + gas_query_fee: None, + gas_wasm_query_fee: None, }, &vec![], ) @@ -1052,7 +1056,7 @@ fn check_gas_minimum() { let stake = StakingMsg::Delegate { validator, amount }; let msg: CosmosMsg = stake.clone().into(); let gas_limit = 150_000; - let base_gas = GAS_BASE_FEE_JUNO; + let base_gas = GAS_BASE_FEE; let create_task_msg = ExecuteMsg::CreateTask { task: TaskRequest { @@ -1070,8 +1074,9 @@ fn check_gas_minimum() { }; // create 1 token off task let gas_for_two = (base_gas + gas_limit) * 2; - let enough_for_two = - u128::from((gas_for_two + gas_for_two * 5 / 100) / GAS_DENOMINATOR_DEFAULT_JUNO + 3 * 2); + let enough_for_two = u128::from( + (gas_for_two + gas_for_two * 5 / 100) * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR + 3 * 2, + ); let res: ContractError = app .execute_contract( Addr::unchecked(ANYONE), @@ -1109,8 +1114,8 @@ fn check_gas_default() { let amount = coin(3, NATIVE_DENOM); let stake = StakingMsg::Delegate { validator, amount }; let msg: CosmosMsg = stake.clone().into(); - let gas_limit = GAS_ACTION_FEE_JUNO; - let base_gas = GAS_BASE_FEE_JUNO; + let gas_limit = GAS_ACTION_FEE; + let base_gas = GAS_BASE_FEE; // let send = BankMsg::Send { // to_address: validator, // amount: vec![amount], @@ -1135,7 +1140,8 @@ fn check_gas_default() { let gas_for_one = base_gas + gas_limit; let gas_for_one_with_fee = gas_for_one + gas_for_one * 5 / 100; - let enough_for_two = 2 * u128::from(gas_for_one_with_fee / GAS_DENOMINATOR_DEFAULT_JUNO + 3); + let enough_for_two = + 2 * u128::from(gas_for_one_with_fee * GAS_NUMERATOR_DEFAULT / GAS_DENOMINATOR + 3); let res: ContractError = app .execute_contract( diff --git a/contracts/cw-rules/Cargo.toml b/contracts/cw-rules/Cargo.toml index 867db4eb..3be7286d 100644 --- a/contracts/cw-rules/Cargo.toml +++ b/contracts/cw-rules/Cargo.toml @@ -47,8 +47,7 @@ thiserror = { version = "1.0.31" } # This thing saved our lives thanks @hashedone for implementing it serde-cw-value = "0.7.0" -# TODO: update when this feature is merged -serde-json-wasm = { version = "0.4.1", git = "https://github.com/CyberHoward/serde-json-wasm", rev = "cdc78130b25d65981b74a5e4a10a9f8667292d36" } +serde-json-wasm = { version = "0.5.0" } [dev-dependencies] cw721-base = "0.15.0" @@ -69,3 +68,4 @@ cw4 = "0.16.0" cw4-group = "0.16.0" base64 = "0.13.0" serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +rusty-hook = "0.11.2" diff --git a/justfile b/justfile index 3acd01b8..89074adf 100644 --- a/justfile +++ b/justfile @@ -1,6 +1,6 @@ test_addrs := env_var_or_default('TEST_ADDR', `jq -r '.[].address' ci/test_accounts.json | tr '\n' ' '`) set export -check: +lint: cargo fmt --all && cargo clippy -- -D warnings test: #!/bin/bash @@ -24,6 +24,7 @@ schema: gen: #!/usr/bin/env bash cd typescript + yarn --cwd ./typescript build yarn --cwd ./typescript install --frozen-lockfile yarn --cwd ./typescript codegen juno-local: @@ -54,7 +55,7 @@ download-deps: wget https://github.com/CosmWasm/cw-plus/releases/latest/download/cw20_base.wasm -O artifacts/cw20_base.wasm # TODO?: test dao-contracts -all: build test check schema gen optimize checksum +all: build test lint schema gen optimize checksum #!/usr/bin/env bash gas-benchmark: juno-local download-deps optimize diff --git a/packages/cw-croncat-core/Cargo.toml b/packages/cw-croncat-core/Cargo.toml index d9bfcb02..2a36ee8d 100644 --- a/packages/cw-croncat-core/Cargo.toml +++ b/packages/cw-croncat-core/Cargo.toml @@ -23,13 +23,13 @@ cw20 = { version = "0.13.4" } schemars = "0.8" serde = { version = "1.0", default-features = false, features = ["derive"] } thiserror = { version = "1.0" } -hex = "0.4" -sha2 = "0.10.6" +hex = { version = "0.4", default-features = false } +sha2 = { version = "0.10.6", default-features = false } serde-cw-value = "0.7.0" -# TODO: update when this feature is merged -serde-json-wasm = { version = "0.4.1", git = "https://github.com/CyberHoward/serde-json-wasm", rev = "cdc78130b25d65981b74a5e4a10a9f8667292d36" } +serde-json-wasm = { version = "0.5.0" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } cw-multi-test = { version = "0.16.0", features = ["staking"] } -cw20-base = { version = "0.13.4", features = ["library"] } \ No newline at end of file +cw20-base = { version = "0.13.4", features = ["library"] } +rusty-hook = "0.11.2" diff --git a/packages/cw-croncat-core/examples/schema.rs b/packages/cw-croncat-core/examples/schema.rs index d2671d43..fdddc0ef 100644 --- a/packages/cw-croncat-core/examples/schema.rs +++ b/packages/cw-croncat-core/examples/schema.rs @@ -3,7 +3,7 @@ use std::fs::create_dir_all; use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; use cw_croncat_core::msg::{ - AgentResponse, Croncat, CwCroncatResponse, ExecuteMsg, InstantiateMsg, QueryMsg, TaskResponse, + AgentResponse, Croncat, ExecuteMsg, InstantiateMsg, QueryMsg, TaskResponse, TaskWithQueriesResponse, }; @@ -51,9 +51,4 @@ fn main() { &out_dir, "GetAgentTasksResponse", ); - export_schema_with_title( - &schema_for!(CwCroncatResponse), - &out_dir, - "GetStateResponse", - ); } diff --git a/packages/cw-croncat-core/schema/execute_msg.json b/packages/cw-croncat-core/schema/execute_msg.json index 4f5d11f4..b701e547 100644 --- a/packages/cw-croncat-core/schema/execute_msg.json +++ b/packages/cw-croncat-core/schema/execute_msg.json @@ -57,6 +57,26 @@ } ] }, + "gas_query_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + }, + "gas_wasm_query_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + }, "min_tasks_per_agent": { "type": [ "integer", diff --git a/packages/cw-croncat-core/schema/get_state_response.json b/packages/cw-croncat-core/schema/get_state_response.json deleted file mode 100644 index f72806ec..00000000 --- a/packages/cw-croncat-core/schema/get_state_response.json +++ /dev/null @@ -1,1749 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetStateResponse", - "type": "object", - "required": [ - "agent_active_queue", - "agent_pending_queue", - "agents", - "balancer_mode", - "balances", - "block_slots", - "block_slots_queries", - "config", - "reply_index", - "task_total", - "tasks", - "tasks_with_queries", - "tasks_with_queries_total", - "time_slots", - "time_slots_queries" - ], - "properties": { - "agent_active_queue": { - "type": "array", - "items": { - "$ref": "#/definitions/Addr" - } - }, - "agent_nomination_begin_time": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - }, - "agent_pending_queue": { - "type": "array", - "items": { - "$ref": "#/definitions/Addr" - } - }, - "agents": { - "type": "array", - "items": { - "$ref": "#/definitions/AgentResponse" - } - }, - "balancer_mode": { - "$ref": "#/definitions/RoundRobinBalancerModeResponse" - }, - "balances": { - "type": "array", - "items": { - "$ref": "#/definitions/BalancesResponse" - } - }, - "block_slots": { - "type": "array", - "items": { - "$ref": "#/definitions/SlotResponse" - } - }, - "block_slots_queries": { - "type": "array", - "items": { - "$ref": "#/definitions/SlotWithQueriesResponse" - } - }, - "config": { - "$ref": "#/definitions/GetConfigResponse" - }, - "reply_index": { - "$ref": "#/definitions/Uint64" - }, - "task_total": { - "$ref": "#/definitions/Uint64" - }, - "tasks": { - "type": "array", - "items": { - "$ref": "#/definitions/TaskResponse" - } - }, - "tasks_with_queries": { - "type": "array", - "items": { - "$ref": "#/definitions/TaskWithQueriesResponse" - } - }, - "tasks_with_queries_total": { - "$ref": "#/definitions/Uint64" - }, - "time_slots": { - "type": "array", - "items": { - "$ref": "#/definitions/SlotResponse" - } - }, - "time_slots_queries": { - "type": "array", - "items": { - "$ref": "#/definitions/SlotWithQueriesResponse" - } - } - }, - "definitions": { - "Action_for_Empty": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "gas_limit": { - "description": "The gas needed to safely process the execute msg", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "msg": { - "description": "Supported CosmosMsgs only!", - "allOf": [ - { - "$ref": "#/definitions/CosmosMsg_for_Empty" - } - ] - } - } - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AgentResponse": { - "type": "object", - "required": [ - "balance", - "last_executed_slot", - "payable_account_id", - "register_start", - "status", - "total_tasks_executed" - ], - "properties": { - "balance": { - "$ref": "#/definitions/GenericBalance" - }, - "last_executed_slot": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "payable_account_id": { - "$ref": "#/definitions/Addr" - }, - "register_start": { - "$ref": "#/definitions/Timestamp" - }, - "status": { - "$ref": "#/definitions/AgentStatus" - }, - "total_tasks_executed": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, - "AgentStatus": { - "type": "string", - "enum": [ - "Active", - "Pending", - "Nominated" - ] - }, - "Balance": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/NativeBalance" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20CoinVerified" - } - }, - "additionalProperties": false - } - ] - }, - "BalancesResponse": { - "type": "object", - "required": [ - "address", - "balances" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20CoinVerified" - } - } - } - }, - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Boundary": { - "oneOf": [ - { - "type": "object", - "required": [ - "Height" - ], - "properties": { - "Height": { - "type": "object", - "properties": { - "end": { - "anyOf": [ - { - "$ref": "#/definitions/Uint64" - }, - { - "type": "null" - } - ] - }, - "start": { - "anyOf": [ - { - "$ref": "#/definitions/Uint64" - }, - { - "type": "null" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "Time" - ], - "properties": { - "Time": { - "type": "object", - "properties": { - "end": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - }, - "start": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - } - } - }, - "additionalProperties": false - } - ] - }, - "CheckOwnerOfNft": { - "type": "object", - "required": [ - "address", - "nft_address", - "token_id" - ], - "properties": { - "address": { - "type": "string" - }, - "nft_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - }, - "CheckProposalStatus": { - "type": "object", - "required": [ - "dao_address", - "proposal_id", - "status" - ], - "properties": { - "dao_address": { - "type": "string" - }, - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "status": { - "$ref": "#/definitions/Status" - } - } - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CosmosMsg_for_Empty": { - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "staking" - ], - "properties": { - "staking": { - "$ref": "#/definitions/StakingMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "distribution" - ], - "properties": { - "distribution": { - "$ref": "#/definitions/DistributionMsg" - } - }, - "additionalProperties": false - }, - { - "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", - "type": "object", - "required": [ - "stargate" - ], - "properties": { - "stargate": { - "type": "object", - "required": [ - "type_url", - "value" - ], - "properties": { - "type_url": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ibc" - ], - "properties": { - "ibc": { - "$ref": "#/definitions/IbcMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "gov" - ], - "properties": { - "gov": { - "$ref": "#/definitions/GovMsg" - } - }, - "additionalProperties": false - } - ] - }, - "CroncatQuery": { - "oneOf": [ - { - "type": "object", - "required": [ - "query" - ], - "properties": { - "query": { - "type": "object", - "required": [ - "contract_addr", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "has_balance_gte" - ], - "properties": { - "has_balance_gte": { - "$ref": "#/definitions/HasBalanceGte" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "check_owner_of_nft" - ], - "properties": { - "check_owner_of_nft": { - "$ref": "#/definitions/CheckOwnerOfNft" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "check_proposal_status" - ], - "properties": { - "check_proposal_status": { - "$ref": "#/definitions/CheckProposalStatus" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "generic_query" - ], - "properties": { - "generic_query": { - "$ref": "#/definitions/GenericQuery" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "smart_query" - ], - "properties": { - "smart_query": { - "$ref": "#/definitions/SmartQueryHead" - } - }, - "additionalProperties": false - } - ] - }, - "Cw20CoinVerified": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - } - }, - "DistributionMsg": { - "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "set_withdraw_address" - ], - "properties": { - "set_withdraw_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The `withdraw_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "withdraw_delegator_reward" - ], - "properties": { - "withdraw_delegator_reward": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "validator": { - "description": "The `validator_address`", - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "GasFraction": { - "type": "object", - "required": [ - "denominator", - "numerator" - ], - "properties": { - "denominator": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "numerator": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, - "GenericBalance": { - "type": "object", - "required": [ - "cw20", - "native" - ], - "properties": { - "cw20": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20CoinVerified" - } - }, - "native": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - }, - "GenericQuery": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "ordering", - "path_to_value", - "value" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "ordering": { - "$ref": "#/definitions/ValueOrdering" - }, - "path_to_value": { - "$ref": "#/definitions/PathToValue" - }, - "value": { - "$ref": "#/definitions/Binary" - } - } - }, - "GetConfigResponse": { - "type": "object", - "required": [ - "agent_active_indices", - "agent_fee", - "agent_nomination_duration", - "agents_eject_threshold", - "available_balance", - "cw20_whitelist", - "cw_rules_addr", - "gas_action_fee", - "gas_base_fee", - "gas_fraction", - "limit", - "min_tasks_per_agent", - "native_denom", - "owner_id", - "paused", - "proxy_callback_gas", - "slot_granularity_time", - "staked_balance" - ], - "properties": { - "agent_active_indices": { - "type": "array", - "items": { - "type": "array", - "items": [ - { - "$ref": "#/definitions/SlotType" - }, - { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - ], - "maxItems": 3, - "minItems": 3 - } - }, - "agent_fee": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "agent_nomination_duration": { - "type": "integer", - "format": "uint16", - "minimum": 0.0 - }, - "agents_eject_threshold": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "available_balance": { - "$ref": "#/definitions/GenericBalance" - }, - "cw20_whitelist": { - "type": "array", - "items": { - "$ref": "#/definitions/Addr" - } - }, - "cw_rules_addr": { - "$ref": "#/definitions/Addr" - }, - "gas_action_fee": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "gas_base_fee": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "gas_fraction": { - "$ref": "#/definitions/GasFraction" - }, - "limit": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "min_tasks_per_agent": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "native_denom": { - "type": "string" - }, - "owner_id": { - "$ref": "#/definitions/Addr" - }, - "paused": { - "type": "boolean" - }, - "proxy_callback_gas": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "slot_granularity_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "staked_balance": { - "$ref": "#/definitions/GenericBalance" - } - } - }, - "GovMsg": { - "oneOf": [ - { - "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "$ref": "#/definitions/VoteOption" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "HasBalanceGte": { - "type": "object", - "required": [ - "address", - "required_balance" - ], - "properties": { - "address": { - "type": "string" - }, - "required_balance": { - "$ref": "#/definitions/Balance" - } - } - }, - "IbcMsg": { - "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", - "oneOf": [ - { - "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "channel_id", - "timeout", - "to_address" - ], - "properties": { - "amount": { - "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "channel_id": { - "description": "exisiting channel to send the tokens over", - "type": "string" - }, - "timeout": { - "description": "when packet times out, measured on remote chain", - "allOf": [ - { - "$ref": "#/definitions/IbcTimeout" - } - ] - }, - "to_address": { - "description": "address on the remote chain to receive these tokens", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", - "type": "object", - "required": [ - "send_packet" - ], - "properties": { - "send_packet": { - "type": "object", - "required": [ - "channel_id", - "data", - "timeout" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "data": { - "$ref": "#/definitions/Binary" - }, - "timeout": { - "description": "when packet times out, measured on remote chain", - "allOf": [ - { - "$ref": "#/definitions/IbcTimeout" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", - "type": "object", - "required": [ - "close_channel" - ], - "properties": { - "close_channel": { - "type": "object", - "required": [ - "channel_id" - ], - "properties": { - "channel_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "IbcTimeout": { - "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", - "type": "object", - "properties": { - "block": { - "anyOf": [ - { - "$ref": "#/definitions/IbcTimeoutBlock" - }, - { - "type": "null" - } - ] - }, - "timestamp": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - } - }, - "IbcTimeoutBlock": { - "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", - "type": "object", - "required": [ - "height", - "revision" - ], - "properties": { - "height": { - "description": "block height after which the packet times out. the height within the given revision", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, - "Interval": { - "description": "Defines the spacing of execution NOTES: - Block Height Based: Once, Immediate, Block - Timestamp Based: Cron - No Epoch support directly, advised to use block heights instead", - "oneOf": [ - { - "description": "For when this is a non-recurring future scheduled TXN", - "type": "string", - "enum": [ - "Once" - ] - }, - { - "description": "The ugly batch schedule type, in case you need to exceed single TXN gas limits, within fewest block(s)", - "type": "string", - "enum": [ - "Immediate" - ] - }, - { - "description": "Allows timing based on block intervals rather than timestamps", - "type": "object", - "required": [ - "Block" - ], - "properties": { - "Block": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Crontab Spec String", - "type": "object", - "required": [ - "Cron" - ], - "properties": { - "Cron": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "NativeBalance": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "PathToValue": { - "type": "array", - "items": { - "$ref": "#/definitions/ValueIndex" - } - }, - "RoundRobinBalancerModeResponse": { - "type": "string", - "enum": [ - "ActivationOrder", - "Equalizer" - ] - }, - "SlotResponse": { - "type": "object", - "required": [ - "slot", - "tasks" - ], - "properties": { - "slot": { - "$ref": "#/definitions/Uint64" - }, - "tasks": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - } - }, - "SlotType": { - "type": "string", - "enum": [ - "Block", - "Cron" - ] - }, - "SlotWithQueriesResponse": { - "type": "object", - "required": [ - "slot", - "task_hash" - ], - "properties": { - "slot": { - "$ref": "#/definitions/Uint64" - }, - "task_hash": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - }, - "SmartQueries": { - "type": "array", - "items": { - "$ref": "#/definitions/SmartQuery" - } - }, - "SmartQuery": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "path_to_msg_value", - "path_to_query_value" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "path_to_msg_value": { - "description": "Replace value inside this query", - "allOf": [ - { - "$ref": "#/definitions/PathToValue" - } - ] - }, - "path_to_query_value": { - "description": "Value passed to the next iteration", - "allOf": [ - { - "$ref": "#/definitions/PathToValue" - } - ] - } - } - }, - "SmartQueryHead": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "ordering", - "path_to_query_value", - "queries", - "value" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "First query without placeholder!", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "ordering": { - "$ref": "#/definitions/ValueOrdering" - }, - "path_to_query_value": { - "description": "Value from this message", - "allOf": [ - { - "$ref": "#/definitions/PathToValue" - } - ] - }, - "queries": { - "$ref": "#/definitions/SmartQueries" - }, - "value": { - "$ref": "#/definitions/Binary" - } - } - }, - "StakingMsg": { - "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", - "oneOf": [ - { - "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "amount", - "validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "amount", - "dst_validator", - "src_validator" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Coin" - }, - "dst_validator": { - "type": "string" - }, - "src_validator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Status": { - "oneOf": [ - { - "type": "string", - "enum": [ - "execution_failed" - ] - }, - { - "description": "The proposal is open for voting.", - "type": "string", - "enum": [ - "open" - ] - }, - { - "description": "The proposal has been rejected.", - "type": "string", - "enum": [ - "rejected" - ] - }, - { - "description": "The proposal has been passed but has not been executed.", - "type": "string", - "enum": [ - "passed" - ] - }, - { - "description": "The proposal has been passed and executed.", - "type": "string", - "enum": [ - "executed" - ] - }, - { - "description": "The proposal has failed or expired and has been closed. A proposal deposit refund has been issued if applicable.", - "type": "string", - "enum": [ - "closed" - ] - } - ] - }, - "TaskResponse": { - "type": "object", - "required": [ - "actions", - "amount_for_one_task_cw20", - "amount_for_one_task_native", - "interval", - "owner_id", - "stop_on_fail", - "task_hash", - "total_cw20_deposit", - "total_deposit" - ], - "properties": { - "actions": { - "type": "array", - "items": { - "$ref": "#/definitions/Action_for_Empty" - } - }, - "amount_for_one_task_cw20": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20CoinVerified" - } - }, - "amount_for_one_task_native": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "boundary": { - "anyOf": [ - { - "$ref": "#/definitions/Boundary" - }, - { - "type": "null" - } - ] - }, - "interval": { - "$ref": "#/definitions/Interval" - }, - "owner_id": { - "$ref": "#/definitions/Addr" - }, - "queries": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/CroncatQuery" - } - }, - "stop_on_fail": { - "type": "boolean" - }, - "task_hash": { - "type": "string" - }, - "total_cw20_deposit": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20CoinVerified" - } - }, - "total_deposit": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - }, - "TaskWithQueriesResponse": { - "type": "object", - "required": [ - "interval", - "task_hash" - ], - "properties": { - "boundary": { - "anyOf": [ - { - "$ref": "#/definitions/Boundary" - }, - { - "type": "null" - } - ] - }, - "interval": { - "$ref": "#/definitions/Interval" - }, - "queries": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/CroncatQuery" - } - }, - "task_hash": { - "type": "string" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "ValueIndex": { - "oneOf": [ - { - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "index" - ], - "properties": { - "index": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "ValueOrdering": { - "type": "string", - "enum": [ - "unit_above", - "unit_above_equal", - "unit_below", - "unit_below_equal", - "equal", - "not_equal" - ] - }, - "VoteOption": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "no_with_veto" - ] - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.16.0-alpha1/x/wasm/internal/types/tx.proto#L47-L61). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/cw-croncat-core/schema/instantiate_msg.json b/packages/cw-croncat-core/schema/instantiate_msg.json index 8ecab164..ac8a7dd7 100644 --- a/packages/cw-croncat-core/schema/instantiate_msg.json +++ b/packages/cw-croncat-core/schema/instantiate_msg.json @@ -51,6 +51,26 @@ } ] }, + "gas_query_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + }, + "gas_wasm_query_fee": { + "anyOf": [ + { + "$ref": "#/definitions/Uint64" + }, + { + "type": "null" + } + ] + }, "owner_id": { "type": [ "string", diff --git a/packages/cw-croncat-core/schema/query_msg.json b/packages/cw-croncat-core/schema/query_msg.json index e14cd494..8e9f7906 100644 --- a/packages/cw-croncat-core/schema/query_msg.json +++ b/packages/cw-croncat-core/schema/query_msg.json @@ -271,36 +271,6 @@ } }, "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_state" - ], - "properties": { - "get_state": { - "type": "object", - "properties": { - "from_index": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false } ], "definitions": { diff --git a/packages/cw-croncat-core/src/msg.rs b/packages/cw-croncat-core/src/msg.rs index bb4e7d4a..671c3cbf 100644 --- a/packages/cw-croncat-core/src/msg.rs +++ b/packages/cw-croncat-core/src/msg.rs @@ -64,6 +64,8 @@ pub struct InstantiateMsg { pub owner_id: Option, pub gas_base_fee: Option, pub gas_action_fee: Option, + pub gas_query_fee: Option, + pub gas_wasm_query_fee: Option, pub gas_fraction: Option, pub agent_nomination_duration: Option, } @@ -78,6 +80,8 @@ pub enum ExecuteMsg { agent_fee: Option, gas_base_fee: Option, gas_action_fee: Option, + gas_query_fee: Option, + gas_wasm_query_fee: Option, gas_fraction: Option, proxy_callback_gas: Option, min_tasks_per_agent: Option, @@ -164,68 +168,6 @@ pub enum QueryMsg { GetWalletBalances { wallet: String, }, - GetState { - from_index: Option, - limit: Option, - }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct GetConfigResponse { - pub paused: bool, - pub owner_id: Addr, - // pub treasury_id: Option, - pub min_tasks_per_agent: u64, - pub agents_eject_threshold: u64, - pub agent_active_indices: Vec<(SlotType, u32, u32)>, - pub agent_nomination_duration: u16, - - pub cw_rules_addr: Addr, - - pub agent_fee: u64, - pub gas_fraction: GasFraction, - pub gas_base_fee: u64, - pub gas_action_fee: u64, - pub proxy_callback_gas: u32, - pub slot_granularity_time: u64, - - pub cw20_whitelist: Vec, - pub native_denom: String, - pub available_balance: GenericBalance, // tasks + rewards balances - pub staked_balance: GenericBalance, // surplus that is temporary staking (to be used in conjunction with external treasury) - - // The default amount of tasks to query - pub limit: u64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct GetBalancesResponse { - pub native_denom: String, - pub available_balance: GenericBalance, - pub staked_balance: GenericBalance, - pub cw20_whitelist: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct GetWalletBalancesResponse { - pub cw20_balances: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct GetAgentIdsResponse { - pub active: Vec, - pub pending: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct AgentResponse { - // This field doesn't exist in the Agent struct and is the only one that differs - pub status: AgentStatus, - pub payable_account_id: Addr, - pub balance: GenericBalance, - pub total_tasks_executed: u64, - pub last_executed_slot: u64, - pub register_start: Timestamp, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] @@ -416,70 +358,32 @@ pub struct TaskWithQueriesResponse { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct CwCroncatResponse { - pub config: GetConfigResponse, - - pub agent_active_queue: Vec, - pub agent_pending_queue: Vec, - pub agents: Vec, - - pub tasks: Vec, - pub task_total: Uint64, - - pub time_slots: Vec, - pub block_slots: Vec, - pub tasks_with_queries: Vec, - pub tasks_with_queries_total: Uint64, - - pub time_slots_queries: Vec, - pub block_slots_queries: Vec, - - pub reply_index: Uint64, - - pub agent_nomination_begin_time: Option, - - pub balancer_mode: RoundRobinBalancerModeResponse, - pub balances: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct SlotResponse { - pub slot: Uint64, - pub tasks: Vec>, +pub struct GetBalancesResponse { + pub native_denom: String, + pub available_balance: GenericBalance, + pub staked_balance: GenericBalance, + pub cw20_whitelist: Vec, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct BalancesResponse { - pub address: Addr, - pub balances: Vec, +pub struct GetWalletBalancesResponse { + pub cw20_balances: Vec, } - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub enum RoundRobinBalancerModeResponse { - ActivationOrder, - Equalizer, +pub struct GetAgentIdsResponse { + pub active: Vec, + pub pending: Vec, } -// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -// pub struct ReplyQueueResponse { -// pub index: Uint64, -// pub item: QueueItemResponse, -// } - -// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -// pub struct QueueItemResponse { -// pub contract_addr: Option, -// pub action_idx: Uint64, -// pub task_hash: Option>, -// pub task_is_extra: Option, -// pub agent_id: Option, -// pub failed: bool, -// } - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct SlotWithQueriesResponse { - pub task_hash: Vec, - pub slot: Uint64, +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct AgentResponse { + // This field doesn't exist in the Agent struct and is the only one that differs + pub status: AgentStatus, + pub payable_account_id: Addr, + pub balance: GenericBalance, + pub total_tasks_executed: u64, + pub last_executed_slot: u64, + pub register_start: Timestamp, } impl From for TaskResponse { @@ -594,3 +498,31 @@ pub struct GetSlotIdsResponse { pub struct QueryConstruct { pub queries: Vec, } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct GetConfigResponse { + pub paused: bool, + pub owner_id: Addr, + // pub treasury_id: Option, + pub min_tasks_per_agent: u64, + pub agents_eject_threshold: u64, + pub agent_active_indices: Vec<(SlotType, u32, u32)>, + pub agent_nomination_duration: u16, + + pub cw_rules_addr: Addr, + + pub agent_fee: u64, + pub gas_fraction: GasFraction, + pub gas_base_fee: u64, + pub gas_action_fee: u64, + pub proxy_callback_gas: u32, + pub slot_granularity_time: u64, + + pub cw20_whitelist: Vec, + pub native_denom: String, + pub available_balance: GenericBalance, // tasks + rewards balances + pub staked_balance: GenericBalance, // surplus that is temporary staking (to be used in conjunction with external treasury) + + // The default amount of tasks to query + pub limit: u64, +} diff --git a/packages/cw-croncat-core/src/tests/types.rs b/packages/cw-croncat-core/src/tests/types.rs index 64fd5178..28b127e6 100644 --- a/packages/cw-croncat-core/src/tests/types.rs +++ b/packages/cw-croncat-core/src/tests/types.rs @@ -40,6 +40,8 @@ fn is_valid_msg_once_block_based() { &Addr::unchecked("bob"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .is_ok()); @@ -74,6 +76,8 @@ fn is_valid_msg_once_time_based() { &Addr::unchecked("bob"), 5, 5, + 5, + 5 ) .is_ok()); } @@ -104,6 +108,8 @@ fn is_valid_msg_recurring() { &Addr::unchecked("bob"), 5, 5, + 5, + 5 ) .is_ok()); } @@ -138,6 +144,8 @@ fn is_valid_msg_wrong_account() { &Addr::unchecked("sender"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .unwrap_err() @@ -173,6 +181,8 @@ fn is_valid_msg_vote() { &Addr::unchecked("sender"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .unwrap_err() @@ -210,6 +220,8 @@ fn is_valid_msg_transfer() { &Addr::unchecked("sender"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .unwrap_err() @@ -244,6 +256,8 @@ fn is_valid_msg_burn() { &Addr::unchecked("sender"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .unwrap_err() @@ -278,6 +292,8 @@ fn is_valid_msg_send_doesnt_fail() { &Addr::unchecked("sender"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .is_ok()); @@ -311,6 +327,8 @@ fn is_valid_msg_send_should_success() { &Addr::unchecked("sender"), &Addr::unchecked("bob"), 5, + 5, + 5, 5 ) .is_ok()); @@ -508,8 +526,8 @@ fn hashing() { }; let message = format!( - "{:?}{:?}{:?}{:?}{:?}", - task.owner_id, task.interval, task.boundary, task.actions, task.queries + "{:?}{:?}{:?}{:?}{:?}{:?}", + task.owner_id, task.interval, task.boundary, task.actions, task.queries, task.transforms ); let hash = Sha256::digest(message.as_bytes()); diff --git a/packages/cw-croncat-core/src/types.rs b/packages/cw-croncat-core/src/types.rs index ab1db318..474bfc0d 100644 --- a/packages/cw-croncat-core/src/types.rs +++ b/packages/cw-croncat-core/src/types.rs @@ -238,6 +238,8 @@ impl TaskRequest { /// Validate the task actions only use the supported messages /// We're iterating over all actions /// so it's a great place for calculaing balance usages + // Consider moving Config to teh cw-croncat-core so this method can take reference of that + #[allow(clippy::too_many_arguments)] pub fn is_valid_msg_calculate_usage( &self, api: &dyn Api, @@ -246,6 +248,8 @@ impl TaskRequest { owner_id: &Addr, base_gas: u64, action_gas: u64, + query_gas: u64, + wasm_query_gas: u64, ) -> Result<(GenericBalance, u64), CoreError> { let mut gas_amount: u64 = base_gas; let mut amount_for_one_task = GenericBalance::default(); @@ -335,6 +339,27 @@ impl TaskRequest { _ => (), } } + + if let Some(queries) = self.queries.as_ref() { + // If task has queries - Rules contract is queried which is wasm query + gas_amount = gas_amount + .checked_add(wasm_query_gas) + .ok_or(CoreError::InvalidWasmMsg {})?; + for query in queries.iter() { + match query { + CroncatQuery::HasBalanceGte(_) => { + gas_amount = gas_amount + .checked_add(query_gas) + .ok_or(CoreError::InvalidWasmMsg {})?; + } + _ => { + gas_amount = gas_amount + .checked_add(wasm_query_gas) + .ok_or(CoreError::InvalidWasmMsg {})?; + } + } + } + } Ok((amount_for_one_task, gas_amount)) } } @@ -371,8 +396,13 @@ impl Task { /// Get the hash of a task based on parameters pub fn to_hash(&self) -> String { let message = format!( - "{:?}{:?}{:?}{:?}{:?}", - self.owner_id, self.interval, self.boundary, self.actions, self.queries + "{:?}{:?}{:?}{:?}{:?}{:?}", + self.owner_id, + self.interval, + self.boundary, + self.actions, + self.queries, + self.transforms ); let hash = Sha256::digest(message.as_bytes()); @@ -445,6 +475,8 @@ impl Task { &self, base_gas: u64, action_gas: u64, + query_gas: u64, + wasm_query_gas: u64, next_idx: u64, ) -> Result<(Vec>, u64), CoreError> { let mut gas: u64 = base_gas; @@ -460,6 +492,25 @@ impl Task { sub_msgs.push(sub_msg); } } + + if let Some(queries) = self.queries.as_ref() { + // If task has queries - Rules contract is queried which is wasm query + gas = gas + .checked_add(wasm_query_gas) + .ok_or(CoreError::InvalidGas {})?; + for query in queries.iter() { + match query { + CroncatQuery::HasBalanceGte(_) => { + gas = gas.checked_add(query_gas).ok_or(CoreError::InvalidGas {})?; + } + _ => { + gas = gas + .checked_add(wasm_query_gas) + .ok_or(CoreError::InvalidGas {})?; + } + } + } + } Ok((sub_msgs, gas)) } diff --git a/packages/cw-rules-core/Cargo.toml b/packages/cw-rules-core/Cargo.toml index f8ea32d2..c2d3855d 100644 --- a/packages/cw-rules-core/Cargo.toml +++ b/packages/cw-rules-core/Cargo.toml @@ -20,3 +20,4 @@ cw20 = { version = "0.13.4" } [dev-dependencies] cosmwasm-schema = { version = "1.0.0" } +rusty-hook = "0.11.2" diff --git a/typescript/build/contracts/cw-croncat-core/CwCroncatCore.client.js b/typescript/build/contracts/cw-croncat-core/CwCroncatCore.client.js index e7ff693c..59d0ebd6 100644 --- a/typescript/build/contracts/cw-croncat-core/CwCroncatCore.client.js +++ b/typescript/build/contracts/cw-croncat-core/CwCroncatCore.client.js @@ -109,14 +109,6 @@ class CwCroncatCoreQueryClient { } }); }); - this.getState = ({ fromIndex, limit }) => __awaiter(this, void 0, void 0, function* () { - return this.client.queryContractSmart(this.contractAddress, { - get_state: { - from_index: fromIndex, - limit - } - }); - }); this.client = client; this.contractAddress = contractAddress; this.getConfig = this.getConfig.bind(this); @@ -133,14 +125,13 @@ class CwCroncatCoreQueryClient { this.getSlotHashes = this.getSlotHashes.bind(this); this.getSlotIds = this.getSlotIds.bind(this); this.getWalletBalances = this.getWalletBalances.bind(this); - this.getState = this.getState.bind(this); } } exports.CwCroncatCoreQueryClient = CwCroncatCoreQueryClient; class CwCroncatCoreClient extends CwCroncatCoreQueryClient { constructor(client, sender, contractAddress) { super(client, contractAddress); - this.updateSettings = ({ agentFee, agentsEjectThreshold, gasActionFee, gasBaseFee, gasFraction, minTasksPerAgent, ownerId, paused, proxyCallbackGas, slotGranularityTime }, fee = "auto", memo, funds) => __awaiter(this, void 0, void 0, function* () { + this.updateSettings = ({ agentFee, agentsEjectThreshold, gasActionFee, gasBaseFee, gasFraction, gasQueryFee, gasWasmQueryFee, minTasksPerAgent, ownerId, paused, proxyCallbackGas, slotGranularityTime }, fee = "auto", memo, funds) => __awaiter(this, void 0, void 0, function* () { return yield this.client.execute(this.sender, this.contractAddress, { update_settings: { agent_fee: agentFee, @@ -148,6 +139,8 @@ class CwCroncatCoreClient extends CwCroncatCoreQueryClient { gas_action_fee: gasActionFee, gas_base_fee: gasBaseFee, gas_fraction: gasFraction, + gas_query_fee: gasQueryFee, + gas_wasm_query_fee: gasWasmQueryFee, min_tasks_per_agent: minTasksPerAgent, owner_id: ownerId, paused, diff --git a/typescript/contracts/cw-croncat-core/CwCroncatCore.client.ts b/typescript/contracts/cw-croncat-core/CwCroncatCore.client.ts index befe9a5f..2969ef8f 100644 --- a/typescript/contracts/cw-croncat-core/CwCroncatCore.client.ts +++ b/typescript/contracts/cw-croncat-core/CwCroncatCore.client.ts @@ -6,7 +6,7 @@ import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; import { StdFee } from "@cosmjs/amino"; -import { Addr, Uint128, Timestamp, Uint64, SlotType, AgentStatus, CosmosMsgForEmpty, BankMsg, StakingMsg, DistributionMsg, Binary, IbcMsg, WasmMsg, GovMsg, VoteOption, Boundary, Interval, CroncatQuery, Balance, NativeBalance, Status, ValueOrdering, ValueIndex, PathToValue, SmartQueries, Croncat, Agent, GenericBalance, Cw20CoinVerified, Coin, GetBalancesResponse, GetConfigResponse, GasFraction, GetAgentIdsResponse, AgentResponse, AgentTaskResponse, GetSlotHashesResponse, GetSlotIdsResponse, TaskResponse, ActionForEmpty, Empty, IbcTimeout, IbcTimeoutBlock, HasBalanceGte, CheckOwnerOfNft, CheckProposalStatus, GenericQuery, SmartQueryHead, SmartQuery, GetWalletBalancesResponse, Task, BoundaryValidated, Transform, TaskRequest, Cw20Coin, ExecuteMsg, Cw20ReceiveMsg, GetAgentResponse, GetAgentTasksResponse, RoundRobinBalancerModeResponse, GetStateResponse, BalancesResponse, SlotResponse, SlotWithQueriesResponse, TaskWithQueriesResponse, GetTaskHashResponse, GetTaskResponse, GetTasksByOwnerResponse, GetTasksResponse, GetTasksWithQueriesResponse, InstantiateMsg, QueryMsg, ValidateIntervalResponse } from "./CwCroncatCore.types"; +import { Addr, Uint128, Timestamp, Uint64, SlotType, AgentStatus, CosmosMsgForEmpty, BankMsg, StakingMsg, DistributionMsg, Binary, IbcMsg, WasmMsg, GovMsg, VoteOption, Boundary, Interval, CroncatQuery, Balance, NativeBalance, Status, ValueOrdering, ValueIndex, PathToValue, SmartQueries, Croncat, Agent, GenericBalance, Cw20CoinVerified, Coin, GetBalancesResponse, GetConfigResponse, GasFraction, GetAgentIdsResponse, AgentResponse, AgentTaskResponse, GetSlotHashesResponse, GetSlotIdsResponse, TaskResponse, ActionForEmpty, Empty, IbcTimeout, IbcTimeoutBlock, HasBalanceGte, CheckOwnerOfNft, CheckProposalStatus, GenericQuery, SmartQueryHead, SmartQuery, GetWalletBalancesResponse, Task, BoundaryValidated, Transform, TaskRequest, Cw20Coin, ExecuteMsg, Cw20ReceiveMsg, GetAgentResponse, GetAgentTasksResponse, GetTaskHashResponse, GetTaskResponse, GetTasksByOwnerResponse, GetTasksResponse, GetTasksWithQueriesResponse, TaskWithQueriesResponse, InstantiateMsg, QueryMsg, ValidateIntervalResponse } from "./CwCroncatCore.types"; export interface CwCroncatCoreReadOnlyInterface { contractAddress: string; getConfig: () => Promise; @@ -67,13 +67,6 @@ export interface CwCroncatCoreReadOnlyInterface { }: { wallet: string; }) => Promise; - getState: ({ - fromIndex, - limit - }: { - fromIndex?: number; - limit?: number; - }) => Promise; } export class CwCroncatCoreQueryClient implements CwCroncatCoreReadOnlyInterface { client: CosmWasmClient; @@ -96,7 +89,6 @@ export class CwCroncatCoreQueryClient implements CwCroncatCoreReadOnlyInterface this.getSlotHashes = this.getSlotHashes.bind(this); this.getSlotIds = this.getSlotIds.bind(this); this.getWalletBalances = this.getWalletBalances.bind(this); - this.getState = this.getState.bind(this); } getConfig = async (): Promise => { @@ -235,20 +227,6 @@ export class CwCroncatCoreQueryClient implements CwCroncatCoreReadOnlyInterface } }); }; - getState = async ({ - fromIndex, - limit - }: { - fromIndex?: number; - limit?: number; - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - get_state: { - from_index: fromIndex, - limit - } - }); - }; } export interface CwCroncatCoreInterface extends CwCroncatCoreReadOnlyInterface { contractAddress: string; @@ -259,6 +237,8 @@ export interface CwCroncatCoreInterface extends CwCroncatCoreReadOnlyInterface { gasActionFee, gasBaseFee, gasFraction, + gasQueryFee, + gasWasmQueryFee, minTasksPerAgent, ownerId, paused, @@ -270,6 +250,8 @@ export interface CwCroncatCoreInterface extends CwCroncatCoreReadOnlyInterface { gasActionFee?: Uint64; gasBaseFee?: Uint64; gasFraction?: GasFraction; + gasQueryFee?: Uint64; + gasWasmQueryFee?: Uint64; minTasksPerAgent?: number; ownerId?: string; paused?: boolean; @@ -376,6 +358,8 @@ export class CwCroncatCoreClient extends CwCroncatCoreQueryClient implements CwC gasActionFee, gasBaseFee, gasFraction, + gasQueryFee, + gasWasmQueryFee, minTasksPerAgent, ownerId, paused, @@ -387,6 +371,8 @@ export class CwCroncatCoreClient extends CwCroncatCoreQueryClient implements CwC gasActionFee?: Uint64; gasBaseFee?: Uint64; gasFraction?: GasFraction; + gasQueryFee?: Uint64; + gasWasmQueryFee?: Uint64; minTasksPerAgent?: number; ownerId?: string; paused?: boolean; @@ -400,6 +386,8 @@ export class CwCroncatCoreClient extends CwCroncatCoreQueryClient implements CwC gas_action_fee: gasActionFee, gas_base_fee: gasBaseFee, gas_fraction: gasFraction, + gas_query_fee: gasQueryFee, + gas_wasm_query_fee: gasWasmQueryFee, min_tasks_per_agent: minTasksPerAgent, owner_id: ownerId, paused, diff --git a/typescript/contracts/cw-croncat-core/CwCroncatCore.types.ts b/typescript/contracts/cw-croncat-core/CwCroncatCore.types.ts index 84c73fea..bd117fdd 100644 --- a/typescript/contracts/cw-croncat-core/CwCroncatCore.types.ts +++ b/typescript/contracts/cw-croncat-core/CwCroncatCore.types.ts @@ -423,6 +423,8 @@ export type ExecuteMsg = { gas_action_fee?: Uint64 | null; gas_base_fee?: Uint64 | null; gas_fraction?: GasFraction | null; + gas_query_fee?: Uint64 | null; + gas_wasm_query_fee?: Uint64 | null; min_tasks_per_agent?: number | null; owner_id?: string | null; paused?: boolean | null; @@ -505,41 +507,11 @@ export interface Cw20ReceiveMsg { } export type GetAgentResponse = AgentResponse | null; export type GetAgentTasksResponse = TaskResponse | null; -export type RoundRobinBalancerModeResponse = "ActivationOrder" | "Equalizer"; -export interface GetStateResponse { - agent_active_queue: Addr[]; - agent_nomination_begin_time?: Timestamp | null; - agent_pending_queue: Addr[]; - agents: AgentResponse[]; - balancer_mode: RoundRobinBalancerModeResponse; - balances: BalancesResponse[]; - block_slots: SlotResponse[]; - block_slots_queries: SlotWithQueriesResponse[]; - config: GetConfigResponse; - reply_index: Uint64; - task_total: Uint64; - tasks: TaskResponse[]; - tasks_with_queries: TaskWithQueriesResponse[]; - tasks_with_queries_total: Uint64; - time_slots: SlotResponse[]; - time_slots_queries: SlotWithQueriesResponse[]; - [k: string]: unknown; -} -export interface BalancesResponse { - address: Addr; - balances: Cw20CoinVerified[]; - [k: string]: unknown; -} -export interface SlotResponse { - slot: Uint64; - tasks: number[][]; - [k: string]: unknown; -} -export interface SlotWithQueriesResponse { - slot: Uint64; - task_hash: number[]; - [k: string]: unknown; -} +export type GetTaskHashResponse = string; +export type GetTaskResponse = TaskResponse | null; +export type GetTasksByOwnerResponse = TaskResponse[]; +export type GetTasksResponse = TaskResponse[]; +export type GetTasksWithQueriesResponse = TaskWithQueriesResponse[]; export interface TaskWithQueriesResponse { boundary?: Boundary | null; interval: Interval; @@ -547,11 +519,6 @@ export interface TaskWithQueriesResponse { task_hash: string; [k: string]: unknown; } -export type GetTaskHashResponse = string; -export type GetTaskResponse = TaskResponse | null; -export type GetTasksByOwnerResponse = TaskResponse[]; -export type GetTasksResponse = TaskResponse[]; -export type GetTasksWithQueriesResponse = TaskWithQueriesResponse[]; export interface InstantiateMsg { agent_nomination_duration?: number | null; cw_rules_addr: string; @@ -559,6 +526,8 @@ export interface InstantiateMsg { gas_action_fee?: Uint64 | null; gas_base_fee?: Uint64 | null; gas_fraction?: GasFraction | null; + gas_query_fee?: Uint64 | null; + gas_wasm_query_fee?: Uint64 | null; owner_id?: string | null; [k: string]: unknown; } @@ -630,11 +599,5 @@ export type QueryMsg = { wallet: string; [k: string]: unknown; }; -} | { - get_state: { - from_index?: number | null; - limit?: number | null; - [k: string]: unknown; - }; }; export type ValidateIntervalResponse = boolean; \ No newline at end of file