From c1171ba3f208d4a7cac02a57863f02f8d79bce96 Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Fri, 14 Jan 2022 21:42:21 -0500 Subject: [PATCH 1/8] ran cargo check and clippy --- contracts/airdrop/src/contract.rs | 15 +++---- contracts/airdrop/src/handle.rs | 19 ++++---- contracts/airdrop/src/query.rs | 7 +-- contracts/airdrop/src/state.rs | 2 +- contracts/governance/src/handle.rs | 17 ++++--- contracts/governance/src/query.rs | 4 +- contracts/initializer/src/contract.rs | 4 +- contracts/micro_mint/src/handle.rs | 44 ++++++++---------- contracts/mint/src/contract.rs | 45 +++++++++---------- contracts/mock_band/src/contract.rs | 14 +++--- contracts/oracle/src/contract.rs | 3 +- contracts/oracle/src/handle.rs | 2 +- contracts/oracle/src/query.rs | 26 +++++------ contracts/oracle/src/state.rs | 1 - contracts/scrt_staking/src/contract.rs | 6 +-- contracts/scrt_staking/src/handle.rs | 16 +++---- contracts/staking/src/contract.rs | 2 +- contracts/treasury/src/query.rs | 22 +++++---- .../src/contract_helpers/governance.rs | 16 +++---- .../src/contract_helpers/initializer.rs | 10 +++-- .../src/contract_helpers/minter.rs | 10 ++--- .../src/contract_helpers/stake.rs | 5 +-- .../src/testnet_airdrop.rs | 6 +-- .../tests/testnet_integration.rs | 3 +- packages/secretcli/src/secretcli.rs | 2 +- packages/shade_protocol/src/oracle.rs | 2 +- 26 files changed, 145 insertions(+), 158 deletions(-) diff --git a/contracts/airdrop/src/contract.rs b/contracts/airdrop/src/contract.rs index c8b3658e0..2e5766d07 100644 --- a/contracts/airdrop/src/contract.rs +++ b/contracts/airdrop/src/contract.rs @@ -61,11 +61,8 @@ pub fn init( } let config = Config{ - admin: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } - }, - contract: env.contract.address.clone(), + admin: msg.admin.unwrap_or(env.message.sender), + contract: env.contract.address, dump_address: msg.dump_address, airdrop_snip20: msg.airdrop_token.clone(), airdrop_amount: msg.airdrop_amount, @@ -123,10 +120,10 @@ pub fn query( msg: QueryMsg, ) -> StdResult { match msg { - QueryMsg::Config { } => to_binary(&query::config(&deps)?), - QueryMsg::Dates { current_date } => to_binary(&query::dates(&deps, current_date)?), - QueryMsg::TotalClaimed {} => to_binary(&query::total_claimed(&deps)?), + QueryMsg::Config { } => to_binary(&query::config(deps)?), + QueryMsg::Dates { current_date } => to_binary(&query::dates(deps, current_date)?), + QueryMsg::TotalClaimed {} => to_binary(&query::total_claimed(deps)?), QueryMsg::Account { permit, current_date } => to_binary( - &query::account(&deps, permit, current_date)?), + &query::account(deps, permit, current_date)?), } } \ No newline at end of file diff --git a/contracts/airdrop/src/handle.rs b/contracts/airdrop/src/handle.rs index d10021b96..13950830a 100644 --- a/contracts/airdrop/src/handle.rs +++ b/contracts/airdrop/src/handle.rs @@ -6,6 +6,7 @@ use shade_protocol::{airdrop::{HandleAnswer, Config, claim_info::{RequiredTask}, generic_response::ResponseStatus}; use secret_toolkit::snip20::send_msg; +#[allow(clippy::too_many_arguments)] pub fn try_update_config( deps: &mut Extern, env: Env, @@ -136,7 +137,7 @@ pub fn try_create_account( let config = config_r(&deps.storage).load()?; // Check that airdrop hasn't ended - available(&config, &env)?; + available(&config, env)?; // Check that account doesnt exist let sender = env.message.sender.to_string(); @@ -162,7 +163,7 @@ pub fn try_create_account( // Claim the airdrop after account creation let (completed_percentage, unclaimed_percentage) = update_tasks(&mut deps.storage, - &config, sender.to_string())?; + &config, sender)?; let mut messages = vec![]; // Avoid calculating if theres nothing to claim if unclaimed_percentage > Uint128::zero() { @@ -241,7 +242,7 @@ pub fn try_update_account( Ok(claimed + new_redeem) } else { - return Err(StdError::generic_err("Account total claimed not set")) + Err(StdError::generic_err("Account total claimed not set")) } })?; @@ -304,7 +305,7 @@ pub fn try_complete_task( } } - return Ok(HandleResponse { + Ok(HandleResponse { messages: vec![], log: vec![], data: Some( to_binary( &HandleAnswer::Claim { @@ -319,8 +320,8 @@ pub fn try_claim( let config = config_r(&deps.storage).load()?; - // Check that airdrop hasnt ended - available(&config, &env)?; + // Check that airdrop hasn't ended + available(&config, env)?; // Get account let sender = env.message.sender.clone(); @@ -364,7 +365,7 @@ pub fn try_claim_decay( if env.block.time > end_date { decay_claimed_w(&mut deps.storage).update(| claimed | { if claimed { - return Err(StdError::generic_err("Decay already claimed")) + Err(StdError::generic_err("Decay already claimed")) } else { Ok(true) @@ -449,12 +450,12 @@ pub fn claim_tokens( } // Update redeem amount with the decay multiplier - redeem_amount = redeem_amount * decay_factor(env.block.time, &config); + redeem_amount = redeem_amount * decay_factor(env.block.time, config); Ok(claimed + redeem_amount) } else { - return Err(StdError::generic_err("Account total claimed not set")) + Err(StdError::generic_err("Account total claimed not set")) } })?; diff --git a/contracts/airdrop/src/query.rs b/contracts/airdrop/src/query.rs index 30a24f8e4..5c31086e6 100644 --- a/contracts/airdrop/src/query.rs +++ b/contracts/airdrop/src/query.rs @@ -19,10 +19,7 @@ pub fn dates start: config.start_date, end: config.end_date, decay_start: config.decay_start, - decay_factor: match current_date { - None => None, - Some(date) => Some(Uint128(100) * decay_factor(date, &config)) - } + decay_factor: current_date.map(|date| Uint128(100) * decay_factor(date, &config)) }) } @@ -48,7 +45,7 @@ pub fn account( let config = config_r(&deps.storage).load()?; - let account_address = validate_account_permit(&deps, &permit, config.contract)?; + let account_address = validate_account_permit(deps, &permit, config.contract)?; let account = account_r(&deps.storage).load(account_address.to_string().as_bytes())?; diff --git a/contracts/airdrop/src/state.rs b/contracts/airdrop/src/state.rs index bd68ec67a..af8dedae9 100644 --- a/contracts/airdrop/src/state.rs +++ b/contracts/airdrop/src/state.rs @@ -116,7 +116,7 @@ pub fn validate_address_permit( } // Authenticate permit - authenticate_ownership(&permit) + authenticate_ownership(permit) } pub fn validate_account_permit( diff --git a/contracts/governance/src/handle.rs b/contracts/governance/src/handle.rs index c075281d0..90d3bcc84 100644 --- a/contracts/governance/src/handle.rs +++ b/contracts/governance/src/handle.rs @@ -116,7 +116,7 @@ pub fn try_fund_proposal( proposal_id.to_string().as_bytes(), &ProposalStatus::Expired)?; // Send back amount - messages.push(send_msg(sender.clone(), + messages.push(send_msg(sender, amount, None, None, @@ -193,7 +193,7 @@ pub fn try_fund_proposal( None, 1, config.funding_token.code_hash, - config.funding_token.address.clone())?) + config.funding_token.address)?) } proposal_funding_w(&mut deps.storage).save( @@ -281,11 +281,11 @@ pub fn try_trigger_proposal( } // Check if proposal passed or has a valid target contract - if vote_status != ProposalStatus::Passed || target.is_none() { + if vote_status != ProposalStatus::Passed { run_status = Failure; } - else { - run_status = match try_execute_msg(target.unwrap(), proposal.msg) { + else if let Some(target) = target { + run_status = match try_execute_msg(target, proposal.msg) { Ok(msg) => { messages.push(msg); Success @@ -293,6 +293,9 @@ pub fn try_trigger_proposal( Err(_) => Failure, }; } + else { + run_status = Failure; + } // Overwrite proposal_run_status_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &run_status)?; @@ -479,7 +482,7 @@ pub fn try_create_proposal( description: String, ) -> StdResult { - let proposal_id = create_proposal(deps, &env, target_contract, proposal, description)?; + let proposal_id = create_proposal(deps, env, target_contract, proposal, description)?; Ok(HandleResponse { messages: vec![], @@ -491,7 +494,7 @@ pub fn try_create_proposal( }) } -#[warn(clippy::too_many_arguments)] +#[allow(clippy::too_many_arguments)] pub fn try_update_config( deps: &mut Extern, env: &Env, diff --git a/contracts/governance/src/query.rs b/contracts/governance/src/query.rs index b2d3344de..574ab5f12 100644 --- a/contracts/governance/src/query.rs +++ b/contracts/governance/src/query.rs @@ -48,7 +48,7 @@ pub fn proposals( let clamped_start = start.max(Uint128(1)); for i in clamped_start.u128()..((end +clamped_start).min(max).u128() + 1) { - let proposal = build_proposal(&deps, Uint128(i))?; + let proposal = build_proposal(deps, Uint128(i))?; // Filter proposal by status if it was specified in fn params. if let Some(s) = &status { @@ -67,7 +67,7 @@ pub fn proposal( proposal_id: Uint128) -> StdResult { Ok(QueryAnswer::Proposal { - proposal: build_proposal(&deps, proposal_id)? + proposal: build_proposal(deps, proposal_id)? }) } diff --git a/contracts/initializer/src/contract.rs b/contracts/initializer/src/contract.rs index 659a8b8b1..e8b12438f 100644 --- a/contracts/initializer/src/contract.rs +++ b/contracts/initializer/src/contract.rs @@ -58,7 +58,7 @@ pub fn init( decimals: 6, initial_balances: msg.shade.initial_balances.clone(), prng_seed: msg.shade.prng_seed, - config: coin_config.clone() + config: coin_config }; state.contracts.push(Snip20InitHistory{ label: msg.shade.label.clone(), @@ -82,7 +82,7 @@ pub fn handle( _env: Env, _msg: HandleMsg, ) -> StdResult { - return Ok(HandleResponse { + Ok(HandleResponse { messages: vec![], log: vec![], data: None diff --git a/contracts/micro_mint/src/handle.rs b/contracts/micro_mint/src/handle.rs index b8faac85f..8e5ff7499 100644 --- a/contracts/micro_mint/src/handle.rs +++ b/contracts/micro_mint/src/handle.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::convert::TryFrom; use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, Querier, StdError, StdResult, Storage, CosmosMsg, HumanAddr, Uint128, from_binary}; use secret_toolkit::{ @@ -73,7 +74,7 @@ pub fn try_burn( // This will calculate the total mint value - let amount_to_mint: Uint128 = mint_amount(&deps, amount, &burn_asset, &mint_asset)?; + let amount_to_mint: Uint128 = mint_amount(deps, amount, &burn_asset, &mint_asset)?; let mut messages = vec![]; let msgs: MintMsgHook = match msg { @@ -161,7 +162,7 @@ pub fn try_burn( let mint_asset = native_asset_r(&deps.storage).load()?; // This will calculate the total mint value - let amount_to_mint: Uint128 = mint_amount(&deps, amount, &burn_asset, &mint_asset)?; + let amount_to_mint: Uint128 = mint_amount(deps, amount, &burn_asset, &mint_asset)?; // Check against slippage amount if amount_to_mint < msgs.minimum_expected_amount { @@ -198,7 +199,7 @@ pub fn try_burn( None, 256, mint_asset.contract.code_hash.clone(), - mint_asset.contract.address.clone())?); + mint_asset.contract.address)?); Ok(HandleResponse { messages, @@ -336,7 +337,7 @@ pub fn try_register_asset( }; debug_print!("Registering {}", asset_info.symbol); - assets.save(&contract_str.as_bytes(), &SupportedAsset { + assets.save(contract_str.as_bytes(), &SupportedAsset { asset: Snip20Asset { contract: contract.clone(), token_info: asset_info, @@ -349,7 +350,7 @@ pub fn try_register_asset( } })?; - total_burned_w(&mut deps.storage).save(&contract_str.as_bytes(), &Uint128(0))?; + total_burned_w(&mut deps.storage).save(contract_str.as_bytes(), &Uint128(0))?; // Add the asset to list asset_list_w(&mut deps.storage).update(|mut state| { @@ -358,8 +359,7 @@ pub fn try_register_asset( })?; // Register contract in asset - let mut messages = vec![]; - messages.push(register_receive(env, contract)?); + let messages = vec![register_receive(env, contract)?]; Ok(HandleResponse { messages, @@ -387,7 +387,7 @@ pub fn try_remove_asset( })?; // Remove supported asset - assets_w(&mut deps.storage).remove(&address_str.as_bytes()); + assets_w(&mut deps.storage).remove(address_str.as_bytes()); // We wont remove the total burned since we want to keep track of all the burned assets @@ -405,15 +405,13 @@ pub fn register_receive ( env: &Env, contract: &Contract, ) -> StdResult { - let cosmos_msg = register_receive_msg( + register_receive_msg( env.contract_code_hash.clone(), None, 256, contract.code_hash.clone(), contract.address.clone(), - ); - - cosmos_msg + ) } pub fn mint_amount( @@ -429,10 +427,10 @@ pub fn mint_amount( burn_asset.asset.token_info.symbol, mint_asset.token_info.symbol); - let burn_price = oracle(&deps, &burn_asset.asset.token_info.symbol)?; + let burn_price = oracle(deps, burn_asset.asset.token_info.symbol.clone())?; debug_print!("Burn Price: {}", burn_price); - let mint_price = oracle(&deps, &asset_peg_r(&deps.storage).load()?)?; + let mint_price = oracle(deps, asset_peg_r(&deps.storage).load()?)?; debug_print!("Mint Price: {}", mint_price); Ok(calculate_mint(burn_price, burn_amount, burn_asset.asset.token_info.decimals, @@ -462,14 +460,10 @@ pub fn calculate_mint(burn_price: Uint128, burn_amount: Uint128, burn_decimals: let difference: i32 = mint_decimals as i32 - burn_decimals as i32; // To avoid a mess of different types doing math - if difference < 0 { - burn_value.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())) - } - else if difference > 0 { - Uint128(burn_value.u128() * 10u128.pow(u32::try_from(difference).unwrap())) - } - else { - burn_value + match difference.cmp(&0) { + Ordering::Greater => Uint128(burn_value.u128() * 10u128.pow(u32::try_from(difference).unwrap())), + Ordering::Less => burn_value.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())), + Ordering::Equal => burn_value } } @@ -482,17 +476,17 @@ pub fn calculate_capture( * capture_amount = amount * capture / 10000 */ - return amount.multiply_ratio(capture, 10000u128); + amount.multiply_ratio(capture, 10000u128) } fn oracle( deps: &Extern, - symbol: &String, + symbol: String, ) -> StdResult { let config: Config = config_r(&deps.storage).load()?; let answer: ReferenceData = Price { - symbol: symbol.to_string() + symbol }.query(&deps.querier, config.oracle.code_hash, config.oracle.address)?; diff --git a/contracts/mint/src/contract.rs b/contracts/mint/src/contract.rs index e981406f2..eaa08a60a 100644 --- a/contracts/mint/src/contract.rs +++ b/contracts/mint/src/contract.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdError, StdResult, Storage, CosmosMsg, HumanAddr, Uint128, from_binary}; use crate::state::{config, config_read, assets_w, assets_r, asset_list, asset_list_read}; use secret_toolkit::{ @@ -168,22 +169,18 @@ pub fn try_register_asset( Some(x) => x, }, contract, - burnable: match burnable { - None => false, - Some(x) => x - }, + burnable: burnable.unwrap_or(false), total_burned: match total_burned { None => Uint128(0), Some(amount) => amount, } }; - if !authorized(deps, &env, AllowedAccess::Admin)? { + if !authorized(deps, env, AllowedAccess::Admin)? { return Err(StdError::Unauthorized { backtrace: None }); } - let mut messages = vec![]; - messages.push(save_asset(deps, env, asset)?); + let messages = vec![save_asset(deps, env, asset)?]; Ok(HandleResponse { messages, @@ -233,8 +230,8 @@ pub fn try_burn( } // Query prices - let in_price = call_oracle(&deps, burning_asset.name)?; - let target_price = call_oracle(&deps, minting_asset.name)?; + let in_price = call_oracle(deps, burning_asset.name)?; + let target_price = call_oracle(deps, minting_asset.name)?; // Get asset decimals // Load the decimal information for both coins @@ -308,25 +305,31 @@ fn authorized( return Ok(false) } } - return Ok(true) + Ok(true) } fn register_receive ( env: &Env, contract: Contract ) -> StdResult { - let cosmos_msg = register_receive_msg( + + register_receive_msg( env.contract_code_hash.clone(), None, 256, contract.code_hash, contract.address, - ); - - cosmos_msg + ) } -fn calculate_mint(in_price: Uint128, target_price: Uint128, in_amount: Uint128, in_decimals: u32, target_decimals: u32) -> Uint128 { +fn calculate_mint( + in_price: Uint128, + target_price: Uint128, + in_amount: Uint128, + in_decimals: u32, + target_decimals: u32 +) -> Uint128 { + // Math must only be made in integers // in_decimals = x // target_decimals = y @@ -347,14 +350,10 @@ fn calculate_mint(in_price: Uint128, target_price: Uint128, in_amount: Uint128, let difference: i32 = target_decimals as i32 - in_decimals as i32; // To avoid a mess of different types doing math - if difference < 0 { - in_total.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())) - } - else if difference > 0 { - Uint128(in_total.u128() * 10u128.pow(u32::try_from(difference).unwrap())) - } - else { - in_total + match difference.cmp(&0) { + Ordering::Greater => Uint128(in_total.u128() * 10u128.pow(u32::try_from(difference).unwrap())), + Ordering::Less => in_total.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())), + Ordering::Equal => in_total } } diff --git a/contracts/mock_band/src/contract.rs b/contracts/mock_band/src/contract.rs index fa797de81..422106f3b 100644 --- a/contracts/mock_band/src/contract.rs +++ b/contracts/mock_band/src/contract.rs @@ -43,11 +43,11 @@ pub fn handle( deps: &mut Extern, _env: Env, msg: HandleMsg, -) -> StdResult { - match msg { +) -> StdResult { + return match msg { HandleMsg::MockPrice { symbol, price } => { - price_w(&mut deps.storage).save(&symbol.as_bytes(), &price)?; - return Ok(HandleResponse::default()) + price_w(&mut deps.storage).save(symbol.as_bytes(), &price)?; + Ok(HandleResponse::default()) } } } @@ -73,14 +73,14 @@ pub fn query( base_symbol, quote_symbol: _ } => { - if let Some(price) = price_r(&deps.storage).may_load(&base_symbol.as_bytes())? { + if let Some(price) = price_r(&deps.storage).may_load(base_symbol.as_bytes())? { return to_binary(&ReferenceData { rate: price, last_updated_base: 0, last_updated_quote: 0 }) } - return Err(StdError::GenericErr { msg: "Missing Price Feed".to_string(), backtrace: None}) + Err(StdError::generic_err("Missing Price Feed")) }, QueryMsg::GetReferenceDataBulk { base_symbols, @@ -89,7 +89,7 @@ pub fn query( let mut results = Vec::new(); for sym in base_symbols { - if let Some(price) = price_r(&deps.storage).may_load(&sym.as_bytes())? { + if let Some(price) = price_r(&deps.storage).may_load(sym.as_bytes())? { results.push(ReferenceData { rate: price, last_updated_base: 0, diff --git a/contracts/oracle/src/contract.rs b/contracts/oracle/src/contract.rs index 1ef5ce5df..ef886e19e 100644 --- a/contracts/oracle/src/contract.rs +++ b/contracts/oracle/src/contract.rs @@ -1,14 +1,13 @@ use cosmwasm_std::{ debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, - Querier, StdResult, Storage, Uint128, + Querier, StdResult, Storage, }; use shade_protocol::{ oracle::{ InitMsg, HandleMsg, QueryMsg, OracleConfig, }, - band::ReferenceData, }; use crate::{ state::{ config_w }, diff --git a/contracts/oracle/src/handle.rs b/contracts/oracle/src/handle.rs index 5c35115cf..fd4a7dc2a 100644 --- a/contracts/oracle/src/handle.rs +++ b/contracts/oracle/src/handle.rs @@ -143,7 +143,7 @@ pub fn register_index( return Err(StdError::Unauthorized { backtrace: None }); } - match sswap_pairs_r(&deps.storage).may_load(&symbol.as_bytes())? { + match sswap_pairs_r(&deps.storage).may_load(symbol.as_bytes())? { None => { } Some(_) => { return Err(StdError::GenericErr { diff --git a/contracts/oracle/src/query.rs b/contracts/oracle/src/query.rs index 533f5004b..adad6d9cc 100644 --- a/contracts/oracle/src/query.rs +++ b/contracts/oracle/src/query.rs @@ -51,7 +51,7 @@ pub fn price( // Index if let Some(index) = index_r(&deps.storage).may_load(symbol.as_bytes())? { return Ok(ReferenceData { - rate: eval_index(&deps, &symbol, index)?, + rate: eval_index(deps, &symbol, index)?, last_updated_base: 0, last_updated_quote: 0, }) @@ -73,12 +73,12 @@ pub fn prices( for (i, sym) in symbols.iter().enumerate() { if let Some(sswap_pair) = sswap_pairs_r(&deps.storage).may_load(sym.as_bytes())? { - results[i] = sswap_price(&deps, sswap_pair)?.rate; + results[i] = sswap_price(deps, sswap_pair)?.rate; } else if let Some(index) = index_r(&deps.storage).may_load(sym.as_bytes())? { - results[i] = eval_index(&deps, sym, index)?; + results[i] = eval_index(deps, sym, index)?; } else { @@ -99,7 +99,7 @@ pub fn prices( pub fn eval_index( deps: &Extern, - symbol: &String, + symbol: &str, index: Vec, ) -> StdResult { @@ -112,10 +112,10 @@ pub fn eval_index( for element in index { - weight_total = weight_total + element.weight; + weight_total += element.weight; if let Some(sswap_pair) = sswap_pairs_r(&deps.storage).may_load(symbol.as_bytes())? { - price += sswap_price(&deps, sswap_pair)?.rate.multiply_ratio(element.weight, 10u128.pow(18)); + price += sswap_price(deps, sswap_pair)?.rate.multiply_ratio(element.weight, 10u128.pow(18)); } else { band_weights.push(element.weight); @@ -166,13 +166,13 @@ pub fn sswap_price( sswap_pair: SswapPair, ) -> StdResult { - let trade_price = sswap_simulate(&deps, sswap_pair)?; + let trade_price = sswap_simulate(deps, sswap_pair)?; let scrt_result = reference_data(deps, "SCRT".to_string(), "USD".to_string())?; //return Err(StdError::NotFound { kind: translate_price(scrt_result.rate, trade_price).to_string(), backtrace: None }); - return Ok(ReferenceData { + Ok(ReferenceData { // SCRT-USD / SCRT-symbol rate: translate_price(scrt_result.rate, trade_price), last_updated_base: 0, @@ -204,7 +204,7 @@ pub fn sswap_simulate( sswap_pair.pair.address, )?; - return Ok(normalize_price(response.return_amount, sswap_pair.asset.token_info.decimals)); + Ok(normalize_price(response.return_amount, sswap_pair.asset.token_info.decimals)) } // BAND interactions @@ -217,14 +217,14 @@ pub fn reference_data( let config_r = config_r(&deps.storage).load()?; - Ok(BandQuery::GetReferenceData { + BandQuery::GetReferenceData { base_symbol, quote_symbol, }.query( &deps.querier, config_r.band.code_hash, config_r.band.address, - )?) + ) } pub fn reference_data_bulk( @@ -235,12 +235,12 @@ pub fn reference_data_bulk( let config_r = config_r(&deps.storage).load()?; - Ok(BandQuery::GetReferenceDataBulk { + BandQuery::GetReferenceDataBulk { base_symbols, quote_symbols, }.query( &deps.querier, config_r.band.code_hash, config_r.band.address, - )?) + ) } diff --git a/contracts/oracle/src/state.rs b/contracts/oracle/src/state.rs index d288269b5..923e55737 100644 --- a/contracts/oracle/src/state.rs +++ b/contracts/oracle/src/state.rs @@ -13,7 +13,6 @@ use shade_protocol::{ SswapPair, IndexElement, }, - band::ReferenceData, }; pub static CONFIG_KEY: &[u8] = b"config"; diff --git a/contracts/scrt_staking/src/contract.rs b/contracts/scrt_staking/src/contract.rs index 824f78114..6c1d55a38 100644 --- a/contracts/scrt_staking/src/contract.rs +++ b/contracts/scrt_staking/src/contract.rs @@ -62,11 +62,11 @@ pub fn init( config.sscrt.address.clone(), )?, register_receive_msg( - env.contract_code_hash.clone(), + env.contract_code_hash, None, 256, - config.sscrt.code_hash.clone(), - config.sscrt.address.clone(), + config.sscrt.code_hash, + config.sscrt.address, )?, ], log: vec![] diff --git a/contracts/scrt_staking/src/handle.rs b/contracts/scrt_staking/src/handle.rs index d4bdf91bb..6992e1db0 100644 --- a/contracts/scrt_staking/src/handle.rs +++ b/contracts/scrt_staking/src/handle.rs @@ -56,11 +56,11 @@ pub fn receive( None, 256, config.sscrt.code_hash.clone(), - config.sscrt.address.clone(), + config.sscrt.address, )? ); - let validator = choose_validator(&deps, env.block.time)?; + let validator = choose_validator(deps, env.block.time)?; messages.push(CosmosMsg::Staking(StakingMsg::Delegate { validator: validator.address.clone(), @@ -71,7 +71,7 @@ pub fn receive( })); Ok(HandleResponse { - messages: messages, + messages, log: vec![], data: Some( to_binary( &HandleAnswer::Receive { @@ -125,15 +125,13 @@ pub fn unbond( if let Some(delegation) = deps.querier.query_delegation(env.contract.address, validator.clone())? { - let mut messages: Vec = vec![]; - - messages.push(CosmosMsg::Staking(StakingMsg::Undelegate { + let messages: Vec = vec![CosmosMsg::Staking(StakingMsg::Undelegate { validator, amount: delegation.amount.clone(), - })); + })]; return Ok(HandleResponse { - messages: messages, + messages, log: vec![], data: Some( to_binary( &HandleAnswer::Unbond { @@ -199,7 +197,7 @@ pub fn choose_validator( validators = candidates; } - if validators.len() == 0 { + if validators.is_empty() { return Err(StdError::GenericErr { msg: "No validators within bounds".to_string(), backtrace: None diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 73d19040f..011ac497a 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -36,7 +36,7 @@ pub fn init( let cosmos_msg = register_receive_msg( env.contract_code_hash, None, 256, state.staked_token.code_hash.clone(), - state.staked_token.address.clone())?; + state.staked_token.address)?; // Initialize binary heap let unbonding_heap = BinaryHeap::new_min(); diff --git a/contracts/treasury/src/query.rs b/contracts/treasury/src/query.rs index a0201344d..74a83c0cf 100644 --- a/contracts/treasury/src/query.rs +++ b/contracts/treasury/src/query.rs @@ -30,22 +30,20 @@ pub fn balance( //TODO: restrict to admin - match assets_r(&deps.storage).may_load(&contract.to_string().as_bytes())? { + return match assets_r(&deps.storage).may_load(contract.to_string().as_bytes())? { Some(a) => { - return Ok(snip20::QueryMsg::Balance { - address: self_address_r(&deps.storage).load()?, + Ok(snip20::QueryMsg::Balance { + address: self_address_r(&deps.storage).load()?, key: viewing_key_r(&deps.storage).load()?, }.query( - &deps.querier, - 1, - a.contract.code_hash, - contract.clone(), - )?) + &deps.querier, + 1, + a.contract.code_hash, + contract, + )?) } - None => { - return Err(StdError::NotFound { - kind: contract.to_string(), - backtrace: None }) + None => { + Err(StdError::not_found(contract.to_string())) } }; diff --git a/packages/network_integration/src/contract_helpers/governance.rs b/packages/network_integration/src/contract_helpers/governance.rs index 9eca22bf2..06073043b 100644 --- a/packages/network_integration/src/contract_helpers/governance.rs +++ b/packages/network_integration/src/contract_helpers/governance.rs @@ -11,7 +11,7 @@ use secretcli::{cli_types::NetContract, secretcli::{query_contract, test_contrac pub fn init_contract( governance: &NetContract, contract_name: String, contract_path: &str, contract_init: Init) -> Result { - print_header(&format!("{}{}", "Initializing ", contract_name.clone())); + print_header(&format!("{}{}", "Initializing ", contract_name)); let contract = test_inst_init(&contract_init, contract_path, &*generate_label(8), ACCOUNT_KEY, @@ -20,7 +20,7 @@ pub fn init_contract( print_contract(&contract); - add_contract(contract_name, &contract, &governance)?; + add_contract(contract_name, &contract, governance)?; Ok(contract) } @@ -29,7 +29,7 @@ pub fn get_contract(governance: &NetContract, target: String) -> Result Result Result<()>{ - print_warning(&format!("{}{}", "Adding ", name.clone())); + print_warning(&format!("{}{}", "Adding ", name)); let msg = governance::HandleMsg::AddSupportedContract { name: name.clone(), @@ -78,13 +78,13 @@ pub fn create_and_trigger_proposal( governance: &NetContract, target: String, handle: Handle, desc: Option<&str>) -> Result { create_proposal(governance, target, handle, desc)?; - Ok(trigger_latest_proposal(governance)?) + trigger_latest_proposal(governance) } pub fn get_latest_proposal(governance: &NetContract) -> Result { let query_msg = governance::QueryMsg::GetTotalProposals {}; - let query: governance::QueryAnswer = query_contract(&governance, &query_msg)?; + let query: governance::QueryAnswer = query_contract(governance, &query_msg)?; let mut proposals = Uint128(1); @@ -114,7 +114,7 @@ pub fn create_proposal( //let proposals = get_latest_proposal(governance)?; - test_contract_handle(&proposal_msg, &governance, ACCOUNT_KEY, Some(GAS), + test_contract_handle(&proposal_msg, governance, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; //assert_eq!(proposals, get_latest_proposal(governance)?); @@ -128,7 +128,7 @@ pub fn trigger_latest_proposal(governance: &NetContract) -> Result { let handle_msg = governance::HandleMsg::TriggerProposal { proposal_id: proposals }; - test_contract_handle(&handle_msg, &governance, ACCOUNT_KEY, Some(GAS), + test_contract_handle(&handle_msg, governance, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; Ok(proposals) diff --git a/packages/network_integration/src/contract_helpers/initializer.rs b/packages/network_integration/src/contract_helpers/initializer.rs index 9d872c369..445658150 100644 --- a/packages/network_integration/src/contract_helpers/initializer.rs +++ b/packages/network_integration/src/contract_helpers/initializer.rs @@ -9,7 +9,11 @@ use secretcli::{cli_types::NetContract, secretcli::{test_contract_handle, test_inst_init, list_contracts_by_code}}; pub fn initialize_initializer( - admin: &String, sscrt: &NetContract, account: &String) -> Result<(NetContract, NetContract, NetContract)> { + admin: String, + sscrt: &NetContract, + account: String +) -> Result<(NetContract, NetContract, NetContract)> { + print_header("Initializing Initializer"); let mut shade = NetContract { label: generate_label(8), @@ -37,7 +41,7 @@ pub fn initialize_initializer( }, silk: Snip20ContractInfo { label: silk.label.clone(), - admin: Some(HumanAddr::from(admin.clone())), + admin: Some(HumanAddr::from(admin)), prng_seed: Default::default(), initial_balances: None } @@ -88,7 +92,7 @@ pub fn initialize_initializer( Some("test"), None)?; } - println!("\tTotal silk: {}", get_balance(&silk, account.clone())); + println!("\tTotal silk: {}", get_balance(&silk, account)); Ok((initializer, shade, silk)) } diff --git a/packages/network_integration/src/contract_helpers/minter.rs b/packages/network_integration/src/contract_helpers/minter.rs index 31c8bf5c2..7f827dc95 100644 --- a/packages/network_integration/src/contract_helpers/minter.rs +++ b/packages/network_integration/src/contract_helpers/minter.rs @@ -34,25 +34,25 @@ pub fn initialize_minter(governance: &NetContract, contract_name: String, pub fn setup_minters(governance: &NetContract, mint_shade: &NetContract, mint_silk: &NetContract, shade: &Contract, silk: &Contract, sscrt: &NetContract) -> Result<()> { print_header("Registering allowed tokens in mint contracts"); - create_and_trigger_proposal(&governance, "shade_minter".to_string(), + create_and_trigger_proposal(governance, "shade_minter".to_string(), micro_mint::HandleMsg::RegisterAsset { contract: Contract { address: HumanAddr::from(sscrt.address.clone()), code_hash: sscrt.code_hash.clone() }, capture: Some(Uint128(1000))}, Some("Register asset"))?; - create_and_trigger_proposal(&governance, "shade_minter".to_string(), + create_and_trigger_proposal(governance, "shade_minter".to_string(), micro_mint::HandleMsg::RegisterAsset { contract: silk.clone(), capture: Some(Uint128(1000))}, Some("Register asset"))?; - create_and_trigger_proposal(&governance, "silk_minter".to_string(), + create_and_trigger_proposal(governance, "silk_minter".to_string(), micro_mint::HandleMsg::RegisterAsset { contract: shade.clone(), capture: Some(Uint128(1000))}, Some("Register asset"))?; print_header("Adding allowed minters in Snip20s"); - create_and_trigger_proposal(&governance, "shade".to_string(), + create_and_trigger_proposal(governance, "shade".to_string(), snip20::HandleMsg::SetMinters { minters: vec![HumanAddr::from(mint_shade.address.clone())], padding: None }, Some("Set minters"))?; @@ -72,7 +72,7 @@ pub fn setup_minters(governance: &NetContract, mint_shade: &NetContract, mint_si } } - create_and_trigger_proposal(&governance, "silk".to_string(), + create_and_trigger_proposal(governance, "silk".to_string(), snip20::HandleMsg::SetMinters { minters: vec![HumanAddr::from(mint_silk.address.clone())], padding: None }, Some("Set minters"))?; diff --git a/packages/network_integration/src/contract_helpers/stake.rs b/packages/network_integration/src/contract_helpers/stake.rs index d63b11d13..f1ebd8d69 100644 --- a/packages/network_integration/src/contract_helpers/stake.rs +++ b/packages/network_integration/src/contract_helpers/stake.rs @@ -12,7 +12,7 @@ use std::time::UNIX_EPOCH; pub fn setup_staker(governance: &NetContract, shade: &Contract, staking_account: String) -> Result { - let staker = init_contract(&governance, "staking".to_string(), + let staker = init_contract(governance, "staking".to_string(), STAKING_FILE, staking::InitMsg{ admin: Some(Contract{ @@ -127,8 +127,7 @@ pub fn setup_staker(governance: &NetContract, shade: &Contract, } // Query total Shade now - assert_eq!((balance_after_stake + unbond_amount), get_balance(&shade_net, - staking_account.clone())); + assert_eq!((balance_after_stake + unbond_amount), get_balance(&shade_net, staking_account)); Ok(staker) } diff --git a/packages/network_integration/src/testnet_airdrop.rs b/packages/network_integration/src/testnet_airdrop.rs index 211a09a92..cab9b43a9 100644 --- a/packages/network_integration/src/testnet_airdrop.rs +++ b/packages/network_integration/src/testnet_airdrop.rs @@ -2,7 +2,7 @@ use std::fs; use std::env; use serde_json::Result; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Binary, to_binary, Uint128, HumanAddr}; +use cosmwasm_std::{Binary, Uint128, HumanAddr}; use rs_merkle::{algorithms::Sha256, Hasher, MerkleTree}; use network_integration::utils::{AIRDROP_FILE, GAS, generate_label, print_contract, print_header, SNIP20_FILE, STORE_GAS}; use secretcli::secretcli::{account_address, test_contract_handle, test_inst_init}; @@ -107,7 +107,7 @@ fn main() -> Result<()> { max_amount: args.max_amount, default_claim: Uint128(20), task_claim: vec![RequiredTask { - address: HumanAddr::from(account_addr.clone()), + address: HumanAddr::from(account_addr), percent: Uint128(50) }], query_rounding: Uint128(10000000000) }; @@ -120,7 +120,7 @@ fn main() -> Result<()> { print_header("Funding airdrop"); test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(airdrop.address.clone()), + recipient: HumanAddr::from(airdrop.address), amount: args.initial_amount, msg: None, memo: None, diff --git a/packages/network_integration/tests/testnet_integration.rs b/packages/network_integration/tests/testnet_integration.rs index b7222c75b..6ad4e557d 100644 --- a/packages/network_integration/tests/testnet_integration.rs +++ b/packages/network_integration/tests/testnet_integration.rs @@ -155,7 +155,6 @@ fn run_airdrop() -> Result<()> { }, airdrop_amount: total_airdrop+decay_amount, start_date: None, - // Add one more minute for testing decay end_date: Some(end_date), decay_start: Some(decay_date), merkle_root: Binary(merlke_tree.root().unwrap().to_vec()), @@ -468,7 +467,7 @@ fn run_testnet() -> Result<()> { } // Initialize initializer and snip20s - let (initializer, shade, silk) = initialize_initializer(&account, &s_sCRT, &account)?; + let (initializer, shade, silk) = initialize_initializer(account.clone(), &s_sCRT, account.clone())?; // Initialize Governance print_header("Initializing Governance"); diff --git a/packages/secretcli/src/secretcli.rs b/packages/secretcli/src/secretcli.rs index fdcc6b590..254d16cc9 100644 --- a/packages/secretcli/src/secretcli.rs +++ b/packages/secretcli/src/secretcli.rs @@ -26,7 +26,7 @@ fn vec_str_to_vec_string (str_in: Vec<&str>) -> Vec { /// pub fn secretcli_run(command: Vec) -> Result { let retry = 20; - let mut commands = command.clone(); + let mut commands = command; commands.append(&mut vec_str_to_vec_string(vec!["--output", "json"])); let mut cli = Command::new("secretd".to_string()); if commands.len() > 0 { diff --git a/packages/shade_protocol/src/oracle.rs b/packages/shade_protocol/src/oracle.rs index ad7eec19c..b1d34ed2e 100644 --- a/packages/shade_protocol/src/oracle.rs +++ b/packages/shade_protocol/src/oracle.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{HumanAddr, Decimal, Uint128}; +use cosmwasm_std::{HumanAddr, Uint128}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use secret_toolkit::utils::{InitCallback, HandleCallback, Query}; From 94d27ca11f29686aa1f91a8f1b41603674448b17 Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Fri, 14 Jan 2022 21:54:24 -0500 Subject: [PATCH 2/8] formatted --- contracts/airdrop/src/contract.rs | 124 +-- contracts/airdrop/src/handle.rs | 367 +++++---- contracts/airdrop/src/lib.rs | 9 +- contracts/airdrop/src/query.rs | 72 +- contracts/airdrop/src/state.rs | 83 ++- contracts/airdrop/src/test.rs | 81 +- contracts/governance/src/contract.rs | 166 +++-- contracts/governance/src/handle.rs | 445 ++++++----- contracts/governance/src/lib.rs | 11 +- contracts/governance/src/proposal_state.rs | 49 +- contracts/governance/src/query.rs | 104 ++- contracts/governance/src/state.rs | 20 +- contracts/governance/src/test.rs | 123 +-- contracts/initializer/src/contract.rs | 68 +- contracts/initializer/src/lib.rs | 9 +- contracts/initializer/src/query.rs | 12 +- contracts/micro_mint/src/contract.rs | 74 +- contracts/micro_mint/src/handle.rs | 322 ++++---- contracts/micro_mint/src/lib.rs | 9 +- contracts/micro_mint/src/query.rs | 74 +- contracts/micro_mint/src/state.rs | 17 +- contracts/micro_mint/src/test.rs | 82 +- contracts/mint/src/contract.rs | 313 +++++--- contracts/mint/src/lib.rs | 7 +- contracts/mint/src/state.rs | 19 +- contracts/mock_band/src/contract.rs | 65 +- contracts/mock_band/src/lib.rs | 7 +- contracts/oracle/src/contract.rs | 53 +- contracts/oracle/src/handle.rs | 105 ++- contracts/oracle/src/lib.rs | 9 +- contracts/oracle/src/query.rs | 115 ++- contracts/oracle/src/state.rs | 24 +- contracts/oracle/src/test.rs | 20 +- contracts/scrt_staking/src/contract.rs | 60 +- contracts/scrt_staking/src/handle.rs | 128 ++-- contracts/scrt_staking/src/lib.rs | 9 +- contracts/scrt_staking/src/query.rs | 31 +- contracts/scrt_staking/src/state.rs | 7 +- contracts/staking/src/contract.rs | 91 ++- contracts/staking/src/handle.rs | 163 ++-- contracts/staking/src/lib.rs | 9 +- contracts/staking/src/query.rs | 41 +- contracts/staking/src/state.rs | 36 +- contracts/staking/src/test.rs | 40 +- contracts/treasury/src/contract.rs | 49 +- contracts/treasury/src/handle.rs | 87 +-- contracts/treasury/src/lib.rs | 9 +- contracts/treasury/src/query.rs | 52 +- contracts/treasury/src/state.rs | 16 +- .../src/contract_helpers/governance.rs | 111 ++- .../src/contract_helpers/initializer.rs | 77 +- .../src/contract_helpers/minter.rs | 184 +++-- .../src/contract_helpers/mod.rs | 4 +- .../src/contract_helpers/stake.rs | 157 ++-- packages/network_integration/src/lib.rs | 2 +- .../src/testnet_airdrop.rs | 107 ++- packages/network_integration/src/utils.rs | 27 +- .../tests/testnet_integration.rs | 703 ++++++++++++------ packages/secretcli/src/cli_types.rs | 22 +- packages/secretcli/src/lib.rs | 2 +- packages/secretcli/src/secretcli.rs | 240 ++++-- .../shade_protocol/src/airdrop/account.rs | 12 +- .../shade_protocol/src/airdrop/claim_info.rs | 4 +- packages/shade_protocol/src/airdrop/mod.rs | 64 +- packages/shade_protocol/src/asset.rs | 2 +- packages/shade_protocol/src/band.rs | 11 +- .../shade_protocol/src/generic_response.rs | 2 +- packages/shade_protocol/src/governance/mod.rs | 125 +++- .../shade_protocol/src/governance/proposal.rs | 6 +- .../shade_protocol/src/governance/vote.rs | 4 +- packages/shade_protocol/src/initializer.rs | 15 +- packages/shade_protocol/src/lib.rs | 12 +- packages/shade_protocol/src/math.rs | 6 +- packages/shade_protocol/src/micro_mint.rs | 65 +- packages/shade_protocol/src/mint.rs | 39 +- packages/shade_protocol/src/oracle.rs | 19 +- packages/shade_protocol/src/scrt_staking.rs | 36 +- packages/shade_protocol/src/secretswap.rs | 12 +- packages/shade_protocol/src/snip20.rs | 29 +- packages/shade_protocol/src/staking/mod.rs | 60 +- packages/shade_protocol/src/staking/stake.rs | 8 +- packages/shade_protocol/src/treasury.rs | 45 +- 82 files changed, 3654 insertions(+), 2444 deletions(-) diff --git a/contracts/airdrop/src/contract.rs b/contracts/airdrop/src/contract.rs index 2e5766d07..aa0c87672 100644 --- a/contracts/airdrop/src/contract.rs +++ b/contracts/airdrop/src/contract.rs @@ -1,15 +1,32 @@ -use cosmwasm_std::{to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdResult, Storage, Uint128, StdError}; -use shade_protocol::{ - airdrop::{ - InitMsg, HandleMsg, - QueryMsg, Config, claim_info::RequiredTask - } +use crate::{ + handle::{ + try_add_tasks, + try_claim, + try_claim_decay, + try_complete_task, + try_create_account, + try_disable_permit_key, + try_update_account, + try_update_config, + }, + query, + state::{config_w, decay_claimed_w, total_claimed_w}, +}; +use cosmwasm_std::{ + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdError, + StdResult, + Storage, + Uint128, }; -use crate::{state::{config_w, total_claimed_w}, - handle::{try_update_config, try_add_tasks, try_complete_task, try_create_account, - try_update_account, try_disable_permit_key, try_claim, try_claim_decay}, - query }; -use crate::state::decay_claimed_w; +use shade_protocol::airdrop::{claim_info::RequiredTask, Config, HandleMsg, InitMsg, QueryMsg}; pub fn init( deps: &mut Extern, @@ -17,9 +34,9 @@ pub fn init( msg: InitMsg, ) -> StdResult { // Setup task claim - let mut task_claim= vec![RequiredTask { + let mut task_claim = vec![RequiredTask { address: env.contract.address.clone(), - percent: msg.default_claim + percent: msg.default_claim, }]; let mut claim = msg.task_claim; task_claim.append(&mut claim); @@ -31,36 +48,44 @@ pub fn init( } if count > Uint128(100) { - return Err(StdError::GenericErr { msg: "tasks above 100%".to_string(), backtrace: None }) + return Err(StdError::GenericErr { + msg: "tasks above 100%".to_string(), + backtrace: None, + }); } let start_date = match msg.start_date { None => env.block.time, - Some(date) => date + Some(date) => date, }; if let Some(end_date) = msg.end_date { if end_date < start_date { - return Err(StdError::generic_err("Start date must come before end date")) + return Err(StdError::generic_err( + "Start date must come before end date", + )); } } // Avoid decay collisions if let Some(start_decay) = msg.decay_start { if start_decay < start_date { - return Err(StdError::generic_err("Decay cannot start before start date")) + return Err(StdError::generic_err( + "Decay cannot start before start date", + )); } if let Some(end_date) = msg.end_date { if start_decay > end_date { - return Err(StdError::generic_err("Decay cannot start after the end date")) + return Err(StdError::generic_err( + "Decay cannot start after the end date", + )); } - } - else { - return Err(StdError::generic_err("Decay must have an end date")) + } else { + return Err(StdError::generic_err("Decay must have an end date")); } } - let config = Config{ + let config = Config { admin: msg.admin.unwrap_or(env.message.sender), contract: env.contract.address, dump_address: msg.dump_address, @@ -73,7 +98,7 @@ pub fn init( merkle_root: msg.merkle_root, total_accounts: msg.total_accounts, max_amount: msg.max_amount, - query_rounding: msg.query_rounding + query_rounding: msg.query_rounding, }; config_w(&mut deps.storage).save(&config)?; @@ -85,7 +110,7 @@ pub fn init( Ok(InitResponse { messages: vec![], - log: vec![] + log: vec![], }) } @@ -96,22 +121,35 @@ pub fn handle( ) -> StdResult { match msg { HandleMsg::UpdateConfig { - admin, dump_address, query_rounding: redeem_step_size, - start_date, end_date, decay_start: start_decay - } => try_update_config(deps, env, admin, dump_address, redeem_step_size, - start_date, end_date, start_decay), - HandleMsg::AddTasks { tasks - } => try_add_tasks(deps, &env, tasks), - HandleMsg::CompleteTask { address - } => try_complete_task(deps, &env, address), - HandleMsg::CreateAccount { addresses, partial_tree + admin, + dump_address, + query_rounding: redeem_step_size, + start_date, + end_date, + decay_start: start_decay, + } => try_update_config( + deps, + env, + admin, + dump_address, + redeem_step_size, + start_date, + end_date, + start_decay, + ), + HandleMsg::AddTasks { tasks } => try_add_tasks(deps, &env, tasks), + HandleMsg::CompleteTask { address } => try_complete_task(deps, &env, address), + HandleMsg::CreateAccount { + addresses, + partial_tree, } => try_create_account(deps, &env, addresses, partial_tree), - HandleMsg::UpdateAccount { addresses, partial_tree + HandleMsg::UpdateAccount { + addresses, + partial_tree, } => try_update_account(deps, &env, addresses, partial_tree), - HandleMsg::DisablePermitKey { key - } => try_disable_permit_key(deps, &env, key), - HandleMsg::Claim { } => try_claim(deps, &env), - HandleMsg::ClaimDecay { } => try_claim_decay(deps, &env), + HandleMsg::DisablePermitKey { key } => try_disable_permit_key(deps, &env, key), + HandleMsg::Claim {} => try_claim(deps, &env), + HandleMsg::ClaimDecay {} => try_claim_decay(deps, &env), } } @@ -120,10 +158,12 @@ pub fn query( msg: QueryMsg, ) -> StdResult { match msg { - QueryMsg::Config { } => to_binary(&query::config(deps)?), + QueryMsg::Config {} => to_binary(&query::config(deps)?), QueryMsg::Dates { current_date } => to_binary(&query::dates(deps, current_date)?), QueryMsg::TotalClaimed {} => to_binary(&query::total_claimed(deps)?), - QueryMsg::Account { permit, current_date } => to_binary( - &query::account(deps, permit, current_date)?), + QueryMsg::Account { + permit, + current_date, + } => to_binary(&query::account(deps, permit, current_date)?), } -} \ No newline at end of file +} diff --git a/contracts/airdrop/src/handle.rs b/contracts/airdrop/src/handle.rs index 13950830a..8cec4c8aa 100644 --- a/contracts/airdrop/src/handle.rs +++ b/contracts/airdrop/src/handle.rs @@ -1,10 +1,44 @@ -use cosmwasm_std::{to_binary, Api, Env, Extern, HandleResponse, Querier, StdError, StdResult, Storage, HumanAddr, Uint128, Binary, Decimal}; -use rs_merkle::{Hasher, MerkleProof, algorithms::Sha256}; -use crate::state::{config_r, config_w, claim_status_w, claim_status_r, account_total_claimed_w, total_claimed_w, total_claimed_r, account_r, address_in_account_w, account_w, validate_address_permit, revoke_permit, decay_claimed_w}; -use shade_protocol::{airdrop::{HandleAnswer, Config, claim_info::{RequiredTask}, - account::{Account, AddressProofPermit}}, - generic_response::ResponseStatus}; +use crate::state::{ + account_r, + account_total_claimed_w, + account_w, + address_in_account_w, + claim_status_r, + claim_status_w, + config_r, + config_w, + decay_claimed_w, + revoke_permit, + total_claimed_r, + total_claimed_w, + validate_address_permit, +}; +use cosmwasm_std::{ + to_binary, + Api, + Binary, + Decimal, + Env, + Extern, + HandleResponse, + HumanAddr, + Querier, + StdError, + StdResult, + Storage, + Uint128, +}; +use rs_merkle::{algorithms::Sha256, Hasher, MerkleProof}; use secret_toolkit::snip20::send_msg; +use shade_protocol::{ + airdrop::{ + account::{Account, AddressProofPermit}, + claim_info::RequiredTask, + Config, + HandleAnswer, + }, + generic_response::ResponseStatus, +}; #[allow(clippy::too_many_arguments)] pub fn try_update_config( @@ -15,7 +49,7 @@ pub fn try_update_config( query_rounding: Option, start_date: Option, end_date: Option, - decay_start: Option + decay_start: Option, ) -> StdResult { let config = config_r(&deps.storage).load()?; // Check if admin @@ -29,32 +63,38 @@ pub fn try_update_config( if let Some(admin) = admin { state.admin = admin; } - if let Some(dump_address)= dump_address { + if let Some(dump_address) = dump_address { state.dump_address = Some(dump_address); } - if let Some(query_rounding)= query_rounding { + if let Some(query_rounding) = query_rounding { state.query_rounding = query_rounding; } if let Some(start_date) = start_date { // Avoid date collisions if let Some(end_date) = end_date { if start_date > end_date { - return Err(StdError::generic_err("New start date is greater than end date")) + return Err(StdError::generic_err( + "New start date is greater than end date", + )); } - } - else if let Some(end_date) = state.end_date { + } else if let Some(end_date) = state.end_date { if start_date > end_date { - return Err(StdError::generic_err("New start date is greater than the current end date")) + return Err(StdError::generic_err( + "New start date is greater than the current end date", + )); } } if let Some(start_decay) = decay_start { if start_date > start_decay { - return Err(StdError::generic_err("New start date is greater than start of decay")) + return Err(StdError::generic_err( + "New start date is greater than start of decay", + )); } - } - else if let Some(start_decay) = state.decay_start { + } else if let Some(start_decay) = state.decay_start { if start_date > start_decay { - return Err(StdError::generic_err("New start date is greater than the current start of decay")) + return Err(StdError::generic_err( + "New start date is greater than the current start of decay", + )); } } @@ -64,12 +104,15 @@ pub fn try_update_config( // Avoid date collisions if let Some(decay_start) = decay_start { if decay_start > end_date { - return Err(StdError::generic_err("New end date is before start of decay")) + return Err(StdError::generic_err( + "New end date is before start of decay", + )); } - } - else if let Some(decay_start) = state.decay_start { + } else if let Some(decay_start) = state.decay_start { if decay_start > end_date { - return Err(StdError::generic_err("New end date is before current start of decay")) + return Err(StdError::generic_err( + "New end date is before current start of decay", + )); } } @@ -85,17 +128,17 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateConfig { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateConfig { + status: ResponseStatus::Success, + })?), }) } pub fn try_add_tasks( deps: &mut Extern, env: &Env, - tasks: Vec + tasks: Vec, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check if admin if env.message.sender != config.admin { @@ -113,7 +156,7 @@ pub fn try_add_tasks( } if count > Uint128(100) { - return Err(StdError::generic_err("tasks above 100%")) + return Err(StdError::generic_err("tasks above 100%")); } Ok(config) @@ -122,8 +165,9 @@ pub fn try_add_tasks( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::AddTask { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::AddTask { + status: ResponseStatus::Success, + })?), }) } @@ -133,7 +177,6 @@ pub fn try_create_account( addresses: Vec, partial_tree: Vec, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check that airdrop hasn't ended @@ -141,18 +184,27 @@ pub fn try_create_account( // Check that account doesnt exist let sender = env.message.sender.to_string(); - if account_r(&deps.storage).may_load(sender.as_bytes())?.is_some() { - return Err(StdError::generic_err("Account already made")) + if account_r(&deps.storage) + .may_load(sender.as_bytes())? + .is_some() + { + return Err(StdError::generic_err("Account already made")); } let mut account = Account { addresses: vec![], - total_claimable: Uint128::zero() + total_claimable: Uint128::zero(), }; // Validate permits - try_add_account_addresses(&mut deps.storage, &config, &env.message.sender, &mut account, - addresses, partial_tree)?; + try_add_account_addresses( + &mut deps.storage, + &config, + &env.message.sender, + &mut account, + addresses, + partial_tree, + )?; // Save account account_w(&mut deps.storage).save(sender.as_bytes(), &account)?; @@ -162,29 +214,39 @@ pub fn try_create_account( claim_status_w(&mut deps.storage, 0).save(sender.as_bytes(), &false)?; // Claim the airdrop after account creation - let (completed_percentage, unclaimed_percentage) = update_tasks(&mut deps.storage, - &config, sender)?; + let (completed_percentage, unclaimed_percentage) = + update_tasks(&mut deps.storage, &config, sender)?; let mut messages = vec![]; // Avoid calculating if theres nothing to claim if unclaimed_percentage > Uint128::zero() { - let redeem_amount = claim_tokens(&mut deps.storage, env, &config, &account, - completed_percentage, unclaimed_percentage)?; - - total_claimed_w(&mut deps.storage).update(|claimed| { - Ok(claimed + redeem_amount) - })?; - - messages.push(send_msg(env.message.sender.clone(), redeem_amount, - None, None, 0, - config.airdrop_snip20.code_hash, - config.airdrop_snip20.address)?); + let redeem_amount = claim_tokens( + &mut deps.storage, + env, + &config, + &account, + completed_percentage, + unclaimed_percentage, + )?; + + total_claimed_w(&mut deps.storage).update(|claimed| Ok(claimed + redeem_amount))?; + + messages.push(send_msg( + env.message.sender.clone(), + redeem_amount, + None, + None, + 0, + config.airdrop_snip20.code_hash, + config.airdrop_snip20.address, + )?); } Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::CreateAccount { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::CreateAccount { + status: ResponseStatus::Success, + })?), }) } @@ -194,7 +256,6 @@ pub fn try_update_account( addresses: Vec, partial_tree: Vec, ) -> StdResult { - // Check if airdrop active let config = config_r(&deps.storage).load()?; @@ -207,19 +268,31 @@ pub fn try_update_account( // Run the claim function if theres something to claim let old_claim_amount = account.total_claimable; - let (completed_percentage, unclaimed_percentage) = update_tasks(&mut deps.storage, - &config, sender.to_string())?; + let (completed_percentage, unclaimed_percentage) = + update_tasks(&mut deps.storage, &config, sender.to_string())?; let mut redeem_amount = Uint128::zero(); if unclaimed_percentage > Uint128::zero() { - redeem_amount = claim_tokens(&mut deps.storage, env, &config, &account, - completed_percentage, unclaimed_percentage)?; + redeem_amount = claim_tokens( + &mut deps.storage, + env, + &config, + &account, + completed_percentage, + unclaimed_percentage, + )?; } // Setup the new addresses - try_add_account_addresses(&mut deps.storage, &config, &env.message.sender, &mut account, - addresses, partial_tree)?; + try_add_account_addresses( + &mut deps.storage, + &config, + &env.message.sender, + &mut account, + addresses, + partial_tree, + )?; let mut messages = vec![]; if completed_percentage > Uint128::zero() { @@ -229,31 +302,31 @@ pub fn try_update_account( if let Some(claimed) = claimed { let new_redeem: Uint128; if completed_percentage == Uint128(100) { - new_redeem = added_address_total * decay_factor( - env.block.time, &config); - } - else { - new_redeem = completed_percentage.multiply_ratio( - added_address_total, Uint128(100)) * decay_factor( - env.block.time, &config); + new_redeem = added_address_total * decay_factor(env.block.time, &config); + } else { + new_redeem = completed_percentage + .multiply_ratio(added_address_total, Uint128(100)) + * decay_factor(env.block.time, &config); } redeem_amount += new_redeem; Ok(claimed + new_redeem) - } - else { + } else { Err(StdError::generic_err("Account total claimed not set")) } })?; - total_claimed_w(&mut deps.storage).update(|claimed| { - Ok(claimed + redeem_amount) - })?; - - messages.push(send_msg(env.message.sender.clone(), redeem_amount, - None, None, 0, - config.airdrop_snip20.code_hash, - config.airdrop_snip20.address)?); + total_claimed_w(&mut deps.storage).update(|claimed| Ok(claimed + redeem_amount))?; + + messages.push(send_msg( + env.message.sender.clone(), + redeem_amount, + None, + None, + 0, + config.airdrop_snip20.code_hash, + config.airdrop_snip20.address, + )?); } account_w(&mut deps.storage).save(sender.as_bytes(), &account)?; @@ -261,8 +334,9 @@ pub fn try_update_account( Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateAccount { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateAccount { + status: ResponseStatus::Success, + })?), }) } @@ -271,14 +345,14 @@ pub fn try_disable_permit_key( env: &Env, key: String, ) -> StdResult { - revoke_permit(&mut deps.storage, env.message.sender.to_string(), key); Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::DisablePermitKey { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::DisablePermitKey { + status: ResponseStatus::Success, + })?), }) } @@ -287,29 +361,30 @@ pub fn try_complete_task( env: &Env, account: HumanAddr, ) -> StdResult { - let config = config_r(&deps.storage).load()?; for (i, task) in config.task_claim.iter().enumerate() { if task.address == env.message.sender { claim_status_w(&mut deps.storage, i).update( - account.to_string().as_bytes(), |status| { + account.to_string().as_bytes(), + |status| { // If there was a state then ignore if let Some(status) = status { Ok(status) - } - else { + } else { Ok(false) } - })?; + }, + )?; } } Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::Claim { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::Claim { + status: ResponseStatus::Success, + })?), }) } @@ -317,7 +392,6 @@ pub fn try_claim( deps: &mut Extern, env: &Env, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check that airdrop hasn't ended @@ -328,28 +402,38 @@ pub fn try_claim( let account = account_r(&deps.storage).load(sender.to_string().as_bytes())?; // Calculate airdrop - let (completed_percentage, unclaimed_percentage) = update_tasks(&mut deps.storage, - &config, sender.to_string())?; + let (completed_percentage, unclaimed_percentage) = + update_tasks(&mut deps.storage, &config, sender.to_string())?; if unclaimed_percentage == Uint128::zero() { - return Err(StdError::generic_err("No claimable amount available")) + return Err(StdError::generic_err("No claimable amount available")); } - let redeem_amount = claim_tokens(&mut deps.storage, env, &config, &account, - completed_percentage, unclaimed_percentage)?; + let redeem_amount = claim_tokens( + &mut deps.storage, + env, + &config, + &account, + completed_percentage, + unclaimed_percentage, + )?; - total_claimed_w(&mut deps.storage).update(|claimed| { - Ok(claimed + redeem_amount) - })?; + total_claimed_w(&mut deps.storage).update(|claimed| Ok(claimed + redeem_amount))?; Ok(HandleResponse { - messages: vec![send_msg(sender, redeem_amount, - None, None, 0, - config.airdrop_snip20.code_hash, - config.airdrop_snip20.address)?], + messages: vec![send_msg( + sender, + redeem_amount, + None, + None, + 0, + config.airdrop_snip20.code_hash, + config.airdrop_snip20.address, + )?], log: vec![], - data: Some( to_binary( &HandleAnswer::Claim { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::Claim { + status: ResponseStatus::Success, + })?), }) } @@ -363,27 +447,33 @@ pub fn try_claim_decay( if let Some(end_date) = config.end_date { if let Some(dump_address) = config.dump_address { if env.block.time > end_date { - decay_claimed_w(&mut deps.storage).update(| claimed | { + decay_claimed_w(&mut deps.storage).update(|claimed| { if claimed { Err(StdError::generic_err("Decay already claimed")) - } - else { + } else { Ok(true) } })?; - let send_total = (config.airdrop_amount - total_claimed_r(&deps.storage).load()?)?; + let send_total = + (config.airdrop_amount - total_claimed_r(&deps.storage).load()?)?; let messages = vec![send_msg( - dump_address, send_total, None, None, - 1, config.airdrop_snip20.code_hash, - config.airdrop_snip20.address)?]; + dump_address, + send_total, + None, + None, + 1, + config.airdrop_snip20.code_hash, + config.airdrop_snip20.address, + )?]; return Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::ClaimDecay { - status: ResponseStatus::Success } )? ) - }) + data: Some(to_binary(&HandleAnswer::ClaimDecay { + status: ResponseStatus::Success, + })?), + }); } } } @@ -402,8 +492,7 @@ pub fn update_tasks( let mut unclaimed_percentage = Uint128::zero(); for (index, task) in config.task_claim.iter().enumerate() { // Check if task has been completed - let state = claim_status_r(storage, index).may_load( - sender.as_bytes())?; + let state = claim_status_r(storage, index).may_load(sender.as_bytes())?; match state { // Ignore if none @@ -412,8 +501,7 @@ pub fn update_tasks( completed_percentage += task.percent; if !claimed { // Set claim status to true since we're going to claim it now - claim_status_w(storage, index).save( - sender.as_bytes(), &true)?; + claim_status_w(storage, index).save(sender.as_bytes(), &true)?; unclaimed_percentage += task.percent; } @@ -431,7 +519,8 @@ pub fn claim_tokens( account: &Account, completed_percentage: Uint128, unclaimed_percentage: Uint128, -) -> StdResult { // send_amount +) -> StdResult { + // send_amount let sender = env.message.sender.to_string(); // Amount to be redeemed @@ -443,18 +532,16 @@ pub fn claim_tokens( // This solves possible uToken inaccuracies if completed_percentage == Uint128(100) { redeem_amount = (account.total_claimable - claimed)?; - } - else { - redeem_amount = unclaimed_percentage.multiply_ratio( - account.total_claimable, Uint128(100)); + } else { + redeem_amount = + unclaimed_percentage.multiply_ratio(account.total_claimable, Uint128(100)); } // Update redeem amount with the decay multiplier redeem_amount = redeem_amount * decay_factor(env.block.time, config); Ok(claimed + redeem_amount) - } - else { + } else { Err(StdError::generic_err("Account total claimed not set")) } })?; @@ -482,30 +569,34 @@ pub fn try_add_account_addresses( // Check permit legitimacy address = validate_address_permit(storage, permit, config.contract.clone())?; if address != permit.params.address { - return Err(StdError::generic_err("Signer address is not the same as the permit address")) + return Err(StdError::generic_err( + "Signer address is not the same as the permit address", + )); } - } - else { + } else { address = sender.clone(); } // Check that airdrop amount does not exceed maximum if permit.params.amount > config.max_amount { - return Err(StdError::generic_err("Amount exceeds maximum amount")) + return Err(StdError::generic_err("Amount exceeds maximum amount")); } // Update address if its not in an account address_in_account_w(storage).update(address.to_string().as_bytes(), |state| { if state.is_some() { - return Err(StdError::generic_err( - format!("{:?} already in an account", address.to_string()))) + return Err(StdError::generic_err(format!( + "{:?} already in an account", + address.to_string() + ))); } Ok(true) })?; // Add account as a leaf - let leaf_hash = Sha256::hash((address.to_string() + &permit.params.amount.to_string()).as_bytes()); + let leaf_hash = + Sha256::hash((address.to_string() + &permit.params.amount.to_string()).as_bytes()); leaves_to_validate.push((permit.params.index as usize, leaf_hash)); // If valid then add to account array and sum total amount @@ -522,7 +613,7 @@ pub fn try_add_account_addresses( for leaf in leaves_to_validate.iter() { indices.push(leaf.0); leaves.push(leaf.1); - }; + } // Convert partial tree from base64 to binary let mut partial_tree_binary: Vec<[u8; 32]> = vec![]; @@ -538,22 +629,28 @@ pub fn try_add_account_addresses( let mut root: [u8; 32] = Default::default(); root.clone_from_slice(config.merkle_root.as_slice()); if !proof.verify(root, &indices, &leaves, config.total_accounts as usize) { - return Err(StdError::generic_err("Invalid proof")) + return Err(StdError::generic_err("Invalid proof")); } Ok(()) } -pub fn available( config: &Config, env: &Env ) -> StdResult<()> { +pub fn available(config: &Config, env: &Env) -> StdResult<()> { let current_time = env.block.time; // Check if airdrop started if current_time < config.start_date { - return Err(StdError::generic_err(format!("Airdrop starts on {}", config.start_date))) + return Err(StdError::generic_err(format!( + "Airdrop starts on {}", + config.start_date + ))); } if let Some(end_date) = config.end_date { if current_time > end_date { - return Err(StdError::generic_err(format!("Airdrop ended on {}", end_date))) + return Err(StdError::generic_err(format!( + "Airdrop ended on {}", + end_date + ))); } } @@ -565,7 +662,7 @@ pub fn decay_factor(current_time: u64, config: &Config) -> Decimal { // Calculate redeem amount after applying decay if let Some(decay_start) = config.decay_start { if current_time >= decay_start { - return inverse_normalizer(decay_start, current_time, config.end_date.unwrap()) + return inverse_normalizer(decay_start, current_time, config.end_date.unwrap()); } } Decimal::one() @@ -574,4 +671,4 @@ pub fn decay_factor(current_time: u64, config: &Config) -> Decimal { /// Get the inverse normalized value [0,1] of x between [min, max] pub fn inverse_normalizer(min: u64, x: u64, max: u64) -> Decimal { Decimal::from_ratio(max - x, max - min) -} \ No newline at end of file +} diff --git a/contracts/airdrop/src/lib.rs b/contracts/airdrop/src/lib.rs index 603e0d230..84be1cef6 100644 --- a/contracts/airdrop/src/lib.rs +++ b/contracts/airdrop/src/lib.rs @@ -10,7 +10,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] @@ -41,4 +46,4 @@ mod wasm { // Other C externs like cosmwasm_vm_version_1, allocate, deallocate are available // automatically because we `use cosmwasm_std`. -} \ No newline at end of file +} diff --git a/contracts/airdrop/src/query.rs b/contracts/airdrop/src/query.rs index 5c31086e6..f372484ac 100644 --- a/contracts/airdrop/src/query.rs +++ b/contracts/airdrop/src/query.rs @@ -1,48 +1,63 @@ +use crate::{ + handle::decay_factor, + state::{ + account_r, + account_total_claimed_r, + claim_status_r, + config_r, + decay_claimed_r, + total_claimed_r, + validate_account_permit, + }, +}; use cosmwasm_std::{Api, Extern, Querier, StdResult, Storage, Uint128}; -use shade_protocol::airdrop::{QueryAnswer, account::AccountPermit, claim_info::RequiredTask}; -use shade_protocol::math::{div, mult}; -use crate::handle::decay_factor; -use crate::state::{config_r, claim_status_r, total_claimed_r, account_r, account_total_claimed_r, validate_account_permit, decay_claimed_r}; +use shade_protocol::{ + airdrop::{account::AccountPermit, claim_info::RequiredTask, QueryAnswer}, + math::{div, mult}, +}; -pub fn config -(deps: &Extern) -> StdResult { +pub fn config(deps: &Extern) -> StdResult { Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()?, total_claimed: total_claimed_r(&deps.storage).load()?, }) } -pub fn dates -(deps: &Extern, current_date: Option) -> StdResult { +pub fn dates( + deps: &Extern, + current_date: Option, +) -> StdResult { let config = config_r(&deps.storage).load()?; Ok(QueryAnswer::Dates { start: config.start_date, end: config.end_date, decay_start: config.decay_start, - decay_factor: current_date.map(|date| Uint128(100) * decay_factor(date, &config)) + decay_factor: current_date.map(|date| Uint128(100) * decay_factor(date, &config)), }) } -pub fn total_claimed -(deps: &Extern) -> StdResult { +pub fn total_claimed( + deps: &Extern, +) -> StdResult { let claimed: Uint128; let total_claimed = total_claimed_r(&deps.storage).load()?; if decay_claimed_r(&deps.storage).load()? { claimed = total_claimed; - } - else { + } else { let config = config_r(&deps.storage).load()?; - claimed = mult(div(total_claimed, config.query_rounding)?, config.query_rounding); + claimed = mult( + div(total_claimed, config.query_rounding)?, + config.query_rounding, + ); } - Ok(QueryAnswer::TotalClaimed { - claimed - }) + Ok(QueryAnswer::TotalClaimed { claimed }) } pub fn account( - deps: &Extern, permit: AccountPermit, current_date: Option + deps: &Extern, + permit: AccountPermit, + current_date: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; let account_address = validate_account_permit(deps, &permit, config.contract)?; @@ -51,13 +66,13 @@ pub fn account( // Calculate eligible tasks let config = config_r(&deps.storage).load()?; - let mut finished_tasks: Vec = vec!(); + let mut finished_tasks: Vec = vec![]; let mut completed_percentage = Uint128::zero(); let mut unclaimed_percentage = Uint128::zero(); for (index, task) in config.task_claim.iter().enumerate() { // Check if task has been completed - let state = claim_status_r(&deps.storage, index).may_load( - account_address.to_string().as_bytes())?; + let state = claim_status_r(&deps.storage, index) + .may_load(account_address.to_string().as_bytes())?; match state { // Ignore if none @@ -66,8 +81,7 @@ pub fn account( finished_tasks.push(task.clone()); if !claimed { unclaimed_percentage += task.percent; - } - else { + } else { completed_percentage += task.percent; } } @@ -78,8 +92,7 @@ pub fn account( if unclaimed_percentage == Uint128(100) { unclaimed = account.total_claimable; - } - else { + } else { unclaimed = unclaimed_percentage.multiply_ratio(account.total_claimable, Uint128(100)); } @@ -89,8 +102,9 @@ pub fn account( Ok(QueryAnswer::Account { total: account.total_claimable, - claimed: account_total_claimed_r(&deps.storage).load(account_address.to_string().as_bytes())?, + claimed: account_total_claimed_r(&deps.storage) + .load(account_address.to_string().as_bytes())?, unclaimed, - finished_tasks + finished_tasks, }) -} \ No newline at end of file +} diff --git a/contracts/airdrop/src/state.rs b/contracts/airdrop/src/state.rs index af8dedae9..28165038f 100644 --- a/contracts/airdrop/src/state.rs +++ b/contracts/airdrop/src/state.rs @@ -1,7 +1,18 @@ -use cosmwasm_std::{Storage, Uint128, StdResult, HumanAddr, StdError, Api, Querier, Extern}; -use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, - bucket, Bucket, bucket_read, ReadonlyBucket}; -use shade_protocol::airdrop::{Config, account::{Account, AccountPermit, AddressProofPermit, authenticate_ownership}}; +use cosmwasm_std::{Api, Extern, HumanAddr, Querier, StdError, StdResult, Storage, Uint128}; +use cosmwasm_storage::{ + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, +}; +use shade_protocol::airdrop::{ + account::{authenticate_ownership, Account, AccountPermit, AddressProofPermit}, + Config, +}; pub static CONFIG_KEY: &[u8] = b"config"; pub static DECAY_CLAIMED_KEY: &[u8] = b"decay_claimed"; @@ -29,7 +40,7 @@ pub fn decay_claimed_r(storage: &S) -> ReadonlySingleton { } // Is address added to an account -pub fn address_in_account_r(storage: & S) -> ReadonlyBucket { +pub fn address_in_account_r(storage: &S) -> ReadonlyBucket { bucket_read(REWARD_IN_ACCOUNT_KEY, storage) } @@ -38,7 +49,7 @@ pub fn address_in_account_w(storage: &mut S) -> Bucket { } // airdrop account -pub fn account_r(storage: & S) -> ReadonlyBucket { +pub fn account_r(storage: &S) -> ReadonlyBucket { bucket_read(ACCOUNTS_KEY, storage) } @@ -47,7 +58,7 @@ pub fn account_w(storage: &mut S) -> Bucket { } // If not found then its unrewarded; if true then claimed -pub fn claim_status_r(storage: & S, index: usize) -> ReadonlyBucket { +pub fn claim_status_r(storage: &S, index: usize) -> ReadonlyBucket { let mut key = CLAIM_STATUS_KEY.to_vec(); key.push(index as u8); bucket_read(&key, storage) @@ -69,7 +80,7 @@ pub fn total_claimed_w(storage: &mut S) -> Singleton { } // Total account claimed -pub fn account_total_claimed_r(storage: & S) -> ReadonlyBucket { +pub fn account_total_claimed_r(storage: &S) -> ReadonlyBucket { bucket_read(USER_TOTAL_CLAIMED_KEY, storage) } @@ -78,7 +89,7 @@ pub fn account_total_claimed_w(storage: &mut S) -> Bucket(storage: & S, account: String) -> ReadonlyBucket { +pub fn account_permit_key_r(storage: &S, account: String) -> ReadonlyBucket { let key = ACCOUNT_PERMIT_KEY.to_string() + &account; bucket_read(key.as_bytes(), storage) } @@ -89,30 +100,43 @@ pub fn account_permit_key_w(storage: &mut S, account: String) -> Buc } pub fn revoke_permit(storage: &mut S, account: String, permit_key: String) { - account_permit_key_w(storage, account).save(permit_key.as_bytes(), &false).unwrap(); -} - -pub fn is_permit_revoked(storage: &S, account: String, permit_key: String) -> StdResult { - if account_permit_key_r(storage, account).may_load(permit_key.as_bytes())?.is_some() { + account_permit_key_w(storage, account) + .save(permit_key.as_bytes(), &false) + .unwrap(); +} + +pub fn is_permit_revoked( + storage: &S, + account: String, + permit_key: String, +) -> StdResult { + if account_permit_key_r(storage, account) + .may_load(permit_key.as_bytes())? + .is_some() + { Ok(true) - } - else { + } else { Ok(false) } } pub fn validate_address_permit( - storage: &S, permit: &AddressProofPermit, contract: HumanAddr + storage: &S, + permit: &AddressProofPermit, + contract: HumanAddr, ) -> StdResult { // Check that contract matches if permit.params.contract != contract { - return Err(StdError::unauthorized()) + return Err(StdError::unauthorized()); } // Check that permit is not revoked - if is_permit_revoked(storage, permit.params.address.to_string(), - permit.params.key.clone())? { - return Err(StdError::generic_err("permit key revoked")) + if is_permit_revoked( + storage, + permit.params.address.to_string(), + permit.params.key.clone(), + )? { + return Err(StdError::generic_err("permit key revoked")); } // Authenticate permit @@ -120,21 +144,26 @@ pub fn validate_address_permit( } pub fn validate_account_permit( - deps: &Extern, permit: &AccountPermit, contract: HumanAddr + deps: &Extern, + permit: &AccountPermit, + contract: HumanAddr, ) -> StdResult { // Check that contract matches if permit.params.contract != contract { - return Err(StdError::unauthorized()) + return Err(StdError::unauthorized()); } // Authenticate permit let address = permit.validate()?.as_humanaddr(&deps.api)?; // Check that permit is not revoked - if is_permit_revoked(&deps.storage, address.to_string(), - permit.params.key.clone())? { - return Err(StdError::generic_err("permit key revoked")) + if is_permit_revoked( + &deps.storage, + address.to_string(), + permit.params.key.clone(), + )? { + return Err(StdError::generic_err("permit key revoked")); } Ok(address) -} \ No newline at end of file +} diff --git a/contracts/airdrop/src/test.rs b/contracts/airdrop/src/test.rs index 5ce714bc0..5c3cda3cd 100644 --- a/contracts/airdrop/src/test.rs +++ b/contracts/airdrop/src/test.rs @@ -1,16 +1,33 @@ #[cfg(test)] pub mod tests { - use cosmwasm_std::{testing::{mock_dependencies, mock_env}, Binary, CanonicalAddr, - HumanAddr, Uint128}; - use shade_protocol::{airdrop::{account::{AddressProofMsg, AddressProofPermit}, - claim_info::RequiredTask, InitMsg}, asset::Contract}; - use flexible_permits::{transaction::{PermitSignature, PubKey}, permit::bech32_to_canonical}; - use shade_protocol::math::{div, mult}; - use crate::{handle::inverse_normalizer, contract::init}; + use crate::{contract::init, handle::inverse_normalizer}; + use cosmwasm_std::{ + testing::{mock_dependencies, mock_env}, + Binary, + CanonicalAddr, + HumanAddr, + Uint128, + }; + use flexible_permits::{ + permit::bech32_to_canonical, + transaction::{PermitSignature, PubKey}, + }; + use shade_protocol::{ + airdrop::{ + account::{AddressProofMsg, AddressProofPermit}, + claim_info::RequiredTask, + InitMsg, + }, + asset::Contract, + math::{div, mult}, + }; #[test] fn decay_factor() { - assert_eq!(Uint128(50), Uint128(100) * inverse_normalizer(100, 200, 300)); + assert_eq!( + Uint128(50), + Uint128(100) * inverse_normalizer(100, 200, 300) + ); assert_eq!(Uint128(25), Uint128(100) * inverse_normalizer(0, 75, 100)); } @@ -40,8 +57,14 @@ pub mod tests { }; let permit_addr = permit.validate().expect("Signature validation failed"); - assert_eq!(permit_addr.as_canonical(), bech32_to_canonical(permit.params.address.clone().as_str())); - assert_ne!(permit_addr.as_canonical(), bech32_to_canonical("secret17q23878cx2pmjn8cp7sqhylqfpvdw9r8p5q8um")); + assert_eq!( + permit_addr.as_canonical(), + bech32_to_canonical(permit.params.address.clone().as_str()) + ); + assert_ne!( + permit_addr.as_canonical(), + bech32_to_canonical("secret17q23878cx2pmjn8cp7sqhylqfpvdw9r8p5q8um") + ); } #[test] @@ -69,8 +92,14 @@ pub mod tests { }; let permit_addr = permit.validate().expect("Signature validation failed"); - assert_eq!(permit_addr.as_canonical(), bech32_to_canonical(permit.params.address.clone().as_str())); - assert_ne!(permit_addr.as_canonical(), bech32_to_canonical("cosmos1ceqk06xpqrq45melc9f8khae0fwaa5y5w0gz6x")); + assert_eq!( + permit_addr.as_canonical(), + bech32_to_canonical(permit.params.address.clone().as_str()) + ); + assert_ne!( + permit_addr.as_canonical(), + bech32_to_canonical("cosmos1ceqk06xpqrq45melc9f8khae0fwaa5y5w0gz6x") + ); } #[test] @@ -98,23 +127,37 @@ pub mod tests { }; let permit_addr = permit.validate().expect("Signature validation failed"); - assert_eq!(permit_addr.as_canonical(), bech32_to_canonical(permit.params.address.clone().as_str())); - assert_ne!(permit_addr.as_canonical(), bech32_to_canonical("terra19m2zgdyuq0crpww00jc2a9k70ut944dum53p7x")); + assert_eq!( + permit_addr.as_canonical(), + bech32_to_canonical(permit.params.address.clone().as_str()) + ); + assert_ne!( + permit_addr.as_canonical(), + bech32_to_canonical("terra19m2zgdyuq0crpww00jc2a9k70ut944dum53p7x") + ); } #[test] fn claim_query() { - - assert_eq!(Uint128(300), mult(div(Uint128(345), Uint128(100)).unwrap(), Uint128(100))) + assert_eq!( + Uint128(300), + mult(div(Uint128(345), Uint128(100)).unwrap(), Uint128(100)) + ) } #[test] fn claim_query_odd_multiple() { - assert_eq!(Uint128(13475), mult(div(Uint128(13480), Uint128(7)).unwrap(), Uint128(7))) + assert_eq!( + Uint128(13475), + mult(div(Uint128(13480), Uint128(7)).unwrap(), Uint128(7)) + ) } #[test] fn claim_query_under_step() { - assert_eq!(Uint128(0), mult(div(Uint128(200), Uint128(1000)).unwrap(), Uint128(1000))) + assert_eq!( + Uint128(0), + mult(div(Uint128(200), Uint128(1000)).unwrap(), Uint128(1000)) + ) } -} \ No newline at end of file +} diff --git a/contracts/governance/src/contract.rs b/contracts/governance/src/contract.rs index bd411a348..900be82ef 100644 --- a/contracts/governance/src/contract.rs +++ b/contracts/governance/src/contract.rs @@ -1,35 +1,41 @@ -use cosmwasm_std::{to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdResult, Storage, Uint128}; -use shade_protocol::{ - governance::{ - InitMsg, HandleMsg, - QueryMsg, Config, - }, -}; use crate::{ - state::{config_w, admin_commands_list_w, supported_contracts_list_w}, - proposal_state::total_proposals_w, handle, - query + proposal_state::total_proposals_w, + query, + state::{admin_commands_list_w, config_w, supported_contracts_list_w}, +}; +use cosmwasm_std::{ + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, + Uint128, }; use secret_toolkit::snip20::register_receive_msg; +use shade_protocol::governance::{Config, HandleMsg, InitMsg, QueryMsg}; pub fn init( deps: &mut Extern, env: Env, msg: InitMsg, ) -> StdResult { - let state = Config { admin: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } + None => env.message.sender.clone(), + Some(admin) => admin, }, staker: msg.staker, funding_token: msg.funding_token.clone(), funding_amount: msg.funding_amount, funding_deadline: msg.funding_deadline, voting_deadline: msg.voting_deadline, - minimum_votes: msg.quorum + minimum_votes: msg.quorum, }; config_w(&mut deps.storage).save(&state)?; @@ -43,13 +49,13 @@ pub fn init( Ok(InitResponse { messages: vec![register_receive_msg( - env.contract_code_hash, - None, - 256, - msg.funding_token.code_hash, - msg.funding_token.address, - )?], - log: vec![] + env.contract_code_hash, + None, + 256, + msg.funding_token.code_hash, + msg.funding_token.address, + )?], + log: vec![], }) } @@ -60,52 +66,89 @@ pub fn handle( ) -> StdResult { match msg { // Proposals - HandleMsg::CreateProposal { target_contract, proposal, description - } => handle::try_create_proposal(deps, &env, target_contract, - Binary::from(proposal.as_bytes()), description), - - HandleMsg::Receive {sender, amount, msg + HandleMsg::CreateProposal { + target_contract, + proposal, + description, + } => handle::try_create_proposal( + deps, + &env, + target_contract, + Binary::from(proposal.as_bytes()), + description, + ), + + HandleMsg::Receive { + sender, + amount, + msg, } => handle::try_fund_proposal(deps, &env, sender, amount, msg), // Self interactions // Config - HandleMsg::UpdateConfig { admin, staker, proposal_deadline, - funding_amount, funding_deadline, minimum_votes } => - handle::try_update_config(deps, &env, admin, staker, proposal_deadline, - funding_amount, funding_deadline, minimum_votes), + HandleMsg::UpdateConfig { + admin, + staker, + proposal_deadline, + funding_amount, + funding_deadline, + minimum_votes, + } => handle::try_update_config( + deps, + &env, + admin, + staker, + proposal_deadline, + funding_amount, + funding_deadline, + minimum_votes, + ), HandleMsg::DisableStaker {} => handle::try_disable_staker(deps, &env), // Supported contract - HandleMsg::AddSupportedContract { name, contract - } => handle::try_add_supported_contract(deps, &env, name, contract), + HandleMsg::AddSupportedContract { name, contract } => { + handle::try_add_supported_contract(deps, &env, name, contract) + } - HandleMsg::RemoveSupportedContract { name - } => handle::try_remove_supported_contract(deps, &env, name), + HandleMsg::RemoveSupportedContract { name } => { + handle::try_remove_supported_contract(deps, &env, name) + } - HandleMsg::UpdateSupportedContract { name, contract - } => handle::try_update_supported_contract(deps, &env, name, contract), + HandleMsg::UpdateSupportedContract { name, contract } => { + handle::try_update_supported_contract(deps, &env, name, contract) + } // Admin command - HandleMsg::AddAdminCommand { name, proposal - } => handle::try_add_admin_command(deps, &env, name, proposal), + HandleMsg::AddAdminCommand { name, proposal } => { + handle::try_add_admin_command(deps, &env, name, proposal) + } - HandleMsg::RemoveAdminCommand { name - } => handle::try_remove_admin_command(deps, &env, name), + HandleMsg::RemoveAdminCommand { name } => { + handle::try_remove_admin_command(deps, &env, name) + } - HandleMsg::UpdateAdminCommand { name, proposal - } => handle::try_update_admin_command(deps, &env, name, proposal), + HandleMsg::UpdateAdminCommand { name, proposal } => { + handle::try_update_admin_command(deps, &env, name, proposal) + } // User interaction - HandleMsg::MakeVote { voter, proposal_id, votes + HandleMsg::MakeVote { + voter, + proposal_id, + votes, } => handle::try_vote(deps, &env, voter, proposal_id, votes), - HandleMsg::TriggerProposal { proposal_id - } => handle::try_trigger_proposal(deps, &env, proposal_id), + HandleMsg::TriggerProposal { proposal_id } => { + handle::try_trigger_proposal(deps, &env, proposal_id) + } // Admin interactions - HandleMsg::TriggerAdminCommand { target, command, - variables, description + HandleMsg::TriggerAdminCommand { + target, + command, + variables, + description, } => handle::try_trigger_admin_command(deps, &env, target, command, variables, description), } } @@ -115,27 +158,26 @@ pub fn query( msg: QueryMsg, ) -> StdResult { match msg { - QueryMsg::GetProposals { - start, end, status - } => to_binary(&query::proposals(deps, start, end, status)?), + QueryMsg::GetProposals { start, end, status } => { + to_binary(&query::proposals(deps, start, end, status)?) + } - QueryMsg::GetProposal { proposal_id } => to_binary( - &query::proposal(deps, proposal_id)?), + QueryMsg::GetProposal { proposal_id } => to_binary(&query::proposal(deps, proposal_id)?), - QueryMsg::GetTotalProposals {} => to_binary( - &query::total_proposals(deps)?), + QueryMsg::GetTotalProposals {} => to_binary(&query::total_proposals(deps)?), - QueryMsg::GetProposalVotes { proposal_id } => to_binary( - &query::proposal_votes(deps, proposal_id)?), + QueryMsg::GetProposalVotes { proposal_id } => { + to_binary(&query::proposal_votes(deps, proposal_id)?) + } - QueryMsg::GetSupportedContracts { } => to_binary(&query::supported_contracts(deps)?), + QueryMsg::GetSupportedContracts {} => to_binary(&query::supported_contracts(deps)?), - QueryMsg::GetSupportedContract { name } => to_binary( - &query::supported_contract(deps, name)?), + QueryMsg::GetSupportedContract { name } => { + to_binary(&query::supported_contract(deps, name)?) + } QueryMsg::GetAdminCommands {} => to_binary(&query::admin_commands(deps)?), - QueryMsg::GetAdminCommand { name - } => to_binary(&query::admin_command(deps, name)?), + QueryMsg::GetAdminCommand { name } => to_binary(&query::admin_command(deps, name)?), } -} \ No newline at end of file +} diff --git a/contracts/governance/src/handle.rs b/contracts/governance/src/handle.rs index 90d3bcc84..05462b8e9 100644 --- a/contracts/governance/src/handle.rs +++ b/contracts/governance/src/handle.rs @@ -1,30 +1,67 @@ -use cosmwasm_std::{ - to_binary, Api, Binary, Env, Extern, HandleResponse, Querier, StdError, - StdResult, Storage, CosmosMsg, HumanAddr, Uint128, WasmMsg, from_binary -}; use crate::{ proposal_state::{ - proposal_w, proposal_r, total_proposals_w, - total_proposal_votes_w, total_proposal_votes_r, proposal_votes_w, proposal_votes_r, - proposal_funding_deadline_w, proposal_funding_deadline_r, - proposal_voting_deadline_w, proposal_voting_deadline_r, proposal_status_w, proposal_status_r, - proposal_run_status_w, proposal_funding_r, proposal_funding_w, proposal_funding_batch_w, + proposal_funding_deadline_r, + proposal_funding_deadline_w, + proposal_funding_r, + proposal_funding_w, + proposal_r, + proposal_run_status_w, + proposal_status_r, + proposal_status_w, + proposal_votes_r, + proposal_votes_w, + proposal_voting_deadline_r, + proposal_voting_deadline_w, + proposal_w, + total_proposal_votes_r, + total_proposal_votes_w, + total_proposals_w, }, state::{ - supported_contract_r, config_r, config_w, supported_contract_w, - admin_commands_r, admin_commands_w, admin_commands_list_w, supported_contracts_list_w - } + admin_commands_list_w, + admin_commands_r, + admin_commands_w, + config_r, + config_w, + supported_contract_r, + supported_contract_w, + supported_contracts_list_w, + }, +}; +use cosmwasm_std::{ + from_binary, + to_binary, + Api, + Binary, + CosmosMsg, + Env, + Extern, + HandleResponse, + HumanAddr, + Querier, + StdError, + StdResult, + Storage, + Uint128, + WasmMsg, }; +use secret_toolkit::snip20::{batch_send_msg, send_msg, SendAction}; use shade_protocol::{ - generic_response::ResponseStatus::{Success, Failure}, asset::Contract, + asset::Contract, + generic_response::{ + ResponseStatus, + ResponseStatus::{Failure, Success}, + }, governance::{ - proposal::{Proposal, ProposalStatus}, HandleAnswer, - GOVERNANCE_SELF, AdminCommand, ADMIN_COMMAND_VARIABLE, vote::VoteTally - } + proposal::{Proposal, ProposalStatus}, + vote::VoteTally, + AdminCommand, + HandleAnswer, + ADMIN_COMMAND_VARIABLE, + GOVERNANCE_SELF, + }, }; -use shade_protocol::generic_response::ResponseStatus; -use secret_toolkit::snip20::{send_msg, SendAction, batch_send_msg}; pub fn create_proposal( deps: &mut Extern, @@ -33,12 +70,16 @@ pub fn create_proposal( proposal: Binary, description: String, ) -> StdResult { - // Check that the target contract is neither the governance or a supported contract - if supported_contract_r(&deps.storage).may_load(target_contract.as_bytes())?.is_none() && - target_contract != *GOVERNANCE_SELF{ + if supported_contract_r(&deps.storage) + .may_load(target_contract.as_bytes())? + .is_none() + && target_contract != *GOVERNANCE_SELF + { return Err(StdError::NotFound { - kind: "contract is not found".to_string(), backtrace: None }) + kind: "contract is not found".to_string(), + backtrace: None, + }); } // Create new proposal ID @@ -58,27 +99,31 @@ pub fn create_proposal( let config = config_r(&deps.storage).load()?; // Store the proposal - proposal_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &proposal)?; + proposal_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &proposal)?; // Initialize deadline proposal_funding_deadline_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &(env.block.time + config.funding_deadline))?; - proposal_status_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &ProposalStatus::Funding)?; + proposal_id.to_string().as_bytes(), + &(env.block.time + config.funding_deadline), + )?; + proposal_status_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &ProposalStatus::Funding)?; // Initialize total funding - proposal_funding_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &Uint128::zero())?; + proposal_funding_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &Uint128::zero())?; // Initialize the funding batch - proposal_funding_batch_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &vec![])?; + proposal_funding_batch_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &vec![])?; // Create proposal votes total_proposal_votes_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &VoteTally{ - yes: Uint128::zero(), - no: Uint128::zero(), - abstain: Uint128::zero() - })?; + proposal_id.to_string().as_bytes(), + &VoteTally { + yes: Uint128::zero(), + no: Uint128::zero(), + abstain: Uint128::zero(), + }, + )?; Ok(proposal_id) } @@ -90,51 +135,51 @@ pub fn try_fund_proposal( amount: Uint128, msg: Option, ) -> StdResult { - - let proposal_id: Uint128 = from_binary(&msg.ok_or_else(|| - StdError::not_found("Proposal ID in msg"))?)?; + let proposal_id: Uint128 = + from_binary(&msg.ok_or_else(|| StdError::not_found("Proposal ID in msg"))?)?; // Check if proposal is in funding - let status = proposal_status_r(&deps.storage).may_load( - proposal_id.to_string().as_bytes())?.ok_or_else(|| - StdError::not_found("Proposal"))?; + let status = proposal_status_r(&deps.storage) + .may_load(proposal_id.to_string().as_bytes())? + .ok_or_else(|| StdError::not_found("Proposal"))?; if status != ProposalStatus::Funding { - return Err(StdError::unauthorized()) + return Err(StdError::unauthorized()); } - let mut total = proposal_funding_r(&deps.storage).load( - proposal_id.to_string().as_bytes())?; + let mut total = proposal_funding_r(&deps.storage).load(proposal_id.to_string().as_bytes())?; let config = config_r(&deps.storage).load()?; let mut messages = vec![]; // Check if deadline is reached - if env.block.time >= proposal_funding_deadline_r(&deps.storage).load( - proposal_id.to_string().as_bytes())? { - - proposal_status_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &ProposalStatus::Expired)?; + if env.block.time + >= proposal_funding_deadline_r(&deps.storage).load(proposal_id.to_string().as_bytes())? + { + proposal_status_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &ProposalStatus::Expired)?; // Send back amount - messages.push(send_msg(sender, - amount, - None, - None, - None, - 1, - config.funding_token.code_hash.clone(), - config.funding_token.address)?); + messages.push(send_msg( + sender, + amount, + None, + None, + None, + 1, + config.funding_token.code_hash.clone(), + config.funding_token.address, + )?); // TODO: send total over to treasury return Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::FundProposal { + data: Some(to_binary(&HandleAnswer::FundProposal { status: Failure, - total_funding: total + total_funding: total, })?), - }) + }); } // Sum amount @@ -149,15 +194,16 @@ pub fn try_fund_proposal( // Set total to max total = config.funding_amount; - messages.push(send_msg(sender.clone(), - excess, - None, - None, - None, - 1, - config.funding_token.code_hash.clone(), - config.funding_token.address.clone())?); - + messages.push(send_msg( + sender.clone(), + excess, + None, + None, + None, + 1, + config.funding_token.code_hash.clone(), + config.funding_token.address.clone(), + )?); } // Update list of people that funded @@ -165,46 +211,49 @@ pub fn try_fund_proposal( proposal_id.to_string().as_bytes(), |amounts| { if let Some(mut amounts) = amounts { - amounts.push(SendAction{ + amounts.push(SendAction { recipient: sender.clone(), amount: adjusted_amount, msg: None, - memo: None + memo: None, }); - return Ok(amounts) + return Ok(amounts); } Err(StdError::not_found("Funding batch")) - })?; + }, + )?; // Update proposal status if total == config.funding_amount { // Update proposal status - proposal_status_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &ProposalStatus::Voting)?; + proposal_status_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &ProposalStatus::Voting)?; // Set vote deadline proposal_voting_deadline_w(&mut deps.storage).save( proposal_id.to_string().as_bytes(), - &(env.block.time + config.voting_deadline))?; + &(env.block.time + config.voting_deadline), + )?; // Send back all of the invested prop amount - messages.push(batch_send_msg(amounts, - None, - 1, - config.funding_token.code_hash, - config.funding_token.address)?) + messages.push(batch_send_msg( + amounts, + None, + 1, + config.funding_token.code_hash, + config.funding_token.address, + )?) } - proposal_funding_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), &total)?; + proposal_funding_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &total)?; Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::FundProposal { + data: Some(to_binary(&HandleAnswer::FundProposal { status: Success, - total_funding: total + total_funding: total, })?), }) } @@ -212,15 +261,13 @@ pub fn try_fund_proposal( pub fn try_trigger_proposal( deps: &mut Extern, env: &Env, - proposal_id: Uint128 + proposal_id: Uint128, ) -> StdResult { - // Get proposal - let proposal = proposal_r(&deps.storage).load( - proposal_id.to_string().as_bytes())?; + let proposal = proposal_r(&deps.storage).load(proposal_id.to_string().as_bytes())?; let run_status: ResponseStatus; - let mut vote_status = proposal_status_r(&deps.storage).load( - proposal_id.to_string().as_bytes())?; + let mut vote_status = + proposal_status_r(&deps.storage).load(proposal_id.to_string().as_bytes())?; // Check if proposal has run // TODO: This might not be needed @@ -232,28 +279,26 @@ pub fn try_trigger_proposal( let config = config_r(&deps.storage).load()?; vote_status = match config.staker { Some(_) => { - // When staking is enabled funding is required if vote_status != ProposalStatus::Voting { - return Err(StdError::unauthorized()) + return Err(StdError::unauthorized()); } - let total_votes = total_proposal_votes_r(&deps.storage).load( - proposal_id.to_string().as_bytes())?; + let total_votes = + total_proposal_votes_r(&deps.storage).load(proposal_id.to_string().as_bytes())?; // Check if proposal can be run - let voting_deadline = proposal_voting_deadline_r(&deps.storage).may_load( - proposal_id.to_string().as_bytes())?.ok_or_else(|| StdError::generic_err("No deadline set"))?; + let voting_deadline = proposal_voting_deadline_r(&deps.storage) + .may_load(proposal_id.to_string().as_bytes())? + .ok_or_else(|| StdError::generic_err("No deadline set"))?; if voting_deadline > env.block.time { Err(StdError::unauthorized()) - } - else if total_votes.yes + total_votes.no + total_votes.abstain < config.minimum_votes { + } else if total_votes.yes + total_votes.no + total_votes.abstain < config.minimum_votes + { Ok(ProposalStatus::Expired) - } - else if total_votes.yes > total_votes.no { + } else if total_votes.yes > total_votes.no { Ok(ProposalStatus::Passed) - } - else { + } else { Ok(ProposalStatus::Rejected) } } @@ -276,15 +321,13 @@ pub fn try_trigger_proposal( code_hash: env.contract_code_hash.clone(), }) } else { - target = supported_contract_r(&deps.storage).may_load( - proposal.target.as_bytes())?; + target = supported_contract_r(&deps.storage).may_load(proposal.target.as_bytes())?; } // Check if proposal passed or has a valid target contract if vote_status != ProposalStatus::Passed { run_status = Failure; - } - else if let Some(target) = target { + } else if let Some(target) = target { run_status = match try_execute_msg(target, proposal.msg) { Ok(msg) => { messages.push(msg); @@ -292,29 +335,25 @@ pub fn try_trigger_proposal( } Err(_) => Failure, }; - } - else { + } else { run_status = Failure; } // Overwrite - proposal_run_status_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &run_status)?; + proposal_run_status_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &run_status)?; proposal_status_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &vote_status)?; - Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::TriggerProposal { + data: Some(to_binary(&HandleAnswer::TriggerProposal { status: run_status, })?), }) } -pub fn try_execute_msg( - contract: Contract, - msg: Binary, -) -> StdResult { +pub fn try_execute_msg(contract: Contract, msg: Binary) -> StdResult { let execute = WasmMsg::Execute { msg, contract_addr: contract.address, @@ -331,30 +370,30 @@ pub fn try_vote( proposal_id: Uint128, votes: VoteTally, ) -> StdResult { - // Check that sender is staking contract and staking is enabled let config = config_r(&deps.storage).load()?; if config.staker.is_none() || config.staker.unwrap().address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Check that proposal is votable - let vote_status = proposal_status_r(&deps.storage).may_load( - proposal_id.to_string().as_bytes())?.ok_or_else(|| StdError::not_found("Proposal"))?; - let voting_deadline = proposal_voting_deadline_r(&deps.storage).may_load( - proposal_id.to_string().as_bytes())?.ok_or_else(|| StdError::generic_err("No deadline set"))?; + let vote_status = proposal_status_r(&deps.storage) + .may_load(proposal_id.to_string().as_bytes())? + .ok_or_else(|| StdError::not_found("Proposal"))?; + let voting_deadline = proposal_voting_deadline_r(&deps.storage) + .may_load(proposal_id.to_string().as_bytes())? + .ok_or_else(|| StdError::generic_err("No deadline set"))?; if vote_status != ProposalStatus::Voting || voting_deadline <= env.block.time { - return Err(StdError::unauthorized()) + return Err(StdError::unauthorized()); } // Get proposal voting state - let mut proposal_voting_state = total_proposal_votes_r(&deps.storage).load( - proposal_id.to_string().as_bytes())?; + let mut proposal_voting_state = + total_proposal_votes_r(&deps.storage).load(proposal_id.to_string().as_bytes())?; // Check if user has already voted - match proposal_votes_r(&deps.storage, proposal_id).may_load( - voter.to_string().as_bytes())? { + match proposal_votes_r(&deps.storage, proposal_id).may_load(voter.to_string().as_bytes())? { None => {} Some(old_votes) => { // Remove those votes from state @@ -370,16 +409,14 @@ pub fn try_vote( proposal_voting_state.abstain += votes.abstain; // Save staker info - total_proposal_votes_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), - &proposal_voting_state)?; + total_proposal_votes_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &proposal_voting_state)?; proposal_votes_w(&mut deps.storage, proposal_id).save(voter.to_string().as_bytes(), &votes)?; Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::MakeVote { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::MakeVote { status: Success })?), }) } @@ -393,25 +430,37 @@ pub fn try_trigger_admin_command( ) -> StdResult { // Check that user is admin if config_r(&deps.storage).load()?.admin != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // First validate that the contract exists let target_contract = match supported_contract_r(&deps.storage).may_load(target.as_bytes())? { - None => return Err(StdError::NotFound { kind: "Contract not found".to_string(), backtrace: None }), + None => { + return Err(StdError::NotFound { + kind: "Contract not found".to_string(), + backtrace: None, + }); + } Some(contract) => contract, }; // Check that command exists let admin_command = match admin_commands_r(&deps.storage).may_load(command.as_bytes())? { - None => return Err(StdError::NotFound { kind: "Command not found".to_string(), backtrace: None }), + None => { + return Err(StdError::NotFound { + kind: "Command not found".to_string(), + backtrace: None, + }); + } Some(admin_c) => admin_c, }; // With command validate that number of variables is equal if admin_command.total_arguments != variables.len() as u16 { return Err(StdError::GenericErr { - msg: "Variable number doesnt match up".to_string(), backtrace: None }) + msg: "Variable number doesnt match up".to_string(), + backtrace: None, + }); } // Replace variable spaces @@ -420,7 +469,7 @@ pub fn try_trigger_admin_command( finished_command = finished_command.replacen(ADMIN_COMMAND_VARIABLE, item, 1); } - let mut messages= vec![]; + let mut messages = vec![]; // Create new proposal ID let proposal_id = total_proposals_w(&mut deps.storage).update(|mut id| { @@ -438,36 +487,31 @@ pub fn try_trigger_admin_command( // Store the proposal proposal_w(&mut deps.storage).save(proposal_id.to_string().as_bytes(), &proposal)?; - proposal_funding_deadline_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), - &env.block.time - )?; - proposal_voting_deadline_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), - &env.block.time - )?; + proposal_funding_deadline_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &env.block.time)?; + proposal_voting_deadline_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &env.block.time)?; proposal_status_w(&mut deps.storage).save( proposal_id.to_string().as_bytes(), - &ProposalStatus::AdminRequested - )?; - let run_status = match try_execute_msg(target_contract, Binary::from(finished_command.as_bytes())) { - Ok(executed_msg) => { - messages.push(executed_msg); - Success - }, - Err(_) => Failure - }; - proposal_run_status_w(&mut deps.storage).save( - proposal_id.to_string().as_bytes(), - &run_status + &ProposalStatus::AdminRequested, )?; + let run_status = + match try_execute_msg(target_contract, Binary::from(finished_command.as_bytes())) { + Ok(executed_msg) => { + messages.push(executed_msg); + Success + } + Err(_) => Failure, + }; + proposal_run_status_w(&mut deps.storage) + .save(proposal_id.to_string().as_bytes(), &run_status)?; Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::TriggerAdminCommand { + data: Some(to_binary(&HandleAnswer::TriggerAdminCommand { status: run_status, - proposal_id + proposal_id, })?), }) } @@ -481,15 +525,14 @@ pub fn try_create_proposal( proposal: Binary, description: String, ) -> StdResult { - let proposal_id = create_proposal(deps, env, target_contract, proposal, description)?; Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::CreateProposal { + data: Some(to_binary(&HandleAnswer::CreateProposal { status: Success, - proposal_id + proposal_id, })?), }) } @@ -505,10 +548,9 @@ pub fn try_update_config( funding_deadline: Option, minimum_votes: Option, ) -> StdResult { - // It has to be self if env.contract.address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } config_w(&mut deps.storage).update(|mut state| { @@ -537,9 +579,7 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateConfig { - status: Success - })?), + data: Some(to_binary(&HandleAnswer::UpdateConfig { status: Success })?), }) } @@ -547,7 +587,6 @@ pub fn try_disable_staker( deps: &mut Extern, _env: &Env, ) -> StdResult { - config_w(&mut deps.storage).update(|mut state| { state.staker = None; Ok(state) @@ -556,9 +595,7 @@ pub fn try_disable_staker( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::DisableStaker { - status: Success - })?), + data: Some(to_binary(&HandleAnswer::DisableStaker { status: Success })?), }) } @@ -568,20 +605,22 @@ pub fn try_add_supported_contract( name: String, contract: Contract, ) -> StdResult { - // It has to be self if env.contract.address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Cannot be the same name as governance default if name == *GOVERNANCE_SELF { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Supported contract cannot exist - if supported_contract_r(&deps.storage).may_load(name.as_bytes())?.is_some() { - return Err(StdError::Unauthorized { backtrace: None }) + if supported_contract_r(&deps.storage) + .may_load(name.as_bytes())? + .is_some() + { + return Err(StdError::Unauthorized { backtrace: None }); } // Save contract @@ -596,8 +635,8 @@ pub fn try_add_supported_contract( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::AddSupportedContract { - status: Success + data: Some(to_binary(&HandleAnswer::AddSupportedContract { + status: Success, })?), }) } @@ -607,15 +646,14 @@ pub fn try_remove_supported_contract( env: &Env, name: String, ) -> StdResult { - // It has to be self if env.contract.address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Cannot be the same name as governance default if name == *GOVERNANCE_SELF { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Remove contract @@ -630,8 +668,8 @@ pub fn try_remove_supported_contract( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::RemoveSupportedContract { - status: Success + data: Some(to_binary(&HandleAnswer::RemoveSupportedContract { + status: Success, })?), }) } @@ -642,22 +680,19 @@ pub fn try_update_supported_contract( name: String, contract: Contract, ) -> StdResult { - // It has to be self and cannot be the same name as governance default if env.contract.address != env.message.sender || name == *GOVERNANCE_SELF { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Replace contract - supported_contract_w(&mut deps.storage).update(name.as_bytes(), |_state| { - Ok(contract) - })?; + supported_contract_w(&mut deps.storage).update(name.as_bytes(), |_state| Ok(contract))?; Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateSupportedContract { - status: Success + data: Some(to_binary(&HandleAnswer::UpdateSupportedContract { + status: Success, })?), }) } @@ -668,15 +703,17 @@ pub fn try_add_admin_command( name: String, proposal: String, ) -> StdResult { - // It has to be self if env.contract.address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Admin command cannot exist - if admin_commands_r(&deps.storage).may_load(name.as_bytes())?.is_some() { - return Err(StdError::Unauthorized { backtrace: None }) + if admin_commands_r(&deps.storage) + .may_load(name.as_bytes())? + .is_some() + { + return Err(StdError::Unauthorized { backtrace: None }); } // Save command @@ -694,8 +731,8 @@ pub fn try_add_admin_command( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::AddAdminCommand { - status: Success + data: Some(to_binary(&HandleAnswer::AddAdminCommand { + status: Success, })?), }) } @@ -705,10 +742,9 @@ pub fn try_remove_admin_command( env: &Env, name: String, ) -> StdResult { - // It has to be self if env.contract.address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Remove command @@ -723,8 +759,8 @@ pub fn try_remove_admin_command( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::RemoveAdminCommand { - status: Success + data: Some(to_binary(&HandleAnswer::RemoveAdminCommand { + status: Success, })?), }) } @@ -735,10 +771,9 @@ pub fn try_update_admin_command( name: String, proposal: String, ) -> StdResult { - // It has to be self if env.contract.address != env.message.sender { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } // Replace contract @@ -752,8 +787,8 @@ pub fn try_update_admin_command( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateAdminCommand { - status: Success + data: Some(to_binary(&HandleAnswer::UpdateAdminCommand { + status: Success, })?), }) -} \ No newline at end of file +} diff --git a/contracts/governance/src/lib.rs b/contracts/governance/src/lib.rs index 391ce9279..d82e1f663 100644 --- a/contracts/governance/src/lib.rs +++ b/contracts/governance/src/lib.rs @@ -1,8 +1,8 @@ pub mod contract; -pub mod state; -pub mod proposal_state; pub mod handle; +pub mod proposal_state; pub mod query; +pub mod state; #[cfg(test)] mod test; @@ -11,7 +11,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/governance/src/proposal_state.rs b/contracts/governance/src/proposal_state.rs index 00188cd85..9c20ddbbf 100644 --- a/contracts/governance/src/proposal_state.rs +++ b/contracts/governance/src/proposal_state.rs @@ -1,10 +1,22 @@ use cosmwasm_std::{Storage, Uint128}; -use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket}; +use cosmwasm_storage::{ + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, +}; +use secret_toolkit::snip20::batch::SendAction; use shade_protocol::{ - governance::{proposal::{Proposal, ProposalStatus}, vote::VoteTally}, generic_response::ResponseStatus, + governance::{ + proposal::{Proposal, ProposalStatus}, + vote::VoteTally, + }, }; -use secret_toolkit::snip20::batch::SendAction; // Proposals pub static PROPOSAL_KEY: &[u8] = b"proposals"; @@ -28,7 +40,7 @@ pub fn total_proposals_r(storage: &S) -> ReadonlySingleton(storage: & S) -> ReadonlyBucket { +pub fn proposal_r(storage: &S) -> ReadonlyBucket { bucket_read(PROPOSAL_KEY, storage) } @@ -37,7 +49,7 @@ pub fn proposal_w(storage: &mut S) -> Bucket { } // Proposal funding deadline -pub fn proposal_funding_deadline_r(storage: & S) -> ReadonlyBucket { +pub fn proposal_funding_deadline_r(storage: &S) -> ReadonlyBucket { bucket_read(PROPOSAL_FUNDING_DEADLINE_KEY, storage) } @@ -46,7 +58,7 @@ pub fn proposal_funding_deadline_w(storage: &mut S) -> Bucket(storage: & S) -> ReadonlyBucket { +pub fn proposal_voting_deadline_r(storage: &S) -> ReadonlyBucket { bucket_read(PROPOSAL_VOTE_DEADLINE_KEY, storage) } @@ -55,7 +67,7 @@ pub fn proposal_voting_deadline_w(storage: &mut S) -> Bucket } // Proposal status -pub fn proposal_status_r(storage: & S) -> ReadonlyBucket { +pub fn proposal_status_r(storage: &S) -> ReadonlyBucket { bucket_read(PROPOSAL_STATUS_KEY, storage) } @@ -64,7 +76,7 @@ pub fn proposal_status_w(storage: &mut S) -> Bucket(storage: & S) -> ReadonlyBucket { +pub fn proposal_funding_r(storage: &S) -> ReadonlyBucket { bucket_read(PROPOSAL_FUNDING_KEY, storage) } @@ -73,7 +85,7 @@ pub fn proposal_funding_w(storage: &mut S) -> Bucket { } // Proposal funding batch -pub fn proposal_funding_batch_r(storage: & S) -> ReadonlyBucket> { +pub fn proposal_funding_batch_r(storage: &S) -> ReadonlyBucket> { bucket_read(PROPOSAL_FUNDING_BATCH_KEY, storage) } @@ -82,7 +94,7 @@ pub fn proposal_funding_batch_w(storage: &mut S) -> Bucket(storage: & S) -> ReadonlyBucket { +pub fn proposal_run_status_r(storage: &S) -> ReadonlyBucket { bucket_read(PROPOSAL_RUN_KEY, storage) } @@ -91,16 +103,25 @@ pub fn proposal_run_status_w(storage: &mut S) -> Bucket(storage: & S, proposal: Uint128) -> ReadonlyBucket { - bucket_read((proposal.to_string() + PROPOSAL_VOTES_KEY).as_bytes(), storage) +pub fn proposal_votes_r( + storage: &S, + proposal: Uint128, +) -> ReadonlyBucket { + bucket_read( + (proposal.to_string() + PROPOSAL_VOTES_KEY).as_bytes(), + storage, + ) } pub fn proposal_votes_w(storage: &mut S, proposal: Uint128) -> Bucket { - bucket((proposal.to_string() + PROPOSAL_VOTES_KEY).as_bytes(), storage) + bucket( + (proposal.to_string() + PROPOSAL_VOTES_KEY).as_bytes(), + storage, + ) } // Total proposal votes -pub fn total_proposal_votes_r(storage: & S) -> ReadonlyBucket { +pub fn total_proposal_votes_r(storage: &S) -> ReadonlyBucket { bucket_read(TOTAL_PROPOSAL_VOTES_KEY, storage) } diff --git a/contracts/governance/src/query.rs b/contracts/governance/src/query.rs index 574ab5f12..7572db8cc 100644 --- a/contracts/governance/src/query.rs +++ b/contracts/governance/src/query.rs @@ -1,33 +1,48 @@ use cosmwasm_std::{Api, Extern, Querier, StdError, StdResult, Storage, Uint128}; -use shade_protocol::governance::{QueryAnswer, proposal::QueriedProposal, proposal::ProposalStatus}; +use shade_protocol::governance::{ + proposal::{ProposalStatus, QueriedProposal}, + QueryAnswer, +}; use crate::{ proposal_state::{ - total_proposals_r, proposal_r, total_proposal_votes_r, proposal_funding_deadline_r, - proposal_voting_deadline_r, proposal_funding_r, proposal_run_status_r, proposal_status_r + proposal_funding_deadline_r, + proposal_funding_r, + proposal_r, + proposal_run_status_r, + proposal_status_r, + proposal_voting_deadline_r, + total_proposal_votes_r, + total_proposals_r, }, state::{ - supported_contracts_list_r, admin_commands_list_r, supported_contract_r, admin_commands_r - } + admin_commands_list_r, + admin_commands_r, + supported_contract_r, + supported_contracts_list_r, + }, }; fn build_proposal( deps: &Extern, - proposal_id: Uint128) -> StdResult { - + proposal_id: Uint128, +) -> StdResult { let proposal = proposal_r(&deps.storage).load(proposal_id.to_string().as_bytes())?; - - Ok(QueriedProposal{ + Ok(QueriedProposal { id: proposal.id, target: proposal.target, msg: proposal.msg, description: proposal.description, - funding_deadline: proposal_funding_deadline_r(&deps.storage).load(proposal_id.to_string().as_bytes())?, - voting_deadline: proposal_voting_deadline_r(&deps.storage).may_load(proposal_id.to_string().as_bytes())?, - total_funding: proposal_funding_r(&deps.storage).load(proposal_id.to_string().as_bytes())?, + funding_deadline: proposal_funding_deadline_r(&deps.storage) + .load(proposal_id.to_string().as_bytes())?, + voting_deadline: proposal_voting_deadline_r(&deps.storage) + .may_load(proposal_id.to_string().as_bytes())?, + total_funding: proposal_funding_r(&deps.storage) + .load(proposal_id.to_string().as_bytes())?, status: proposal_status_r(&deps.storage).load(proposal_id.to_string().as_bytes())?, - run_status: proposal_run_status_r(&deps.storage).may_load(proposal_id.to_string().as_bytes())? + run_status: proposal_run_status_r(&deps.storage) + .may_load(proposal_id.to_string().as_bytes())?, }) } @@ -35,25 +50,28 @@ pub fn proposals( deps: &Extern, start: Uint128, end: Uint128, - status: Option) -> StdResult { - + status: Option, +) -> StdResult { let mut proposals: Vec = vec![]; let max = total_proposals_r(&deps.storage).load()?; if start > max { - return Err(StdError::NotFound { kind: "Proposal doesnt exist".to_string(), backtrace: None }) + return Err(StdError::NotFound { + kind: "Proposal doesnt exist".to_string(), + backtrace: None, + }); } let clamped_start = start.max(Uint128(1)); - for i in clamped_start.u128()..((end +clamped_start).min(max).u128() + 1) { + for i in clamped_start.u128()..((end + clamped_start).min(max).u128() + 1) { let proposal = build_proposal(deps, Uint128(i))?; // Filter proposal by status if it was specified in fn params. if let Some(s) = &status { if s != &proposal.status { - continue + continue; } } proposals.push(proposal) @@ -64,54 +82,60 @@ pub fn proposals( pub fn proposal( deps: &Extern, - proposal_id: Uint128) -> StdResult { - + proposal_id: Uint128, +) -> StdResult { Ok(QueryAnswer::Proposal { - proposal: build_proposal(deps, proposal_id)? + proposal: build_proposal(deps, proposal_id)?, }) } pub fn total_proposals( - deps: &Extern) -> StdResult { - + deps: &Extern, +) -> StdResult { Ok(QueryAnswer::TotalProposals { - total: total_proposals_r(&deps.storage).load()? + total: total_proposals_r(&deps.storage).load()?, }) } pub fn proposal_votes( - deps: &Extern, proposal_id: Uint128) -> StdResult { - + deps: &Extern, + proposal_id: Uint128, +) -> StdResult { Ok(QueryAnswer::ProposalVotes { - status: total_proposal_votes_r(&deps.storage).load(proposal_id.to_string().as_bytes())? + status: total_proposal_votes_r(&deps.storage).load(proposal_id.to_string().as_bytes())?, }) } pub fn supported_contracts( - deps: &Extern) -> StdResult { - + deps: &Extern, +) -> StdResult { Ok(QueryAnswer::SupportedContracts { - contracts: supported_contracts_list_r(&deps.storage).load()? }) + contracts: supported_contracts_list_r(&deps.storage).load()?, + }) } pub fn supported_contract( deps: &Extern, - name: String) -> StdResult { - + name: String, +) -> StdResult { Ok(QueryAnswer::SupportedContract { - contract: supported_contract_r(&deps.storage).load(name.as_bytes())? }) + contract: supported_contract_r(&deps.storage).load(name.as_bytes())?, + }) } pub fn admin_commands( - deps: &Extern) -> StdResult { - - Ok(QueryAnswer::AdminCommands { commands: admin_commands_list_r(&deps.storage).load()? }) + deps: &Extern, +) -> StdResult { + Ok(QueryAnswer::AdminCommands { + commands: admin_commands_list_r(&deps.storage).load()?, + }) } pub fn admin_command( deps: &Extern, - name: String) -> StdResult { - + name: String, +) -> StdResult { Ok(QueryAnswer::AdminCommand { - command: admin_commands_r(&deps.storage).load(name.as_bytes())? }) -} \ No newline at end of file + command: admin_commands_r(&deps.storage).load(name.as_bytes())?, + }) +} diff --git a/contracts/governance/src/state.rs b/contracts/governance/src/state.rs index 4ec9302b6..79875edc3 100644 --- a/contracts/governance/src/state.rs +++ b/contracts/governance/src/state.rs @@ -1,10 +1,18 @@ -use cosmwasm_std::{Storage}; -use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket}; +use cosmwasm_std::Storage; +use cosmwasm_storage::{ + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, +}; use shade_protocol::{ - governance::{Config}, asset::Contract, + governance::{AdminCommand, Config}, }; -use shade_protocol::governance::{AdminCommand}; pub static CONFIG_KEY: &[u8] = b"config"; // Saved contracts @@ -24,7 +32,7 @@ pub fn config_r(storage: &S) -> ReadonlySingleton { // Supported contracts -pub fn supported_contract_r(storage: & S) -> ReadonlyBucket { +pub fn supported_contract_r(storage: &S) -> ReadonlyBucket { bucket_read(CONTRACT_KEY, storage) } @@ -42,7 +50,7 @@ pub fn supported_contracts_list_r(storage: &S) -> ReadonlySingleton< // Admin commands -pub fn admin_commands_r(storage: & S) -> ReadonlyBucket { +pub fn admin_commands_r(storage: &S) -> ReadonlyBucket { bucket_read(ADMIN_COMMANDS_KEY, storage) } diff --git a/contracts/governance/src/test.rs b/contracts/governance/src/test.rs index fa61d3a80..a7eae36bb 100644 --- a/contracts/governance/src/test.rs +++ b/contracts/governance/src/test.rs @@ -1,14 +1,23 @@ #[cfg(test)] mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env}; - use cosmwasm_std::{HumanAddr, Uint128, coins, from_binary, Extern, Storage, Api, Querier}; + use crate::contract; + use cosmwasm_std::{ + coins, + from_binary, + testing::{mock_dependencies, mock_env}, + Api, + Extern, + HumanAddr, + Querier, + Storage, + Uint128, + }; use shade_protocol::{ - generic_response::ResponseStatus, asset::Contract, governance, - governance::{ - proposal::{ProposalStatus, QueriedProposal} - } + asset::Contract, + generic_response::ResponseStatus, + governance, + governance::proposal::{ProposalStatus, QueriedProposal}, }; - use crate::contract; #[test] fn get_proposals_by_status() { @@ -22,29 +31,32 @@ mod tests { staker: None, funding_token: Contract { address: HumanAddr::from(""), - code_hash: String::from("") + code_hash: String::from(""), }, funding_amount: Uint128(1000000), funding_deadline: 180, voting_deadline: 180, // 5 shade is the minimum - quorum: Uint128(5000000) + quorum: Uint128(5000000), }; - let res = contract::init(&mut deps, env, governance_init_msg).unwrap(); + let res = contract::init(&mut deps, env, governance_init_msg).unwrap(); assert_eq!(1, res.messages.len()); // Initialized governance contract has no proposals. let res = contract::query(&deps, governance::QueryMsg::GetProposals { start: Uint128(0), end: Uint128(100), - status: Some(ProposalStatus::Funding) - }).unwrap(); + status: Some(ProposalStatus::Funding), + }) + .unwrap(); let value: governance::QueryAnswer = from_binary(&res).unwrap(); match value { governance::QueryAnswer::Proposals { proposals } => { assert_eq!(0, proposals.len()); } - _ => { panic!("Received wrong answer") } + _ => { + panic!("Received wrong answer") + } } // Create a proposal on governance contract. @@ -53,49 +65,68 @@ mod tests { target_contract: String::from(governance::GOVERNANCE_SELF), proposal: serde_json::to_string(&governance::HandleMsg::AddAdminCommand { name: "random data here".to_string(), - proposal: "{\"update_config\":{\"unbond_time\": {}, \"admin\": null}}".to_string() - }).unwrap(), - description: String::from("Proposal on governance contract") - }).unwrap(); + proposal: "{\"update_config\":{\"unbond_time\": {}, \"admin\": null}}".to_string(), + }) + .unwrap(), + description: String::from("Proposal on governance contract"), + }) + .unwrap(); let value: governance::HandleAnswer = from_binary(&res.data.unwrap()).unwrap(); match value { - governance::HandleAnswer::CreateProposal { status, proposal_id } => { + governance::HandleAnswer::CreateProposal { + status, + proposal_id, + } => { assert_eq!(ResponseStatus::Success, status); assert!(!proposal_id.is_zero()); } - _ => { panic!("Received wrong answer") } + _ => { + panic!("Received wrong answer") + } } // Now we should have single proposal in `funding`. // Should return this proposal when no specific status is specified. - assert_get_proposals(&deps, governance::QueryMsg::GetProposals { - start: Uint128(0), - end: Uint128(100), - status: None - }, |proposals| { - assert_eq!(1, proposals.len()); - assert_eq!(proposals[0].status, ProposalStatus::Funding); - }); + assert_get_proposals( + &deps, + governance::QueryMsg::GetProposals { + start: Uint128(0), + end: Uint128(100), + status: None, + }, + |proposals| { + assert_eq!(1, proposals.len()); + assert_eq!(proposals[0].status, ProposalStatus::Funding); + }, + ); // Should return this proposal when `funding` status is specified. - assert_get_proposals(&deps, governance::QueryMsg::GetProposals { - start: Uint128(0), - end: Uint128(100), - status: Some(ProposalStatus::Funding) - }, |proposals| { - assert_eq!(1, proposals.len()); - assert_eq!(proposals[0].status, ProposalStatus::Funding); - }); + assert_get_proposals( + &deps, + governance::QueryMsg::GetProposals { + start: Uint128(0), + end: Uint128(100), + status: Some(ProposalStatus::Funding), + }, + |proposals| { + assert_eq!(1, proposals.len()); + assert_eq!(proposals[0].status, ProposalStatus::Funding); + }, + ); // Shouldn't return this proposal when querying by status different from `funding`. - assert_get_proposals(&deps, governance::QueryMsg::GetProposals { - start: Uint128(0), - end: Uint128(100), - status: Some(ProposalStatus::Voting) - }, |proposals| { - assert_eq!(0, proposals.len()); - }); + assert_get_proposals( + &deps, + governance::QueryMsg::GetProposals { + start: Uint128(0), + end: Uint128(100), + status: Some(ProposalStatus::Voting), + }, + |proposals| { + assert_eq!(0, proposals.len()); + }, + ); } /// @@ -110,15 +141,15 @@ mod tests { pub fn assert_get_proposals( deps: &Extern, msg: governance::QueryMsg, - assert_fn: fn(result: Vec) + assert_fn: fn(result: Vec), ) { let res = contract::query(&deps, msg).unwrap(); let value: governance::QueryAnswer = from_binary(&res).unwrap(); match value { - governance::QueryAnswer::Proposals { proposals } => { - assert_fn(proposals) + governance::QueryAnswer::Proposals { proposals } => assert_fn(proposals), + _ => { + panic!("Received wrong answer") } - _ => { panic!("Received wrong answer") } } } } diff --git a/contracts/initializer/src/contract.rs b/contracts/initializer/src/contract.rs index e8b12438f..1d2aa7e81 100644 --- a/contracts/initializer/src/contract.rs +++ b/contracts/initializer/src/contract.rs @@ -1,17 +1,32 @@ -use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdResult, Storage}; -use crate::state::{config_w}; -use shade_protocol::initializer::{InitMsg, InitializerConfig, HandleMsg, QueryMsg, Snip20InitHistory}; +use crate::{query::query_contracts, state::config_w}; +use cosmwasm_std::{ + debug_print, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, +}; use secret_toolkit::utils::InitCallback; -use crate::query::query_contracts; +use shade_protocol::initializer::{ + HandleMsg, + InitMsg, + InitializerConfig, + QueryMsg, + Snip20InitHistory, +}; pub fn init( deps: &mut Extern, env: Env, msg: InitMsg, ) -> StdResult { - let mut state = InitializerConfig { - contracts: vec![], - }; + let mut state = InitializerConfig { contracts: vec![] }; let mut messages = vec![]; @@ -21,7 +36,7 @@ pub fn init( enable_deposit: Option::from(false), enable_redeem: Option::from(false), enable_mint: Option::from(true), - enable_burn: Option::from(true) + enable_burn: Option::from(true), }); // Initialize Silk @@ -29,51 +44,54 @@ pub fn init( name: "Silk".to_string(), admin: Option::from(match msg.silk.admin { None => env.message.sender.clone(), - Some(admin) => admin + Some(admin) => admin, }), symbol: "SILK".to_string(), decimals: 6, initial_balances: msg.silk.initial_balances.clone(), prng_seed: msg.silk.prng_seed, - config: coin_config.clone() + config: coin_config.clone(), }; state.contracts.push(Snip20InitHistory { label: msg.silk.label.clone(), balances: msg.silk.initial_balances.clone(), }); - messages.push(silk_init_msg.to_cosmos_msg(msg.silk.label.clone(), - msg.snip20_id, - msg.snip20_code_hash.clone(), - None)?); - + messages.push(silk_init_msg.to_cosmos_msg( + msg.silk.label.clone(), + msg.snip20_id, + msg.snip20_code_hash.clone(), + None, + )?); // Initialize Shade let shade_init_msg = shade_protocol::snip20::InitMsg { name: "Shade".to_string(), admin: Option::from(match msg.shade.admin { None => env.message.sender.clone(), - Some(admin) => admin + Some(admin) => admin, }), symbol: "SHD".to_string(), decimals: 6, initial_balances: msg.shade.initial_balances.clone(), prng_seed: msg.shade.prng_seed, - config: coin_config + config: coin_config, }; - state.contracts.push(Snip20InitHistory{ + state.contracts.push(Snip20InitHistory { label: msg.shade.label.clone(), - balances: msg.shade.initial_balances.clone() + balances: msg.shade.initial_balances.clone(), }); - messages.push(shade_init_msg.to_cosmos_msg(msg.shade.label.clone(), - msg.snip20_id, - msg.snip20_code_hash.clone(), - None)?); + messages.push(shade_init_msg.to_cosmos_msg( + msg.shade.label.clone(), + msg.snip20_id, + msg.snip20_code_hash.clone(), + None, + )?); debug_print!("Contract was initialized by {}", env.message.sender); config_w(&mut deps.storage).save(&state)?; Ok(InitResponse { messages, - log: vec![] + log: vec![], }) } @@ -85,7 +103,7 @@ pub fn handle( Ok(HandleResponse { messages: vec![], log: vec![], - data: None + data: None, }) } diff --git a/contracts/initializer/src/lib.rs b/contracts/initializer/src/lib.rs index eefc8eff7..03ea1d570 100644 --- a/contracts/initializer/src/lib.rs +++ b/contracts/initializer/src/lib.rs @@ -1,12 +1,17 @@ pub mod contract; -pub mod state; pub mod query; +pub mod state; #[cfg(target_arch = "wasm32")] mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/initializer/src/query.rs b/contracts/initializer/src/query.rs index bea3f503a..4d01c5b68 100644 --- a/contracts/initializer/src/query.rs +++ b/contracts/initializer/src/query.rs @@ -1,7 +1,11 @@ -use cosmwasm_std::{Storage, Api, Querier, Extern, StdResult}; -use shade_protocol::initializer::QueryAnswer; use crate::state::config_r; +use cosmwasm_std::{Api, Extern, Querier, StdResult, Storage}; +use shade_protocol::initializer::QueryAnswer; -pub fn query_contracts(deps: &Extern) -> StdResult { - Ok(QueryAnswer::Contracts { contracts: config_r(&deps.storage).load()?.contracts }) +pub fn query_contracts( + deps: &Extern, +) -> StdResult { + Ok(QueryAnswer::Contracts { + contracts: config_r(&deps.storage).load()?.contracts, + }) } diff --git a/contracts/micro_mint/src/contract.rs b/contracts/micro_mint/src/contract.rs index 3c2fb60f3..1dc2cb0e9 100644 --- a/contracts/micro_mint/src/contract.rs +++ b/contracts/micro_mint/src/contract.rs @@ -1,39 +1,40 @@ -use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdResult, Storage, Uint128}; +use cosmwasm_std::{ + debug_print, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, + Uint128, +}; use secret_toolkit::snip20::token_info_query; use shade_protocol::{ - micro_mint::{ - InitMsg, HandleMsg, - QueryMsg, Config, - }, - snip20::{ - Snip20Asset, - token_config_query, - }, + micro_mint::{Config, HandleMsg, InitMsg, QueryMsg}, + snip20::{token_config_query, Snip20Asset}, }; use crate::{ - state::{ - config_w, - native_asset_w, - asset_peg_w, - asset_list_w, - }, - handle, query, + handle, + query, + state::{asset_list_w, asset_peg_w, config_w, limit_w, native_asset_w}, }; use shade_protocol::micro_mint::MintLimit; -use crate::state::limit_w; pub fn init( deps: &mut Extern, env: Env, msg: InitMsg, ) -> StdResult { - let state = Config { admin: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } + None => env.message.sender.clone(), + Some(admin) => admin, }, oracle: msg.oracle, treasury: msg.treasury, @@ -49,7 +50,7 @@ pub fn init( }, mint_capacity: match msg.epoch_mint_limit { None => Uint128(0), - Some(capacity) => capacity + Some(capacity) => capacity, }, total_minted: Uint128(0), next_epoch: match msg.epoch_frequency { @@ -66,16 +67,17 @@ pub fn init( config_w(&mut deps.storage).save(&state)?; let token_info = token_info_query( - &deps.querier, 1, - msg.native_asset.code_hash.clone(), - msg.native_asset.address.clone())?; + &deps.querier, + 1, + msg.native_asset.code_hash.clone(), + msg.native_asset.address.clone(), + )?; - let token_config = token_config_query(&deps.querier, - msg.native_asset.clone())?; + let token_config = token_config_query(&deps.querier, msg.native_asset.clone())?; let peg = match msg.peg { - Some(p) => { p } - None => { token_info.symbol.clone() } + Some(p) => p, + None => token_info.symbol.clone(), }; asset_peg_w(&mut deps.storage).save(&peg)?; @@ -93,7 +95,7 @@ pub fn init( Ok(InitResponse { messages: vec![], - log: vec![] + log: vec![], }) } @@ -114,19 +116,17 @@ pub fn handle( epoch_frequency, epoch_limit, } => handle::try_update_limit(deps, env, start_epoch, epoch_frequency, epoch_limit), - HandleMsg::RegisterAsset { - contract, - capture, - } => handle::try_register_asset(deps, &env, &contract, capture), - HandleMsg::RemoveAsset { - address - } => handle::try_remove_asset(deps, &env, address), + HandleMsg::RegisterAsset { contract, capture } => { + handle::try_register_asset(deps, &env, &contract, capture) + } + HandleMsg::RemoveAsset { address } => handle::try_remove_asset(deps, &env, address), HandleMsg::Receive { sender, from, amount, msg, - ..} => handle::try_burn(deps, env, sender, from, amount, msg), + .. + } => handle::try_burn(deps, env, sender, from, amount, msg), } } diff --git a/contracts/micro_mint/src/handle.rs b/contracts/micro_mint/src/handle.rs index 8e5ff7499..01e473115 100644 --- a/contracts/micro_mint/src/handle.rs +++ b/contracts/micro_mint/src/handle.rs @@ -1,38 +1,45 @@ -use std::cmp::Ordering; -use std::convert::TryFrom; -use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, Querier, StdError, StdResult, Storage, CosmosMsg, HumanAddr, Uint128, from_binary}; +use cosmwasm_std::{ + debug_print, + from_binary, + to_binary, + Api, + Binary, + CosmosMsg, + Env, + Extern, + HandleResponse, + HumanAddr, + Querier, + StdError, + StdResult, + Storage, + Uint128, +}; use secret_toolkit::{ - snip20::{ - token_info_query, - mint_msg, burn_msg, send_msg, - register_receive_msg, - }, + snip20::{burn_msg, mint_msg, register_receive_msg, send_msg, token_info_query}, + utils::Query, }; -use secret_toolkit::utils::Query; use shade_protocol::{ - micro_mint::{ - HandleAnswer, - Config, - SupportedAsset, - }, - mint::MintMsgHook, - snip20::{Snip20Asset, token_config_query, TokenConfig}, - oracle::{ - QueryMsg::Price, - }, - band::ReferenceData, asset::Contract, + band::ReferenceData, generic_response::ResponseStatus, + micro_mint::{Config, HandleAnswer, SupportedAsset}, + mint::MintMsgHook, + oracle::QueryMsg::Price, + snip20::{token_config_query, Snip20Asset, TokenConfig}, }; +use std::{cmp::Ordering, convert::TryFrom}; use crate::state::{ - config_w, config_r, - native_asset_r, - asset_peg_r, - assets_w, assets_r, - asset_list_w, - total_burned_w, - limit_w + asset_list_w, + asset_peg_r, + assets_r, + assets_w, + config_r, + config_w, + limit_w, + native_asset_r, + total_burned_w, }; pub fn try_burn( @@ -43,7 +50,6 @@ pub fn try_burn( amount: Uint128, msg: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check if contract enabled if !config.activated { @@ -54,25 +60,30 @@ pub fn try_burn( // Prevent sender to be native asset if mint_asset.contract.address == env.message.sender { - return Err(StdError::generic_err("Sender cannot be the same as the native asset.")) + return Err(StdError::generic_err( + "Sender cannot be the same as the native asset.", + )); } // Check that sender is a supported snip20 asset let assets = assets_r(&deps.storage); let burn_asset = match assets.may_load(env.message.sender.to_string().as_bytes())? { Some(supported_asset) => { - debug_print!("Found Burn Asset: {} {}", - &supported_asset.asset.token_info.symbol, - env.message.sender.to_string()); + debug_print!( + "Found Burn Asset: {} {}", + &supported_asset.asset.token_info.symbol, + env.message.sender.to_string() + ); supported_asset - }, - None => return Err(StdError::NotFound { - kind: env.message.sender.to_string(), - backtrace: None - }), + } + None => { + return Err(StdError::NotFound { + kind: env.message.sender.to_string(), + backtrace: None, + }); + } }; - // This will calculate the total mint value let amount_to_mint: Uint128 = mint_amount(deps, amount, &burn_asset, &mint_asset)?; @@ -84,7 +95,9 @@ pub fn try_burn( // Check against slippage amount if amount_to_mint < msgs.minimum_expected_amount { - return Err(StdError::generic_err("Mint amount is less than the minimum expected.")) + return Err(StdError::generic_err( + "Mint amount is less than the minimum expected.", + )); } // Check against mint cap @@ -102,7 +115,9 @@ pub fn try_burn( let new_total = limit.total_minted + amount_to_mint; if new_total > limit.mint_capacity { - return Err(StdError::generic_err("Amount to be minted exceeds mint capacity")) + return Err(StdError::generic_err( + "Amount to be minted exceeds mint capacity", + )); } limit.total_minted = new_total; @@ -117,13 +132,15 @@ pub fn try_burn( let capture_amount = calculate_capture(amount, burn_asset.capture); // Commission to treasury - messages.push(send_msg(treasury.address, - capture_amount, - None, - None, - 1, - burn_asset.asset.contract.code_hash.clone(), - burn_asset.asset.contract.address.clone())?); + messages.push(send_msg( + treasury.address, + capture_amount, + None, + None, + 1, + burn_asset.asset.contract.code_hash.clone(), + burn_asset.asset.contract.address.clone(), + )?); burn_amount = (amount - capture_amount)?; } @@ -132,32 +149,44 @@ pub fn try_burn( // Try to burn if let Some(token_config) = &burn_asset.asset.token_config { if token_config.burn_enabled { - messages.push(burn_msg(burn_amount, None, 256, - burn_asset.asset.contract.code_hash.clone(), - burn_asset.asset.contract.address.clone())?); - } - else if let Some(recipient) = config.secondary_burn { - messages.push(send_msg(recipient, burn_amount, None, None, 1, - burn_asset.asset.contract.code_hash.clone(), - burn_asset.asset.contract.address.clone())?) + messages.push(burn_msg( + burn_amount, + None, + 256, + burn_asset.asset.contract.code_hash.clone(), + burn_asset.asset.contract.address.clone(), + )?); + } else if let Some(recipient) = config.secondary_burn { + messages.push(send_msg( + recipient, + burn_amount, + None, + None, + 1, + burn_asset.asset.contract.code_hash.clone(), + burn_asset.asset.contract.address.clone(), + )?) } - - } - else if let Some(recipient) = config.secondary_burn { - messages.push(send_msg(recipient, burn_amount, None, None, 1, - burn_asset.asset.contract.code_hash.clone(), - burn_asset.asset.contract.address.clone())?) + } else if let Some(recipient) = config.secondary_burn { + messages.push(send_msg( + recipient, + burn_amount, + None, + None, + 1, + burn_asset.asset.contract.code_hash.clone(), + burn_asset.asset.contract.address.clone(), + )?) } // Update burned amount total_burned_w(&mut deps.storage).update( burn_asset.asset.contract.address.to_string().as_bytes(), - |burned| { - match burned { - Some(burned) => { Ok(burned + burn_amount) } - None => { Ok(burn_amount) } - } - })?; + |burned| match burned { + Some(burned) => Ok(burned + burn_amount), + None => Ok(burn_amount), + }, + )?; let mint_asset = native_asset_r(&deps.storage).load()?; @@ -166,7 +195,9 @@ pub fn try_burn( // Check against slippage amount if amount_to_mint < msgs.minimum_expected_amount { - return Err(StdError::generic_err("Mint amount is less than the minimum expected.")) + return Err(StdError::generic_err( + "Mint amount is less than the minimum expected.", + )); } // Check against mint cap @@ -184,7 +215,9 @@ pub fn try_burn( let new_total = limit.total_minted + amount_to_mint; if new_total > limit.mint_capacity { - return Err(StdError::generic_err("Amount to be minted exceeds mint capacity")) + return Err(StdError::generic_err( + "Amount to be minted exceeds mint capacity", + )); } limit.total_minted = new_total; @@ -192,22 +225,28 @@ pub fn try_burn( limit_storage.save(&limit)?; } - debug_print!("Minting: {} {}", amount_to_mint, &mint_asset.token_info.symbol); + debug_print!( + "Minting: {} {}", + amount_to_mint, + &mint_asset.token_info.symbol + ); - messages.push(mint_msg(from, - amount_to_mint, - None, - 256, - mint_asset.contract.code_hash.clone(), - mint_asset.contract.address)?); + messages.push(mint_msg( + from, + amount_to_mint, + None, + 256, + mint_asset.contract.code_hash.clone(), + mint_asset.contract.address, + )?); Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::Burn { + data: Some(to_binary(&HandleAnswer::Burn { status: ResponseStatus::Success, - mint_amount: amount_to_mint - } )? ), + mint_amount: amount_to_mint, + })?), }) } @@ -219,7 +258,6 @@ pub fn try_update_config( treasury: Option, secondary_burn: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check if admin if env.message.sender != config.admin { @@ -251,8 +289,9 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateConfig { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateConfig { + status: ResponseStatus::Success, + })?), }) } @@ -288,11 +327,9 @@ pub fn try_update_limit( // Reset next epoch if state.frequency == 0 { state.next_epoch = 0; - } - else if let Some(next_epoch) = start_epoch { + } else if let Some(next_epoch) = start_epoch { state.next_epoch = next_epoch.u128() as u64; - } - else { + } else { state.next_epoch = env.block.time + state.frequency; } Ok(state) @@ -301,8 +338,9 @@ pub fn try_update_limit( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateMintLimit { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateMintLimit { + status: ResponseStatus::Success, + })?), }) } @@ -310,9 +348,8 @@ pub fn try_register_asset( deps: &mut Extern, env: &Env, contract: &Contract, - capture: Option + capture: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check if admin if env.message.sender != config.admin { @@ -327,14 +364,18 @@ pub fn try_register_asset( let contract_str = contract.address.to_string(); // Add the new asset - let asset_info = token_info_query(&deps.querier, 1, - contract.code_hash.clone(), - contract.address.clone())?; + let asset_info = token_info_query( + &deps.querier, + 1, + contract.code_hash.clone(), + contract.address.clone(), + )?; - let asset_config: Option = match token_config_query(&deps.querier, contract.clone()) { - Ok(c) => { Option::from(c) } - Err(_) => { None } - }; + let asset_config: Option = + match token_config_query(&deps.querier, contract.clone()) { + Ok(c) => Option::from(c), + Err(_) => None, + }; debug_print!("Registering {}", asset_info.symbol); assets.save(contract_str.as_bytes(), &SupportedAsset { @@ -346,8 +387,8 @@ pub fn try_register_asset( // If capture is not set then default to 0 capture: match capture { None => Uint128(0), - Some(value) => value - } + Some(value) => value, + }, })?; total_burned_w(&mut deps.storage).save(contract_str.as_bytes(), &Uint128(0))?; @@ -364,20 +405,17 @@ pub fn try_register_asset( Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( - &HandleAnswer::RegisterAsset { - status: ResponseStatus::Success } - )? - ) + data: Some(to_binary(&HandleAnswer::RegisterAsset { + status: ResponseStatus::Success, + })?), }) } pub fn try_remove_asset( deps: &mut Extern, _env: &Env, - address: HumanAddr + address: HumanAddr, ) -> StdResult { - let address_str = address.to_string(); // Remove asset from the array @@ -394,17 +432,13 @@ pub fn try_remove_asset( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( - &HandleAnswer::RemoveAsset { - status: ResponseStatus::Success } - )?) + data: Some(to_binary(&HandleAnswer::RemoveAsset { + status: ResponseStatus::Success, + })?), }) } -pub fn register_receive ( - env: &Env, - contract: &Contract, -) -> StdResult { +pub fn register_receive(env: &Env, contract: &Contract) -> StdResult { register_receive_msg( env.contract_code_hash.clone(), None, @@ -418,14 +452,14 @@ pub fn mint_amount( deps: &Extern, burn_amount: Uint128, burn_asset: &SupportedAsset, - mint_asset: &Snip20Asset, + mint_asset: &Snip20Asset, ) -> StdResult { - - - debug_print!("Burning {} {} for {}", - burn_amount, - burn_asset.asset.token_info.symbol, - mint_asset.token_info.symbol); + debug_print!( + "Burning {} {} for {}", + burn_amount, + burn_asset.asset.token_info.symbol, + mint_asset.token_info.symbol + ); let burn_price = oracle(deps, burn_asset.asset.token_info.symbol.clone())?; debug_print!("Burn Price: {}", burn_price); @@ -433,13 +467,22 @@ pub fn mint_amount( let mint_price = oracle(deps, asset_peg_r(&deps.storage).load()?)?; debug_print!("Mint Price: {}", mint_price); - Ok(calculate_mint(burn_price, burn_amount, burn_asset.asset.token_info.decimals, - mint_price, mint_asset.token_info.decimals)) + Ok(calculate_mint( + burn_price, + burn_amount, + burn_asset.asset.token_info.decimals, + mint_price, + mint_asset.token_info.decimals, + )) } -pub fn calculate_mint(burn_price: Uint128, burn_amount: Uint128, burn_decimals: u8, - mint_price: Uint128, mint_decimals: u8 - ) -> Uint128 { +pub fn calculate_mint( + burn_price: Uint128, + burn_amount: Uint128, + burn_decimals: u8, + mint_price: Uint128, + mint_decimals: u8, +) -> Uint128 { // Math must only be made in integers // in_decimals = x // target_decimals = y @@ -461,34 +504,35 @@ pub fn calculate_mint(burn_price: Uint128, burn_amount: Uint128, burn_decimals: // To avoid a mess of different types doing math match difference.cmp(&0) { - Ordering::Greater => Uint128(burn_value.u128() * 10u128.pow(u32::try_from(difference).unwrap())), - Ordering::Less => burn_value.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())), - Ordering::Equal => burn_value + Ordering::Greater => { + Uint128(burn_value.u128() * 10u128.pow(u32::try_from(difference).unwrap())) + } + Ordering::Less => { + burn_value.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())) + } + Ordering::Equal => burn_value, } } -pub fn calculate_capture( - amount: Uint128, capture: Uint128 -) -> Uint128 { +pub fn calculate_capture(amount: Uint128, capture: Uint128) -> Uint128 { /* amount: total amount sent to burn (uSSCRT/uSILK/uSHD) * capture: capture_percent * 10,000 e.g. 532 = 5.32% = .0532 * * capture_amount = amount * capture / 10000 */ - amount.multiply_ratio(capture, 10000u128) + amount.multiply_ratio(capture, 10000u128) } fn oracle( deps: &Extern, symbol: String, ) -> StdResult { - let config: Config = config_r(&deps.storage).load()?; - let answer: ReferenceData = Price { - symbol - }.query(&deps.querier, - config.oracle.code_hash, - config.oracle.address)?; + let answer: ReferenceData = Price { symbol }.query( + &deps.querier, + config.oracle.code_hash, + config.oracle.address, + )?; Ok(answer.rate) } diff --git a/contracts/micro_mint/src/lib.rs b/contracts/micro_mint/src/lib.rs index 14d4d23b1..84be1cef6 100644 --- a/contracts/micro_mint/src/lib.rs +++ b/contracts/micro_mint/src/lib.rs @@ -1,7 +1,7 @@ pub mod contract; -pub mod state; pub mod handle; pub mod query; +pub mod state; #[cfg(test)] mod test; @@ -10,7 +10,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/micro_mint/src/query.rs b/contracts/micro_mint/src/query.rs index 97df2426f..73c382760 100644 --- a/contracts/micro_mint/src/query.rs +++ b/contracts/micro_mint/src/query.rs @@ -1,46 +1,58 @@ -use cosmwasm_std::{ - Api, Extern, Querier, StdError, StdResult, Storage, -}; -use crate::state::{config_r, native_asset_r, asset_peg_r, assets_r, asset_list_r, - total_burned_r, limit_r}; -use shade_protocol::{ - micro_mint::{ - QueryAnswer - }, +use crate::state::{ + asset_list_r, + asset_peg_r, + assets_r, + config_r, + limit_r, + native_asset_r, + total_burned_r, }; +use cosmwasm_std::{Api, Extern, Querier, StdError, StdResult, Storage}; +use shade_protocol::micro_mint::QueryAnswer; -pub fn native_asset -(deps: &Extern) -> StdResult { - Ok(QueryAnswer::NativeAsset { asset: native_asset_r(&deps.storage).load()?, - peg: asset_peg_r(&deps.storage).load()? }) +pub fn native_asset( + deps: &Extern, +) -> StdResult { + Ok(QueryAnswer::NativeAsset { + asset: native_asset_r(&deps.storage).load()?, + peg: asset_peg_r(&deps.storage).load()?, + }) } -pub fn supported_assets -(deps: &Extern) -> StdResult { - Ok(QueryAnswer::SupportedAssets { assets: asset_list_r(&deps.storage).load()? }) +pub fn supported_assets( + deps: &Extern, +) -> StdResult { + Ok(QueryAnswer::SupportedAssets { + assets: asset_list_r(&deps.storage).load()?, + }) } -pub fn asset -(deps: &Extern, contract: String) -> StdResult { +pub fn asset( + deps: &Extern, + contract: String, +) -> StdResult { let assets = assets_r(&deps.storage); return match assets.may_load(contract.as_bytes())? { - Some(asset) => { - Ok(QueryAnswer::Asset { - asset, - burned: total_burned_r(&deps.storage).load(contract.as_bytes())?, - }) - } - None => Err(StdError::NotFound { kind: contract, backtrace: None }), + Some(asset) => Ok(QueryAnswer::Asset { + asset, + burned: total_burned_r(&deps.storage).load(contract.as_bytes())?, + }), + None => Err(StdError::NotFound { + kind: contract, + backtrace: None, + }), }; } -pub fn config -(deps: &Extern) -> StdResult { - Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()? }) +pub fn config(deps: &Extern) -> StdResult { + Ok(QueryAnswer::Config { + config: config_r(&deps.storage).load()?, + }) } -pub fn limit -(deps: &Extern) -> StdResult { - Ok(QueryAnswer::MintLimit { limit: limit_r(&deps.storage).load()? }) +pub fn limit(deps: &Extern) -> StdResult { + Ok(QueryAnswer::MintLimit { + limit: limit_r(&deps.storage).load()?, + }) } diff --git a/contracts/micro_mint/src/state.rs b/contracts/micro_mint/src/state.rs index c8fb70ca6..17c68cf8d 100644 --- a/contracts/micro_mint/src/state.rs +++ b/contracts/micro_mint/src/state.rs @@ -1,7 +1,16 @@ use cosmwasm_std::{Storage, Uint128}; -use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket}; +use cosmwasm_storage::{ + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, +}; use shade_protocol::{ - micro_mint::{Config, SupportedAsset, MintLimit}, + micro_mint::{Config, MintLimit, SupportedAsset}, snip20::Snip20Asset, }; @@ -53,7 +62,7 @@ pub fn asset_list_r(storage: &S) -> ReadonlySingleton singleton_read(storage, ASSET_LIST_KEY) } -pub fn assets_r(storage: & S) -> ReadonlyBucket { +pub fn assets_r(storage: &S) -> ReadonlyBucket { bucket_read(ASSET_KEY, storage) } @@ -61,7 +70,7 @@ pub fn assets_w(storage: &mut S) -> Bucket { bucket(ASSET_KEY, storage) } -pub fn total_burned_r(storage: & S) -> ReadonlyBucket { +pub fn total_burned_r(storage: &S) -> ReadonlyBucket { bucket_read(BURN_COUNT_KEY, storage) } diff --git a/contracts/micro_mint/src/test.rs b/contracts/micro_mint/src/test.rs index 2ede162dc..6c75ae70b 100644 --- a/contracts/micro_mint/src/test.rs +++ b/contracts/micro_mint/src/test.rs @@ -1,52 +1,42 @@ #[cfg(test)] pub mod tests { use cosmwasm_std::{ - testing::{ - mock_dependencies, mock_env, MockStorage, MockApi, MockQuerier - }, - coins, from_binary, StdError, Uint128, + coins, + from_binary, + testing::{mock_dependencies, mock_env, MockApi, MockQuerier, MockStorage}, Extern, + StdError, + Uint128, }; + use mockall_double::double; use shade_protocol::{ - micro_mint::{ - QueryAnswer, InitMsg, HandleMsg, - QueryMsg, - }, asset::Contract, + micro_mint::{HandleMsg, InitMsg, QueryAnswer, QueryMsg}, }; - use mockall_double::double; use crate::{ - contract::{ - init, handle, query, - }, - handle::{ - calculate_capture, - calculate_mint, - try_burn, - }, + contract::{handle, init, query}, + handle::{calculate_capture, calculate_mint, try_burn}, }; mod mock_secret_toolkit { - - use cosmwasm_std::{Querier, HumanAddr, StdResult, Uint128}; - use secret_toolkit::snip20::TokenInfo; - - pub fn mock_token_info_query( - _querier: &Q, - _block_size: usize, - _callback_code_hash: String, - _contract_addr: HumanAddr, - ) -> StdResult { - Ok(TokenInfo { - name: "Token".to_string(), - symbol: "TKN".to_string(), - decimals: 6, - total_supply: Option::from(Uint128(150)), - }) - } - + use cosmwasm_std::{HumanAddr, Querier, StdResult, Uint128}; + use secret_toolkit::snip20::TokenInfo; + + pub fn mock_token_info_query( + _querier: &Q, + _block_size: usize, + _callback_code_hash: String, + _contract_addr: HumanAddr, + ) -> StdResult { + Ok(TokenInfo { + name: "Token".to_string(), + symbol: "TKN".to_string(), + decimals: 6, + total_supply: Option::from(Uint128(150)), + }) + } } #[double] @@ -54,13 +44,20 @@ pub mod tests { fn create_contract(address: &str, code_hash: &str) -> Contract { let env = mock_env(address.to_string(), &[]); - return Contract{ + return Contract { address: env.message.sender, - code_hash: code_hash.to_string() - } + code_hash: code_hash.to_string(), + }; } - fn dummy_init(admin: String, native_asset: Contract, oracle: Contract, peg: Option, treasury: Option, capture: Option) -> Extern { + fn dummy_init( + admin: String, + native_asset: Contract, + oracle: Contract, + peg: Option, + treasury: Option, + capture: Option, + ) -> Extern { let mut deps = mock_dependencies(20, &[]); let msg = InitMsg { admin: None, @@ -71,12 +68,12 @@ pub mod tests { secondary_burn: None, start_epoch: None, epoch_frequency: None, - epoch_mint_limit: None + epoch_mint_limit: None, }; let env = mock_env(admin, &coins(1000, "earth")); let _res = init(&mut deps, env, msg).unwrap(); - return deps + return deps; } #[test] @@ -179,7 +176,7 @@ pub mod tests { create_contract("", ""), create_contract("", ""), None, - None, + None, None); // Admin should be allowed to add an item @@ -369,7 +366,6 @@ pub mod tests { } } */ - #[test] fn capture_calc() { let amount = Uint128(1_000_000_000_000_000_000); diff --git a/contracts/mint/src/contract.rs b/contracts/mint/src/contract.rs index eaa08a60a..1d5b4be9f 100644 --- a/contracts/mint/src/contract.rs +++ b/contracts/mint/src/contract.rs @@ -1,20 +1,43 @@ -use std::cmp::Ordering; -use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdError, StdResult, Storage, CosmosMsg, HumanAddr, Uint128, from_binary}; -use crate::state::{config, config_read, assets_w, assets_r, asset_list, asset_list_read}; +use crate::state::{asset_list, asset_list_read, assets_r, assets_w, config, config_read}; +use cosmwasm_std::{ + debug_print, + from_binary, + to_binary, + Api, + Binary, + CosmosMsg, + Env, + Extern, + HandleResponse, + HumanAddr, + InitResponse, + Querier, + StdError, + StdResult, + Storage, + Uint128, +}; use secret_toolkit::{ - snip20::{mint_msg, burn_msg, register_receive_msg, token_info_query, minters_query}, - utils::{InitCallback, Query} + snip20::{burn_msg, mint_msg, minters_query, register_receive_msg, token_info_query}, + utils::{InitCallback, Query}, }; use shade_protocol::{ - mint::{InitMsg, HandleMsg, HandleAnswer, QueryMsg, QueryAnswer, MintConfig, SupportedAsset, SnipMsgHook}, - oracle::{ - QueryMsg::Price, - }, + asset::Contract, band::ReferenceData, - asset::{Contract}, generic_response::ResponseStatus, + mint::{ + HandleAnswer, + HandleMsg, + InitMsg, + MintConfig, + QueryAnswer, + QueryMsg, + SnipMsgHook, + SupportedAsset, + }, + oracle::QueryMsg::Price, }; -use std::convert::TryFrom; +use std::{cmp::Ordering, convert::TryFrom}; // TODO: add remove asset // TODO: add spacepad padding @@ -25,8 +48,8 @@ pub fn init( ) -> StdResult { let state = MintConfig { owner: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } + None => env.message.sender.clone(), + Some(admin) => admin, }, oracle: msg.oracle, activated: true, @@ -47,7 +70,7 @@ pub fn init( Ok(InitResponse { messages, - log: vec![] + log: vec![], }) } @@ -60,12 +83,9 @@ pub fn handle( HandleMsg::Migrate { code_id, code_hash, - label + label, } => try_migrate(deps, env, label, code_id, code_hash), - HandleMsg::UpdateConfig { - owner, - oracle - } => try_update_config(deps, env, owner, oracle), + HandleMsg::UpdateConfig { owner, oracle } => try_update_config(deps, env, owner, oracle), HandleMsg::RegisterAsset { name, contract, @@ -77,7 +97,8 @@ pub fn handle( from, amount, msg, - ..} => try_burn(deps, env, sender, from, amount, msg), + .. + } => try_burn(deps, env, sender, from, amount, msg), } } @@ -107,20 +128,21 @@ pub fn try_migrate( if let Some(item) = assets.may_load(asset_addr.as_bytes())? { initial_assets.push(item) } - }; + } // Move config let init_msg = InitMsg { admin: Option::from(config_read.owner), oracle: config_read.oracle, - initial_assets: Some(initial_assets) + initial_assets: Some(initial_assets), }; Ok(HandleResponse { messages: vec![init_msg.to_cosmos_msg(label, code_id, code_hash, None)?], log: vec![], - data: Some( to_binary( &HandleAnswer::Migrate { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::Migrate { + status: ResponseStatus::Success, + })?), }) } @@ -149,8 +171,9 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateConfig { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateConfig { + status: ResponseStatus::Success, + })?), }) } @@ -162,10 +185,17 @@ pub fn try_register_asset( burnable: Option, total_burned: Option, ) -> StdResult { - let asset = SupportedAsset { name: match name { - None => { token_info_query(&deps.querier, 1, contract.code_hash.clone(), contract.address.clone())?.symbol } + None => { + token_info_query( + &deps.querier, + 1, + contract.code_hash.clone(), + contract.address.clone(), + )? + .symbol + } Some(x) => x, }, contract, @@ -173,7 +203,7 @@ pub fn try_register_asset( total_burned: match total_burned { None => Uint128(0), Some(amount) => amount, - } + }, }; if !authorized(deps, env, AllowedAccess::Admin)? { @@ -185,8 +215,9 @@ pub fn try_register_asset( Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::RegisterAsset { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::RegisterAsset { + status: ResponseStatus::Success, + })?), }) } @@ -196,7 +227,7 @@ pub fn try_burn( _sender: HumanAddr, from: HumanAddr, amount: Uint128, - msg: Option + msg: Option, ) -> StdResult { if !authorized(deps, &env, AllowedAccess::User)? { return Err(StdError::Unauthorized { backtrace: None }); @@ -213,20 +244,36 @@ pub fn try_burn( let assets = assets_r(&deps.storage); let burning_asset = match assets.may_load(env.message.sender.to_string().as_bytes())? { Some(asset) => asset, - None => return Err(StdError::NotFound { kind: env.message.sender.to_string(), backtrace: None }), + None => { + return Err(StdError::NotFound { + kind: env.message.sender.to_string(), + backtrace: None, + }); + } }; let minting_asset = match assets.may_load(msgs.to_mint.to_string().as_bytes())? { Some(asset) => asset, - None => return Err(StdError::NotFound { kind: msgs.to_mint.to_string(), backtrace: None }), + None => { + return Err(StdError::NotFound { + kind: msgs.to_mint.to_string(), + backtrace: None, + }); + } }; // Check that requested snip20 is supported and mint address is inside the mintable array - let mintable = minters_query(&deps.querier, 1, - minting_asset.contract.code_hash.clone(), - minting_asset.contract.address.clone())?.minters; + let mintable = minters_query( + &deps.querier, + 1, + minting_asset.contract.code_hash.clone(), + minting_asset.contract.address.clone(), + )? + .minters; if !mintable.contains(&env.contract.address) { - return Err(StdError::generic_err("Asset does allow mint contract to mint")) + return Err(StdError::generic_err( + "Asset does allow mint contract to mint", + )); } // Query prices @@ -235,26 +282,39 @@ pub fn try_burn( // Get asset decimals // Load the decimal information for both coins - let in_decimals = token_info_query(&deps.querier, 1, - burning_asset.contract.code_hash.clone(), - burning_asset.contract.address.clone())?.decimals as u32; - let target_decimals = token_info_query(&deps.querier, 1, - minting_asset.contract.code_hash.clone(), - minting_asset.contract.address.clone())?.decimals as u32; + let in_decimals = token_info_query( + &deps.querier, + 1, + burning_asset.contract.code_hash.clone(), + burning_asset.contract.address.clone(), + )? + .decimals as u32; + let target_decimals = token_info_query( + &deps.querier, + 1, + minting_asset.contract.code_hash.clone(), + minting_asset.contract.address.clone(), + )? + .decimals as u32; // Calculate value to mint - let amount_to_mint = calculate_mint(in_price, target_price, amount, in_decimals, target_decimals); + let amount_to_mint = + calculate_mint(in_price, target_price, amount, in_decimals, target_decimals); // If minimum amount is greater then ignore the process if msgs.minimum_expected_amount > amount_to_mint { - return Err(StdError::generic_err("did not exceed expected amount")) + return Err(StdError::generic_err("did not exceed expected amount")); } // if burnable then burn if not ignore if burning_asset.burnable { - messages.push(burn_msg(amount, None, 256, - burning_asset.contract.code_hash, - burning_asset.contract.address)?); + messages.push(burn_msg( + amount, + None, + 256, + burning_asset.contract.code_hash, + burning_asset.contract.address, + )?); } // Set burned amount @@ -266,24 +326,29 @@ pub fn try_burn( })?; // Mint - messages.push(mint_msg(from, amount_to_mint, None, 256, - minting_asset.contract.code_hash, - minting_asset.contract.address)?); + messages.push(mint_msg( + from, + amount_to_mint, + None, + 256, + minting_asset.contract.code_hash, + minting_asset.contract.address, + )?); Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::Burn { + data: Some(to_binary(&HandleAnswer::Burn { status: ResponseStatus::Success, - mint_amount: amount_to_mint - } )? ), + mint_amount: amount_to_mint, + })?), }) } // Helper functions #[derive(PartialEq)] -pub enum AllowedAccess{ +pub enum AllowedAccess { Admin, User, } @@ -296,23 +361,19 @@ fn authorized( let config = config_read(&deps.storage).load()?; // Check if contract is still activated if !config.activated { - return Ok(false) + return Ok(false); } if access == AllowedAccess::Admin { // Check if admin if env.message.sender != config.owner { - return Ok(false) + return Ok(false); } } Ok(true) } -fn register_receive ( - env: &Env, - contract: Contract -) -> StdResult { - +fn register_receive(env: &Env, contract: Contract) -> StdResult { register_receive_msg( env.contract_code_hash.clone(), None, @@ -327,9 +388,8 @@ fn calculate_mint( target_price: Uint128, in_amount: Uint128, in_decimals: u32, - target_decimals: u32 + target_decimals: u32, ) -> Uint128 { - // Math must only be made in integers // in_decimals = x // target_decimals = y @@ -351,18 +411,21 @@ fn calculate_mint( // To avoid a mess of different types doing math match difference.cmp(&0) { - Ordering::Greater => Uint128(in_total.u128() * 10u128.pow(u32::try_from(difference).unwrap())), - Ordering::Less => in_total.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())), - Ordering::Equal => in_total + Ordering::Greater => { + Uint128(in_total.u128() * 10u128.pow(u32::try_from(difference).unwrap())) + } + Ordering::Less => { + in_total.multiply_ratio(1u128, 10u128.pow(u32::try_from(difference.abs()).unwrap())) + } + Ordering::Equal => in_total, } } -fn save_asset ( +fn save_asset( deps: &mut Extern, env: &Env, asset: SupportedAsset, ) -> StdResult { - let mut assets = assets_w(&mut deps.storage); // Save the asset @@ -387,9 +450,11 @@ fn call_oracle( ) -> StdResult { let config = config_read(&deps.storage).load()?; let query_msg = Price { symbol }; - let answer: ReferenceData = query_msg.query(&deps.querier, - config.oracle.code_hash, - config.oracle.address)?; + let answer: ReferenceData = query_msg.query( + &deps.querier, + config.oracle.code_hash, + config.oracle.address, + )?; Ok(answer.rate) } @@ -404,36 +469,52 @@ pub fn query( } } -fn query_supported_assets(deps: &Extern) -> StdResult { - Ok(QueryAnswer::SupportedAssets { assets: asset_list_read(&deps.storage).load()? }) +fn query_supported_assets( + deps: &Extern, +) -> StdResult { + Ok(QueryAnswer::SupportedAssets { + assets: asset_list_read(&deps.storage).load()?, + }) } -fn query_asset(deps: &Extern, contract: String) -> StdResult { +fn query_asset( + deps: &Extern, + contract: String, +) -> StdResult { let assets = assets_r(&deps.storage); return match assets.may_load(contract.as_bytes())? { Some(asset) => Ok(QueryAnswer::Asset { asset }), - None => Err(StdError::NotFound { kind: contract, backtrace: None }), + None => Err(StdError::NotFound { + kind: contract, + backtrace: None, + }), }; } fn query_config(deps: &Extern) -> StdResult { - Ok(QueryAnswer::Config { config: config_read(&deps.storage).load()? }) + Ok(QueryAnswer::Config { + config: config_read(&deps.storage).load()?, + }) } #[cfg(test)] mod tests { use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, MockStorage, MockApi, MockQuerier}; - use cosmwasm_std::{coins, from_binary, StdError}; + use cosmwasm_std::{ + coins, + from_binary, + testing::{mock_dependencies, mock_env, MockApi, MockQuerier, MockStorage}, + StdError, + }; use shade_protocol::mint::QueryAnswer; fn create_contract(address: &str, code_hash: &str) -> Contract { let env = mock_env(address.to_string(), &[]); - return Contract{ + return Contract { address: env.message.sender, - code_hash: code_hash.to_string() - } + code_hash: code_hash.to_string(), + }; } fn dummy_init(admin: String, oracle: Contract) -> Extern { @@ -441,12 +522,12 @@ mod tests { let msg = InitMsg { admin: None, oracle, - initial_assets: None + initial_assets: None, }; let env = mock_env(admin, &coins(1000, "earth")); let _res = init(&mut deps, env, msg).unwrap(); - return deps + return deps; } #[test] @@ -456,12 +537,12 @@ mod tests { let msg = InitMsg { admin: None, oracle: create_contract("", ""), - initial_assets: Some(vec![SupportedAsset{ + initial_assets: Some(vec![SupportedAsset { name: "some_asset".to_string(), contract: some_contract, burnable: false, - total_burned: Uint128(0) - }]) + total_burned: Uint128(0), + }]), }; let env = mock_env("creator", &coins(1000, "earth")); @@ -484,7 +565,9 @@ mod tests { QueryAnswer::Config { config } => { assert_eq!(config.oracle, oracle_contract); } - _ => { panic!("Received wrong answer") } + _ => { + panic!("Received wrong answer") + } } // Update config @@ -503,17 +586,16 @@ mod tests { match value { QueryAnswer::Config { config } => { assert_eq!(config.oracle, new_oracle_contract); - } - _ => { panic!("Received wrong answer") } + _ => { + panic!("Received wrong answer") + } } - } #[test] fn user_register_asset() { - let mut deps = dummy_init("admin".to_string(), - create_contract("", "")); + let mut deps = dummy_init("admin".to_string(), create_contract("", "")); // User should not be allowed to add an item let user_env = mock_env("user", &coins(1000, "earth")); @@ -522,7 +604,7 @@ mod tests { name: Some("asset".to_string()), contract: dummy_contract, burnable: None, - total_burned: None + total_burned: None, }; let res = handle(&mut deps, user_env, msg); match res { @@ -534,15 +616,18 @@ mod tests { let res = query(&deps, QueryMsg::GetSupportedAssets {}).unwrap(); let value: QueryAnswer = from_binary(&res).unwrap(); match value { - QueryAnswer::SupportedAssets { assets } => { assert_eq!(0, assets.len()) } - _ => { panic!("Expected empty array") } + QueryAnswer::SupportedAssets { assets } => { + assert_eq!(0, assets.len()) + } + _ => { + panic!("Expected empty array") + } } } #[test] fn admin_register_asset() { - let mut deps = dummy_init("admin".to_string(), - create_contract("", "")); + let mut deps = dummy_init("admin".to_string(), create_contract("", "")); // Admin should be allowed to add an item let env = mock_env("admin", &coins(1000, "earth")); @@ -551,7 +636,7 @@ mod tests { name: Some("asset".to_string()), contract: dummy_contract, burnable: None, - total_burned: None + total_burned: None, }; let _res = handle(&mut deps, env, msg).unwrap(); @@ -559,15 +644,18 @@ mod tests { let res = query(&deps, QueryMsg::GetSupportedAssets {}).unwrap(); let value: QueryAnswer = from_binary(&res).unwrap(); match value { - QueryAnswer::SupportedAssets { assets } => { assert_eq!(1, assets.len()) } - _ => { panic!("Received wrong answer") } + QueryAnswer::SupportedAssets { assets } => { + assert_eq!(1, assets.len()) + } + _ => { + panic!("Received wrong answer") + } } } #[test] fn admin_update_asset() { - let mut deps = dummy_init("admin".to_string(), - create_contract("", "")); + let mut deps = dummy_init("admin".to_string(), create_contract("", "")); // Add a supported asset let env = mock_env("admin", &coins(1000, "earth")); @@ -576,7 +664,7 @@ mod tests { name: Some("old_asset".to_string()), contract: dummy_contract, burnable: None, - total_burned: None + total_burned: None, }; let _res = handle(&mut deps, env, msg).unwrap(); @@ -587,16 +675,23 @@ mod tests { name: Some("new_asset".to_string()), contract: dummy_contract, burnable: None, - total_burned: None + total_burned: None, }; let _res = handle(&mut deps, env, msg).unwrap(); // Response should be new dummy contract - let res = query(&deps, QueryMsg::GetAsset { contract: "some_contract".to_string() }).unwrap(); + let res = query(&deps, QueryMsg::GetAsset { + contract: "some_contract".to_string(), + }) + .unwrap(); let value: QueryAnswer = from_binary(&res).unwrap(); match value { - QueryAnswer::Asset { asset } => { assert_eq!("new_asset".to_string(), asset.name) } - _ => { panic!("Received wrong answer") } + QueryAnswer::Asset { asset } => { + assert_eq!("new_asset".to_string(), asset.name) + } + _ => { + panic!("Received wrong answer") + } }; } diff --git a/contracts/mint/src/lib.rs b/contracts/mint/src/lib.rs index 18d548e3f..f30cca474 100644 --- a/contracts/mint/src/lib.rs +++ b/contracts/mint/src/lib.rs @@ -5,7 +5,12 @@ pub mod state; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/mint/src/state.rs b/contracts/mint/src/state.rs index cecf77216..da9022bbd 100644 --- a/contracts/mint/src/state.rs +++ b/contracts/mint/src/state.rs @@ -1,8 +1,15 @@ -use cosmwasm_std::{Storage}; -use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket}; -use shade_protocol::{ - mint::{MintConfig, SupportedAsset}, +use cosmwasm_std::Storage; +use cosmwasm_storage::{ + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, }; +use shade_protocol::mint::{MintConfig, SupportedAsset}; pub static CONFIG_KEY: &[u8] = b"config"; pub static NATIVE_COIN_KEY: &[u8] = b"native_coin"; @@ -25,10 +32,10 @@ pub fn asset_list_read(storage: &S) -> ReadonlySingleton(storage: & S) -> ReadonlyBucket { +pub fn assets_r(storage: &S) -> ReadonlyBucket { bucket_read(ASSET_KEY, storage) } pub fn assets_w(storage: &mut S) -> Bucket { bucket(ASSET_KEY, storage) -} \ No newline at end of file +} diff --git a/contracts/mock_band/src/contract.rs b/contracts/mock_band/src/contract.rs index 422106f3b..bdcf20344 100644 --- a/contracts/mock_band/src/contract.rs +++ b/contracts/mock_band/src/contract.rs @@ -1,16 +1,22 @@ use cosmwasm_std::{ - to_binary, Api, Binary, - Env, Extern, HandleResponse, InitResponse, - Querier, StdResult, StdError, Storage, Uint128, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdError, + StdResult, + Storage, + Uint128, }; -use serde::{Deserialize, Serialize}; use schemars::JsonSchema; -use shade_protocol::band::{ReferenceData, InitMsg}; +use serde::{Deserialize, Serialize}; +use shade_protocol::band::{InitMsg, ReferenceData}; -use cosmwasm_storage::{ - bucket, bucket_read, - Bucket, ReadonlyBucket -}; +use cosmwasm_storage::{bucket, bucket_read, Bucket, ReadonlyBucket}; pub static PRICE: &[u8] = b"prices"; @@ -33,10 +39,7 @@ pub fn init( #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleMsg { - MockPrice { - symbol: String, - price: Uint128, - } + MockPrice { symbol: String, price: Uint128 }, } pub fn handle( @@ -49,7 +52,7 @@ pub fn handle( price_w(&mut deps.storage).save(symbol.as_bytes(), &price)?; Ok(HandleResponse::default()) } - } + }; } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -59,7 +62,7 @@ pub enum QueryMsg { base_symbol: String, quote_symbol: String, }, - GetReferenceDataBulk{ + GetReferenceDataBulk { base_symbols: Vec, quote_symbols: Vec, }, @@ -69,38 +72,40 @@ pub fn query( msg: QueryMsg, ) -> StdResult { match msg { - QueryMsg::GetReferenceData { + QueryMsg::GetReferenceData { base_symbol, - quote_symbol: _ + quote_symbol: _, } => { if let Some(price) = price_r(&deps.storage).may_load(base_symbol.as_bytes())? { return to_binary(&ReferenceData { - rate: price, - last_updated_base: 0, - last_updated_quote: 0 - }) + rate: price, + last_updated_base: 0, + last_updated_quote: 0, + }); } Err(StdError::generic_err("Missing Price Feed")) - }, + } QueryMsg::GetReferenceDataBulk { base_symbols, - quote_symbols: _ + quote_symbols: _, } => { let mut results = Vec::new(); for sym in base_symbols { if let Some(price) = price_r(&deps.storage).may_load(sym.as_bytes())? { results.push(ReferenceData { - rate: price, - last_updated_base: 0, - last_updated_quote: 0 + rate: price, + last_updated_base: 0, + last_updated_quote: 0, + }); + } else { + return Err(StdError::GenericErr { + msg: "Missing Price Feed".to_string(), + backtrace: None, }); - } - else { - return Err(StdError::GenericErr { msg: "Missing Price Feed".to_string(), backtrace: None}) } } to_binary(&results) - }, + } } } diff --git a/contracts/mock_band/src/lib.rs b/contracts/mock_band/src/lib.rs index 4d128dcb3..1669817dd 100644 --- a/contracts/mock_band/src/lib.rs +++ b/contracts/mock_band/src/lib.rs @@ -4,7 +4,12 @@ pub mod contract; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/oracle/src/contract.rs b/contracts/oracle/src/contract.rs index ef886e19e..2eeef4040 100644 --- a/contracts/oracle/src/contract.rs +++ b/contracts/oracle/src/contract.rs @@ -1,18 +1,18 @@ +use crate::{handle, query, state::config_w}; use cosmwasm_std::{ - debug_print, to_binary, Api, Binary, - Env, Extern, HandleResponse, InitResponse, - Querier, StdResult, Storage, -}; -use shade_protocol::{ - oracle::{ - InitMsg, HandleMsg, - QueryMsg, OracleConfig, - }, -}; -use crate::{ - state::{ config_w }, - query, handle, + debug_print, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, }; +use shade_protocol::oracle::{HandleMsg, InitMsg, OracleConfig, QueryMsg}; pub fn init( deps: &mut Extern, @@ -21,8 +21,8 @@ pub fn init( ) -> StdResult { let state = OracleConfig { admin: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } + None => env.message.sender.clone(), + Some(admin) => admin, }, band: msg.band, sscrt: msg.sscrt, @@ -40,22 +40,15 @@ pub fn handle( env: Env, msg: HandleMsg, ) -> StdResult { - match msg { - HandleMsg::UpdateConfig { - admin, - band, - } => handle::try_update_config(deps, env, admin, band), - HandleMsg::RegisterSswapPair { - pair, - } => handle::register_sswap_pair(deps, env, pair), - HandleMsg::UnregisterSswapPair { - pair, - } => handle::unregister_sswap_pair(deps, env, pair), - HandleMsg::RegisterIndex { - symbol, - basket, - } => handle::register_index(deps, env, symbol, basket), + HandleMsg::UpdateConfig { admin, band } => { + handle::try_update_config(deps, env, admin, band) + } + HandleMsg::RegisterSswapPair { pair } => handle::register_sswap_pair(deps, env, pair), + HandleMsg::UnregisterSswapPair { pair } => handle::unregister_sswap_pair(deps, env, pair), + HandleMsg::RegisterIndex { symbol, basket } => { + handle::register_index(deps, env, symbol, basket) + } } } diff --git a/contracts/oracle/src/handle.rs b/contracts/oracle/src/handle.rs index fd4a7dc2a..07899a703 100644 --- a/contracts/oracle/src/handle.rs +++ b/contracts/oracle/src/handle.rs @@ -1,34 +1,26 @@ +use crate::state::{config_r, config_w, index_w, sswap_pairs_r, sswap_pairs_w}; use cosmwasm_std::{ - to_binary, Api, - Env, Extern, HandleResponse, - Querier, StdResult, StdError, Storage, + to_binary, + Api, + Env, + Extern, + HandleResponse, HumanAddr, + Querier, + StdError, + StdResult, + Storage, }; use secret_toolkit::{ + snip20::{token_info_query, TokenInfo}, utils::Query, - snip20::{ - token_info_query, - TokenInfo, - }, }; use shade_protocol::{ - oracle::{ - HandleAnswer, - SswapPair, - IndexElement, - }, asset::Contract, generic_response::ResponseStatus, + oracle::{HandleAnswer, IndexElement, SswapPair}, + secretswap::{PairQuery, PairResponse}, snip20::Snip20Asset, - secretswap::{ - PairQuery, - PairResponse, - } -}; -use crate::state::{ - config_w, config_r, - sswap_pairs_w, sswap_pairs_r, - index_w, }; pub fn register_sswap_pair( @@ -36,17 +28,13 @@ pub fn register_sswap_pair( env: Env, pair: Contract, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.admin { return Err(StdError::Unauthorized { backtrace: None }); } - let (token_contract, token_info) = fetch_token_paired_to_sscrt_on_sswap( - deps, - config.sscrt.address, - &pair - )?; + let (token_contract, token_info) = + fetch_token_paired_to_sscrt_on_sswap(deps, config.sscrt.address, &pair)?; sswap_pairs_w(&mut deps.storage).save(token_info.symbol.as_bytes(), &SswapPair { pair, @@ -54,14 +42,15 @@ pub fn register_sswap_pair( contract: token_contract, token_info: token_info.clone(), token_config: None, - } + }, })?; Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::RegisterSswapPair { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::RegisterSswapPair { + status: ResponseStatus::Success, + })?), }) } @@ -70,25 +59,21 @@ pub fn unregister_sswap_pair( env: Env, pair: Contract, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.admin { return Err(StdError::Unauthorized { backtrace: None }); } - let (_, token_info) = fetch_token_paired_to_sscrt_on_sswap( - deps, - config.sscrt.address, - &pair - )?; + let (_, token_info) = fetch_token_paired_to_sscrt_on_sswap(deps, config.sscrt.address, &pair)?; sswap_pairs_w(&mut deps.storage).remove(token_info.symbol.as_bytes()); Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UnregisterSswapPair { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UnregisterSswapPair { + status: ResponseStatus::Success, + })?), }) } @@ -102,11 +87,8 @@ fn fetch_token_paired_to_sscrt_on_sswap( pair: &Contract, ) -> StdResult<(Contract, TokenInfo)> { // Query for snip20's in the pair - let response: PairResponse = PairQuery::Pair{}.query( - &deps.querier, - pair.code_hash.clone(), - pair.address.clone(), - )?; + let response: PairResponse = + PairQuery::Pair {}.query(&deps.querier, pair.code_hash.clone(), pair.address.clone())?; let mut token_contract = Contract { address: response.asset_infos[0].token.contract_addr.clone(), @@ -121,12 +103,18 @@ fn fetch_token_paired_to_sscrt_on_sswap( } // if neither is sscrt else if response.asset_infos[1].token.contract_addr != sscrt_addr { - return Err(StdError::NotFound { kind: "Not an SSCRT Pair".to_string(), backtrace: None }); + return Err(StdError::NotFound { + kind: "Not an SSCRT Pair".to_string(), + backtrace: None, + }); } - let token_info = token_info_query(&deps.querier, 1, - token_contract.code_hash.clone(), - token_contract.address.clone())?; + let token_info = token_info_query( + &deps.querier, + 1, + token_contract.code_hash.clone(), + token_contract.address.clone(), + )?; Ok((token_contract, token_info)) } @@ -137,19 +125,18 @@ pub fn register_index( symbol: String, basket: Vec, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.admin { return Err(StdError::Unauthorized { backtrace: None }); } match sswap_pairs_r(&deps.storage).may_load(symbol.as_bytes())? { - None => { } + None => {} Some(_) => { return Err(StdError::GenericErr { msg: "symbol collides with an existing SecretSwap Pair".to_string(), - backtrace: None - }) + backtrace: None, + }); } } @@ -166,11 +153,10 @@ pub fn register_index( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::RegisterIndex { - status: ResponseStatus::Success - })?) + data: Some(to_binary(&HandleAnswer::RegisterIndex { + status: ResponseStatus::Success, + })?), }) - } pub fn try_update_config( @@ -179,7 +165,6 @@ pub fn try_update_config( admin: Option, band: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.admin { return Err(StdError::Unauthorized { backtrace: None }); @@ -201,10 +186,8 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some(to_binary( - &HandleAnswer::UpdateConfig { - status: ResponseStatus::Success - } - )?) + data: Some(to_binary(&HandleAnswer::UpdateConfig { + status: ResponseStatus::Success, + })?), }) } diff --git a/contracts/oracle/src/lib.rs b/contracts/oracle/src/lib.rs index 14d4d23b1..84be1cef6 100644 --- a/contracts/oracle/src/lib.rs +++ b/contracts/oracle/src/lib.rs @@ -1,7 +1,7 @@ pub mod contract; -pub mod state; pub mod handle; pub mod query; +pub mod state; #[cfg(test)] mod test; @@ -10,7 +10,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/oracle/src/query.rs b/contracts/oracle/src/query.rs index adad6d9cc..83b4498a0 100644 --- a/contracts/oracle/src/query.rs +++ b/contracts/oracle/src/query.rs @@ -1,43 +1,23 @@ -use cosmwasm_std::{ - Api, - Extern, - Querier, StdResult, Storage, - Uint128, -}; +use crate::state::{config_r, index_r, sswap_pairs_r}; +use cosmwasm_std::{Api, Extern, Querier, StdResult, Storage, Uint128}; use secret_toolkit::utils::Query; use shade_protocol::{ - oracle::{ - QueryAnswer, SswapPair, - IndexElement, - }, - band::{ - BandQuery, ReferenceData, - }, - secretswap::{ - PairQuery, - SimulationResponse, - Asset, - AssetInfo, - Token, - }, - -}; -use crate::state::{ - config_r, - sswap_pairs_r, - index_r, + band::{BandQuery, ReferenceData}, + oracle::{IndexElement, QueryAnswer, SswapPair}, + secretswap::{Asset, AssetInfo, PairQuery, SimulationResponse, Token}, }; use std::convert::TryFrom; pub fn config(deps: &Extern) -> StdResult { - Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()? }) + Ok(QueryAnswer::Config { + config: config_r(&deps.storage).load()?, + }) } pub fn price( deps: &Extern, symbol: String, ) -> StdResult { - if symbol == "SSCRT" { return reference_data(deps, "SCRT".to_string(), "USD".to_string()); } @@ -45,7 +25,7 @@ pub fn price( // secret swap pair // TODO: sienna pair if let Some(sswap_pair) = sswap_pairs_r(&deps.storage).may_load(symbol.as_bytes())? { - return sswap_price(deps, sswap_pair) + return sswap_price(deps, sswap_pair); } // Index @@ -54,7 +34,7 @@ pub fn price( rate: eval_index(deps, &symbol, index)?, last_updated_base: 0, last_updated_quote: 0, - }) + }); } // symbol/USD price from BAND @@ -65,23 +45,16 @@ pub fn prices( deps: &Extern, symbols: Vec, ) -> StdResult> { - let mut band_symbols = vec![]; let mut band_quotes = vec![]; let mut results = vec![Uint128(0); symbols.len()]; for (i, sym) in symbols.iter().enumerate() { - if let Some(sswap_pair) = sswap_pairs_r(&deps.storage).may_load(sym.as_bytes())? - { + if let Some(sswap_pair) = sswap_pairs_r(&deps.storage).may_load(sym.as_bytes())? { results[i] = sswap_price(deps, sswap_pair)?.rate; - } - else if let Some(index) = index_r(&deps.storage).may_load(sym.as_bytes())? - { - + } else if let Some(index) = index_r(&deps.storage).may_load(sym.as_bytes())? { results[i] = eval_index(deps, sym, index)?; - } - else - { + } else { band_symbols.push(sym.clone()); band_quotes.push("USD".to_string()); } @@ -90,7 +63,12 @@ pub fn prices( let ref_data = reference_data_bulk(deps, band_symbols.clone(), band_quotes)?; for (data, sym) in ref_data.iter().zip(band_symbols.iter()) { - let result_index = symbols.iter().enumerate().find(|&s| s.1.to_string() == sym.to_string()).unwrap().0; + let result_index = symbols + .iter() + .enumerate() + .find(|&s| s.1.to_string() == sym.to_string()) + .unwrap() + .0; results[result_index] = data.rate; } @@ -102,7 +80,6 @@ pub fn eval_index( symbol: &str, index: Vec, ) -> StdResult { - let mut weight_total = Uint128::zero(); let mut price = Uint128::zero(); @@ -111,13 +88,13 @@ pub fn eval_index( let mut band_weights = vec![]; for element in index { - weight_total += element.weight; if let Some(sswap_pair) = sswap_pairs_r(&deps.storage).may_load(symbol.as_bytes())? { - price += sswap_price(deps, sswap_pair)?.rate.multiply_ratio(element.weight, 10u128.pow(18)); - } - else { + price += sswap_price(deps, sswap_pair)? + .rate + .multiply_ratio(element.weight, 10u128.pow(18)); + } else { band_weights.push(element.weight); band_bases.push(element.symbol.clone()); band_quotes.push("USD".to_string()); @@ -139,11 +116,7 @@ pub fn eval_index( * trade_price: SCRT/token trade amount from 1 sSCRT (normalized to price * 10^18) * return: token/USD price */ -pub fn translate_price( - scrt_price: Uint128, - trade_price: Uint128 -) -> Uint128 { - +pub fn translate_price(scrt_price: Uint128, trade_price: Uint128) -> Uint128 { scrt_price.multiply_ratio(10u128.pow(18), trade_price) } @@ -151,11 +124,7 @@ pub fn translate_price( * amount: unsigned quantity received in trade for 1sSCRT * decimals: number of decimals for received snip20 */ -pub fn normalize_price( - amount: Uint128, - decimals: u8 -) -> Uint128 { - +pub fn normalize_price(amount: Uint128, decimals: u8) -> Uint128 { (amount.u128() * 10u128.pow(18u32 - u32::try_from(decimals).unwrap())).into() } @@ -165,7 +134,6 @@ pub fn sswap_price( deps: &Extern, sswap_pair: SswapPair, ) -> StdResult { - let trade_price = sswap_simulate(deps, sswap_pair)?; let scrt_result = reference_data(deps, "SCRT".to_string(), "USD".to_string())?; @@ -176,7 +144,7 @@ pub fn sswap_price( // SCRT-USD / SCRT-symbol rate: translate_price(scrt_result.rate, trade_price), last_updated_base: 0, - last_updated_quote: 0 + last_updated_quote: 0, }) } @@ -184,7 +152,6 @@ pub fn sswap_simulate( deps: &Extern, sswap_pair: SswapPair, ) -> StdResult { - let config = config_r(&deps.storage).load()?; let response: SimulationResponse = PairQuery::Simulation { @@ -195,16 +162,20 @@ pub fn sswap_simulate( contract_addr: config.sscrt.address, token_code_hash: config.sscrt.code_hash, viewing_key: "SecretSwap".to_string(), - } - } - } - }.query( + }, + }, + }, + } + .query( &deps.querier, sswap_pair.pair.code_hash, sswap_pair.pair.address, )?; - Ok(normalize_price(response.return_amount, sswap_pair.asset.token_info.decimals)) + Ok(normalize_price( + response.return_amount, + sswap_pair.asset.token_info.decimals, + )) } // BAND interactions @@ -214,13 +185,13 @@ pub fn reference_data( base_symbol: String, quote_symbol: String, ) -> StdResult { - let config_r = config_r(&deps.storage).load()?; BandQuery::GetReferenceData { - base_symbol, - quote_symbol, - }.query( + base_symbol, + quote_symbol, + } + .query( &deps.querier, config_r.band.code_hash, config_r.band.address, @@ -232,13 +203,13 @@ pub fn reference_data_bulk( base_symbols: Vec, quote_symbols: Vec, ) -> StdResult> { - let config_r = config_r(&deps.storage).load()?; BandQuery::GetReferenceDataBulk { - base_symbols, - quote_symbols, - }.query( + base_symbols, + quote_symbols, + } + .query( &deps.querier, config_r.band.code_hash, config_r.band.address, diff --git a/contracts/oracle/src/state.rs b/contracts/oracle/src/state.rs index 923e55737..69c95ec71 100644 --- a/contracts/oracle/src/state.rs +++ b/contracts/oracle/src/state.rs @@ -1,19 +1,15 @@ -use cosmwasm_std::{ - Storage -}; +use cosmwasm_std::Storage; use cosmwasm_storage::{ - singleton, singleton_read, - Singleton, ReadonlySingleton, - bucket, bucket_read, - Bucket, ReadonlyBucket -}; -use shade_protocol::{ - oracle::{ - OracleConfig, - SswapPair, - IndexElement, - }, + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, }; +use shade_protocol::oracle::{IndexElement, OracleConfig, SswapPair}; pub static CONFIG_KEY: &[u8] = b"config"; pub static SSWAP_PAIRS: &[u8] = b"sswap_pairs"; diff --git a/contracts/oracle/src/test.rs b/contracts/oracle/src/test.rs index adbfd7d72..0db36a1dc 100644 --- a/contracts/oracle/src/test.rs +++ b/contracts/oracle/src/test.rs @@ -1,8 +1,8 @@ #[cfg(test)] mod tests { use crate::query; - - use cosmwasm_std::{Uint128}; + + use cosmwasm_std::Uint128; macro_rules! normalize_price_tests { ($($name:ident: $value:expr,)*) => { @@ -55,7 +55,7 @@ mod tests { translate_price_tests! { translate_0: ( // 1.62 USD per SCRT - Uint128( 1_622_110_000_000_000_000), + Uint128( 1_622_110_000_000_000_000), // 1 sSCRT -> sETH Uint128( 1_413_500_852_332_497), // sETH/USD price @@ -63,7 +63,7 @@ mod tests { ), translate_1: ( // 1.62 USD per SCRT - Uint128( 1_622_110_000_000_000_000), + Uint128( 1_622_110_000_000_000_000), // .000425 ETH per sSCRT Uint128( 425_600_000_000_000), // 3811.34 ETH per USD @@ -71,19 +71,19 @@ mod tests { ), translate_2: ( // 1 USD per scrt - Uint128( 1_000_000_000_000_000_000), + Uint128( 1_000_000_000_000_000_000), // 1 sscrt for .1 SHD - Uint128( 100_000_000_000_000_000), + Uint128( 100_000_000_000_000_000), // 10 SHD per USD - Uint128(10_000_000_000_000_000_000), + Uint128(10_000_000_000_000_000_000), ), translate_3: ( // 1 USD per scrt - Uint128( 1_000_000_000_000_000_000), + Uint128( 1_000_000_000_000_000_000), // 1 sscrt for .02 SHD - Uint128( 20_000_000_000_000_000), + Uint128( 20_000_000_000_000_000), // 50 SHD per USD - Uint128(50_000_000_000_000_000_000), + Uint128(50_000_000_000_000_000_000), ), } } diff --git a/contracts/scrt_staking/src/contract.rs b/contracts/scrt_staking/src/contract.rs index 6c1d55a38..28d85448d 100644 --- a/contracts/scrt_staking/src/contract.rs +++ b/contracts/scrt_staking/src/contract.rs @@ -1,44 +1,36 @@ use cosmwasm_std::{ - debug_print, to_binary, Api, Binary, - Env, Extern, HandleResponse, InitResponse, - Querier, StdResult, Storage, + debug_print, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, }; -use shade_protocol::{ - scrt_staking::{ - Config, - InitMsg, - HandleMsg, - QueryMsg, - }, -}; +use shade_protocol::scrt_staking::{Config, HandleMsg, InitMsg, QueryMsg}; -use secret_toolkit::{ - snip20::{ - register_receive_msg, - set_viewing_key_msg, - }, -}; +use secret_toolkit::snip20::{register_receive_msg, set_viewing_key_msg}; use crate::{ - state::{ - viewing_key_w, viewing_key_r, - config_w, self_address_w, - }, - handle, query, + handle, + query, + state::{config_w, self_address_w, viewing_key_r, viewing_key_w}, }; - pub fn init( deps: &mut Extern, env: Env, msg: InitMsg, ) -> StdResult { - let config = Config { admin: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } + None => env.message.sender.clone(), + Some(admin) => admin, }, sscrt: msg.sscrt, treasury: msg.treasury, @@ -69,7 +61,7 @@ pub fn init( config.sscrt.address, )?, ], - log: vec![] + log: vec![], }) } @@ -86,17 +78,11 @@ pub fn handle( msg, .. } => handle::receive(deps, env, sender, from, amount, msg), - HandleMsg::UpdateConfig { - admin, - } => handle::try_update_config(deps, env, admin), + HandleMsg::UpdateConfig { admin } => handle::try_update_config(deps, env, admin), // Begin unbonding of a certain amount of scrt - HandleMsg::Unbond { - validator, - } => handle::unbond(deps, env, validator), + HandleMsg::Unbond { validator } => handle::unbond(deps, env, validator), // Collect a completed unbonding/rewards - HandleMsg::Claim { - validator, - } => handle::claim(deps, env, validator), + HandleMsg::Claim { validator } => handle::claim(deps, env, validator), } } @@ -107,7 +93,7 @@ pub fn query( match msg { QueryMsg::GetConfig {} => to_binary(&query::config(deps)?), // All delegations - QueryMsg::Delegations { } => to_binary(&query::delegations(deps)?), + QueryMsg::Delegations {} => to_binary(&query::delegations(deps)?), QueryMsg::Delegation { validator } => to_binary(&query::delegation(deps, validator)?), } } diff --git a/contracts/scrt_staking/src/handle.rs b/contracts/scrt_staking/src/handle.rs index 6992e1db0..8d0b974af 100644 --- a/contracts/scrt_staking/src/handle.rs +++ b/contracts/scrt_staking/src/handle.rs @@ -1,24 +1,30 @@ use cosmwasm_std::{ - debug_print, to_binary, Api, Binary, - Env, Extern, Storage, HandleResponse, - StdResult, StdError, - CosmosMsg, Uint128, - Coin, StakingMsg, - Validator, Querier, HumanAddr, + debug_print, + to_binary, + Api, + Binary, + Coin, + CosmosMsg, + Env, + Extern, + HandleResponse, + HumanAddr, + Querier, + StakingMsg, + StdError, + StdResult, + Storage, + Uint128, + Validator, }; use secret_toolkit::snip20::redeem_msg; use shade_protocol::{ - scrt_staking::{ - HandleAnswer, - ValidatorBounds, - }, generic_response::ResponseStatus, + scrt_staking::{HandleAnswer, ValidatorBounds}, }; -use crate::state::{ - config_w, config_r, -}; +use crate::state::{config_r, config_w}; pub fn receive( deps: &mut Extern, @@ -28,7 +34,6 @@ pub fn receive( amount: Uint128, _msg: Option, ) -> StdResult { - debug_print!("Received {}", amount); //TODO: verify sscrt else (fail/send to treasury) @@ -42,23 +47,21 @@ pub fn receive( let config = config_r(&deps.storage).load()?; if config.sscrt.address != env.message.sender { - return Err(StdError::GenericErr { - msg: "Only accepts sSCRT".to_string(), - backtrace: None + return Err(StdError::GenericErr { + msg: "Only accepts sSCRT".to_string(), + backtrace: None, }); } // Redeem sSCRT -> SCRT - messages.push( - redeem_msg( - amount, - None, - None, - 256, - config.sscrt.code_hash.clone(), - config.sscrt.address, - )? - ); + messages.push(redeem_msg( + amount, + None, + None, + 256, + config.sscrt.code_hash.clone(), + config.sscrt.address, + )?); let validator = choose_validator(deps, env.block.time)?; @@ -67,18 +70,16 @@ pub fn receive( amount: Coin { amount, denom: "uscrt".to_string(), - } + }, })); Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( - &HandleAnswer::Receive { - status: ResponseStatus::Success, - validator, - } - )?), + data: Some(to_binary(&HandleAnswer::Receive { + status: ResponseStatus::Success, + validator, + })?), }) } @@ -87,7 +88,6 @@ pub fn try_update_config( env: Env, admin: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.admin { @@ -106,8 +106,9 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateConfig { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateConfig { + status: ResponseStatus::Success, + })?), }) } @@ -116,15 +117,16 @@ pub fn unbond( env: Env, validator: HumanAddr, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.admin && env.message.sender != config.treasury { return Err(StdError::Unauthorized { backtrace: None }); } - if let Some(delegation) = deps.querier.query_delegation(env.contract.address, validator.clone())? { - + if let Some(delegation) = deps + .querier + .query_delegation(env.contract.address, validator.clone())? + { let messages: Vec = vec![CosmosMsg::Staking(StakingMsg::Undelegate { validator, amount: delegation.amount.clone(), @@ -133,18 +135,16 @@ pub fn unbond( return Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( - &HandleAnswer::Unbond { - status: ResponseStatus::Success, - delegation, - } - )?), + data: Some(to_binary(&HandleAnswer::Unbond { + status: ResponseStatus::Success, + delegation, + })?), }); } - Err(StdError::GenericErr { + Err(StdError::GenericErr { msg: "No delegation".to_string(), - backtrace: None + backtrace: None, }) } @@ -159,22 +159,17 @@ pub fn claim( _env: Env, validator: HumanAddr, ) -> StdResult { - let config = config_r(&deps.storage).load()?; Ok(HandleResponse { - messages: vec![ - CosmosMsg::Staking(StakingMsg::Withdraw { - validator, - recipient: Some(config.treasury), - }) - ], + messages: vec![CosmosMsg::Staking(StakingMsg::Withdraw { + validator, + recipient: Some(config.treasury), + })], log: vec![], - data: Some( to_binary( - &HandleAnswer::Claim { - status: ResponseStatus::Success, - } - )?), + data: Some(to_binary(&HandleAnswer::Claim { + status: ResponseStatus::Success, + })?), }) } @@ -182,7 +177,6 @@ pub fn choose_validator( deps: &Extern, seed: u64, ) -> StdResult { - let mut validators = deps.querier.query_validators()?; let bounds = (config_r(&deps.storage).load()?).validator_bounds; @@ -198,19 +192,15 @@ pub fn choose_validator( } if validators.is_empty() { - return Err(StdError::GenericErr { + return Err(StdError::GenericErr { msg: "No validators within bounds".to_string(), - backtrace: None - }) + backtrace: None, + }); } // seed will likely be env.block.time Ok(validators[(seed % validators.len() as u64) as usize].clone()) } -pub fn is_validator_inbounds( - validator: &Validator, - bounds: &ValidatorBounds, -) -> bool { - +pub fn is_validator_inbounds(validator: &Validator, bounds: &ValidatorBounds) -> bool { validator.commission <= bounds.max_commission && validator.commission >= bounds.min_commission } diff --git a/contracts/scrt_staking/src/lib.rs b/contracts/scrt_staking/src/lib.rs index 14d4d23b1..84be1cef6 100644 --- a/contracts/scrt_staking/src/lib.rs +++ b/contracts/scrt_staking/src/lib.rs @@ -1,7 +1,7 @@ pub mod contract; -pub mod state; pub mod handle; pub mod query; +pub mod state; #[cfg(test)] mod test; @@ -10,7 +10,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/scrt_staking/src/query.rs b/contracts/scrt_staking/src/query.rs index 716521f6c..c8e2bebab 100644 --- a/contracts/scrt_staking/src/query.rs +++ b/contracts/scrt_staking/src/query.rs @@ -1,28 +1,26 @@ use cosmwasm_std::{ - Api, Extern, Querier, Storage, - StdResult, HumanAddr, - Delegation, FullDelegation, -}; -use shade_protocol::{ - scrt_staking::QueryAnswer, -}; - -use crate::state::{ - config_r, - self_address_r, + Api, + Delegation, + Extern, + FullDelegation, + HumanAddr, + Querier, + StdResult, + Storage, }; +use shade_protocol::scrt_staking::QueryAnswer; -pub fn config( - deps: &Extern -) -> StdResult { +use crate::state::{config_r, self_address_r}; - Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()? }) +pub fn config(deps: &Extern) -> StdResult { + Ok(QueryAnswer::Config { + config: config_r(&deps.storage).load()?, + }) } pub fn delegations( deps: &Extern, ) -> StdResult> { - let address = self_address_r(&deps.storage).load()?; deps.querier.query_all_delegations(address) } @@ -31,7 +29,6 @@ pub fn delegation( deps: &Extern, validator: HumanAddr, ) -> StdResult> { - let address = self_address_r(&deps.storage).load()?; deps.querier.query_delegation(address, validator) } diff --git a/contracts/scrt_staking/src/state.rs b/contracts/scrt_staking/src/state.rs index 41ae5e1ce..d5f496c76 100644 --- a/contracts/scrt_staking/src/state.rs +++ b/contracts/scrt_staking/src/state.rs @@ -1,8 +1,5 @@ -use cosmwasm_std::{Storage, HumanAddr}; -use cosmwasm_storage::{ - singleton, Singleton, - singleton_read, ReadonlySingleton, -}; +use cosmwasm_std::{HumanAddr, Storage}; +use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton}; use shade_protocol::scrt_staking; pub static CONFIG_KEY: &[u8] = b"config"; diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 011ac497a..240cd6444 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -1,42 +1,63 @@ -use cosmwasm_std::{to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdResult, Storage, Uint128}; -use shade_protocol::{ - staking::{ - InitMsg, HandleMsg, - QueryMsg, Config, stake::Stake +use crate::{ + handle::{ + try_claim_rewards, + try_claim_unbond, + try_set_viewing_key, + try_stake, + try_unbond, + try_update_config, + try_vote, }, - asset::Contract + query, + state::{config_w, stake_state_w, unbonding_w}, }; -use crate::{ - state::{config_w, unbonding_w, stake_state_w}, - handle::{try_update_config, try_stake, try_unbond, - try_claim_unbond, try_claim_rewards, try_vote, try_set_viewing_key}, - query +use binary_heap_plus::BinaryHeap; +use cosmwasm_std::{ + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, + Uint128, }; use secret_toolkit::snip20::register_receive_msg; -use binary_heap_plus::BinaryHeap; +use shade_protocol::{ + asset::Contract, + staking::{stake::Stake, Config, HandleMsg, InitMsg, QueryMsg}, +}; pub fn init( deps: &mut Extern, env: Env, msg: InitMsg, ) -> StdResult { - let state = Config { admin: match msg.admin { - None => { Contract { address: env.message.sender.clone(), code_hash: "".to_string() } } - Some(admin) => { admin } + None => Contract { + address: env.message.sender.clone(), + code_hash: "".to_string(), + }, + Some(admin) => admin, }, unbond_time: msg.unbond_time, - staked_token: msg.staked_token + staked_token: msg.staked_token, }; config_w(&mut deps.storage).save(&state)?; // Register staked_token let cosmos_msg = register_receive_msg( - env.contract_code_hash, None, 256, + env.contract_code_hash, + None, + 256, state.staked_token.code_hash.clone(), - state.staked_token.address)?; + state.staked_token.address, + )?; // Initialize binary heap let unbonding_heap = BinaryHeap::new_min(); @@ -45,12 +66,12 @@ pub fn init( // Initialize stake state stake_state_w(&mut deps.storage).save(&Stake { total_shares: Uint128::zero(), - total_tokens: Uint128::zero() + total_tokens: Uint128::zero(), })?; Ok(InitResponse { messages: vec![cosmos_msg], - log: vec![] + log: vec![], }) } @@ -60,14 +81,16 @@ pub fn handle( msg: HandleMsg, ) -> StdResult { match msg { - HandleMsg::UpdateConfig { admin, unbond_time - } => try_update_config(deps, &env, admin, unbond_time), - HandleMsg::Receive { sender, from, amount + HandleMsg::UpdateConfig { admin, unbond_time } => { + try_update_config(deps, &env, admin, unbond_time) + } + HandleMsg::Receive { + sender, + from, + amount, } => try_stake(deps, &env, sender, from, amount), - HandleMsg::Unbond { amount - } => try_unbond(deps, &env, amount), - HandleMsg::Vote { proposal_id, votes - } => try_vote(deps, &env, proposal_id, votes), + HandleMsg::Unbond { amount } => try_unbond(deps, &env, amount), + HandleMsg::Vote { proposal_id, votes } => try_vote(deps, &env, proposal_id, votes), HandleMsg::ClaimUnbond {} => try_claim_unbond(deps, &env), HandleMsg::ClaimRewards {} => try_claim_rewards(deps, &env), HandleMsg::SetViewingKey { key } => try_set_viewing_key(deps, &env, key), @@ -79,11 +102,13 @@ pub fn query( msg: QueryMsg, ) -> StdResult { match msg { - QueryMsg::Config { } => to_binary(&query::config(deps)?), - QueryMsg::TotalStaked { } => to_binary(&query::total_staked(deps)?), - QueryMsg::TotalUnbonding { start, end - } => to_binary(&query::total_unbonding(deps, start, end)?), - QueryMsg::UserStake { address, key, time - } => to_binary(&query::user_stake(deps, address, key, time)?), + QueryMsg::Config {} => to_binary(&query::config(deps)?), + QueryMsg::TotalStaked {} => to_binary(&query::total_staked(deps)?), + QueryMsg::TotalUnbonding { start, end } => { + to_binary(&query::total_unbonding(deps, start, end)?) + } + QueryMsg::UserStake { address, key, time } => { + to_binary(&query::user_stake(deps, address, key, time)?) + } } } diff --git a/contracts/staking/src/handle.rs b/contracts/staking/src/handle.rs index 96463f4ad..2b879bf54 100644 --- a/contracts/staking/src/handle.rs +++ b/contracts/staking/src/handle.rs @@ -1,19 +1,43 @@ -use binary_heap_plus::{BinaryHeap}; -use cosmwasm_std::{to_binary, Api, Env, Extern, HandleResponse, Querier, StdError, StdResult, Storage, HumanAddr, Uint128}; -use crate::state::{config_r, config_w, staker_w, unbonding_w, staker_r, stake_state_w, stake_state_r, viewking_key_w, user_unbonding_w}; -use shade_protocol::{ - staking::{HandleAnswer, stake::{Stake, UserStake, Unbonding}}, - generic_response::ResponseStatus::{Success}, - governance::{vote::{UserVote, VoteTally, Vote}}, - asset::Contract +use crate::state::{ + config_r, + config_w, + stake_state_r, + stake_state_w, + staker_r, + staker_w, + unbonding_w, + user_unbonding_w, + viewking_key_w, +}; +use binary_heap_plus::BinaryHeap; +use cosmwasm_std::{ + to_binary, + Api, + Env, + Extern, + HandleResponse, + HumanAddr, + Querier, + StdError, + StdResult, + Storage, + Uint128, }; use secret_toolkit::{snip20::send_msg, utils::HandleCallback}; +use shade_protocol::{ + asset::Contract, + generic_response::ResponseStatus::Success, + governance::vote::{UserVote, Vote, VoteTally}, + staking::{ + stake::{Stake, Unbonding, UserStake}, + HandleAnswer, + }, +}; pub(crate) fn calculate_shares(tokens: Uint128, state: &Stake) -> Uint128 { if state.total_shares.is_zero() && state.total_tokens.is_zero() { tokens - } - else { + } else { tokens.multiply_ratio(state.total_shares, state.total_tokens) } } @@ -21,8 +45,7 @@ pub(crate) fn calculate_shares(tokens: Uint128, state: &Stake) -> Uint128 { pub(crate) fn calculate_tokens(shares: Uint128, state: &Stake) -> Uint128 { if state.total_shares.is_zero() && state.total_tokens.is_zero() { shares - } - else { + } else { shares.multiply_ratio(state.total_tokens, state.total_shares) } } @@ -35,9 +58,8 @@ pub fn try_update_config( deps: &mut Extern, env: &Env, admin: Option, - unbond_time: Option + unbond_time: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check if admin if env.message.sender != config.admin.address { @@ -57,7 +79,7 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateUnbondTime { + data: Some(to_binary(&HandleAnswer::UpdateUnbondTime { status: Success, })?), }) @@ -70,7 +92,6 @@ pub fn try_stake( _from: HumanAddr, amount: Uint128, ) -> StdResult { - let config = config_r(&deps.storage).load()?; // Check if staking token if env.message.sender != config.staked_token.address { @@ -93,7 +114,7 @@ pub fn try_stake( user_state.tokens_staked += amount; user_state.shares += shares; user_state - }, + } }; state.total_shares += shares; @@ -108,41 +129,41 @@ pub fn try_stake( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::Stake { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::Stake { status: Success })?), }) } pub fn try_unbond( deps: &mut Extern, env: &Env, - amount: Uint128 + amount: Uint128, ) -> StdResult { - let sender = env.message.sender.clone(); let mut state = stake_state_r(&deps.storage).load()?; // Check if user has >= amount staker_w(&mut deps.storage).update(sender.to_string().as_bytes(), |user_state| { - let shares = calculate_shares(amount, &state); let new_state = match user_state { - None => return Err(StdError::GenericErr { - msg: "Not enough staked".to_string(), - backtrace: None }), + None => { + return Err(StdError::GenericErr { + msg: "Not enough staked".to_string(), + backtrace: None, + }); + } Some(user_state) => { if user_state.tokens_staked >= amount { UserStake { shares: (user_state.shares - shares)?, - tokens_staked: (user_state.tokens_staked - amount)? + tokens_staked: (user_state.tokens_staked - amount)?, } } else { return Err(StdError::GenericErr { msg: "Not enough staked".to_string(), - backtrace: None }) + backtrace: None, + }); } } }; @@ -157,7 +178,7 @@ pub fn try_unbond( let config = config_r(&deps.storage).load()?; let unbonding = Unbonding { amount, - unbond_time: env.block.time + config.unbond_time + unbond_time: env.block.time + config.unbond_time, }; unbonding_w(&mut deps.storage).update(|mut unbonding_queue| { @@ -166,9 +187,9 @@ pub fn try_unbond( })?; user_unbonding_w(&mut deps.storage).update( - env.message.sender.to_string().as_bytes(), |queue| { - - let mut unbonding_queue= match queue { + env.message.sender.to_string().as_bytes(), + |queue| { + let mut unbonding_queue = match queue { None => BinaryHeap::new_min(), Some(queue) => queue, }; @@ -176,16 +197,15 @@ pub fn try_unbond( unbonding_queue.push(unbonding); Ok(unbonding_queue) - })?; + }, + )?; stake_state_w(&mut deps.storage).save(&state)?; Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::Unbond { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::Unbond { status: Success })?), }) } @@ -199,13 +219,12 @@ pub fn try_vote( proposal_id: Uint128, votes: Vec, ) -> StdResult { - let user_state = staker_r(&deps.storage).load(env.message.sender.to_string().as_bytes())?; // check that percentage is <= 100 and calculate distribution let mut total_votes = VoteTally { yes: Uint128(0), no: Uint128(0), - abstain: Uint128(0) + abstain: Uint128(0), }; let mut count = 0; @@ -226,26 +245,27 @@ pub fn try_vote( } if count > 100 { - return Err(StdError::GenericErr { msg: "Total weight must be 100 or less".to_string(), backtrace: None }) + return Err(StdError::GenericErr { + msg: "Total weight must be 100 or less".to_string(), + backtrace: None, + }); } - - // Admin is governance, send to governance let config = config_r(&deps.storage).load()?; - let messages = vec![shade_protocol::governance::HandleMsg::MakeVote { - voter: env.message.sender.clone(), - proposal_id, - votes: total_votes, - }.to_cosmos_msg(config.admin.code_hash, - config.admin.address, None)?]; + let messages = vec![ + shade_protocol::governance::HandleMsg::MakeVote { + voter: env.message.sender.clone(), + proposal_id, + votes: total_votes, + } + .to_cosmos_msg(config.admin.code_hash, config.admin.address, None)?, + ]; Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::Vote { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::Vote { status: Success })?), }) } @@ -280,17 +300,17 @@ pub fn try_claim_unbond( None, 1, config.staked_token.code_hash.clone(), - config.staked_token.address.clone())?); + config.staked_token.address.clone(), + )?); Ok(new_queue) - })?; + }, + )?; Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::ClaimUnbond { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::ClaimUnbond { status: Success })?), }) } @@ -304,8 +324,12 @@ pub fn try_claim_rewards( let mut messages = vec![]; staker_w(&mut deps.storage).update( - env.message.sender.to_string().as_bytes(), |user_state| { - let mut user = user_state.ok_or_else(|| StdError::NotFound { kind: "user".to_string(), backtrace: None })?; + env.message.sender.to_string().as_bytes(), + |user_state| { + let mut user = user_state.ok_or_else(|| StdError::NotFound { + kind: "user".to_string(), + backtrace: None, + })?; let rewards = calculate_rewards(&user, &state); let shares = calculate_shares(rewards, &state); @@ -313,20 +337,24 @@ pub fn try_claim_rewards( state.total_shares = (state.total_shares - shares)?; state.total_tokens = (state.total_tokens - rewards)?; - messages.push(send_msg(env.message.sender.clone(), rewards, - None, None, 1, - config.staked_token.code_hash.clone(), - config.staked_token.address.clone())?); + messages.push(send_msg( + env.message.sender.clone(), + rewards, + None, + None, + 1, + config.staked_token.code_hash.clone(), + config.staked_token.address.clone(), + )?); Ok(user) - })?; + }, + )?; Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( &HandleAnswer::ClaimRewards { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::ClaimRewards { status: Success })?), }) } @@ -335,14 +363,11 @@ pub fn try_set_viewing_key( env: &Env, key: String, ) -> StdResult { - viewking_key_w(&mut deps.storage).save(env.message.sender.to_string().as_bytes(), &key)?; Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::SetViewingKey { - status: Success, - })?), + data: Some(to_binary(&HandleAnswer::SetViewingKey { status: Success })?), }) } diff --git a/contracts/staking/src/lib.rs b/contracts/staking/src/lib.rs index 14d4d23b1..84be1cef6 100644 --- a/contracts/staking/src/lib.rs +++ b/contracts/staking/src/lib.rs @@ -1,7 +1,7 @@ pub mod contract; -pub mod state; pub mod handle; pub mod query; +pub mod state; #[cfg(test)] mod test; @@ -10,7 +10,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/staking/src/query.rs b/contracts/staking/src/query.rs index 221dee716..fd5bc4859 100644 --- a/contracts/staking/src/query.rs +++ b/contracts/staking/src/query.rs @@ -1,28 +1,29 @@ +use crate::{ + handle::calculate_rewards, + state::{config_r, stake_state_r, staker_r, unbonding_r, user_unbonding_r, viewking_key_r}, +}; use cosmwasm_std::{Api, Extern, HumanAddr, Querier, StdError, StdResult, Storage, Uint128}; use shade_protocol::staking::QueryAnswer; -use crate::{state::{config_r, stake_state_r}}; -use crate::handle::calculate_rewards; -use crate::state::{staker_r, unbonding_r, user_unbonding_r, viewking_key_r}; - -pub fn config( - deps: &Extern) -> StdResult { +pub fn config(deps: &Extern) -> StdResult { Ok(QueryAnswer::Config { - config: config_r(&deps.storage).load()? + config: config_r(&deps.storage).load()?, }) } pub fn total_staked( - deps: &Extern) -> StdResult { - + deps: &Extern, +) -> StdResult { Ok(QueryAnswer::TotalStaked { total: stake_state_r(&deps.storage).load()?.total_tokens, }) } pub fn total_unbonding( - deps: &Extern, start_limit: Option, end_limit: Option) -> StdResult { - + deps: &Extern, + start_limit: Option, + end_limit: Option, +) -> StdResult { let mut total = Uint128::zero(); let mut queue = unbonding_r(&deps.storage).load()?; @@ -36,16 +37,17 @@ pub fn total_unbonding( } } - Ok(QueryAnswer::TotalUnbonding { - total, - }) + Ok(QueryAnswer::TotalUnbonding { total }) } pub fn user_stake( - deps: &Extern, address: HumanAddr, key: String, time: u64) -> StdResult { - + deps: &Extern, + address: HumanAddr, + key: String, + time: u64, +) -> StdResult { if viewking_key_r(&deps.storage).load(address.to_string().as_bytes())? != key { - return Err(StdError::Unauthorized { backtrace: None }) + return Err(StdError::Unauthorized { backtrace: None }); } let state = stake_state_r(&deps.storage).load()?; @@ -54,8 +56,7 @@ pub fn user_stake( let mut unbonding = Uint128::zero(); let mut unbonded = Uint128::zero(); - let queue = user_unbonding_r(&deps.storage).may_load( - address.to_string().as_bytes())?; + let queue = user_unbonding_r(&deps.storage).may_load(address.to_string().as_bytes())?; if let Some(mut queue) = queue { while !queue.is_empty() { @@ -73,6 +74,6 @@ pub fn user_stake( staked: user_state.tokens_staked, pending_rewards: calculate_rewards(&user_state, &state), unbonding, - unbonded + unbonded, }) } diff --git a/contracts/staking/src/state.rs b/contracts/staking/src/state.rs index 5faa93998..deaad8543 100644 --- a/contracts/staking/src/state.rs +++ b/contracts/staking/src/state.rs @@ -1,8 +1,20 @@ use cosmwasm_std::Storage; -use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket}; +use cosmwasm_storage::{ + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, +}; -use shade_protocol::staking::{Config, stake::{Stake, UserStake, Unbonding}}; use binary_heap_plus::{BinaryHeap, MinComparator}; +use shade_protocol::staking::{ + stake::{Stake, Unbonding, UserStake}, + Config, +}; pub static CONFIG_KEY: &[u8] = b"config"; pub static STAKE_STATE_KEY: &[u8] = b"stake_state"; @@ -27,7 +39,7 @@ pub fn stake_state_r(storage: &S) -> ReadonlySingleton { singleton_read(storage, STAKE_STATE_KEY) } -pub fn staker_r(storage: & S) -> ReadonlyBucket { +pub fn staker_r(storage: &S) -> ReadonlyBucket { bucket_read(STAKER_KEY, storage) } @@ -36,23 +48,31 @@ pub fn staker_w(storage: &mut S) -> Bucket { } // Ideally these queues will be removed -pub fn unbonding_w(storage: &mut S) -> Singleton> { +pub fn unbonding_w( + storage: &mut S, +) -> Singleton> { singleton(storage, UNBONDING_KEY) } -pub fn unbonding_r(storage: &S) -> ReadonlySingleton> { +pub fn unbonding_r( + storage: &S, +) -> ReadonlySingleton> { singleton_read(storage, UNBONDING_KEY) } -pub fn user_unbonding_r(storage: & S) -> ReadonlyBucket> { +pub fn user_unbonding_r( + storage: &S, +) -> ReadonlyBucket> { bucket_read(USER_UNBONDING_KEY, storage) } -pub fn user_unbonding_w(storage: &mut S) -> Bucket> { +pub fn user_unbonding_w( + storage: &mut S, +) -> Bucket> { bucket(USER_UNBONDING_KEY, storage) } -pub fn viewking_key_r(storage: & S) -> ReadonlyBucket { +pub fn viewking_key_r(storage: &S) -> ReadonlyBucket { bucket_read(VIEWKING_KEY, storage) } diff --git a/contracts/staking/src/test.rs b/contracts/staking/src/test.rs index c7ba37489..c2492e16b 100644 --- a/contracts/staking/src/test.rs +++ b/contracts/staking/src/test.rs @@ -1,9 +1,9 @@ #[cfg(test)] pub mod tests { + use crate::handle::{calculate_shares, calculate_tokens, stake_weight}; use binary_heap_plus::{BinaryHeap, MinComparator}; + use cosmwasm_std::Uint128; use shade_protocol::staking::stake::{Stake, Unbonding, UserStake}; - use cosmwasm_std::{Uint128}; - use crate::handle::{calculate_shares, calculate_tokens, stake_weight}; #[test] fn test_weight_calculation() { @@ -20,15 +20,15 @@ pub mod tests { // Add the three values in a non order fashion let val1 = Unbonding { amount: Default::default(), - unbond_time: 0 + unbond_time: 0, }; let val2 = Unbonding { amount: Default::default(), - unbond_time: 1 + unbond_time: 1, }; let val3 = Unbonding { amount: Default::default(), - unbond_time: 2 + unbond_time: 2, }; unbonding_heap.push(val2); @@ -43,7 +43,7 @@ pub mod tests { fn init_user() -> UserStake { UserStake { shares: Uint128::zero(), - tokens_staked: Uint128::zero() + tokens_staked: Uint128::zero(), } } @@ -71,7 +71,7 @@ pub mod tests { fn standard_staking() { let mut state = Stake { total_shares: Uint128::zero(), - total_tokens: Uint128::zero() + total_tokens: Uint128::zero(), }; // User 1 stakes 100 @@ -103,7 +103,7 @@ pub mod tests { fn unbonding() { let mut state = Stake { total_shares: Uint128::zero(), - total_tokens: Uint128::zero() + total_tokens: Uint128::zero(), }; // User 1 stakes 100 @@ -126,16 +126,18 @@ pub mod tests { unbond(&mut state, &mut u2, u2_unbond); assert_eq!(u1_stake, calculate_tokens(u1.shares, &state)); - assert_eq!((u2_stake - u2_unbond).unwrap(), calculate_tokens(u2.shares, &state)); + assert_eq!( + (u2_stake - u2_unbond).unwrap(), + calculate_tokens(u2.shares, &state) + ); assert_eq!(u3_stake, calculate_tokens(u3.shares, &state)); - } #[test] fn rewards_distribution() { let mut state = Stake { total_shares: Uint128::zero(), - total_tokens: Uint128::zero() + total_tokens: Uint128::zero(), }; // User 1 stakes 100 @@ -156,9 +158,17 @@ pub mod tests { // Add a 200 reward, (should double user amounts) state.total_tokens += Uint128(200); - assert_eq!(u1_stake.multiply_ratio(Uint128(2), Uint128(1)), calculate_tokens(u1.shares, &state)); - assert_eq!(u2_stake.multiply_ratio(Uint128(2), Uint128(1)), calculate_tokens(u2.shares, &state)); - assert_eq!(u3_stake.multiply_ratio(Uint128(2), Uint128(1)), calculate_tokens(u3.shares, &state)); + assert_eq!( + u1_stake.multiply_ratio(Uint128(2), Uint128(1)), + calculate_tokens(u1.shares, &state) + ); + assert_eq!( + u2_stake.multiply_ratio(Uint128(2), Uint128(1)), + calculate_tokens(u2.shares, &state) + ); + assert_eq!( + u3_stake.multiply_ratio(Uint128(2), Uint128(1)), + calculate_tokens(u3.shares, &state) + ); } - } diff --git a/contracts/treasury/src/contract.rs b/contracts/treasury/src/contract.rs index bed349ed1..69cc0cb58 100644 --- a/contracts/treasury/src/contract.rs +++ b/contracts/treasury/src/contract.rs @@ -1,38 +1,34 @@ use cosmwasm_std::{ - debug_print, to_binary, Api, Binary, - Env, Extern, HandleResponse, InitResponse, - Querier, StdResult, Storage, + debug_print, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + InitResponse, + Querier, + StdResult, + Storage, }; -use shade_protocol::{ - treasury::{ - InitMsg, - Config, - HandleMsg, - QueryMsg, - }, -}; +use shade_protocol::treasury::{Config, HandleMsg, InitMsg, QueryMsg}; use crate::{ - state::{ - viewing_key_w, - config_w, - self_address_w, - }, - handle, query, + handle, + query, + state::{config_w, self_address_w, viewing_key_w}, }; - pub fn init( deps: &mut Extern, env: Env, msg: InitMsg, ) -> StdResult { - let state = Config { owner: match msg.admin { - None => { env.message.sender.clone() } - Some(admin) => { admin } + None => env.message.sender.clone(), + Some(admin) => admin, }, }; @@ -44,7 +40,7 @@ pub fn init( Ok(InitResponse { messages: vec![], - log: vec![] + log: vec![], }) } @@ -61,15 +57,12 @@ pub fn handle( msg, .. } => handle::receive(deps, env, sender, from, amount, msg), - HandleMsg::UpdateConfig { - owner, - } => handle::try_update_config(deps, env, owner), + HandleMsg::UpdateConfig { owner } => handle::try_update_config(deps, env, owner), HandleMsg::RegisterAsset { contract, allocations, } => handle::try_register_asset(deps, &env, &contract, allocations), - HandleMsg::Rebalance { - } => handle::rebalance(deps, &env), + HandleMsg::Rebalance {} => handle::rebalance(deps, &env), } } @@ -80,6 +73,6 @@ pub fn query( match msg { QueryMsg::GetConfig {} => to_binary(&query::config(deps)?), QueryMsg::GetBalance { contract } => to_binary(&query::balance(deps, contract)?), - QueryMsg::CanRebalance { } => to_binary(&query::can_rebalance(deps)?), + QueryMsg::CanRebalance {} => to_binary(&query::can_rebalance(deps)?), } } diff --git a/contracts/treasury/src/handle.rs b/contracts/treasury/src/handle.rs index fd8a4cee6..fb3926b8a 100644 --- a/contracts/treasury/src/handle.rs +++ b/contracts/treasury/src/handle.rs @@ -1,32 +1,27 @@ use cosmwasm_std::{ - debug_print, to_binary, Api, Binary, - Env, Extern, HandleResponse, - Querier, StdError, StdResult, Storage, - HumanAddr, Uint128 -}; -use secret_toolkit::{ - snip20::{ - token_info_query, - register_receive_msg, - set_viewing_key_msg, - }, + debug_print, + to_binary, + Api, + Binary, + Env, + Extern, + HandleResponse, + HumanAddr, + Querier, + StdError, + StdResult, + Storage, + Uint128, }; +use secret_toolkit::snip20::{register_receive_msg, set_viewing_key_msg, token_info_query}; use shade_protocol::{ - treasury::{ - HandleAnswer, - Asset, - Allocation, - }, asset::Contract, generic_response::ResponseStatus, + treasury::{Allocation, Asset, HandleAnswer}, }; -use crate::state::{ - config_w, config_r, - assets_r, assets_w, - viewing_key_r, -}; +use crate::state::{assets_r, assets_w, config_r, config_w, viewing_key_r}; pub fn receive( deps: &mut Extern, @@ -36,7 +31,6 @@ pub fn receive( amount: Uint128, _msg: Option, ) -> StdResult { - let assets = assets_r(&deps.storage); let asset: Asset = assets.load(env.message.sender.to_string().as_bytes())?; @@ -45,9 +39,9 @@ pub fn receive( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::Receive { + data: Some(to_binary(&HandleAnswer::Receive { status: ResponseStatus::Success, - } )? ), + })?), }) } @@ -56,7 +50,6 @@ pub fn try_update_config( env: Env, owner: Option, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.owner { return Err(StdError::Unauthorized { backtrace: None }); @@ -74,8 +67,9 @@ pub fn try_update_config( Ok(HandleResponse { messages: vec![], log: vec![], - data: Some( to_binary( &HandleAnswer::UpdateConfig { - status: ResponseStatus::Success } )? ) + data: Some(to_binary(&HandleAnswer::UpdateConfig { + status: ResponseStatus::Success, + })?), }) } @@ -85,16 +79,18 @@ pub fn try_register_asset( contract: &Contract, allocations: Option>, ) -> StdResult { - let config = config_r(&deps.storage).load()?; if env.message.sender != config.owner { return Err(StdError::Unauthorized { backtrace: None }); } let mut messages = vec![]; - let token_info = token_info_query(&deps.querier, 1, - contract.code_hash.clone(), - contract.address.clone())?; + let token_info = token_info_query( + &deps.querier, + 1, + contract.code_hash.clone(), + contract.address.clone(), + )?; assets_w(&mut deps.storage).save(contract.address.to_string().as_bytes(), &Asset { contract: contract.clone(), @@ -113,21 +109,19 @@ pub fn try_register_asset( // Set viewing key messages.push(set_viewing_key_msg( - viewing_key_r(&deps.storage).load()?, - None, - 1, - contract.code_hash.clone(), - contract.address.clone())?); - + viewing_key_r(&deps.storage).load()?, + None, + 1, + contract.code_hash.clone(), + contract.address.clone(), + )?); Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( - &HandleAnswer::RegisterAsset { - status: ResponseStatus::Success } - )? - ) + data: Some(to_binary(&HandleAnswer::RegisterAsset { + status: ResponseStatus::Success, + })?), }) } @@ -135,15 +129,12 @@ pub fn rebalance( _deps: &mut Extern, _env: &Env, ) -> StdResult { - let messages = vec![]; Ok(HandleResponse { messages, log: vec![], - data: Some( to_binary( - &HandleAnswer::Rebalance { - status: ResponseStatus::Success } - )? - ) + data: Some(to_binary(&HandleAnswer::Rebalance { + status: ResponseStatus::Success, + })?), }) } diff --git a/contracts/treasury/src/lib.rs b/contracts/treasury/src/lib.rs index 14d4d23b1..84be1cef6 100644 --- a/contracts/treasury/src/lib.rs +++ b/contracts/treasury/src/lib.rs @@ -1,7 +1,7 @@ pub mod contract; -pub mod state; pub mod handle; pub mod query; +pub mod state; #[cfg(test)] mod test; @@ -10,7 +10,12 @@ mod test; mod wasm { use super::contract; use cosmwasm_std::{ - do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + do_handle, + do_init, + do_query, + ExternalApi, + ExternalQuerier, + ExternalStorage, }; #[no_mangle] diff --git a/contracts/treasury/src/query.rs b/contracts/treasury/src/query.rs index 74a83c0cf..bf949d664 100644 --- a/contracts/treasury/src/query.rs +++ b/contracts/treasury/src/query.rs @@ -1,59 +1,33 @@ -use cosmwasm_std::{ - Api, Extern, Querier, Storage, - StdResult, StdError, HumanAddr, -}; +use cosmwasm_std::{Api, Extern, HumanAddr, Querier, StdError, StdResult, Storage}; use secret_toolkit::snip20; -use shade_protocol::{ - treasury::{ - QueryAnswer - }, -}; +use shade_protocol::treasury::QueryAnswer; -use crate::state::{ - config_r, - viewing_key_r, - self_address_r, - assets_r, -}; +use crate::state::{assets_r, config_r, self_address_r, viewing_key_r}; -pub fn config( - deps: &Extern -) -> StdResult { - - Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()? }) +pub fn config(deps: &Extern) -> StdResult { + Ok(QueryAnswer::Config { + config: config_r(&deps.storage).load()?, + }) } pub fn balance( deps: &Extern, contract: HumanAddr, ) -> StdResult { - //TODO: restrict to admin return match assets_r(&deps.storage).may_load(contract.to_string().as_bytes())? { - Some(a) => { - Ok(snip20::QueryMsg::Balance { - address: self_address_r(&deps.storage).load()?, - key: viewing_key_r(&deps.storage).load()?, - }.query( - &deps.querier, - 1, - a.contract.code_hash, - contract, - )?) - } - None => { - Err(StdError::not_found(contract.to_string())) + Some(a) => Ok(snip20::QueryMsg::Balance { + address: self_address_r(&deps.storage).load()?, + key: viewing_key_r(&deps.storage).load()?, } + .query(&deps.querier, 1, a.contract.code_hash, contract)?), + None => Err(StdError::not_found(contract.to_string())), }; - } pub fn can_rebalance( _deps: &Extern, ) -> StdResult { - - Ok(QueryAnswer::CanRebalance { - possible: false, - }) + Ok(QueryAnswer::CanRebalance { possible: false }) } diff --git a/contracts/treasury/src/state.rs b/contracts/treasury/src/state.rs index 9b44cd4fd..ab8302269 100644 --- a/contracts/treasury/src/state.rs +++ b/contracts/treasury/src/state.rs @@ -1,9 +1,13 @@ -use cosmwasm_std::{Storage, HumanAddr}; +use cosmwasm_std::{HumanAddr, Storage}; use cosmwasm_storage::{ - singleton, singleton_read, - Singleton, ReadonlySingleton, - Bucket, ReadonlyBucket, - bucket, bucket_read, + bucket, + bucket_read, + singleton, + singleton_read, + Bucket, + ReadonlyBucket, + ReadonlySingleton, + Singleton, }; use shade_protocol::treasury; @@ -29,7 +33,7 @@ pub fn asset_list_read(storage: &S) -> ReadonlySingleton(storage: & S) -> ReadonlyBucket { +pub fn assets_r(storage: &S) -> ReadonlyBucket { bucket_read(ASSET_KEY, storage) } diff --git a/packages/network_integration/src/contract_helpers/governance.rs b/packages/network_integration/src/contract_helpers/governance.rs index 06073043b..cd79e58a9 100644 --- a/packages/network_integration/src/contract_helpers/governance.rs +++ b/packages/network_integration/src/contract_helpers/governance.rs @@ -1,22 +1,39 @@ -use serde_json::{Result}; -use shade_protocol::{governance, asset::Contract}; use cosmwasm_std::{HumanAddr, Uint128}; -use shade_protocol::governance::GOVERNANCE_SELF; - -use crate::utils::{print_header, generate_label, ACCOUNT_KEY, STORE_GAS, GAS, - print_contract, print_warning}; - -use secretcli::{cli_types::NetContract, secretcli::{query_contract, test_contract_handle, test_inst_init}}; +use serde_json::Result; +use shade_protocol::{asset::Contract, governance, governance::GOVERNANCE_SELF}; + +use crate::utils::{ + generate_label, + print_contract, + print_header, + print_warning, + ACCOUNT_KEY, + GAS, + STORE_GAS, +}; + +use secretcli::{ + cli_types::NetContract, + secretcli::{query_contract, test_contract_handle, test_inst_init}, +}; pub fn init_contract( - governance: &NetContract, contract_name: String, - contract_path: &str, contract_init: Init) -> Result { + governance: &NetContract, + contract_name: String, + contract_path: &str, + contract_init: Init, +) -> Result { print_header(&format!("{}{}", "Initializing ", contract_name)); - let contract = test_inst_init(&contract_init, contract_path, - &*generate_label(8), ACCOUNT_KEY, - Some(STORE_GAS), Some(GAS), - Some("test"))?; + let contract = test_inst_init( + &contract_init, + contract_path, + &*generate_label(8), + ACCOUNT_KEY, + Some(STORE_GAS), + Some(GAS), + Some("test"), + )?; print_contract(&contract); @@ -26,14 +43,13 @@ pub fn init_contract( } pub fn get_contract(governance: &NetContract, target: String) -> Result { - let msg = governance::QueryMsg::GetSupportedContract { name: target }; let query: governance::QueryAnswer = query_contract(governance, &msg)?; let mut ctrc = Contract { address: HumanAddr::from("not_found".to_string()), - code_hash: "not_found".to_string() + code_hash: "not_found".to_string(), }; if let governance::QueryAnswer::SupportedContract { contract } = query { @@ -43,24 +59,28 @@ pub fn get_contract(governance: &NetContract, target: String) -> Result Result<()>{ +pub fn add_contract(name: String, target: &NetContract, governance: &NetContract) -> Result<()> { print_warning(&format!("{}{}", "Adding ", name)); let msg = governance::HandleMsg::AddSupportedContract { name: name.clone(), - contract: Contract{ + contract: Contract { address: HumanAddr::from(target.address.clone()), - code_hash: target.code_hash.clone() - } + code_hash: target.code_hash.clone(), + }, }; - create_and_trigger_proposal(governance, GOVERNANCE_SELF.to_string(), - &msg, Some("Add a contract"))?; + create_and_trigger_proposal( + governance, + GOVERNANCE_SELF.to_string(), + &msg, + Some("Add a contract"), + )?; { let query_msg = governance::QueryMsg::GetSupportedContract { name }; - let query: governance::QueryAnswer = query_contract(governance, query_msg)?; + let query: governance::QueryAnswer = query_contract(governance, query_msg)?; if let governance::QueryAnswer::SupportedContract { contract } = query { assert_eq!(contract.address.to_string(), target.address.to_string()); @@ -75,7 +95,11 @@ pub fn add_contract(name: String, target: &NetContract, governance: &NetContract /// Assumes that governance's staker is not activated pub fn create_and_trigger_proposal( - governance: &NetContract, target: String, handle: Handle, desc: Option<&str>) -> Result { + governance: &NetContract, + target: String, + handle: Handle, + desc: Option<&str>, +) -> Result { create_proposal(governance, target, handle, desc)?; trigger_latest_proposal(governance) @@ -89,10 +113,8 @@ pub fn get_latest_proposal(governance: &NetContract) -> Result { let mut proposals = Uint128(1); if let governance::QueryAnswer::TotalProposals { total } = query { - proposals = total; - } - else { + } else { assert!(false, "Query returned unexpected type") } @@ -100,7 +122,11 @@ pub fn get_latest_proposal(governance: &NetContract) -> Result { } pub fn create_proposal( - governance: &NetContract, target: String, handle: Handle, desc: Option<&str>) -> Result<()> { + governance: &NetContract, + target: String, + handle: Handle, + desc: Option<&str>, +) -> Result<()> { let msg = serde_json::to_string(&handle)?; let proposal_msg = governance::HandleMsg::CreateProposal { @@ -108,14 +134,20 @@ pub fn create_proposal( proposal: msg, description: match desc { None => "Custom proposal".to_string(), - Some(description) => description.to_string() - } + Some(description) => description.to_string(), + }, }; //let proposals = get_latest_proposal(governance)?; - test_contract_handle(&proposal_msg, governance, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &proposal_msg, + governance, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; //assert_eq!(proposals, get_latest_proposal(governance)?); @@ -123,13 +155,20 @@ pub fn create_proposal( } pub fn trigger_latest_proposal(governance: &NetContract) -> Result { - let proposals = get_latest_proposal(governance)?; - let handle_msg = governance::HandleMsg::TriggerProposal { proposal_id: proposals }; + let handle_msg = governance::HandleMsg::TriggerProposal { + proposal_id: proposals, + }; - test_contract_handle(&handle_msg, governance, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &handle_msg, + governance, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; Ok(proposals) } diff --git a/packages/network_integration/src/contract_helpers/initializer.rs b/packages/network_integration/src/contract_helpers/initializer.rs index 445658150..06799e56b 100644 --- a/packages/network_integration/src/contract_helpers/initializer.rs +++ b/packages/network_integration/src/contract_helpers/initializer.rs @@ -1,32 +1,48 @@ -use serde_json::Result; +use crate::{ + contract_helpers::minter::get_balance, + utils::{ + generate_label, + print_contract, + print_header, + print_warning, + ACCOUNT_KEY, + GAS, + INITIALIZER_FILE, + STORE_GAS, + VIEW_KEY, + }, +}; use cosmwasm_std::{HumanAddr, Uint128}; -use shade_protocol::{snip20::{InitialBalance}, snip20, - initializer, initializer::Snip20ContractInfo}; -use crate::{utils::{print_header, generate_label, print_contract, print_warning, - STORE_GAS, GAS, VIEW_KEY, ACCOUNT_KEY, INITIALIZER_FILE}, - contract_helpers::minter::get_balance}; -use secretcli::{cli_types::NetContract, - secretcli::{test_contract_handle, test_inst_init, list_contracts_by_code}}; +use secretcli::{ + cli_types::NetContract, + secretcli::{list_contracts_by_code, test_contract_handle, test_inst_init}, +}; +use serde_json::Result; +use shade_protocol::{ + initializer, + initializer::Snip20ContractInfo, + snip20, + snip20::InitialBalance, +}; pub fn initialize_initializer( admin: String, sscrt: &NetContract, - account: String + account: String, ) -> Result<(NetContract, NetContract, NetContract)> { - print_header("Initializing Initializer"); let mut shade = NetContract { label: generate_label(8), id: "".to_string(), address: "".to_string(), - code_hash: sscrt.code_hash.clone() + code_hash: sscrt.code_hash.clone(), }; let mut silk = NetContract { label: generate_label(8), id: "".to_string(), address: "".to_string(), - code_hash: sscrt.code_hash.clone() + code_hash: sscrt.code_hash.clone(), }; let init_msg = initializer::InitMsg { @@ -36,20 +52,28 @@ pub fn initialize_initializer( label: shade.label.clone(), admin: Some(HumanAddr::from(admin.clone())), prng_seed: Default::default(), - initial_balances: Some(vec![InitialBalance{ - address: HumanAddr::from(account.clone()), amount: Uint128(10000000) }]) + initial_balances: Some(vec![InitialBalance { + address: HumanAddr::from(account.clone()), + amount: Uint128(10000000), + }]), }, silk: Snip20ContractInfo { label: silk.label.clone(), admin: Some(HumanAddr::from(admin)), prng_seed: Default::default(), - initial_balances: None - } + initial_balances: None, + }, }; - let initializer = test_inst_init(&init_msg, INITIALIZER_FILE, &*generate_label(8), - ACCOUNT_KEY, Some(STORE_GAS), Some(GAS), - Some("test"))?; + let initializer = test_inst_init( + &init_msg, + INITIALIZER_FILE, + &*generate_label(8), + ACCOUNT_KEY, + Some(STORE_GAS), + Some(GAS), + Some("test"), + )?; print_contract(&initializer); print_header("Getting uploaded Snip20s"); @@ -62,8 +86,7 @@ pub fn initialize_initializer( shade.id = contract.code_id.to_string(); shade.address = contract.address; print_contract(&shade); - } - else if contract.label == silk.label { + } else if contract.label == silk.label { print_warning("Found Silk"); silk.id = contract.code_id.to_string(); silk.address = contract.address; @@ -75,10 +98,10 @@ pub fn initialize_initializer( { let msg = snip20::HandleMsg::SetViewingKey { key: String::from(VIEW_KEY), - padding: None }; + padding: None, + }; - test_contract_handle(&msg, &shade, ACCOUNT_KEY, - Some(GAS), Some("test"), None)?; + test_contract_handle(&msg, &shade, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } println!("\n\tTotal shade: {}", get_balance(&shade, account.clone())); @@ -86,10 +109,10 @@ pub fn initialize_initializer( { let msg = snip20::HandleMsg::SetViewingKey { key: String::from(VIEW_KEY), - padding: None }; + padding: None, + }; - test_contract_handle(&msg, &silk, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &silk, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } println!("\tTotal silk: {}", get_balance(&silk, account)); diff --git a/packages/network_integration/src/contract_helpers/minter.rs b/packages/network_integration/src/contract_helpers/minter.rs index 7f827dc95..d07a8d14b 100644 --- a/packages/network_integration/src/contract_helpers/minter.rs +++ b/packages/network_integration/src/contract_helpers/minter.rs @@ -1,18 +1,33 @@ +use crate::{ + contract_helpers::governance::{create_and_trigger_proposal, get_contract, init_contract}, + utils::{ + print_contract, + print_epoch_info, + print_header, + print_vec, + GAS, + MICRO_MINT_FILE, + VIEW_KEY, + }, +}; +use cosmwasm_std::{to_binary, HumanAddr, Uint128}; +use secretcli::{ + cli_types::NetContract, + secretcli::{query_contract, test_contract_handle}, +}; use serde_json::Result; -use cosmwasm_std::{HumanAddr, Uint128, to_binary}; -use shade_protocol::{snip20, micro_mint, mint, asset::Contract}; -use crate::{utils::{print_header, print_contract, print_epoch_info, print_vec, - GAS, VIEW_KEY, MICRO_MINT_FILE}, - contract_helpers::governance::{init_contract, get_contract, - create_and_trigger_proposal}}; -use secretcli::{cli_types::NetContract, - secretcli::{query_contract, test_contract_handle}}; - -pub fn initialize_minter(governance: &NetContract, contract_name: String, - native_asset: &Contract) -> Result { - let minter = init_contract(governance, contract_name, - MICRO_MINT_FILE, - micro_mint::InitMsg { +use shade_protocol::{asset::Contract, micro_mint, mint, snip20}; + +pub fn initialize_minter( + governance: &NetContract, + contract_name: String, + native_asset: &Contract, +) -> Result { + let minter = init_contract( + governance, + contract_name, + MICRO_MINT_FILE, + micro_mint::InitMsg { admin: Some(HumanAddr::from(governance.address.clone())), native_asset: native_asset.clone(), oracle: get_contract(governance, "oracle".to_string())?, @@ -21,8 +36,9 @@ pub fn initialize_minter(governance: &NetContract, contract_name: String, secondary_burn: None, start_epoch: None, epoch_frequency: Some(Uint128(120)), - epoch_mint_limit: Some(Uint128(1000000000)) - })?; + epoch_mint_limit: Some(Uint128(1000000000)), + }, + )?; print_contract(&minter); @@ -31,61 +47,98 @@ pub fn initialize_minter(governance: &NetContract, contract_name: String, Ok(minter) } -pub fn setup_minters(governance: &NetContract, mint_shade: &NetContract, mint_silk: &NetContract, - shade: &Contract, silk: &Contract, sscrt: &NetContract) -> Result<()> { +pub fn setup_minters( + governance: &NetContract, + mint_shade: &NetContract, + mint_silk: &NetContract, + shade: &Contract, + silk: &Contract, + sscrt: &NetContract, +) -> Result<()> { print_header("Registering allowed tokens in mint contracts"); - create_and_trigger_proposal(governance, "shade_minter".to_string(), - micro_mint::HandleMsg::RegisterAsset { - contract: Contract { - address: HumanAddr::from(sscrt.address.clone()), - code_hash: sscrt.code_hash.clone() - }, - capture: Some(Uint128(1000))}, Some("Register asset"))?; - create_and_trigger_proposal(governance, "shade_minter".to_string(), - micro_mint::HandleMsg::RegisterAsset { - contract: silk.clone(), - capture: Some(Uint128(1000))}, Some("Register asset"))?; - create_and_trigger_proposal(governance, "silk_minter".to_string(), - micro_mint::HandleMsg::RegisterAsset { - contract: shade.clone(), - capture: Some(Uint128(1000))}, Some("Register asset"))?; + create_and_trigger_proposal( + governance, + "shade_minter".to_string(), + micro_mint::HandleMsg::RegisterAsset { + contract: Contract { + address: HumanAddr::from(sscrt.address.clone()), + code_hash: sscrt.code_hash.clone(), + }, + capture: Some(Uint128(1000)), + }, + Some("Register asset"), + )?; + create_and_trigger_proposal( + governance, + "shade_minter".to_string(), + micro_mint::HandleMsg::RegisterAsset { + contract: silk.clone(), + capture: Some(Uint128(1000)), + }, + Some("Register asset"), + )?; + create_and_trigger_proposal( + governance, + "silk_minter".to_string(), + micro_mint::HandleMsg::RegisterAsset { + contract: shade.clone(), + capture: Some(Uint128(1000)), + }, + Some("Register asset"), + )?; print_header("Adding allowed minters in Snip20s"); - create_and_trigger_proposal(governance, "shade".to_string(), - snip20::HandleMsg::SetMinters { - minters: vec![HumanAddr::from(mint_shade.address.clone())], - padding: None }, Some("Set minters"))?; + create_and_trigger_proposal( + governance, + "shade".to_string(), + snip20::HandleMsg::SetMinters { + minters: vec![HumanAddr::from(mint_shade.address.clone())], + padding: None, + }, + Some("Set minters"), + )?; { let msg = snip20::QueryMsg::Minters {}; - let query: snip20::QueryAnswer = query_contract(&NetContract{ - label: "".to_string(), - id: "".to_string(), - address: shade.address.clone().to_string(), - code_hash: shade.code_hash.clone() - }, &msg)?; + let query: snip20::QueryAnswer = query_contract( + &NetContract { + label: "".to_string(), + id: "".to_string(), + address: shade.address.clone().to_string(), + code_hash: shade.code_hash.clone(), + }, + &msg, + )?; if let snip20::QueryAnswer::Minters { minters } = query { print_vec("Shade minters: ", minters); } } - create_and_trigger_proposal(governance, "silk".to_string(), - snip20::HandleMsg::SetMinters { - minters: vec![HumanAddr::from(mint_silk.address.clone())], - padding: None }, Some("Set minters"))?; + create_and_trigger_proposal( + governance, + "silk".to_string(), + snip20::HandleMsg::SetMinters { + minters: vec![HumanAddr::from(mint_silk.address.clone())], + padding: None, + }, + Some("Set minters"), + )?; { let msg = snip20::QueryMsg::Minters {}; - let query: snip20::QueryAnswer = query_contract(&NetContract{ - label: "".to_string(), - id: "".to_string(), - address: silk.address.clone().to_string(), - code_hash: silk.code_hash.clone() - }, &msg)?; + let query: snip20::QueryAnswer = query_contract( + &NetContract { + label: "".to_string(), + id: "".to_string(), + address: silk.address.clone().to_string(), + code_hash: silk.code_hash.clone(), + }, + &msg, + )?; if let snip20::QueryAnswer::Minters { minters } = query { print_vec("Silk minters: ", minters); } @@ -94,7 +147,7 @@ pub fn setup_minters(governance: &NetContract, mint_shade: &NetContract, mint_si Ok(()) } -pub fn get_balance(contract: &NetContract, from: String, ) -> Uint128 { +pub fn get_balance(contract: &NetContract, from: String) -> Uint128 { let msg = snip20::QueryMsg::Balance { address: HumanAddr::from(from), key: String::from(VIEW_KEY), @@ -103,22 +156,31 @@ pub fn get_balance(contract: &NetContract, from: String, ) -> Uint128 { let balance: snip20::QueryAnswer = query_contract(contract, &msg).unwrap(); if let snip20::QueryAnswer::Balance { amount } = balance { - return amount + return amount; } Uint128(0) } -pub fn mint(snip: &NetContract, sender: &str, minter: String, amount: Uint128, - minimum_expected: Uint128, backend: &str) { - +pub fn mint( + snip: &NetContract, + sender: &str, + minter: String, + amount: Uint128, + minimum_expected: Uint128, + backend: &str, +) { let msg = snip20::HandleMsg::Send { recipient: HumanAddr::from(minter), amount, - msg: Some(to_binary(&mint::MintMsgHook { - minimum_expected_amount: minimum_expected}).unwrap()), + msg: Some( + to_binary(&mint::MintMsgHook { + minimum_expected_amount: minimum_expected, + }) + .unwrap(), + ), memo: None, - padding: None + padding: None, }; test_contract_handle(&msg, snip, sender, Some(GAS), Some(backend), None).unwrap(); diff --git a/packages/network_integration/src/contract_helpers/mod.rs b/packages/network_integration/src/contract_helpers/mod.rs index 5a17bae53..78537acd7 100644 --- a/packages/network_integration/src/contract_helpers/mod.rs +++ b/packages/network_integration/src/contract_helpers/mod.rs @@ -1,4 +1,4 @@ +pub mod governance; pub mod initializer; pub mod minter; -pub mod governance; -pub mod stake; \ No newline at end of file +pub mod stake; diff --git a/packages/network_integration/src/contract_helpers/stake.rs b/packages/network_integration/src/contract_helpers/stake.rs index f1ebd8d69..9cd6e9423 100644 --- a/packages/network_integration/src/contract_helpers/stake.rs +++ b/packages/network_integration/src/contract_helpers/stake.rs @@ -1,37 +1,45 @@ -use serde_json::Result; +use crate::{ + contract_helpers::{governance::init_contract, minter::get_balance}, + utils::{print_contract, print_header, ACCOUNT_KEY, GAS, STAKING_FILE}, +}; use cosmwasm_std::{HumanAddr, Uint128}; -use shade_protocol::{staking, snip20, asset::Contract}; -use crate::{utils::{print_header, print_contract, - GAS, ACCOUNT_KEY, STAKING_FILE}, - contract_helpers::governance::{init_contract}}; -use secretcli::{cli_types::NetContract, - secretcli::{query_contract, test_contract_handle}}; -use crate::contract_helpers::minter::get_balance; -use std::{thread, time}; -use std::time::UNIX_EPOCH; - -pub fn setup_staker(governance: &NetContract, shade: &Contract, - staking_account: String) -> Result { - let staker = init_contract(governance, "staking".to_string(), - STAKING_FILE, - staking::InitMsg{ - admin: Some(Contract{ - address: HumanAddr::from(governance.address.clone()), - code_hash: governance.code_hash.clone() }), - unbond_time: 180, - staked_token: Contract { - address: shade.address.clone(), - code_hash: shade.code_hash.clone() - } - })?; +use secretcli::{ + cli_types::NetContract, + secretcli::{query_contract, test_contract_handle}, +}; +use serde_json::Result; +use shade_protocol::{asset::Contract, snip20, staking}; +use std::{thread, time, time::UNIX_EPOCH}; + +pub fn setup_staker( + governance: &NetContract, + shade: &Contract, + staking_account: String, +) -> Result { + let staker = init_contract( + governance, + "staking".to_string(), + STAKING_FILE, + staking::InitMsg { + admin: Some(Contract { + address: HumanAddr::from(governance.address.clone()), + code_hash: governance.code_hash.clone(), + }), + unbond_time: 180, + staked_token: Contract { + address: shade.address.clone(), + code_hash: shade.code_hash.clone(), + }, + }, + )?; print_contract(&staker); - let shade_net = NetContract{ + let shade_net = NetContract { label: "-".to_string(), id: "-".to_string(), address: shade.address.to_string(), - code_hash: shade.code_hash.clone() + code_hash: shade.code_hash.clone(), }; print_header("Testing staking delegation"); @@ -44,10 +52,11 @@ pub fn setup_staker(governance: &NetContract, shade: &Contract, // Make a query key { - let msg = staking::HandleMsg::SetViewingKey { key: "password".to_string() }; + let msg = staking::HandleMsg::SetViewingKey { + key: "password".to_string(), + }; - test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } // Stake some Shade on it @@ -57,40 +66,46 @@ pub fn setup_staker(governance: &NetContract, shade: &Contract, amount: stake_amount, msg: None, memo: None, - padding: None + padding: None, }; - test_contract_handle(&msg, &shade_net, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &shade_net, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } // Check total stake assert_eq!(get_total_staked(&staker), stake_amount); // Check user stake - assert_eq!(get_user_stake(&staker, staking_account.clone(), - "password".to_string()).staked, stake_amount); + assert_eq!( + get_user_stake(&staker, staking_account.clone(), "password".to_string()).staked, + stake_amount + ); // Query total Shade now - assert_eq!(balance_after_stake, get_balance(&shade_net, - staking_account.clone())); + assert_eq!( + balance_after_stake, + get_balance(&shade_net, staking_account.clone()) + ); print_header("Testing unbonding request"); // User unbonds { - let msg = staking::HandleMsg::Unbond { amount: unbond_amount }; + let msg = staking::HandleMsg::Unbond { + amount: unbond_amount, + }; - test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } // Check if unstaking - assert_eq!(get_total_staked(&staker), (stake_amount - unbond_amount).unwrap()); + assert_eq!( + get_total_staked(&staker), + (stake_amount - unbond_amount).unwrap() + ); // Check if user unstaking { - let user_stake = get_user_stake(&staker, staking_account.clone(), - "password".to_string()); + let user_stake = get_user_stake(&staker, staking_account.clone(), "password".to_string()); assert_eq!(user_stake.staked, (stake_amount - unbond_amount).unwrap()); assert_eq!(user_stake.unbonding, unbond_amount); @@ -101,33 +116,38 @@ pub fn setup_staker(governance: &NetContract, shade: &Contract, { let msg = staking::HandleMsg::ClaimUnbond {}; - test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } // Query total Shade now - assert_eq!(balance_after_stake, get_balance(&shade_net, - staking_account.clone())); + assert_eq!( + balance_after_stake, + get_balance(&shade_net, staking_account.clone()) + ); // Wait unbonding time thread::sleep(time::Duration::from_secs(180)); // Check if unbonded - assert_eq!(get_user_stake(&staker, staking_account.clone(), - "password".to_string()).unbonded, unbond_amount); + assert_eq!( + get_user_stake(&staker, staking_account.clone(), "password".to_string()).unbonded, + unbond_amount + ); print_header("Testing unbonding asset release"); // User triggers and receives something { let msg = staking::HandleMsg::ClaimUnbond {}; - test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &staker, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } // Query total Shade now - assert_eq!((balance_after_stake + unbond_amount), get_balance(&shade_net, staking_account)); + assert_eq!( + (balance_after_stake + unbond_amount), + get_balance(&shade_net, staking_account) + ); Ok(staker) } @@ -138,7 +158,7 @@ pub fn get_total_staked(staker: &NetContract) -> Uint128 { let total_stake: staking::QueryAnswer = query_contract(staker, &msg).unwrap(); if let staking::QueryAnswer::TotalStaked { total } = total_stake { - return total + return total; } Uint128::zero() @@ -148,27 +168,40 @@ pub struct TestUserStake { pub staked: Uint128, pub pending_rewards: Uint128, pub unbonding: Uint128, - pub unbonded: Uint128 + pub unbonded: Uint128, } pub fn get_user_stake(staker: &NetContract, address: String, key: String) -> TestUserStake { - let msg = staking::QueryMsg::UserStake { address: HumanAddr::from(address), key, - time: time::SystemTime::now().duration_since(UNIX_EPOCH).expect("").as_secs() }; + let msg = staking::QueryMsg::UserStake { + address: HumanAddr::from(address), + key, + time: time::SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("") + .as_secs(), + }; let query: staking::QueryAnswer = query_contract(staker, &msg).unwrap(); - if let staking::QueryAnswer::UserStake { staked, pending_rewards, - unbonding, unbonded } = query { + if let staking::QueryAnswer::UserStake { + staked, + pending_rewards, + unbonding, + unbonded, + } = query + { return TestUserStake { - staked, pending_rewards, unbonding, unbonded - } + staked, + pending_rewards, + unbonding, + unbonded, + }; } - TestUserStake { staked: Uint128::zero(), pending_rewards: Uint128::zero(), unbonding: Uint128::zero(), - unbonded: Uint128::zero() + unbonded: Uint128::zero(), } } diff --git a/packages/network_integration/src/lib.rs b/packages/network_integration/src/lib.rs index 0cb59cf55..1c845cc7a 100644 --- a/packages/network_integration/src/lib.rs +++ b/packages/network_integration/src/lib.rs @@ -1,2 +1,2 @@ +pub mod contract_helpers; pub mod utils; -pub mod contract_helpers; \ No newline at end of file diff --git a/packages/network_integration/src/testnet_airdrop.rs b/packages/network_integration/src/testnet_airdrop.rs index cab9b43a9..3a3d79fa3 100644 --- a/packages/network_integration/src/testnet_airdrop.rs +++ b/packages/network_integration/src/testnet_airdrop.rs @@ -1,15 +1,25 @@ -use std::fs; -use std::env; -use serde_json::Result; -use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Binary, Uint128, HumanAddr}; +use cosmwasm_std::{Binary, HumanAddr, Uint128}; +use network_integration::utils::{ + generate_label, + print_contract, + print_header, + AIRDROP_FILE, + GAS, + SNIP20_FILE, + STORE_GAS, +}; use rs_merkle::{algorithms::Sha256, Hasher, MerkleTree}; -use network_integration::utils::{AIRDROP_FILE, GAS, generate_label, print_contract, print_header, SNIP20_FILE, STORE_GAS}; use secretcli::secretcli::{account_address, test_contract_handle, test_inst_init}; -use shade_protocol::{airdrop, snip20}; -use shade_protocol::airdrop::claim_info::RequiredTask; -use shade_protocol::asset::Contract; -use shade_protocol::snip20::{InitConfig, InitialBalance}; +use serde::{Deserialize, Serialize}; +use serde_json::Result; +use shade_protocol::{ + airdrop, + airdrop::claim_info::RequiredTask, + asset::Contract, + snip20, + snip20::{InitConfig, InitialBalance}, +}; +use std::{env, fs}; #[derive(Serialize, Deserialize)] pub struct Reward { @@ -30,8 +40,8 @@ pub struct Args { fn main() -> Result<()> { let bin_args: Vec = env::args().collect(); - let args_file = fs::read_to_string(&bin_args.get(1) - .expect("No argument provided")).expect("Unable to read args"); + let args_file = fs::read_to_string(&bin_args.get(1).expect("No argument provided")) + .expect("Unable to read args"); let args: Args = serde_json::from_str(&args_file)?; let account_addr = account_address(&args.admin)?; @@ -41,8 +51,14 @@ fn main() -> Result<()> { let rewards: Vec = serde_json::from_str(&file_data)?; print_header("Converting into merkle tree"); - let raw_leaves: Vec = rewards.iter().map(|x| x.address.clone() + &x.amount).collect(); - let leaves: Vec<[u8; 32]> = raw_leaves.iter().map(|x| Sha256::hash(x.as_bytes())).collect(); + let raw_leaves: Vec = rewards + .iter() + .map(|x| x.address.clone() + &x.amount) + .collect(); + let leaves: Vec<[u8; 32]> = raw_leaves + .iter() + .map(|x| Sha256::hash(x.as_bytes())) + .collect(); let merkle_tree = MerkleTree::::from_leaves(&leaves); let root = merkle_tree.root().unwrap(); @@ -70,22 +86,29 @@ fn main() -> Result<()> { admin: None, symbol: "SHADE".to_string(), decimals: 6, - initial_balances: Some(vec![InitialBalance{ + initial_balances: Some(vec![InitialBalance { address: HumanAddr::from(account_addr.clone()), - amount: args.initial_amount }]), + amount: args.initial_amount, + }]), prng_seed: Default::default(), config: Some(InitConfig { public_total_supply: Some(true), enable_deposit: Some(false), enable_redeem: Some(false), enable_mint: Some(true), - enable_burn: Some(true) - }) + enable_burn: Some(true), + }), }; - let snip = test_inst_init(&snip_init_msg, SNIP20_FILE, - &*generate_label(8), &args.admin, - Some(STORE_GAS), Some(GAS), None)?; + let snip = test_inst_init( + &snip_init_msg, + SNIP20_FILE, + &*generate_label(8), + &args.admin, + Some(STORE_GAS), + Some(GAS), + None, + )?; print_contract(&snip); // Initialize airdrop @@ -96,7 +119,7 @@ fn main() -> Result<()> { dump_address: Some(HumanAddr::from(account_addr.clone())), airdrop_token: Contract { address: HumanAddr::from(snip.address.clone()), - code_hash: snip.code_hash.clone() + code_hash: snip.code_hash.clone(), }, airdrop_amount: args.initial_amount, start_date: Some(args.start_date), @@ -108,24 +131,38 @@ fn main() -> Result<()> { default_claim: Uint128(20), task_claim: vec![RequiredTask { address: HumanAddr::from(account_addr), - percent: Uint128(50) }], - query_rounding: Uint128(10000000000) + percent: Uint128(50), + }], + query_rounding: Uint128(10000000000), }; - let airdrop = test_inst_init(&airdrop_init_msg, AIRDROP_FILE, - &*generate_label(8), &args.admin, - Some(STORE_GAS), Some(GAS), None)?; + let airdrop = test_inst_init( + &airdrop_init_msg, + AIRDROP_FILE, + &*generate_label(8), + &args.admin, + Some(STORE_GAS), + Some(GAS), + None, + )?; print_contract(&airdrop); print_header("Funding airdrop"); - test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(airdrop.address), - amount: args.initial_amount, - msg: None, - memo: None, - padding: None - }, &snip, &args.admin, Some(GAS), None, None)?; + test_contract_handle( + &snip20::HandleMsg::Send { + recipient: HumanAddr::from(airdrop.address), + amount: args.initial_amount, + msg: None, + memo: None, + padding: None, + }, + &snip, + &args.admin, + Some(GAS), + None, + None, + )?; Ok(()) -} \ No newline at end of file +} diff --git a/packages/network_integration/src/utils.rs b/packages/network_integration/src/utils.rs index b89f53a4d..4dcd7417f 100644 --- a/packages/network_integration/src/utils.rs +++ b/packages/network_integration/src/utils.rs @@ -1,10 +1,9 @@ use colored::*; use rand::{distributions::Alphanumeric, Rng}; -use shade_protocol::{micro_mint}; -use std::fmt::Display; +use secretcli::{cli_types::NetContract, secretcli::query_contract}; use serde::Serialize; -use secretcli::{cli_types::NetContract, - secretcli::{query_contract}}; +use shade_protocol::micro_mint; +use std::fmt::Display; // Smart contracts pub const SNIP20_FILE: &str = "../../compiled/snip20.wasm.gz"; @@ -16,13 +15,11 @@ pub const INITIALIZER_FILE: &str = "../../compiled/initializer.wasm.gz"; pub const MICRO_MINT_FILE: &str = "../../compiled/micro_mint.wasm.gz"; pub const STAKING_FILE: &str = "../../compiled/staking.wasm.gz"; - pub const STORE_GAS: &str = "10000000"; pub const GAS: &str = "800000"; pub const VIEW_KEY: &str = "password"; pub const ACCOUNT_KEY: &str = "a"; - pub fn generate_label(size: usize) -> String { rand::thread_rng() .sample_iter(&Alphanumeric) @@ -31,23 +28,21 @@ pub fn generate_label(size: usize) -> String { .collect() } - pub fn print_header(header: &str) { println!("{}", header.on_blue()); } - pub fn print_warning(warn: &str) { println!("{}", warn.on_yellow()); } - pub fn print_contract(contract: &NetContract) { - println!("\tLabel: {}\n\tID: {}\n\tAddress: {}\n\tHash: {}", contract.label, contract.id, - contract.address, contract.code_hash); + println!( + "\tLabel: {}\n\tID: {}\n\tAddress: {}\n\tHash: {}", + contract.label, contract.id, contract.address, contract.code_hash + ); } - pub fn print_epoch_info(minter: &NetContract) { println!("\tEpoch information"); let msg = micro_mint::QueryMsg::GetMintLimit {}; @@ -55,17 +50,17 @@ pub fn print_epoch_info(minter: &NetContract) { let query: micro_mint::QueryAnswer = query_contract(minter, &msg).unwrap(); if let micro_mint::QueryAnswer::MintLimit { limit } = query { - println!("\tFrequency: {}\n\tCapacity: {}\n\tTotal Minted: {}\n\tNext Epoch: {}", - limit.frequency, limit.mint_capacity, limit.total_minted, limit.next_epoch); + println!( + "\tFrequency: {}\n\tCapacity: {}\n\tTotal Minted: {}\n\tNext Epoch: {}", + limit.frequency, limit.mint_capacity, limit.total_minted, limit.next_epoch + ); } } - pub fn print_struct(item: Printable) { println!("{}", serde_json::to_string_pretty(&item).unwrap()); } - pub fn print_vec(prefix: &str, vec: Vec) { for e in vec.iter().take(1) { print!("{}{}", prefix, e); diff --git a/packages/network_integration/tests/testnet_integration.rs b/packages/network_integration/tests/testnet_integration.rs index 6ad4e557d..42a1e9838 100644 --- a/packages/network_integration/tests/testnet_integration.rs +++ b/packages/network_integration/tests/testnet_integration.rs @@ -1,33 +1,77 @@ -use std::{thread, time}; use colored::*; -use serde_json::Result; -use serde::Serialize; -use cosmwasm_std::{HumanAddr, Uint128, to_binary, Binary}; +use cosmwasm_std::{to_binary, Binary, HumanAddr, Uint128}; use flexible_permits::{permit::Permit, transaction::PermitSignature}; -use secretcli::{secretcli::{account_address, query_contract, test_contract_handle, test_inst_init, create_permit}}; -use shade_protocol::{snip20::{self, InitConfig, InitialBalance}, governance, staking, band, oracle, - asset::Contract, airdrop::{self, claim_info::RequiredTask, account::{AddressProofMsg}}, - governance::{vote::{UserVote, Vote}, proposal::ProposalStatus}, - generic_response::ResponseStatus}; -use network_integration::{utils::{print_header, print_warning, generate_label, print_contract, - STORE_GAS, GAS, VIEW_KEY, ACCOUNT_KEY, print_vec, - SNIP20_FILE, AIRDROP_FILE, GOVERNANCE_FILE, MOCK_BAND_FILE, ORACLE_FILE}, - contract_helpers::{initializer::initialize_initializer, - governance::{init_contract, get_contract, add_contract, - create_proposal, get_latest_proposal, - create_and_trigger_proposal, trigger_latest_proposal}, - minter::{initialize_minter, setup_minters, get_balance}, - stake::setup_staker}}; -use rs_merkle::{Hasher, MerkleTree, algorithms::Sha256}; -use shade_protocol::airdrop::account::AccountPermitMsg; +use network_integration::{ + contract_helpers::{ + governance::{ + add_contract, + create_and_trigger_proposal, + create_proposal, + get_contract, + get_latest_proposal, + init_contract, + trigger_latest_proposal, + }, + initializer::initialize_initializer, + minter::{get_balance, initialize_minter, setup_minters}, + stake::setup_staker, + }, + utils::{ + generate_label, + print_contract, + print_header, + print_vec, + print_warning, + ACCOUNT_KEY, + AIRDROP_FILE, + GAS, + GOVERNANCE_FILE, + MOCK_BAND_FILE, + ORACLE_FILE, + SNIP20_FILE, + STORE_GAS, + VIEW_KEY, + }, +}; +use rs_merkle::{algorithms::Sha256, Hasher, MerkleTree}; +use secretcli::secretcli::{ + account_address, + create_permit, + query_contract, + test_contract_handle, + test_inst_init, +}; +use serde::Serialize; +use serde_json::Result; +use shade_protocol::{ + airdrop::{ + self, + account::{AccountPermitMsg, AddressProofMsg}, + claim_info::RequiredTask, + }, + asset::Contract, + band, + generic_response::ResponseStatus, + governance, + governance::{ + proposal::ProposalStatus, + vote::{UserVote, Vote}, + }, + oracle, + snip20::{self, InitConfig, InitialBalance}, + staking, +}; +use std::{thread, time}; fn create_signed_permit(permit_msg: T, signer: &str) -> Permit { let chain_id = Some("testnet".to_string()); let unsigned_msg = flexible_permits::transaction::SignedTx::from_msg( - flexible_permits::transaction::TxMsg{ + flexible_permits::transaction::TxMsg { r#type: "signature_proof".to_string(), - value: permit_msg.clone() - }, chain_id.clone()); + value: permit_msg.clone(), + }, + chain_id.clone(), + ); let signed_info = create_permit(unsigned_msg, signer).unwrap(); @@ -37,10 +81,10 @@ fn create_signed_permit(permit_msg: T, signer: &str) -> Pe signature: PermitSignature { pub_key: flexible_permits::transaction::PubKey { r#type: signed_info.pub_key.msg_type, - value: Binary::from_base64(&signed_info.pub_key.value).unwrap() + value: Binary::from_base64(&signed_info.pub_key.value).unwrap(), }, - signature: Binary::from_base64(&signed_info.signature).unwrap() - } + signature: Binary::from_base64(&signed_info.signature).unwrap(), + }, }; permit @@ -58,10 +102,9 @@ fn proof_from_tree(indices: &Vec, tree: &Vec>) -> Vec Result<()> { let b_airdrop = Uint128(20000000); let ab_half_airdrop = Uint128(35000000); let c_airdrop = Uint128(10000000); - let total_airdrop= a_airdrop + b_airdrop + c_airdrop; // 80000000 + let total_airdrop = a_airdrop + b_airdrop + c_airdrop; // 80000000 let decay_amount = Uint128(10000000); /// Initialize dummy snip20 @@ -102,32 +145,38 @@ fn run_airdrop() -> Result<()> { admin: None, symbol: "TEST".to_string(), decimals: 6, - initial_balances: Some(vec![InitialBalance{ + initial_balances: Some(vec![InitialBalance { address: HumanAddr::from(account_a.clone()), - amount: total_airdrop+decay_amount }]), + amount: total_airdrop + decay_amount, + }]), prng_seed: Default::default(), config: Some(InitConfig { public_total_supply: Some(true), enable_deposit: Some(true), enable_redeem: Some(true), enable_mint: Some(true), - enable_burn: Some(false) - }) + enable_burn: Some(false), + }), }; - let snip = test_inst_init(&snip_init_msg, SNIP20_FILE, - &*generate_label(8), - ACCOUNT_KEY, Some(STORE_GAS), Some(GAS), - Some("test"))?; + let snip = test_inst_init( + &snip_init_msg, + SNIP20_FILE, + &*generate_label(8), + ACCOUNT_KEY, + Some(STORE_GAS), + Some(GAS), + Some("test"), + )?; print_contract(&snip); { let msg = snip20::HandleMsg::SetViewingKey { key: String::from(VIEW_KEY), - padding: None }; + padding: None, + }; - test_contract_handle(&msg, &snip, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &snip, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } print_header("Creating merkle tree"); @@ -135,7 +184,8 @@ fn run_airdrop() -> Result<()> { Sha256::hash((account_a.clone() + &a_airdrop.to_string()).as_bytes()), Sha256::hash((account_b.clone() + &b_airdrop.to_string()).as_bytes()), Sha256::hash((account_c.clone() + &c_airdrop.to_string()).as_bytes()), - Sha256::hash((account_d.clone() + &decay_amount.to_string()).as_bytes())]; + Sha256::hash((account_d.clone() + &decay_amount.to_string()).as_bytes()), + ]; let merlke_tree = MerkleTree::::from_leaves(&leaves); @@ -151,9 +201,9 @@ fn run_airdrop() -> Result<()> { dump_address: Some(HumanAddr::from(account_a.clone())), airdrop_token: Contract { address: HumanAddr::from(snip.address.clone()), - code_hash: snip.code_hash.clone() + code_hash: snip.code_hash.clone(), }, - airdrop_amount: total_airdrop+decay_amount, + airdrop_amount: total_airdrop + decay_amount, start_date: None, end_date: Some(end_date), decay_start: Some(decay_date), @@ -163,24 +213,38 @@ fn run_airdrop() -> Result<()> { default_claim: Uint128(50), task_claim: vec![RequiredTask { address: HumanAddr::from(account_a.clone()), - percent: Uint128(50) }], - query_rounding: Uint128(30000000) + percent: Uint128(50), + }], + query_rounding: Uint128(30000000), }; - let airdrop = test_inst_init(&airdrop_init_msg, AIRDROP_FILE, &*generate_label(8), - ACCOUNT_KEY, Some(STORE_GAS), Some(GAS), - Some("test"))?; + let airdrop = test_inst_init( + &airdrop_init_msg, + AIRDROP_FILE, + &*generate_label(8), + ACCOUNT_KEY, + Some(STORE_GAS), + Some(GAS), + Some("test"), + )?; print_contract(&airdrop); /// Assert that we start with nothing - test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(airdrop.address.clone()), - amount: total_airdrop+decay_amount, - msg: None, - memo: None, - padding: None - }, &snip, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; + test_contract_handle( + &snip20::HandleMsg::Send { + recipient: HumanAddr::from(airdrop.address.clone()), + amount: total_airdrop + decay_amount, + msg: None, + memo: None, + padding: None, + }, + &snip, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; assert_eq!(Uint128(0), get_balance(&snip, account_a.clone())); @@ -191,7 +255,7 @@ fn run_airdrop() -> Result<()> { amount: b_airdrop, contract: HumanAddr(airdrop.address.clone()), index: 1, - key: "key".to_string() + key: "key".to_string(), }; let b_permit = create_signed_permit(b_address_proof, "b"); @@ -201,24 +265,36 @@ fn run_airdrop() -> Result<()> { amount: a_airdrop, contract: HumanAddr(airdrop.address.clone()), index: 0, - key: "key".to_string() + key: "key".to_string(), }; print_warning("Creating proof"); - let initial_proof = proof_from_tree(&vec![0,1], &merlke_tree.layers()); + let initial_proof = proof_from_tree(&vec![0, 1], &merlke_tree.layers()); let a_permit = create_signed_permit(a_address_proof, ACCOUNT_KEY); let account_permit = create_signed_permit( - AccountPermitMsg{ + AccountPermitMsg { contract: HumanAddr(airdrop.address.clone()), - key: "key".to_string() }, ACCOUNT_KEY); + key: "key".to_string(), + }, + ACCOUNT_KEY, + ); /// Create an account which will also claim whatever amount is available print_warning("Creating an account"); { - let tx_info = test_contract_handle(&airdrop::HandleMsg::CreateAccount { - addresses: vec![b_permit, a_permit.clone()], partial_tree: initial_proof }, &airdrop, ACCOUNT_KEY, - Some("1000000"), Some("test"), None)?.1; + let tx_info = test_contract_handle( + &airdrop::HandleMsg::CreateAccount { + addresses: vec![b_permit, a_permit.clone()], + partial_tree: initial_proof, + }, + &airdrop, + ACCOUNT_KEY, + Some("1000000"), + Some("test"), + None, + )? + .1; println!("Gas used: {}", tx_info.gas_used); } @@ -227,13 +303,18 @@ fn run_airdrop() -> Result<()> { { let msg = airdrop::QueryMsg::Account { permit: account_permit.clone(), - current_date: None + current_date: None, }; let query: airdrop::QueryAnswer = query_contract(&airdrop, msg)?; - if let airdrop::QueryAnswer::Account { total, claimed, - unclaimed, finished_tasks } = query { + if let airdrop::QueryAnswer::Account { + total, + claimed, + unclaimed, + finished_tasks, + } = query + { assert_eq!(total, a_airdrop + b_airdrop); assert_eq!(claimed, ab_half_airdrop); assert_eq!(unclaimed, Uint128::zero()); @@ -246,21 +327,32 @@ fn run_airdrop() -> Result<()> { print_warning("Enabling the other half of the airdrop"); - test_contract_handle(&airdrop::HandleMsg::CompleteTask { - address: HumanAddr::from(account_a.clone()) }, - &airdrop, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &airdrop::HandleMsg::CompleteTask { + address: HumanAddr::from(account_a.clone()), + }, + &airdrop, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; { let msg = airdrop::QueryMsg::Account { permit: account_permit.clone(), - current_date: None + current_date: None, }; let query: airdrop::QueryAnswer = query_contract(&airdrop, msg)?; - if let airdrop::QueryAnswer::Account { total, claimed, - unclaimed, finished_tasks } = query { + if let airdrop::QueryAnswer::Account { + total, + claimed, + unclaimed, + finished_tasks, + } = query + { assert_eq!(total, a_airdrop + b_airdrop); assert_eq!(claimed, ab_half_airdrop); assert_eq!(unclaimed, ab_half_airdrop); @@ -271,7 +363,7 @@ fn run_airdrop() -> Result<()> { print_warning("Verifying query step functionality"); { - let msg = airdrop::QueryMsg::TotalClaimed { }; + let msg = airdrop::QueryMsg::TotalClaimed {}; let query: airdrop::QueryAnswer = query_contract(&airdrop, msg)?; @@ -287,15 +379,23 @@ fn run_airdrop() -> Result<()> { amount: c_airdrop, contract: HumanAddr(airdrop.address.clone()), index: 2, - key: "key".to_string() + key: "key".to_string(), }; let c_permit = create_signed_permit(c_address_proof, "c"); let other_proof = proof_from_tree(&vec![2], &merlke_tree.layers()); - test_contract_handle(&airdrop::HandleMsg::UpdateAccount{ - addresses: vec![c_permit], partial_tree: other_proof }, &airdrop, ACCOUNT_KEY, - Some("1000000"), Some("test"), None)?; + test_contract_handle( + &airdrop::HandleMsg::UpdateAccount { + addresses: vec![c_permit], + partial_tree: other_proof, + }, + &airdrop, + ACCOUNT_KEY, + Some("1000000"), + Some("test"), + None, + )?; /// Assert that we claimed assert_eq!(total_airdrop, get_balance(&snip, account_a.clone())); @@ -304,13 +404,18 @@ fn run_airdrop() -> Result<()> { { let msg = airdrop::QueryMsg::Account { permit: account_permit.clone(), - current_date: None + current_date: None, }; let query: airdrop::QueryAnswer = query_contract(&airdrop, msg)?; - if let airdrop::QueryAnswer::Account { total, claimed, - unclaimed, finished_tasks } = query { + if let airdrop::QueryAnswer::Account { + total, + claimed, + unclaimed, + finished_tasks, + } = query + { assert_eq!(total, total_airdrop); assert_eq!(claimed, total_airdrop); assert_eq!(unclaimed, Uint128::zero()); @@ -319,14 +424,21 @@ fn run_airdrop() -> Result<()> { } print_warning("Disabling permit"); - test_contract_handle(&airdrop::HandleMsg::DisablePermitKey{ key: "key".to_string() }, - &airdrop, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &airdrop::HandleMsg::DisablePermitKey { + key: "key".to_string(), + }, + &airdrop, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; { let msg = airdrop::QueryMsg::Account { permit: account_permit.clone(), - current_date: None + current_date: None, }; let query: Result = query_contract(&airdrop, msg); @@ -334,22 +446,29 @@ fn run_airdrop() -> Result<()> { assert!(query.is_err()); } - let new_account_permit = create_signed_permit( - AccountPermitMsg{ + AccountPermitMsg { contract: HumanAddr(airdrop.address.clone()), - key: "new_key".to_string() }, ACCOUNT_KEY); + key: "new_key".to_string(), + }, + ACCOUNT_KEY, + ); { let msg = airdrop::QueryMsg::Account { permit: new_account_permit.clone(), - current_date: None + current_date: None, }; let query: airdrop::QueryAnswer = query_contract(&airdrop, msg)?; - if let airdrop::QueryAnswer::Account { total, claimed, - unclaimed, finished_tasks } = query { + if let airdrop::QueryAnswer::Account { + total, + claimed, + unclaimed, + finished_tasks, + } = query + { assert_eq!(total, total_airdrop); assert_eq!(claimed, total_airdrop); assert_eq!(unclaimed, Uint128::zero()); @@ -376,11 +495,17 @@ fn run_airdrop() -> Result<()> { let d_permit = create_signed_permit(d_address_proof, "d"); let d_proof = proof_from_tree(&vec![3], &merlke_tree.layers()); - test_contract_handle(&airdrop::HandleMsg::UpdateAccount { - addresses: vec![d_permit], - partial_tree: d_proof, - }, &airdrop, ACCOUNT_KEY, - Some("1000000"), Some("test"), None)?; + test_contract_handle( + &airdrop::HandleMsg::UpdateAccount { + addresses: vec![d_permit], + partial_tree: d_proof, + }, + &airdrop, + ACCOUNT_KEY, + Some("1000000"), + Some("test"), + None, + )?; let balance = get_balance(&snip, account_a.clone()); @@ -398,16 +523,24 @@ fn run_airdrop() -> Result<()> { thread::sleep(time::Duration::from_secs(end_date - current + 20)); } - test_contract_handle(&airdrop::HandleMsg::ClaimDecay {}, - &airdrop, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &airdrop::HandleMsg::ClaimDecay {}, + &airdrop, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; - assert_eq!(total_airdrop + decay_amount, get_balance(&snip, account_a.clone())); + assert_eq!( + total_airdrop + decay_amount, + get_balance(&snip, account_a.clone()) + ); print_warning("Verifying query step functionality after decay claim"); { - let msg = airdrop::QueryMsg::TotalClaimed { }; + let msg = airdrop::QueryMsg::TotalClaimed {}; let query: airdrop::QueryAnswer = query_contract(&airdrop, msg)?; @@ -440,34 +573,48 @@ fn run_testnet() -> Result<()> { enable_deposit: Some(true), enable_redeem: Some(true), enable_mint: Some(true), - enable_burn: Some(false) - }) + enable_burn: Some(false), + }), }; - let s_sCRT = test_inst_init(&sscrt_init_msg, SNIP20_FILE, &*generate_label(8), - ACCOUNT_KEY, Some(STORE_GAS), Some(GAS), - Some("test"))?; + let s_sCRT = test_inst_init( + &sscrt_init_msg, + SNIP20_FILE, + &*generate_label(8), + ACCOUNT_KEY, + Some(STORE_GAS), + Some(GAS), + Some("test"), + )?; print_contract(&s_sCRT); { - let msg = snip20::HandleMsg::SetViewingKey { key: String::from(VIEW_KEY), padding: None }; + let msg = snip20::HandleMsg::SetViewingKey { + key: String::from(VIEW_KEY), + padding: None, + }; - test_contract_handle(&msg, &s_sCRT, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &s_sCRT, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } println!("\n\tDepositing 1000000000uscrt"); { - let msg = snip20::HandleMsg::Deposit { padding: None }; - test_contract_handle(&msg, &s_sCRT, ACCOUNT_KEY, Some(GAS), - Some("test"), Some("1000000000uscrt"))?; + test_contract_handle( + &msg, + &s_sCRT, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + Some("1000000000uscrt"), + )?; } // Initialize initializer and snip20s - let (initializer, shade, silk) = initialize_initializer(account.clone(), &s_sCRT, account.clone())?; + let (initializer, shade, silk) = + initialize_initializer(account.clone(), &s_sCRT, account.clone())?; // Initialize Governance print_header("Initializing Governance"); @@ -478,18 +625,24 @@ fn run_testnet() -> Result<()> { staker: None, funding_token: Contract { address: HumanAddr::from(shade.address.clone()), - code_hash: shade.code_hash.clone() + code_hash: shade.code_hash.clone(), }, funding_amount: Uint128(1000000), funding_deadline: 180, voting_deadline: 180, // 5 shade is the minimum - quorum: Uint128(5000000) + quorum: Uint128(5000000), }; - let governance = test_inst_init(&governance_init_msg, GOVERNANCE_FILE, &*generate_label(8), - ACCOUNT_KEY, Some(STORE_GAS), Some(GAS), - Some("test"))?; + let governance = test_inst_init( + &governance_init_msg, + GOVERNANCE_FILE, + &*generate_label(8), + ACCOUNT_KEY, + Some(STORE_GAS), + Some(GAS), + Some("test"), + )?; print_contract(&governance); @@ -502,13 +655,11 @@ fn run_testnet() -> Result<()> { { let msg = snip20::HandleMsg::ChangeAdmin { address: HumanAddr::from(governance.address.clone()), - padding: None + padding: None, }; - test_contract_handle(&msg, &shade, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; - test_contract_handle(&msg, &silk, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle(&msg, &shade, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; + test_contract_handle(&msg, &silk, ACCOUNT_KEY, Some(GAS), Some("test"), None)?; } // Print Contracts so far @@ -529,63 +680,84 @@ fn run_testnet() -> Result<()> { let silk_contract = get_contract(&governance, "silk".to_string())?; // Initialize Band Mock - let band = init_contract(&governance, "band_mock".to_string(), - MOCK_BAND_FILE, - band::InitMsg {})?; + let band = init_contract( + &governance, + "band_mock".to_string(), + MOCK_BAND_FILE, + band::InitMsg {}, + )?; // Initialize Oracle - let oracle = init_contract(&governance, "oracle".to_string(), - ORACLE_FILE, - oracle::InitMsg { - admin: None, - band: Contract { - address: HumanAddr::from(band.address), - code_hash: band.code_hash }, - sscrt: Contract { - address: HumanAddr::from(s_sCRT.address.clone()), - code_hash: s_sCRT.code_hash.clone() } })?; + let oracle = init_contract( + &governance, + "oracle".to_string(), + ORACLE_FILE, + oracle::InitMsg { + admin: None, + band: Contract { + address: HumanAddr::from(band.address), + code_hash: band.code_hash, + }, + sscrt: Contract { + address: HumanAddr::from(s_sCRT.address.clone()), + code_hash: s_sCRT.code_hash.clone(), + }, + }, + )?; // Initialize Mint-Shade - let mint_shade = initialize_minter(&governance, "shade_minter".to_string(), - &shade_contract)?; + let mint_shade = initialize_minter(&governance, "shade_minter".to_string(), &shade_contract)?; // Initialize Mint-Silk - let mint_silk = initialize_minter(&governance, "silk_minter".to_string(), - &silk_contract)?; + let mint_silk = initialize_minter(&governance, "silk_minter".to_string(), &silk_contract)?; // Setup mint contracts // This also tests that governance can update allowed contracts - setup_minters(&governance, &mint_shade, &mint_silk, &shade_contract, &silk_contract, &s_sCRT)?; + setup_minters( + &governance, + &mint_shade, + &mint_silk, + &shade_contract, + &silk_contract, + &s_sCRT, + )?; // Initialize staking let staker = setup_staker(&governance, &shade_contract, account.clone())?; // Set governance to require voting print_warning("Enabling governance voting"); - create_and_trigger_proposal(&governance, governance::GOVERNANCE_SELF.to_string(), - governance::HandleMsg::UpdateConfig { - admin: None, - staker: Some(Contract { - address: HumanAddr::from(staker.address.clone()), - code_hash: staker.code_hash.clone() - }), - proposal_deadline: None, - funding_amount: None, - funding_deadline: None, - minimum_votes: None - }, - Some("Remove control from admin and initialize governance"))?; + create_and_trigger_proposal( + &governance, + governance::GOVERNANCE_SELF.to_string(), + governance::HandleMsg::UpdateConfig { + admin: None, + staker: Some(Contract { + address: HumanAddr::from(staker.address.clone()), + code_hash: staker.code_hash.clone(), + }), + proposal_deadline: None, + funding_amount: None, + funding_deadline: None, + minimum_votes: None, + }, + Some("Remove control from admin and initialize governance"), + )?; // Proposal admin command print_header("Creating proposal expected to fail"); let admin_command = "{\"update_config\":{\"unbond_time\": {}, \"admin\": null}}"; // Create a proposal and vote half of the votes - create_proposal(&governance, governance::GOVERNANCE_SELF.to_string(), - governance::HandleMsg::AddAdminCommand { - name: "stake_unbond_time".to_string(), - proposal: admin_command.to_string() }, - Some("Staker unbond time can be updated by admin whenever"))?; + create_proposal( + &governance, + governance::GOVERNANCE_SELF.to_string(), + governance::HandleMsg::AddAdminCommand { + name: "stake_unbond_time".to_string(), + proposal: admin_command.to_string(), + }, + Some("Staker unbond time can be updated by admin whenever"), + )?; // Fund the proposal print_warning("Funding proposal"); @@ -594,7 +766,9 @@ fn run_testnet() -> Result<()> { // Check that its in a funding period { - let msg = governance::QueryMsg::GetProposal { proposal_id: proposal }; + let msg = governance::QueryMsg::GetProposal { + proposal_id: proposal, + }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -607,18 +781,26 @@ fn run_testnet() -> Result<()> { let balance = get_balance(&shade, account.clone()); - test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(governance.address.clone()), - amount: Uint128(1000000), - msg: Some(to_binary(&proposal).unwrap()), - memo: None, - padding: None - }, &shade, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &snip20::HandleMsg::Send { + recipient: HumanAddr::from(governance.address.clone()), + amount: Uint128(1000000), + msg: Some(to_binary(&proposal).unwrap()), + memo: None, + padding: None, + }, + &shade, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; // Check that its in a voting period { - let msg = governance::QueryMsg::GetProposal { proposal_id: proposal }; + let msg = governance::QueryMsg::GetProposal { + proposal_id: proposal, + }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -639,16 +821,25 @@ fn run_testnet() -> Result<()> { let proposal = get_latest_proposal(&governance)?; // Vote on proposal - test_contract_handle(&staking::HandleMsg::Vote { - proposal_id: proposal, - votes: vec![UserVote { vote: Vote::Yes, weight: 50 }]}, - &staker, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &staking::HandleMsg::Vote { + proposal_id: proposal, + votes: vec![UserVote { + vote: Vote::Yes, + weight: 50, + }], + }, + &staker, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; // Verify that the proposal votes were properly done { let msg = governance::QueryMsg::GetProposalVotes { - proposal_id: proposal + proposal_id: proposal, }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -667,7 +858,9 @@ fn run_testnet() -> Result<()> { // Query its status { - let msg = governance::QueryMsg::GetProposal { proposal_id: proposal }; + let msg = governance::QueryMsg::GetProposal { + proposal_id: proposal, + }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -686,7 +879,9 @@ fn run_testnet() -> Result<()> { // Query its status and expect it to break { - let msg = governance::QueryMsg::GetProposal { proposal_id: proposal }; + let msg = governance::QueryMsg::GetProposal { + proposal_id: proposal, + }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -699,37 +894,62 @@ fn run_testnet() -> Result<()> { } print_header("Creating admin command"); - create_proposal(&governance, governance::GOVERNANCE_SELF.to_string(), - governance::HandleMsg::AddAdminCommand { - name: "stake_unbond_time".to_string(), - proposal: admin_command.to_string() }, - Some("Staker unbond time can be updated by admin whenever"))?; - - + create_proposal( + &governance, + governance::GOVERNANCE_SELF.to_string(), + governance::HandleMsg::AddAdminCommand { + name: "stake_unbond_time".to_string(), + proposal: admin_command.to_string(), + }, + Some("Staker unbond time can be updated by admin whenever"), + )?; { let proposal_time = chrono::offset::Utc::now().timestamp() as u64; let proposal = get_latest_proposal(&governance)?; print_warning("Funding proposal"); - test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(governance.address.clone()), - amount: Uint128(1000000), - msg: Some(to_binary(&proposal).unwrap()), - memo: None, - padding: None - }, &shade, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &snip20::HandleMsg::Send { + recipient: HumanAddr::from(governance.address.clone()), + amount: Uint128(1000000), + msg: Some(to_binary(&proposal).unwrap()), + memo: None, + padding: None, + }, + &shade, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; // Vote on proposal print_warning("Voting on proposal"); - test_contract_handle(&staking::HandleMsg::Vote { - proposal_id: proposal, - votes: vec![UserVote { vote: Vote::Yes, weight: 50 }, - UserVote { vote: Vote::No, weight: 25 }, - UserVote { vote: Vote::Abstain, weight: 25 }]}, - &staker, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &staking::HandleMsg::Vote { + proposal_id: proposal, + votes: vec![ + UserVote { + vote: Vote::Yes, + weight: 50, + }, + UserVote { + vote: Vote::No, + weight: 25, + }, + UserVote { + vote: Vote::Abstain, + weight: 25, + }, + ], + }, + &staker, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; // Wait for the time limit and try to trigger it let now = chrono::offset::Utc::now().timestamp() as u64; @@ -738,7 +958,9 @@ fn run_testnet() -> Result<()> { // Query its status and expect it to finish { - let msg = governance::QueryMsg::GetProposal { proposal_id: proposal }; + let msg = governance::QueryMsg::GetProposal { + proposal_id: proposal, + }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -753,13 +975,19 @@ fn run_testnet() -> Result<()> { // Trigger the admin command print_warning("Triggering admin command"); - test_contract_handle(&governance::HandleMsg::TriggerAdminCommand { + test_contract_handle( + &governance::HandleMsg::TriggerAdminCommand { target: "staking".to_string(), command: "stake_unbond_time".to_string(), variables: vec!["240".to_string()], - description: "Extending unbond time for staking contract".to_string() - }, &governance, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + description: "Extending unbond time for staking contract".to_string(), + }, + &governance, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; // Check that admin command did something { @@ -776,12 +1004,15 @@ fn run_testnet() -> Result<()> { // Make a failed funding period print_header("Testing failed funding"); - create_proposal(&governance, governance::GOVERNANCE_SELF.to_string(), - governance::HandleMsg::AddAdminCommand { - name: "stake_unbond_time".to_string(), - proposal: admin_command.to_string() }, - Some("This wont be funded :("))?; - + create_proposal( + &governance, + governance::GOVERNANCE_SELF.to_string(), + governance::HandleMsg::AddAdminCommand { + name: "stake_unbond_time".to_string(), + proposal: admin_command.to_string(), + }, + Some("This wont be funded :("), + )?; { print_warning("Trying to fund"); @@ -791,14 +1022,20 @@ fn run_testnet() -> Result<()> { let lost_amount = Uint128(500000); let balance_before = get_balance(&shade, account.clone()); - test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(governance.address.clone()), - amount: lost_amount, - msg: Some(to_binary(&proposal).unwrap()), - memo: None, - padding: None - }, &shade, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &snip20::HandleMsg::Send { + recipient: HumanAddr::from(governance.address.clone()), + amount: lost_amount, + msg: Some(to_binary(&proposal).unwrap()), + memo: None, + padding: None, + }, + &shade, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; let balance_after = get_balance(&shade, account.clone()); @@ -809,20 +1046,28 @@ fn run_testnet() -> Result<()> { thread::sleep(time::Duration::from_secs(proposal_time + 184 - now)); // Trigger funding - test_contract_handle(&snip20::HandleMsg::Send { - recipient: HumanAddr::from(governance.address.clone()), - amount: lost_amount, - msg: Some(to_binary(&proposal).unwrap()), - memo: None, - padding: None - }, &shade, ACCOUNT_KEY, Some(GAS), - Some("test"), None)?; + test_contract_handle( + &snip20::HandleMsg::Send { + recipient: HumanAddr::from(governance.address.clone()), + amount: lost_amount, + msg: Some(to_binary(&proposal).unwrap()), + memo: None, + padding: None, + }, + &shade, + ACCOUNT_KEY, + Some(GAS), + Some("test"), + None, + )?; assert_eq!(get_balance(&shade, account.clone()), balance_after); print_warning("Proposal must be expired"); { - let msg = governance::QueryMsg::GetProposal { proposal_id: proposal }; + let msg = governance::QueryMsg::GetProposal { + proposal_id: proposal, + }; let query: governance::QueryAnswer = query_contract(&governance, msg)?; @@ -835,4 +1080,4 @@ fn run_testnet() -> Result<()> { } Ok(()) -} \ No newline at end of file +} diff --git a/packages/secretcli/src/cli_types.rs b/packages/secretcli/src/cli_types.rs index 534985759..ea2b46a3d 100644 --- a/packages/secretcli/src/cli_types.rs +++ b/packages/secretcli/src/cli_types.rs @@ -1,4 +1,4 @@ -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct TxResponse { @@ -7,7 +7,7 @@ pub struct TxResponse { pub codespace: String, pub code: Option, pub data: String, - pub raw_log: String + pub raw_log: String, } #[derive(Serialize, Deserialize)] @@ -34,21 +34,21 @@ pub struct TxQuery { pub struct TxQueryLogs { pub msg_index: i128, pub log: String, - pub events: Vec + pub events: Vec, } #[derive(Serialize, Deserialize)] pub struct TxQueryEvents { - #[serde(rename="type")] + #[serde(rename = "type")] pub msg_type: String, - pub attributes: Vec + pub attributes: Vec, } #[derive(Serialize, Deserialize)] pub struct TxQueryKeyValue { - #[serde(rename="key")] + #[serde(rename = "key")] pub msg_key: String, - pub value: String + pub value: String, } #[derive(Serialize, Deserialize)] @@ -63,7 +63,7 @@ pub struct ListContractCode { pub code_id: u128, pub creator: String, pub label: String, - pub address: String + pub address: String, } #[derive(Serialize, Deserialize)] @@ -82,7 +82,7 @@ pub struct SignedTx { #[derive(Serialize, Deserialize)] pub struct PubKey { - #[serde(rename="type")] + #[serde(rename = "type")] pub msg_type: String, - pub value: String -} \ No newline at end of file + pub value: String, +} diff --git a/packages/secretcli/src/lib.rs b/packages/secretcli/src/lib.rs index eef39583e..98dd50ad7 100644 --- a/packages/secretcli/src/lib.rs +++ b/packages/secretcli/src/lib.rs @@ -1,2 +1,2 @@ +pub mod cli_types; pub mod secretcli; -pub mod cli_types; \ No newline at end of file diff --git a/packages/secretcli/src/secretcli.rs b/packages/secretcli/src/secretcli.rs index 254d16cc9..0b31e0012 100644 --- a/packages/secretcli/src/secretcli.rs +++ b/packages/secretcli/src/secretcli.rs @@ -1,13 +1,18 @@ -use std::process::{Command}; -use serde_json::{Value, Result}; -use crate::cli_types::{TxResponse, NetContract, TxCompute, TxQuery, ListCodeResponse, ListContractCode, SignedTx}; -use std::{thread, time}; -use std::fs::File; -use std::io::Write; +use crate::cli_types::{ + ListCodeResponse, + ListContractCode, + NetContract, + SignedTx, + TxCompute, + TxQuery, + TxResponse, +}; +use serde_json::{Result, Value}; +use std::{fs::File, io::Write, process::Command, thread, time}; //secretcli tx sign-doc tx_to_sign --from sign-test -fn vec_str_to_vec_string (str_in: Vec<&str>) -> Vec { +fn vec_str_to_vec_string(str_in: Vec<&str>) -> Vec { let mut str_out: Vec = vec![]; for val in str_in { @@ -39,9 +44,8 @@ pub fn secretcli_run(command: Vec) -> Result { for _ in 0..retry { if result.stderr.len() > 0 { thread::sleep(time::Duration::from_secs(1)); - } - else { - break + } else { + break; } result = cli.output().expect("Unexpected error"); } @@ -59,12 +63,22 @@ pub fn secretcli_run(command: Vec) -> Result { /// * 'gas' - Gas to pay, defaults to 10000000 /// * 'backend' - The backend keyring, defaults to test /// -pub fn store_contract(contract: &str, user: Option<&str>, - gas: Option<&str>, backend: Option<&str>) -> Result { - - let mut command_arr = vec!["tx", "compute", "store", contract, - "--from", user.unwrap_or("a"), - "--gas", gas.unwrap_or("10000000"), "-y", +pub fn store_contract( + contract: &str, + user: Option<&str>, + gas: Option<&str>, + backend: Option<&str>, +) -> Result { + let mut command_arr = vec![ + "tx", + "compute", + "store", + contract, + "--from", + user.unwrap_or("a"), + "--gas", + gas.unwrap_or("10000000"), + "-y", ]; if let Some(backend) = backend { @@ -94,8 +108,7 @@ pub fn query_hash(hash: String) -> Result { pub fn compute_hash(hash: String) -> Result { let command = vec!["q", "compute", "tx", &hash]; - serde_json::from_value(secretcli_run( - vec_str_to_vec_string(command))?) + serde_json::from_value(secretcli_run(vec_str_to_vec_string(command))?) } /// @@ -137,9 +150,8 @@ pub fn account_address(acc: &str) -> Result { for _ in 0..retry { if result.stderr.len() > 0 { thread::sleep(time::Duration::from_secs(1)); - } - else { - break + } else { + break; } result = cli.output().expect("Unexpected error"); } @@ -166,15 +178,33 @@ pub fn account_address(acc: &str) -> Result { /// * 'gas' - Gas price to use, defaults to 8000000 /// * 'backend' - Keyring backend defaults to none /// -pub fn instantiate_contract -(contract: &NetContract, msg: Init, label: &str, sender: &str, - gas: Option<&str>, backend: Option<&str>) -> Result { +pub fn instantiate_contract( + contract: &NetContract, + msg: Init, + label: &str, + sender: &str, + gas: Option<&str>, + backend: Option<&str>, +) -> Result { let message = serde_json::to_string(&msg)?; - let mut command = vec!["tx", "compute", "instantiate", &contract.id, - &message, "--from", sender, "--label", label, "--gas"]; + let mut command = vec![ + "tx", + "compute", + "instantiate", + &contract.id, + &message, + "--from", + sender, + "--label", + label, + "--gas", + ]; - command.push(match gas {None => "10000000", Some(gas) => gas}); + command.push(match gas { + None => "10000000", + Some(gas) => gas, + }); if let Some(backend) = backend { command.push("--keyring-backend"); @@ -183,7 +213,8 @@ pub fn instantiate_contract command.push("-y"); - let response: TxResponse = serde_json::from_value(secretcli_run(vec_str_to_vec_string(command))?)?; + let response: TxResponse = + serde_json::from_value(secretcli_run(vec_str_to_vec_string(command))?)?; Ok(response) } @@ -200,17 +231,29 @@ pub fn instantiate_contract /// * 'backend' - Keyring backend defaults to none /// pub trait TestInit: serde::Serialize { - fn t_init(&self, contract: &NetContract, label: &str, sender: &str, - gas: Option<&str>, backend: Option<&str>) -> Result { - let tx = instantiate_contract(contract, self, label, sender, - gas, backend)?; + fn t_init( + &self, + contract: &NetContract, + label: &str, + sender: &str, + gas: Option<&str>, + backend: Option<&str>, + ) -> Result { + let tx = instantiate_contract(contract, self, label, sender, gas, backend)?; query_hash(tx.txhash) } - fn inst_init(&self, contract_file: &str, label: &str, sender: &str, store_gas: Option<&str>, - init_gas: Option<&str>, backend: Option<&str>) -> Result { - let store_response = store_contract(contract_file, - Option::from(&*sender), store_gas, backend)?; + fn inst_init( + &self, + contract_file: &str, + label: &str, + sender: &str, + store_gas: Option<&str>, + init_gas: Option<&str>, + backend: Option<&str>, + ) -> Result { + let store_response = + store_contract(contract_file, Option::from(&*sender), store_gas, backend)?; let store_query = query_hash(store_response.txhash)?; @@ -218,19 +261,18 @@ pub trait TestInit: serde::Serialize { label: label.to_string(), id: "".to_string(), address: "".to_string(), - code_hash: "".to_string() + code_hash: "".to_string(), }; // Look for the code ID - for attribute in &store_query.logs[0].events[0].attributes { + for attribute in &store_query.logs[0].events[0].attributes { if attribute.msg_key == "code_id" { contract.id = attribute.value.clone(); break; } } - let init_query = self.t_init(&contract, label, - sender, init_gas, backend)?; + let init_query = self.t_init(&contract, label, sender, init_gas, backend)?; // Look for the contract's address for attribute in &init_query.logs[0].events[0].attributes { @@ -254,35 +296,43 @@ pub trait TestInit: serde::Serialize { } } -pub fn test_init -(msg: &Message, contract: &NetContract, label: &str, sender: &str, gas: Option<&str>, - backend: Option<&str>) -> Result { - let tx = instantiate_contract(contract, msg, label, sender, - gas, backend)?; +pub fn test_init( + msg: &Message, + contract: &NetContract, + label: &str, + sender: &str, + gas: Option<&str>, + backend: Option<&str>, +) -> Result { + let tx = instantiate_contract(contract, msg, label, sender, gas, backend)?; query_hash(tx.txhash) } -pub fn test_inst_init -(msg: &Message, contract_file: &str, label: &str, sender: &str, store_gas: Option<&str>, - init_gas: Option<&str>, backend: Option<&str>) -> Result { - let store_response = store_contract(contract_file, - Option::from(&*sender), store_gas, backend)?; +pub fn test_inst_init( + msg: &Message, + contract_file: &str, + label: &str, + sender: &str, + store_gas: Option<&str>, + init_gas: Option<&str>, + backend: Option<&str>, +) -> Result { + let store_response = store_contract(contract_file, Option::from(&*sender), store_gas, backend)?; let store_query = query_hash(store_response.txhash)?; let mut contract = NetContract { label: label.to_string(), id: "".to_string(), address: "".to_string(), - code_hash: "".to_string() + code_hash: "".to_string(), }; // Look for the code ID - for attribute in &store_query.logs[0].events[0].attributes { + for attribute in &store_query.logs[0].events[0].attributes { if attribute.msg_key == "code_id" { contract.id = attribute.value.clone(); break; } } - let init_query = test_init(&msg, &contract, label, - sender, init_gas, backend)?; + let init_query = test_init(&msg, &contract, label, sender, init_gas, backend)?; // Look for the contract's address for attribute in &init_query.logs[0].events[0].attributes { @@ -315,16 +365,31 @@ pub fn test_inst_init /// * 'backend' - Keyring backend defaults to none /// * 'amount' - Included L1 tokens to send, defaults to none /// -pub fn execute_contract -(contract: &NetContract, msg: Handle, sender: &str, gas: Option<&str>, - backend: Option<&str>, amount: Option<&str>) -> Result { +pub fn execute_contract( + contract: &NetContract, + msg: Handle, + sender: &str, + gas: Option<&str>, + backend: Option<&str>, + amount: Option<&str>, +) -> Result { let message = serde_json::to_string(&msg)?; - let mut command = - vec!["tx", "compute", "execute", &contract.address, - &message, "--from", &sender, "--gas"]; + let mut command = vec![ + "tx", + "compute", + "execute", + &contract.address, + &message, + "--from", + &sender, + "--gas", + ]; - command.push(match gas {None => "800000", Some(gas) => gas}); + command.push(match gas { + None => "800000", + Some(gas) => gas, + }); if let Some(backend) = backend { command.push("--keyring-backend"); @@ -338,7 +403,8 @@ pub fn execute_contract command.push("-y"); - let response: TxResponse = serde_json::from_value(secretcli_run(vec_str_to_vec_string(command))?)?; + let response: TxResponse = + serde_json::from_value(secretcli_run(vec_str_to_vec_string(command))?)?; Ok(response) } @@ -355,28 +421,36 @@ pub fn execute_contract /// * 'amount' - Included L1 tokens to send, defaults to none /// pub trait TestHandle: serde::Serialize { - fn t_handle(&self, contract: &NetContract, sender: &str, gas: Option<&str>, - backend: Option<&str>, amount: Option<&str>) -> Result { - let tx = execute_contract(contract, self, sender, gas, - backend, amount)?; + fn t_handle( + &self, + contract: &NetContract, + sender: &str, + gas: Option<&str>, + backend: Option<&str>, + amount: Option<&str>, + ) -> Result { + let tx = execute_contract(contract, self, sender, gas, backend, amount)?; let response: Result = compute_hash(tx.txhash); response } } - /// /// Function equivalent of the TestHandle trait /// -pub fn test_contract_handle(msg: &Message, contract: &NetContract, sender: &str, gas: Option<&str>, - backend: Option<&str>, amount: Option<&str>) -> Result<(TxCompute, TxQuery)> { - - let tx = execute_contract(contract, msg, sender, gas, - backend, amount)?; +pub fn test_contract_handle( + msg: &Message, + contract: &NetContract, + sender: &str, + gas: Option<&str>, + backend: Option<&str>, + amount: Option<&str>, +) -> Result<(TxCompute, TxQuery)> { + let tx = execute_contract(contract, msg, sender, gas, backend, amount)?; let computed_response = compute_hash(tx.txhash.clone())?; - let queried_response = query_hash(tx.txhash)?; + let queried_response = query_hash(tx.txhash)?; Ok((computed_response, queried_response)) } @@ -388,10 +462,17 @@ pub fn test_contract_handle(msg: &Message, contract: /// * 'contract' - The contract to query /// * 'msg' - The query to serialize, must have serde::Serialized /// -pub fn query_contract -(contract: &NetContract, msg: Query) -> Result { - let command = vec_str_to_vec_string(vec!["query", "compute", "query", - &contract.address, &serde_json::to_string(&msg)?]); +pub fn query_contract( + contract: &NetContract, + msg: Query, +) -> Result { + let command = vec_str_to_vec_string(vec![ + "query", + "compute", + "query", + &contract.address, + &serde_json::to_string(&msg)?, + ]); let response: Result = serde_json::from_value(secretcli_run(command)?); response @@ -427,7 +508,8 @@ pub fn create_permit(tx: Tx, signer: &str) -> Result StdResult, // Protects from leaking user information by limiting amount detail - pub query_rounding: Uint128 + pub query_rounding: Uint128, } impl InitCallback for InitMsg { @@ -81,10 +87,10 @@ pub enum HandleMsg { decay_start: Option, }, AddTasks { - tasks: Vec + tasks: Vec, }, CompleteTask { - address: HumanAddr + address: HumanAddr, }, CreateAccount { addresses: Vec, @@ -95,7 +101,9 @@ pub enum HandleMsg { addresses: Vec, partial_tree: Vec, }, - DisablePermitKey { key: String }, + DisablePermitKey { + key: String, + }, Claim {}, ClaimDecay {}, } @@ -120,10 +128,15 @@ pub enum HandleAnswer { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { - Config { }, - Dates { current_date: Option }, - TotalClaimed { }, - Account { permit: AccountPermit, current_date: Option }, + Config {}, + Dates { + current_date: Option, + }, + TotalClaimed {}, + Account { + permit: AccountPermit, + current_date: Option, + }, } impl Query for QueryMsg { @@ -133,10 +146,19 @@ impl Query for QueryMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - Config { config: Config, total_claimed: Uint128 }, - Dates { start: u64, end: Option, - decay_start: Option, decay_factor: Option }, - TotalClaimed { claimed: Uint128 }, + Config { + config: Config, + total_claimed: Uint128, + }, + Dates { + start: u64, + end: Option, + decay_start: Option, + decay_factor: Option, + }, + TotalClaimed { + claimed: Uint128, + }, Account { // Total eligible total: Uint128, @@ -144,6 +166,6 @@ pub enum QueryAnswer { claimed: Uint128, // Total unclaimed but available unclaimed: Uint128, - finished_tasks: Vec - } -} \ No newline at end of file + finished_tasks: Vec, + }, +} diff --git a/packages/shade_protocol/src/asset.rs b/packages/shade_protocol/src/asset.rs index 1af7fb3d1..6b6cd8196 100644 --- a/packages/shade_protocol/src/asset.rs +++ b/packages/shade_protocol/src/asset.rs @@ -1,6 +1,6 @@ +use cosmwasm_std::HumanAddr; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::HumanAddr; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] diff --git a/packages/shade_protocol/src/band.rs b/packages/shade_protocol/src/band.rs index 077fa92b4..f34bdcc46 100644 --- a/packages/shade_protocol/src/band.rs +++ b/packages/shade_protocol/src/band.rs @@ -1,12 +1,12 @@ -use cosmwasm_std::{Uint128}; -use serde::{Deserialize, Serialize}; +use cosmwasm_std::Uint128; use schemars::JsonSchema; -use secret_toolkit::utils::{Query, InitCallback}; +use secret_toolkit::utils::{InitCallback, Query}; #[cfg(test)] -use secretcli::secretcli::{TestInit, TestHandle, TestQuery}; +use secretcli::secretcli::{TestHandle, TestInit, TestQuery}; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InitMsg { } +pub struct InitMsg {} impl InitCallback for InitMsg { const BLOCK_SIZE: usize = 256; @@ -18,7 +18,6 @@ impl TestInit for InitMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum BandQuery { - GetReferenceData { base_symbol: String, quote_symbol: String, diff --git a/packages/shade_protocol/src/generic_response.rs b/packages/shade_protocol/src/generic_response.rs index 13535d10b..35fd54318 100644 --- a/packages/shade_protocol/src/generic_response.rs +++ b/packages/shade_protocol/src/generic_response.rs @@ -6,4 +6,4 @@ use serde::{Deserialize, Serialize}; pub enum ResponseStatus { Success, Failure, -} \ No newline at end of file +} diff --git a/packages/shade_protocol/src/governance/mod.rs b/packages/shade_protocol/src/governance/mod.rs index 54c4addf4..2c89fc4d7 100644 --- a/packages/shade_protocol/src/governance/mod.rs +++ b/packages/shade_protocol/src/governance/mod.rs @@ -1,14 +1,11 @@ pub mod proposal; pub mod vote; +use crate::{asset::Contract, generic_response::ResponseStatus}; +use cosmwasm_std::{Binary, HumanAddr, Uint128}; use schemars::JsonSchema; +use secret_toolkit::utils::{HandleCallback, InitCallback, Query}; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{HumanAddr, Uint128, Binary}; -use secret_toolkit::utils::{InitCallback, HandleCallback, Query}; -use crate::{ - asset::Contract, - generic_response::ResponseStatus, -}; // This is used when calling itself pub const GOVERNANCE_SELF: &str = "SELF"; @@ -109,7 +106,6 @@ pub enum HandleMsg { DisableStaker {}, // RequestMigration {} - /// Add a contract to send proposal msgs to AddSupportedContract { name: String, @@ -123,8 +119,6 @@ pub enum HandleMsg { contract: Contract, }, - - /// Proposal voting - can only be done by staking contract MakeVote { voter: HumanAddr, @@ -135,7 +129,7 @@ pub enum HandleMsg { /// Trigger proposal TriggerProposal { proposal_id: Uint128, - } + }, } impl HandleCallback for HandleMsg { @@ -145,32 +139,73 @@ impl HandleCallback for HandleMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleAnswer { - CreateProposal { status: ResponseStatus, proposal_id: Uint128 }, - FundProposal { status: ResponseStatus, total_funding: Uint128 }, - AddAdminCommand { status: ResponseStatus }, - RemoveAdminCommand { status: ResponseStatus }, - UpdateAdminCommand { status: ResponseStatus }, - TriggerAdminCommand { status: ResponseStatus, proposal_id: Uint128 }, - UpdateConfig { status: ResponseStatus }, - DisableStaker { status: ResponseStatus }, - AddSupportedContract { status: ResponseStatus }, - RemoveSupportedContract { status: ResponseStatus }, - UpdateSupportedContract { status: ResponseStatus }, - MakeVote { status: ResponseStatus }, - TriggerProposal { status: ResponseStatus }, + CreateProposal { + status: ResponseStatus, + proposal_id: Uint128, + }, + FundProposal { + status: ResponseStatus, + total_funding: Uint128, + }, + AddAdminCommand { + status: ResponseStatus, + }, + RemoveAdminCommand { + status: ResponseStatus, + }, + UpdateAdminCommand { + status: ResponseStatus, + }, + TriggerAdminCommand { + status: ResponseStatus, + proposal_id: Uint128, + }, + UpdateConfig { + status: ResponseStatus, + }, + DisableStaker { + status: ResponseStatus, + }, + AddSupportedContract { + status: ResponseStatus, + }, + RemoveSupportedContract { + status: ResponseStatus, + }, + UpdateSupportedContract { + status: ResponseStatus, + }, + MakeVote { + status: ResponseStatus, + }, + TriggerProposal { + status: ResponseStatus, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { - GetProposalVotes { proposal_id: Uint128 }, - GetProposals { start: Uint128, end: Uint128, status: Option }, - GetProposal { proposal_id: Uint128 }, + GetProposalVotes { + proposal_id: Uint128, + }, + GetProposals { + start: Uint128, + end: Uint128, + status: Option, + }, + GetProposal { + proposal_id: Uint128, + }, GetTotalProposals {}, GetSupportedContracts {}, - GetSupportedContract { name: String }, + GetSupportedContract { + name: String, + }, GetAdminCommands {}, - GetAdminCommand { name: String }, + GetAdminCommand { + name: String, + }, } impl Query for QueryMsg { @@ -180,12 +215,28 @@ impl Query for QueryMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - ProposalVotes { status: vote::VoteTally }, - Proposals { proposals: Vec }, - Proposal { proposal: proposal::QueriedProposal }, - TotalProposals { total: Uint128 }, - SupportedContracts { contracts: Vec }, - SupportedContract { contract: Contract }, - AdminCommands { commands: Vec }, - AdminCommand { command: AdminCommand }, -} \ No newline at end of file + ProposalVotes { + status: vote::VoteTally, + }, + Proposals { + proposals: Vec, + }, + Proposal { + proposal: proposal::QueriedProposal, + }, + TotalProposals { + total: Uint128, + }, + SupportedContracts { + contracts: Vec, + }, + SupportedContract { + contract: Contract, + }, + AdminCommands { + commands: Vec, + }, + AdminCommand { + command: AdminCommand, + }, +} diff --git a/packages/shade_protocol/src/governance/proposal.rs b/packages/shade_protocol/src/governance/proposal.rs index 64e727852..02d1b3164 100644 --- a/packages/shade_protocol/src/governance/proposal.rs +++ b/packages/shade_protocol/src/governance/proposal.rs @@ -1,7 +1,7 @@ +use crate::generic_response::ResponseStatus; +use cosmwasm_std::{Binary, Uint128}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Binary, Uint128}; -use crate::generic_response::ResponseStatus; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -45,4 +45,4 @@ pub enum ProposalStatus { Rejected, // Majority votes yes Passed, -} \ No newline at end of file +} diff --git a/packages/shade_protocol/src/governance/vote.rs b/packages/shade_protocol/src/governance/vote.rs index 196f4ca25..df78a7f58 100644 --- a/packages/shade_protocol/src/governance/vote.rs +++ b/packages/shade_protocol/src/governance/vote.rs @@ -1,6 +1,6 @@ +use cosmwasm_std::Uint128; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::Uint128; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -24,4 +24,4 @@ pub enum Vote { pub struct UserVote { pub vote: Vote, pub weight: u8, -} \ No newline at end of file +} diff --git a/packages/shade_protocol/src/initializer.rs b/packages/shade_protocol/src/initializer.rs index 0fcbde9a6..161b6052e 100644 --- a/packages/shade_protocol/src/initializer.rs +++ b/packages/shade_protocol/src/initializer.rs @@ -1,9 +1,9 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use crate::snip20::InitialBalance; -use cosmwasm_std::{HumanAddr, Binary}; +use cosmwasm_std::{Binary, HumanAddr}; +use schemars::JsonSchema; #[cfg(test)] -use secretcli::secretcli::{TestInit, TestHandle, TestQuery}; +use secretcli::secretcli::{TestHandle, TestInit, TestQuery}; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct InitializerConfig { @@ -37,8 +37,7 @@ impl TestInit for InitMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum HandleMsg { -} +pub enum HandleMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -52,5 +51,5 @@ impl TestQuery for QueryMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - Contracts { contracts: Vec } -} \ No newline at end of file + Contracts { contracts: Vec }, +} diff --git a/packages/shade_protocol/src/lib.rs b/packages/shade_protocol/src/lib.rs index a468552d0..a9e78b0c0 100644 --- a/packages/shade_protocol/src/lib.rs +++ b/packages/shade_protocol/src/lib.rs @@ -1,20 +1,20 @@ // Helper libraries pub mod asset; +pub mod band; pub mod generic_response; +pub mod math; pub mod secretswap; -pub mod band; pub mod snip20; -pub mod math; // Protocol init libraries -pub mod initializer; pub mod airdrop; +pub mod initializer; // Protocol libraries pub mod governance; -pub mod staking; -pub mod mint; pub mod micro_mint; +pub mod mint; pub mod oracle; -pub mod treasury; pub mod scrt_staking; +pub mod staking; +pub mod treasury; diff --git a/packages/shade_protocol/src/math.rs b/packages/shade_protocol/src/math.rs index 4437d33b2..4bf9fcae8 100644 --- a/packages/shade_protocol/src/math.rs +++ b/packages/shade_protocol/src/math.rs @@ -12,7 +12,7 @@ pub fn mult(a: Uint128, b: Uint128) -> Uint128 { pub fn div(nom: Uint128, den: Uint128) -> StdResult { if den == Uint128::zero() { - return Err(StdError::generic_err("Division by 0")) + return Err(StdError::generic_err("Division by 0")); } Ok(Uint128(nom.u128() / den.u128())) @@ -20,8 +20,8 @@ pub fn div(nom: Uint128, den: Uint128) -> StdResult { #[cfg(test)] pub mod tests { - use cosmwasm_std::Uint128; use crate::math::{div, mult}; + use cosmwasm_std::Uint128; #[test] fn multiply() { @@ -37,4 +37,4 @@ pub mod tests { fn divide_by_zero() { assert!(div(Uint128(10), Uint128(0)).is_err()) } -} \ No newline at end of file +} diff --git a/packages/shade_protocol/src/micro_mint.rs b/packages/shade_protocol/src/micro_mint.rs index 41edc81ce..3566ed5cc 100644 --- a/packages/shade_protocol/src/micro_mint.rs +++ b/packages/shade_protocol/src/micro_mint.rs @@ -1,12 +1,8 @@ +use crate::{asset::Contract, generic_response::ResponseStatus, snip20::Snip20Asset}; +use cosmwasm_std::{Binary, HumanAddr, Uint128}; use schemars::JsonSchema; +use secret_toolkit::utils::{HandleCallback, InitCallback, Query}; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{HumanAddr, Uint128, Binary}; -use secret_toolkit::utils::{InitCallback, HandleCallback, Query}; -use crate::{ - snip20::Snip20Asset, - asset::Contract, - generic_response::ResponseStatus, -}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Config { @@ -18,7 +14,6 @@ pub struct Config { pub activated: bool, } - /// Used to store the assets allowed to be burned #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct SupportedAsset { @@ -95,12 +90,26 @@ impl HandleCallback for HandleMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleAnswer { - Init { status: ResponseStatus, address: HumanAddr }, - UpdateConfig { status: ResponseStatus }, - UpdateMintLimit { status: ResponseStatus }, - RegisterAsset { status: ResponseStatus }, - RemoveAsset { status: ResponseStatus }, - Burn { status: ResponseStatus, mint_amount: Uint128 } + Init { + status: ResponseStatus, + address: HumanAddr, + }, + UpdateConfig { + status: ResponseStatus, + }, + UpdateMintLimit { + status: ResponseStatus, + }, + RegisterAsset { + status: ResponseStatus, + }, + RemoveAsset { + status: ResponseStatus, + }, + Burn { + status: ResponseStatus, + mint_amount: Uint128, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -108,9 +117,7 @@ pub enum HandleAnswer { pub enum QueryMsg { GetNativeAsset {}, GetSupportedAssets {}, - GetAsset { - contract: String, - }, + GetAsset { contract: String }, GetConfig {}, GetMintLimit {}, } @@ -122,9 +129,21 @@ impl Query for QueryMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - NativeAsset { asset: Snip20Asset, peg: String }, - SupportedAssets { assets: Vec, }, - Asset { asset: SupportedAsset, burned: Uint128}, - Config { config: Config }, - MintLimit { limit: MintLimit }, -} \ No newline at end of file + NativeAsset { + asset: Snip20Asset, + peg: String, + }, + SupportedAssets { + assets: Vec, + }, + Asset { + asset: SupportedAsset, + burned: Uint128, + }, + Config { + config: Config, + }, + MintLimit { + limit: MintLimit, + }, +} diff --git a/packages/shade_protocol/src/mint.rs b/packages/shade_protocol/src/mint.rs index e13a23235..211dac15c 100644 --- a/packages/shade_protocol/src/mint.rs +++ b/packages/shade_protocol/src/mint.rs @@ -1,11 +1,10 @@ +use crate::{asset::Contract, generic_response::ResponseStatus}; +use cosmwasm_std::{Binary, HumanAddr, Uint128}; use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use cosmwasm_std::{HumanAddr, Uint128, Binary}; -use crate::asset::Contract; -use crate::generic_response::ResponseStatus; -use secret_toolkit::utils::{InitCallback, HandleCallback, Query}; +use secret_toolkit::utils::{HandleCallback, InitCallback, Query}; #[cfg(test)] -use secretcli::secretcli::{TestInit, TestHandle, TestQuery}; +use secretcli::secretcli::{TestHandle, TestInit, TestQuery}; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct MintConfig { @@ -87,20 +86,30 @@ pub struct MintMsgHook { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleAnswer { - Init { status: ResponseStatus, address: HumanAddr }, - Migrate { status: ResponseStatus }, - UpdateConfig { status: ResponseStatus}, - RegisterAsset { status: ResponseStatus}, - Burn { status: ResponseStatus, mint_amount: Uint128 } + Init { + status: ResponseStatus, + address: HumanAddr, + }, + Migrate { + status: ResponseStatus, + }, + UpdateConfig { + status: ResponseStatus, + }, + RegisterAsset { + status: ResponseStatus, + }, + Burn { + status: ResponseStatus, + mint_amount: Uint128, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { GetSupportedAssets {}, - GetAsset { - contract: String, - }, + GetAsset { contract: String }, GetConfig {}, } @@ -114,7 +123,7 @@ impl TestQuery for QueryMsg {} #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - SupportedAssets { assets: Vec, }, + SupportedAssets { assets: Vec }, Asset { asset: SupportedAsset }, Config { config: MintConfig }, } diff --git a/packages/shade_protocol/src/oracle.rs b/packages/shade_protocol/src/oracle.rs index b1d34ed2e..195d7e8da 100644 --- a/packages/shade_protocol/src/oracle.rs +++ b/packages/shade_protocol/src/oracle.rs @@ -1,15 +1,11 @@ +use crate::{asset::Contract, generic_response::ResponseStatus, snip20::Snip20Asset}; use cosmwasm_std::{HumanAddr, Uint128}; use schemars::JsonSchema; +use secret_toolkit::utils::{HandleCallback, InitCallback, Query}; use serde::{Deserialize, Serialize}; -use secret_toolkit::utils::{InitCallback, HandleCallback, Query}; -use crate::{ - asset::Contract, - generic_response::ResponseStatus, - snip20::Snip20Asset, -}; #[cfg(test)] -use secretcli::secretcli::{TestInit, TestHandle, TestQuery}; +use secretcli::secretcli::{TestHandle, TestInit, TestQuery}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct SswapPair { @@ -78,10 +74,10 @@ impl TestHandle for HandleMsg {} #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleAnswer { - UpdateConfig { status: ResponseStatus}, - RegisterSswapPair { status: ResponseStatus}, - UnregisterSswapPair { status: ResponseStatus}, - RegisterIndex { status: ResponseStatus}, + UpdateConfig { status: ResponseStatus }, + RegisterSswapPair { status: ResponseStatus }, + UnregisterSswapPair { status: ResponseStatus }, + RegisterIndex { status: ResponseStatus }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -104,4 +100,3 @@ impl TestQuery for QueryMsg {} pub enum QueryAnswer { Config { config: OracleConfig }, } - diff --git a/packages/shade_protocol/src/scrt_staking.rs b/packages/shade_protocol/src/scrt_staking.rs index 08028ea78..28c664b52 100644 --- a/packages/shade_protocol/src/scrt_staking.rs +++ b/packages/shade_protocol/src/scrt_staking.rs @@ -1,19 +1,8 @@ +use crate::{asset::Contract, generic_response::ResponseStatus}; +use cosmwasm_std::{Binary, Decimal, FullDelegation, HumanAddr, Uint128, Validator}; use schemars::JsonSchema; +use secret_toolkit::utils::{HandleCallback, InitCallback, Query}; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{ - HumanAddr, Binary, - Uint128, Decimal, - Validator, FullDelegation, -}; -use crate::asset::Contract; -use crate::generic_response::ResponseStatus; -use secret_toolkit::{ - utils::{ - InitCallback, - HandleCallback, - Query, - } -}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -79,14 +68,21 @@ impl HandleCallback for HandleMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleAnswer { - Init { status: ResponseStatus, address: HumanAddr }, - UpdateConfig { status: ResponseStatus }, - Receive { + Init { + status: ResponseStatus, + address: HumanAddr, + }, + UpdateConfig { + status: ResponseStatus, + }, + Receive { status: ResponseStatus, validator: Validator, }, - Claim { status: ResponseStatus }, - Unbond { + Claim { + status: ResponseStatus, + }, + Unbond { status: ResponseStatus, delegation: FullDelegation, }, @@ -109,6 +105,6 @@ impl Query for QueryMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - Config { config: Config}, + Config { config: Config }, Balance { amount: Uint128 }, } diff --git a/packages/shade_protocol/src/secretswap.rs b/packages/shade_protocol/src/secretswap.rs index 3e40d80ca..23e2053ae 100644 --- a/packages/shade_protocol/src/secretswap.rs +++ b/packages/shade_protocol/src/secretswap.rs @@ -1,10 +1,8 @@ +use crate::asset::Contract; use cosmwasm_std::{HumanAddr, Uint128}; -use serde::{Deserialize, Serialize}; use schemars::JsonSchema; use secret_toolkit::utils::Query; -use crate::{ - asset::Contract, -}; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -35,12 +33,10 @@ pub struct Simulation { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum PairQuery{ +pub enum PairQuery { Pair {}, Pool {}, - Simulation { - offer_asset: Asset, - }, + Simulation { offer_asset: Asset }, //ReverseSimulation {}, } diff --git a/packages/shade_protocol/src/snip20.rs b/packages/shade_protocol/src/snip20.rs index 1e3d35d91..efa469551 100644 --- a/packages/shade_protocol/src/snip20.rs +++ b/packages/shade_protocol/src/snip20.rs @@ -1,19 +1,13 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use crate::asset::Contract; -use cosmwasm_std::{ - StdResult, Querier, - HumanAddr, - Uint128, Binary, -}; +use cosmwasm_std::{Binary, HumanAddr, Querier, StdResult, Uint128}; +use schemars::JsonSchema; use secret_toolkit::{ - snip20::TokenInfo, - utils::{ - Query, InitCallback, HandleCallback, - }, + snip20::TokenInfo, + utils::{HandleCallback, InitCallback, Query}, }; #[cfg(test)] -use secretcli::secretcli::{TestInit, TestHandle, TestQuery}; +use secretcli::secretcli::{TestHandle, TestInit, TestQuery}; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -49,14 +43,9 @@ pub struct TokenConfigResponse { pub token_config: TokenConfig, } -pub fn token_config_query( - querier: &Q, - contract: Contract, -) -> StdResult { - - let answer: TokenConfigResponse = Snip20Query::TokenConfig {}.query(querier, - contract.code_hash, - contract.address)?; +pub fn token_config_query(querier: &Q, contract: Contract) -> StdResult { + let answer: TokenConfigResponse = + Snip20Query::TokenConfig {}.query(querier, contract.code_hash, contract.address)?; Ok(answer.token_config) } diff --git a/packages/shade_protocol/src/staking/mod.rs b/packages/shade_protocol/src/staking/mod.rs index 459497562..00d971598 100644 --- a/packages/shade_protocol/src/staking/mod.rs +++ b/packages/shade_protocol/src/staking/mod.rs @@ -1,13 +1,9 @@ pub mod stake; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use crate::{asset::Contract, generic_response::ResponseStatus, governance::vote::UserVote}; use cosmwasm_std::{HumanAddr, Uint128}; +use schemars::JsonSchema; use secret_toolkit::utils::{HandleCallback, Query}; -use crate::{ - asset::Contract, - generic_response::ResponseStatus, -}; -use crate::governance::vote::UserVote; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -30,19 +26,29 @@ pub struct InitMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleMsg { - UpdateConfig {admin: Option, unbond_time: Option}, + UpdateConfig { + admin: Option, + unbond_time: Option, + }, // Stake Receive { sender: HumanAddr, from: HumanAddr, amount: Uint128, }, - Unbond { amount: Uint128 }, + Unbond { + amount: Uint128, + }, // While secure querying is resolved - Vote { proposal_id: Uint128, votes: Vec }, + Vote { + proposal_id: Uint128, + votes: Vec, + }, ClaimUnbond {}, ClaimRewards {}, - SetViewingKey { key: String }, + SetViewingKey { + key: String, + }, } impl HandleCallback for HandleMsg { @@ -58,7 +64,7 @@ pub enum HandleAnswer { Vote { status: ResponseStatus }, ClaimUnbond { status: ResponseStatus }, ClaimRewards { status: ResponseStatus }, - SetViewingKey { status: ResponseStatus } + SetViewingKey { status: ResponseStatus }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -66,8 +72,15 @@ pub enum HandleAnswer { pub enum QueryMsg { Config {}, TotalStaked {}, - TotalUnbonding { start: Option, end: Option }, - UserStake { address: HumanAddr, key: String, time: u64}, + TotalUnbonding { + start: Option, + end: Option, + }, + UserStake { + address: HumanAddr, + key: String, + time: u64, + }, } impl Query for QueryMsg { @@ -77,8 +90,19 @@ impl Query for QueryMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryAnswer { - Config { config: Config }, - TotalStaked { total: Uint128 }, - TotalUnbonding { total: Uint128 }, - UserStake { staked: Uint128, pending_rewards: Uint128, unbonding: Uint128, unbonded: Uint128 }, + Config { + config: Config, + }, + TotalStaked { + total: Uint128, + }, + TotalUnbonding { + total: Uint128, + }, + UserStake { + staked: Uint128, + pending_rewards: Uint128, + unbonding: Uint128, + unbonded: Uint128, + }, } diff --git a/packages/shade_protocol/src/staking/stake.rs b/packages/shade_protocol/src/staking/stake.rs index 1f2fcc8e1..3f7acbf2b 100644 --- a/packages/shade_protocol/src/staking/stake.rs +++ b/packages/shade_protocol/src/staking/stake.rs @@ -1,6 +1,6 @@ +use cosmwasm_std::Uint128; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::Uint128; use std::cmp::Ordering; #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] @@ -26,11 +26,13 @@ pub struct Unbonding { } impl Ord for Unbonding { - fn cmp(&self, other: &Unbonding) -> Ordering { self.unbond_time.cmp(&other.unbond_time) } + fn cmp(&self, other: &Unbonding) -> Ordering { + self.unbond_time.cmp(&other.unbond_time) + } } impl PartialOrd for Unbonding { fn partial_cmp(&self, other: &Unbonding) -> Option { Some(self.cmp(other)) } -} \ No newline at end of file +} diff --git a/packages/shade_protocol/src/treasury.rs b/packages/shade_protocol/src/treasury.rs index edb5966ed..89066fe53 100644 --- a/packages/shade_protocol/src/treasury.rs +++ b/packages/shade_protocol/src/treasury.rs @@ -1,9 +1,11 @@ +use crate::{asset::Contract, generic_response::ResponseStatus}; +use cosmwasm_std::{Binary, Decimal, HumanAddr, Uint128}; use schemars::JsonSchema; +use secret_toolkit::{ + snip20, + utils::{HandleCallback, InitCallback, Query}, +}; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{HumanAddr, Uint128, Decimal, Binary}; -use crate::asset::Contract; -use crate::generic_response::ResponseStatus; -use secret_toolkit::{snip20, utils::{InitCallback, HandleCallback, Query}}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Config { @@ -51,13 +53,13 @@ pub enum HandleMsg { RegisterAsset { contract: Contract, /* List of contracts/users given an allowance based on a percentage of the asset balance - * e.g. governance, LP, SKY - */ + * e.g. governance, LP, SKY + */ allocations: Option>, }, // Trigger to re-calc asset allocations - Rebalance { }, + Rebalance {}, } impl HandleCallback for HandleMsg { @@ -67,21 +69,30 @@ impl HandleCallback for HandleMsg { #[derive(Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleAnswer { - Init { status: ResponseStatus, address: HumanAddr }, - UpdateConfig { status: ResponseStatus }, - RegisterAsset { status: ResponseStatus }, - Receive { status: ResponseStatus }, - Rebalance { status: ResponseStatus }, + Init { + status: ResponseStatus, + address: HumanAddr, + }, + UpdateConfig { + status: ResponseStatus, + }, + RegisterAsset { + status: ResponseStatus, + }, + Receive { + status: ResponseStatus, + }, + Rebalance { + status: ResponseStatus, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { GetConfig {}, - GetBalance { - contract: HumanAddr, - }, - CanRebalance { }, + GetBalance { contract: HumanAddr }, + CanRebalance {}, } impl Query for QueryMsg { @@ -93,5 +104,5 @@ impl Query for QueryMsg { pub enum QueryAnswer { Config { config: Config }, Balance { amount: Uint128 }, - CanRebalance { possible: bool}, + CanRebalance { possible: bool }, } From 80ff7cf777de725e17a9c515f08f2cb5879270cf Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Fri, 14 Jan 2022 22:04:10 -0500 Subject: [PATCH 3/8] minor cleanup --- contracts/airdrop/src/handle.rs | 2 +- packages/secretcli/src/secretcli.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/airdrop/src/handle.rs b/contracts/airdrop/src/handle.rs index 8cec4c8aa..a03208615 100644 --- a/contracts/airdrop/src/handle.rs +++ b/contracts/airdrop/src/handle.rs @@ -260,7 +260,7 @@ pub fn try_update_account( let config = config_r(&deps.storage).load()?; // Check that airdrop hasnt ended - available(&config, &env)?; + available(&config, env)?; // Get account let sender = env.message.sender.clone().to_string(); diff --git a/packages/secretcli/src/secretcli.rs b/packages/secretcli/src/secretcli.rs index 0b31e0012..475ea48b6 100644 --- a/packages/secretcli/src/secretcli.rs +++ b/packages/secretcli/src/secretcli.rs @@ -34,15 +34,15 @@ pub fn secretcli_run(command: Vec) -> Result { let mut commands = command; commands.append(&mut vec_str_to_vec_string(vec!["--output", "json"])); let mut cli = Command::new("secretd".to_string()); - if commands.len() > 0 { - cli.args(commands.clone()); + if commands.is_empty() { + cli.args(commands); } let mut result = cli.output().expect("Unexpected error"); // We wait cause sometimes the query/action takes a while for _ in 0..retry { - if result.stderr.len() > 0 { + if result.stderr.is_empty() { thread::sleep(time::Duration::from_secs(1)); } else { break; @@ -140,15 +140,15 @@ pub fn account_address(acc: &str) -> Result { let retry = 20; let mut cli = Command::new("secretd".to_string()); - if command.len() > 0 { - cli.args(command.clone()); + if command.is_empty() { + cli.args(command); } let mut result = cli.output().expect("Unexpected error"); // We wait cause sometimes the query/action takes a while for _ in 0..retry { - if result.stderr.len() > 0 { + if result.stderr.is_empty() { thread::sleep(time::Duration::from_secs(1)); } else { break; @@ -382,7 +382,7 @@ pub fn execute_contract( &contract.address, &message, "--from", - &sender, + sender, "--gas", ]; @@ -506,7 +506,7 @@ pub fn create_permit(tx: Tx, signer: &str) -> Result Date: Sat, 15 Jan 2022 13:50:38 -0500 Subject: [PATCH 4/8] added padding --- contracts/airdrop/src/contract.rs | 25 ++++++++++++++-------- packages/shade_protocol/src/airdrop/mod.rs | 14 ++++++++++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/contracts/airdrop/src/contract.rs b/contracts/airdrop/src/contract.rs index aa0c87672..78f2fb1f2 100644 --- a/contracts/airdrop/src/contract.rs +++ b/contracts/airdrop/src/contract.rs @@ -27,6 +27,10 @@ use cosmwasm_std::{ Uint128, }; use shade_protocol::airdrop::{claim_info::RequiredTask, Config, HandleMsg, InitMsg, QueryMsg}; +use secret_toolkit::utils::{pad_handle_result, pad_query_result}; + +// Used to pad up responses for better privacy. +pub const RESPONSE_BLOCK_SIZE: usize = 256; pub fn init( deps: &mut Extern, @@ -119,7 +123,7 @@ pub fn handle( env: Env, msg: HandleMsg, ) -> StdResult { - match msg { + pad_handle_result(match msg { HandleMsg::UpdateConfig { admin, dump_address, @@ -127,6 +131,7 @@ pub fn handle( start_date, end_date, decay_start: start_decay, + .. } => try_update_config( deps, env, @@ -137,27 +142,29 @@ pub fn handle( end_date, start_decay, ), - HandleMsg::AddTasks { tasks } => try_add_tasks(deps, &env, tasks), - HandleMsg::CompleteTask { address } => try_complete_task(deps, &env, address), + HandleMsg::AddTasks { tasks, .. } => try_add_tasks(deps, &env, tasks), + HandleMsg::CompleteTask { address, .. } => try_complete_task(deps, &env, address), HandleMsg::CreateAccount { addresses, partial_tree, + .. } => try_create_account(deps, &env, addresses, partial_tree), HandleMsg::UpdateAccount { addresses, partial_tree, + .. } => try_update_account(deps, &env, addresses, partial_tree), - HandleMsg::DisablePermitKey { key } => try_disable_permit_key(deps, &env, key), - HandleMsg::Claim {} => try_claim(deps, &env), - HandleMsg::ClaimDecay {} => try_claim_decay(deps, &env), - } + HandleMsg::DisablePermitKey { key, .. } => try_disable_permit_key(deps, &env, key), + HandleMsg::Claim { .. } => try_claim(deps, &env), + HandleMsg::ClaimDecay { .. } => try_claim_decay(deps, &env), + }, RESPONSE_BLOCK_SIZE) } pub fn query( deps: &Extern, msg: QueryMsg, ) -> StdResult { - match msg { + pad_query_result(match msg { QueryMsg::Config {} => to_binary(&query::config(deps)?), QueryMsg::Dates { current_date } => to_binary(&query::dates(deps, current_date)?), QueryMsg::TotalClaimed {} => to_binary(&query::total_claimed(deps)?), @@ -165,5 +172,5 @@ pub fn query( permit, current_date, } => to_binary(&query::account(deps, permit, current_date)?), - } + }, RESPONSE_BLOCK_SIZE) } diff --git a/packages/shade_protocol/src/airdrop/mod.rs b/packages/shade_protocol/src/airdrop/mod.rs index b56c9a639..1d4381836 100644 --- a/packages/shade_protocol/src/airdrop/mod.rs +++ b/packages/shade_protocol/src/airdrop/mod.rs @@ -85,27 +85,37 @@ pub enum HandleMsg { start_date: Option, end_date: Option, decay_start: Option, + padding: Option, }, AddTasks { tasks: Vec, + padding: Option, }, CompleteTask { address: HumanAddr, + padding: Option, }, CreateAccount { addresses: Vec, partial_tree: Vec, + padding: Option, }, /// Adds more addresses to accounts UpdateAccount { addresses: Vec, partial_tree: Vec, + padding: Option, }, DisablePermitKey { key: String, + padding: Option, + }, + Claim { + padding: Option, + }, + ClaimDecay { + padding: Option, }, - Claim {}, - ClaimDecay {}, } impl HandleCallback for HandleMsg { From f5b6af21f4c281380780ae6be669eef2eb74523a Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Sat, 15 Jan 2022 14:00:27 -0500 Subject: [PATCH 5/8] updated tests --- .../network_integration/tests/testnet_integration.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/network_integration/tests/testnet_integration.rs b/packages/network_integration/tests/testnet_integration.rs index 42a1e9838..7cb0e2d98 100644 --- a/packages/network_integration/tests/testnet_integration.rs +++ b/packages/network_integration/tests/testnet_integration.rs @@ -287,6 +287,7 @@ fn run_airdrop() -> Result<()> { &airdrop::HandleMsg::CreateAccount { addresses: vec![b_permit, a_permit.clone()], partial_tree: initial_proof, + padding: None, }, &airdrop, ACCOUNT_KEY, @@ -330,6 +331,7 @@ fn run_airdrop() -> Result<()> { test_contract_handle( &airdrop::HandleMsg::CompleteTask { address: HumanAddr::from(account_a.clone()), + padding: None, }, &airdrop, ACCOUNT_KEY, @@ -389,6 +391,7 @@ fn run_airdrop() -> Result<()> { &airdrop::HandleMsg::UpdateAccount { addresses: vec![c_permit], partial_tree: other_proof, + padding: None, }, &airdrop, ACCOUNT_KEY, @@ -427,6 +430,7 @@ fn run_airdrop() -> Result<()> { test_contract_handle( &airdrop::HandleMsg::DisablePermitKey { key: "key".to_string(), + padding: None, }, &airdrop, ACCOUNT_KEY, @@ -499,6 +503,7 @@ fn run_airdrop() -> Result<()> { &airdrop::HandleMsg::UpdateAccount { addresses: vec![d_permit], partial_tree: d_proof, + padding: None, }, &airdrop, ACCOUNT_KEY, @@ -524,7 +529,9 @@ fn run_airdrop() -> Result<()> { } test_contract_handle( - &airdrop::HandleMsg::ClaimDecay {}, + &airdrop::HandleMsg::ClaimDecay { + padding: None, + }, &airdrop, ACCOUNT_KEY, Some(GAS), From 7e846e41d807d0e84082c7272fc80d66cf6a2a6b Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Sat, 15 Jan 2022 14:31:10 -0500 Subject: [PATCH 6/8] fixed command size check --- packages/secretcli/src/secretcli.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/secretcli/src/secretcli.rs b/packages/secretcli/src/secretcli.rs index 475ea48b6..652008f95 100644 --- a/packages/secretcli/src/secretcli.rs +++ b/packages/secretcli/src/secretcli.rs @@ -34,7 +34,7 @@ pub fn secretcli_run(command: Vec) -> Result { let mut commands = command; commands.append(&mut vec_str_to_vec_string(vec!["--output", "json"])); let mut cli = Command::new("secretd".to_string()); - if commands.is_empty() { + if !commands.is_empty() { cli.args(commands); } @@ -42,7 +42,7 @@ pub fn secretcli_run(command: Vec) -> Result { // We wait cause sometimes the query/action takes a while for _ in 0..retry { - if result.stderr.is_empty() { + if !result.stderr.is_empty() { thread::sleep(time::Duration::from_secs(1)); } else { break; @@ -140,7 +140,7 @@ pub fn account_address(acc: &str) -> Result { let retry = 20; let mut cli = Command::new("secretd".to_string()); - if command.is_empty() { + if !command.is_empty() { cli.args(command); } @@ -148,7 +148,7 @@ pub fn account_address(acc: &str) -> Result { // We wait cause sometimes the query/action takes a while for _ in 0..retry { - if result.stderr.is_empty() { + if !result.stderr.is_empty() { thread::sleep(time::Duration::from_secs(1)); } else { break; From c5f5bfbfa685b59555bdee32dea39a46024d30b1 Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Sat, 15 Jan 2022 15:47:40 -0500 Subject: [PATCH 7/8] fixed privacy leak --- contracts/airdrop/src/query.rs | 1 - packages/shade_protocol/src/airdrop/mod.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/contracts/airdrop/src/query.rs b/contracts/airdrop/src/query.rs index f372484ac..e81e19ba5 100644 --- a/contracts/airdrop/src/query.rs +++ b/contracts/airdrop/src/query.rs @@ -19,7 +19,6 @@ use shade_protocol::{ pub fn config(deps: &Extern) -> StdResult { Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()?, - total_claimed: total_claimed_r(&deps.storage).load()?, }) } diff --git a/packages/shade_protocol/src/airdrop/mod.rs b/packages/shade_protocol/src/airdrop/mod.rs index 1d4381836..77c297be7 100644 --- a/packages/shade_protocol/src/airdrop/mod.rs +++ b/packages/shade_protocol/src/airdrop/mod.rs @@ -158,7 +158,6 @@ impl Query for QueryMsg { pub enum QueryAnswer { Config { config: Config, - total_claimed: Uint128, }, Dates { start: u64, From 479f7c0885dd24fe7a74dcf30ff36d32c79f7822 Mon Sep 17 00:00:00 2001 From: Guy Garcia Date: Sat, 15 Jan 2022 15:48:05 -0500 Subject: [PATCH 8/8] updated documentation --- contracts/airdrop/README.md | 50 +++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/contracts/airdrop/README.md b/contracts/airdrop/README.md index a6e0ad301..619b0784c 100644 --- a/contracts/airdrop/README.md +++ b/contracts/airdrop/README.md @@ -15,11 +15,13 @@ * Messages * [CreateAccount](#CreateAccount) * [UpdateAccount](#UpdateAccount) + * [DisablePermitKey](#DisablePermitKey) * [Claim](#Claim) * Queries - * [GetConfig](#GetConfig) - * [GetDates](#GetDates) - * [GetAccount](#GetAccount) + * [Config](#Config) + * [Dates](#Dates) + * [TotalClaimed](#TotalClaimed) + * [Account](#Account) # Introduction Contract responsible to handle snip20 airdrop @@ -42,6 +44,7 @@ Contract responsible to handle snip20 airdrop |max_amount | String | Used to limit the user permit amounts (lowers exploit possibility) | no| |default_claim | String | The default amount to be gifted regardless of tasks | no | |task_claim | RequiredTasks | The amounts per tasks to gift | no | +|query_rounding | string | To prevent leaking information, total claimed is rounded off to this value | no ##Admin @@ -57,13 +60,15 @@ Updates the given values |start_date | u64 | When the airdrop starts in UNIX time | yes | |end_date | u64 | When the airdrop ends in UNIX time | yes | |decay_start | u64 | When the airdrop decay starts in UNIX time | yes | +|padding | string | Allows for enforcing constant length messages | yes | #### AddTasks Adds more tasks to complete ##### Request |Name |Type |Description | optional | |------|-------|---------------------------|----------| -|Tasks | Tasks | The new tasks to be added | no | +|tasks | Tasks | The new tasks to be added | no | +|padding | string | Allows for enforcing constant length messages | yes | ##### Response ```json @@ -96,6 +101,7 @@ Complete that address' tasks for a given user |Name |Type |Description | optional | |--------|--------|-------------------------------------|----------| |address | String | The address that completed the task | no | +|padding | string | Allows for enforcing constant length messages | yes | ##### Response ```json @@ -117,6 +123,7 @@ Creates an account from which the user will claim all of his given addresses' re |-----------|----------------------------------|------------------------------------------|----------| | addresses | Array of [AddressProofPermit](#AddressProofPermit) | Proof that the user owns those addresses | no | | partial_tree | Array of string | An array of nodes that serve as a proof for the addresses | no | +|padding | string | Allows for enforcing constant length messages | yes | ##### Response ```json @@ -134,6 +141,7 @@ Updates a users accounts with more addresses |-----------|-----------------------------|------------------------------------------|----------| | addresses | Array of [AddressProofPermit](#AddressProofPermit) | Proof that the user owns those addresses | no | | partial_tree | Array of string | An array of nodes that serve as a proof for the addresses | no | +|padding | string | Allows for enforcing constant length messages | yes | ##### Response ```json @@ -144,6 +152,23 @@ Updates a users accounts with more addresses } ``` +### DisablePermitKey +Disables that permit's key. Any permit that has that key for that address will be declined. +##### Request +| Name | Type | Description | optional | +|-----------|-----------------------------|------------------------------------------|----------| +| key | string | Permit key | no | +|padding | string | Allows for enforcing constant length messages | yes | + +##### Response +```json +{ + "disable_permit_key": { + "status": "success" + } +} +``` + #### Claim Claim the user's available claimable amount @@ -169,7 +194,7 @@ Gets the contract's config } ``` -## GetDates +## Dates Get the contracts airdrop timeframe, can calculate the decay factor if a time is given ##### Request |Name |Type |Description | optional | @@ -186,7 +211,18 @@ Get the contracts airdrop timeframe, can calculate the decay factor if a time is } ``` -## GetAccount +## TotalClaimed +Shows the total amount of the token that has been claimed. If airdrop hasn't ended then it'll just show an estimation. +##### Request +```json +{ + "total_claimed": { + "claimed": "Claimed amount" + } +} +``` + +## Account Get the account's information ##### Request |Name |Type |Description | optional | @@ -195,7 +231,7 @@ Get the account's information |current_date | u64 | Current time in UNIT format | yes | ```json { - "eligibility": { + "account": { "total": "Total airdrop amount", "claimed": "Claimed amount", "unclaimed": "Amount available to claim",