From d5422c7f2088eea142e4fb115645381d9ec8eba1 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Thu, 18 Nov 2021 15:11:44 +0900 Subject: [PATCH 01/17] feat: change satking contracts to work with time-based schedule --- contracts/staking/src/contract.rs | 109 ++++++++++++++++++--------- contracts/staking/src/testing.rs | 105 ++++++++++++++++++-------- packages/anchor_token/src/staking.rs | 11 ++- 3 files changed, 153 insertions(+), 72 deletions(-) diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index c034c6d..1da1e0c 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -40,7 +40,7 @@ pub fn instantiate( store_state( deps.storage, &State { - last_distributed: env.block.height, + last_distributed: env.block.time.seconds(), total_bond_amount: Uint128::zero(), global_reward_index: Decimal::zero(), }, @@ -91,7 +91,7 @@ pub fn bond(deps: DepsMut, env: Env, sender_addr: Addr, amount: Uint128) -> StdR let mut staker_info: StakerInfo = read_staker_info(deps.storage, &sender_addr_raw)?; // Compute global reward & staker reward - compute_reward(&config, &mut state, env.block.height); + compute_reward(&config, &mut state, env.block.time.seconds()); compute_staker_reward(&state, &mut staker_info)?; // Increase bond_amount @@ -120,7 +120,7 @@ pub fn unbond(deps: DepsMut, env: Env, info: MessageInfo, amount: Uint128) -> St } // Compute global reward & staker reward - compute_reward(&config, &mut state, env.block.height); + compute_reward(&config, &mut state, env.block.time.seconds()); compute_staker_reward(&state, &mut staker_info)?; // Decrease bond_amount @@ -162,7 +162,7 @@ pub fn withdraw(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult block_height || s.1 < state.last_distributed { + if s.0 > block_time || s.1 < state.last_distributed { continue; } - // min(s.1, block_height) - max(s.0, last_distributed) - let passed_blocks = - std::cmp::min(s.1, block_height) - std::cmp::max(s.0, state.last_distributed); + // min(s.1, block_time) - max(s.0, last_distributed) + let passed_time = + std::cmp::min(s.1, block_time) - std::cmp::max(s.0, state.last_distributed); - let num_blocks = s.1 - s.0; - let distribution_amount_per_block: Decimal = Decimal::from_ratio(s.2, num_blocks); - distributed_amount += distribution_amount_per_block * Uint128::from(passed_blocks as u128); + let time = s.1 - s.0; + let distribution_amount_per_second: Decimal = Decimal::from_ratio(s.2, time); + distributed_amount += distribution_amount_per_second * Uint128::from(passed_time as u128); } - state.last_distributed = block_height; + state.last_distributed = block_time; state.global_reward_index = state.global_reward_index + Decimal::from_ratio(distributed_amount, state.total_bond_amount); } @@ -326,11 +326,10 @@ fn compute_staker_reward(state: &State, staker_info: &mut StakerInfo) -> StdResu pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Config {} => to_binary(&query_config(deps)?), - QueryMsg::State { block_height } => to_binary(&query_state(deps, block_height)?), - QueryMsg::StakerInfo { - staker, - block_height, - } => to_binary(&query_staker_info(deps, staker, block_height)?), + QueryMsg::State { block_time } => to_binary(&query_state(deps, block_time)?), + QueryMsg::StakerInfo { staker, block_time } => { + to_binary(&query_staker_info(deps, staker, block_time)?) + } } } @@ -345,11 +344,11 @@ pub fn query_config(deps: Deps) -> StdResult { Ok(resp) } -pub fn query_state(deps: Deps, block_height: Option) -> StdResult { +pub fn query_state(deps: Deps, block_time: Option) -> StdResult { let mut state: State = read_state(deps.storage)?; - if let Some(block_height) = block_height { + if let Some(block_time) = block_time { let config = read_config(deps.storage)?; - compute_reward(&config, &mut state, block_height); + compute_reward(&config, &mut state, block_time); } Ok(StateResponse { @@ -362,16 +361,16 @@ pub fn query_state(deps: Deps, block_height: Option) -> StdResult, + block_time: Option, ) -> StdResult { let staker_raw = deps.api.addr_canonicalize(&staker)?; let mut staker_info: StakerInfo = read_staker_info(deps.storage, &staker_raw)?; - if let Some(block_height) = block_height { + if let Some(block_time) = block_time { let config = read_config(deps.storage)?; let mut state = read_state(deps.storage)?; - compute_reward(&config, &mut state, block_height); + compute_reward(&config, &mut state, block_time); compute_staker_reward(&state, &mut staker_info)?; } @@ -384,6 +383,44 @@ pub fn query_staker_info( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { + let mut config = read_config(deps.storage)?; + config.distribution_schedule = msg.distribution_schedule; + store_config(deps.storage, &config)?; + Ok(Response::default()) } + +#[cfg(test)] +mod test { + use super::*; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + + #[test] + fn proper_migrate() { + let mut deps = mock_dependencies(&[]); + + // init the contract + let init_msg = InstantiateMsg { + anchor_token: "anchor_token".to_string(), + staking_token: "staking".to_string(), + distribution_schedule: vec![(50, 1000, Uint128::new(50000000u128))], + }; + + let info = mock_info("sender", &[]); + let res = instantiate(deps.as_mut(), mock_env(), info, init_msg).unwrap(); + assert_eq!(0, res.messages.len()); + + let distribution_schedule = vec![(300000, 800000, Uint128::new(50000000u128))]; + + // migrate + let migrate_msg = MigrateMsg { + distribution_schedule: distribution_schedule.clone(), + }; + let res = migrate(deps.as_mut(), mock_env(), migrate_msg).unwrap(); + assert_eq!(res, Response::default()); + + let config = read_config(&deps.storage).unwrap(); + assert_eq!(config.distribution_schedule, distribution_schedule); + } +} diff --git a/contracts/staking/src/testing.rs b/contracts/staking/src/testing.rs index 51391e9..597fa4e 100644 --- a/contracts/staking/src/testing.rs +++ b/contracts/staking/src/testing.rs @@ -40,14 +40,14 @@ fn proper_initialization() { let res = query( deps.as_ref(), mock_env(), - QueryMsg::State { block_height: None }, + QueryMsg::State { block_time: None }, ) .unwrap(); let state: StateResponse = from_binary(&res).unwrap(); assert_eq!( state, StateResponse { - last_distributed: 12345, + last_distributed: mock_env().block.time.seconds(), total_bond_amount: Uint128::zero(), global_reward_index: Decimal::zero(), } @@ -62,8 +62,16 @@ fn test_bond_tokens() { anchor_token: "reward0000".to_string(), staking_token: "staking0000".to_string(), distribution_schedule: vec![ - (12345, 12345 + 100, Uint128::from(1000000u128)), - (12345 + 100, 12345 + 200, Uint128::from(10000000u128)), + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), ], }; @@ -87,7 +95,7 @@ fn test_bond_tokens() { mock_env(), QueryMsg::StakerInfo { staker: "addr0000".to_string(), - block_height: None, + block_time: None, }, ) .unwrap(), @@ -106,7 +114,7 @@ fn test_bond_tokens() { &query( deps.as_ref(), mock_env(), - QueryMsg::State { block_height: None } + QueryMsg::State { block_time: None } ) .unwrap() ) @@ -114,7 +122,7 @@ fn test_bond_tokens() { StateResponse { total_bond_amount: Uint128::from(100u128), global_reward_index: Decimal::zero(), - last_distributed: 12345, + last_distributed: mock_env().block.time.seconds(), } ); @@ -124,7 +132,7 @@ fn test_bond_tokens() { amount: Uint128::from(100u128), msg: to_binary(&Cw20HookMsg::Bond {}).unwrap(), }); - env.block.height += 10; + env.block.time = env.block.time.plus_seconds(10); let _res = execute(deps.as_mut(), env, info, msg).unwrap(); @@ -135,7 +143,7 @@ fn test_bond_tokens() { mock_env(), QueryMsg::StakerInfo { staker: "addr0000".to_string(), - block_height: None, + block_time: None, }, ) .unwrap(), @@ -154,7 +162,7 @@ fn test_bond_tokens() { &query( deps.as_ref(), mock_env(), - QueryMsg::State { block_height: None } + QueryMsg::State { block_time: None } ) .unwrap() ) @@ -162,7 +170,7 @@ fn test_bond_tokens() { StateResponse { total_bond_amount: Uint128::from(200u128), global_reward_index: Decimal::from_ratio(1000u128, 1u128), - last_distributed: 12345 + 10, + last_distributed: mock_env().block.time.seconds() + 10, } ); @@ -249,8 +257,16 @@ fn test_compute_reward() { anchor_token: "reward0000".to_string(), staking_token: "staking0000".to_string(), distribution_schedule: vec![ - (12345, 12345 + 100, Uint128::from(1000000u128)), - (12345 + 100, 12345 + 200, Uint128::from(10000000u128)), + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), ], }; @@ -267,9 +283,9 @@ fn test_compute_reward() { let mut env = mock_env(); let _res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - // 100 blocks passed + // 100 seconds passed // 1,000,000 rewards distributed - env.block.height += 100; + env.block.time = env.block.time.plus_seconds(100); // bond 100 more tokens let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { @@ -286,7 +302,7 @@ fn test_compute_reward() { mock_env(), QueryMsg::StakerInfo { staker: "addr0000".to_string(), - block_height: None, + block_time: None, }, ) .unwrap() @@ -300,9 +316,9 @@ fn test_compute_reward() { } ); - // 100 blocks passed + // 100 seconds passed // 1,000,000 rewards distributed - env.block.height += 10; + env.block.time = env.block.time.plus_seconds(10); let info = mock_info("addr0000", &[]); // unbond @@ -317,7 +333,7 @@ fn test_compute_reward() { mock_env(), QueryMsg::StakerInfo { staker: "addr0000".to_string(), - block_height: None, + block_time: None, }, ) .unwrap() @@ -339,7 +355,7 @@ fn test_compute_reward() { mock_env(), QueryMsg::StakerInfo { staker: "addr0000".to_string(), - block_height: Some(12345 + 120), + block_time: Some(mock_env().block.time.plus_seconds(120).seconds()), }, ) .unwrap() @@ -362,8 +378,16 @@ fn test_withdraw() { anchor_token: "reward0000".to_string(), staking_token: "staking0000".to_string(), distribution_schedule: vec![ - (12345, 12345 + 100, Uint128::from(1000000u128)), - (12345 + 100, 12345 + 200, Uint128::from(10000000u128)), + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), ], }; @@ -380,9 +404,10 @@ fn test_withdraw() { let mut env = mock_env(); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - // 100 blocks passed + // 100 seconds passed // 1,000,000 rewards distributed - env.block.height += 100; + env.block.time = env.block.time.plus_seconds(100); + let info = mock_info("addr0000", &[]); let msg = ExecuteMsg::Withdraw {}; @@ -410,8 +435,16 @@ fn test_migrate_staking() { anchor_token: "reward0000".to_string(), staking_token: "staking0000".to_string(), distribution_schedule: vec![ - (12345, 12345 + 100, Uint128::from(1000000u128)), - (12345 + 100, 12345 + 200, Uint128::from(10000000u128)), + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), ], }; @@ -428,9 +461,9 @@ fn test_migrate_staking() { let mut env = mock_env(); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - // 100 blocks passed + // 100 seconds is passed // 1,000,000 rewards distributed - env.block.height += 100; + env.block.time = env.block.time.plus_seconds(100); let info = mock_info("addr0000", &[]); let msg = ExecuteMsg::Withdraw {}; @@ -449,8 +482,8 @@ fn test_migrate_staking() { }))] ); - // execute migration after 50 blocks - env.block.height += 50; + // execute migration after 50 seconds + env.block.time = env.block.time.plus_seconds(50); deps.querier.with_anc_minter("gov0000".to_string()); @@ -501,8 +534,16 @@ fn test_migrate_staking() { anchor_token: "reward0000".to_string(), staking_token: "staking0000".to_string(), distribution_schedule: vec![ - (12345, 12345 + 100, Uint128::from(1000000u128)), - (12345 + 100, 12345 + 150, Uint128::from(5000000u128)), // slot was modified + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128) + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 150, + Uint128::from(5000000u128) + ), // slot was modified ] } ); diff --git a/packages/anchor_token/src/staking.rs b/packages/anchor_token/src/staking.rs index 2d7254c..1a81dbf 100644 --- a/packages/anchor_token/src/staking.rs +++ b/packages/anchor_token/src/staking.rs @@ -33,20 +33,23 @@ pub enum Cw20HookMsg { Bond {}, } -/// We currently take no arguments for migrations +/// migrate struct for distribution schedule +/// block-based schedule to a time-based schedule #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MigrateMsg {} +pub struct MigrateMsg { + pub distribution_schedule: Vec<(u64, u64, Uint128)>, +} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { Config {}, State { - block_height: Option, + block_time: Option, }, StakerInfo { staker: String, - block_height: Option, + block_time: Option, }, } From a78cd45334b5dd3c9bef8cab5f1d6b64347ceaf0 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Tue, 21 Dec 2021 00:04:28 +0900 Subject: [PATCH 02/17] feat: add update config logic to staking contract --- contracts/staking/src/contract.rs | 63 ++++++ contracts/staking/src/testing.rs | 286 +++++++++++++++++++++++++++ packages/anchor_token/src/staking.rs | 3 + 3 files changed, 352 insertions(+) diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 1da1e0c..69d3ebb 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -58,6 +58,9 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S ExecuteMsg::MigrateStaking { new_staking_contract, } => migrate_staking(deps, env, info, new_staking_contract), + ExecuteMsg::UpdateConfig { + distribution_schedule, + } => update_config(deps, env, info, distribution_schedule), } } @@ -195,6 +198,66 @@ pub fn withdraw(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult StdResult { + // get gov address by querying anc token minter + let config: Config = read_config(deps.storage)?; + let state: State = read_state(deps.storage)?; + + let sender_addr_raw: CanonicalAddr = deps.api.addr_canonicalize(info.sender.as_str())?; + let anc_token: Addr = deps.api.addr_humanize(&config.anchor_token)?; + let gov_addr_raw: CanonicalAddr = deps + .api + .addr_canonicalize(&query_anc_minter(&deps.querier, anc_token)?)?; + if sender_addr_raw != gov_addr_raw { + return Err(StdError::generic_err("unauthorized")); + } + + let mut new_distribution: Vec<(u64, u64, Uint128)> = vec![]; + for s in config.distribution_schedule { + if distribution_schedule.0 > s.0 && distribution_schedule.1 < s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if s.0 == distribution_schedule.0 && distribution_schedule.1 != s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if s.0 != distribution_schedule.0 && distribution_schedule.1 == s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if distribution_schedule.0 <= state.last_distributed && state.last_distributed <= s.1 { + return Err(StdError::generic_err("cannot update the ongoing schedule")); + } + if distribution_schedule.0 <= state.last_distributed && state.last_distributed >= s.1 { + return Err(StdError::generic_err("cannot update a previous schedule")); + } + if s.0 == distribution_schedule.0 && distribution_schedule.1 == s.1 { + new_distribution.push(distribution_schedule); + continue; + } + + new_distribution.push(s) + } + + let new_config = Config { + anchor_token: config.anchor_token, + staking_token: config.staking_token, + distribution_schedule: new_distribution, + }; + store_config(deps.storage, &new_config)?; + + Ok(Response::new().add_attributes(vec![("action", "update_config")])) +} + pub fn migrate_staking( deps: DepsMut, env: Env, diff --git a/contracts/staking/src/testing.rs b/contracts/staking/src/testing.rs index 597fa4e..b89bb1e 100644 --- a/contracts/staking/src/testing.rs +++ b/contracts/staking/src/testing.rs @@ -1,5 +1,6 @@ use crate::contract::{execute, instantiate, query}; use crate::mock_querier::mock_dependencies; +use anchor_token::staking::ExecuteMsg::UpdateConfig; use anchor_token::staking::{ ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, StakerInfoResponse, StateResponse, @@ -548,3 +549,288 @@ fn test_migrate_staking() { } ); } + +#[test] +fn test_update_global_index() { + let mut deps = mock_dependencies(&[]); + + let msg = InstantiateMsg { + anchor_token: "reward0000".to_string(), + staking_token: "staking0000".to_string(), + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ], + }; + + let info = mock_info("addr0000", &[]); + let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(10000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("notgov", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config); + match res { + Err(StdError::GenericErr { msg, .. }) => assert_eq!(msg, "unauthorized"), + _ => panic!("Must return unauthorized error"), + } + + //update the overlapped schedule + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds() + 250, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config); + match res { + Err(StdError::GenericErr { msg, .. }) => { + assert_eq!(msg, "cannot update the overlapped distribution") + } + _ => panic!("Must return unauthorized error"), + } + + //update the overlapped schedule + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds() + 250, + mock_env().block.time.seconds() + 299, + Uint128::from(10000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config); + match res { + Err(StdError::GenericErr { msg, .. }) => { + assert_eq!(msg, "cannot update the overlapped distribution") + } + _ => panic!("Must return unauthorized error"), + } + // do some bond and update rewards + // bond 100 tokens + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "addr0000".to_string(), + amount: Uint128::from(100u128), + msg: to_binary(&Cw20HookMsg::Bond {}).unwrap(), + }); + let info = mock_info("staking0000", &[]); + let mut env = mock_env(); + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // 100 seconds is passed + // 1,000,000 rewards distributed + env.block.time = env.block.time.plus_seconds(100); + let info = mock_info("addr0000", &[]); + + let msg = ExecuteMsg::Withdraw {}; + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + assert_eq!( + res.messages, + vec![SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "reward0000".to_string(), + msg: to_binary(&Cw20ExecuteMsg::Transfer { + recipient: "addr0000".to_string(), + amount: Uint128::from(1000000u128), + }) + .unwrap(), + funds: vec![], + }))] + ); + + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(10000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config); + match res { + Err(StdError::GenericErr { msg, .. }) => { + assert_eq!(msg, "cannot update the ongoing schedule") + } + _ => panic!("Must return unauthorized error"), + } + + // do some bond and update rewards + // bond 100 tokens + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "addr0000".to_string(), + amount: Uint128::from(100u128), + msg: to_binary(&Cw20HookMsg::Bond {}).unwrap(), + }); + let info = mock_info("staking0000", &[]); + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // 100 seconds is passed + // 1,000,000 rewards distributed + env.block.time = env.block.time.plus_seconds(100); + + let info = mock_info("addr0000", &[]); + + let msg = ExecuteMsg::Withdraw {}; + let _res = execute(deps.as_mut(), env, info, msg).unwrap(); + + //cannot update previous scehdule + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(10000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config); + match res { + Err(StdError::GenericErr { msg, .. }) => { + assert_eq!(msg, "cannot update a previous schedule") + } + _ => panic!("Must return unauthorized error"), + } + + //successful one + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(20000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config).unwrap(); + + assert_eq!(res.attributes, vec![("action", "update_config")]); + + // query config + let res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); + let config: ConfigResponse = from_binary(&res).unwrap(); + assert_eq!( + config.distribution_schedule, + vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(20000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ] + ); + + //successful one + let update_config = UpdateConfig { + distribution_schedule: ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(50000000u128), + ), + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config).unwrap(); + + assert_eq!(res.attributes, vec![("action", "update_config")]); + + // query config + let res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); + let config: ConfigResponse = from_binary(&res).unwrap(); + assert_eq!( + config.distribution_schedule, + vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(20000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(50000000u128), + ), + ] + ); +} diff --git a/packages/anchor_token/src/staking.rs b/packages/anchor_token/src/staking.rs index 1a81dbf..4f73b29 100644 --- a/packages/anchor_token/src/staking.rs +++ b/packages/anchor_token/src/staking.rs @@ -25,6 +25,9 @@ pub enum ExecuteMsg { MigrateStaking { new_staking_contract: String, }, + UpdateConfig { + distribution_schedule: (u64, u64, Uint128), + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] From 64aa122d5dfcea08e3380b82be827dca1e1c72f3 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Tue, 23 Nov 2021 18:08:50 +0900 Subject: [PATCH 03/17] feat: burn percentage of ANC buy backs --- contracts/collector/src/contract.rs | 7 ++----- contracts/collector/src/testing.rs | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index 9b9e068..30f52ef 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -160,14 +160,11 @@ pub fn distribute(deps: DepsMut, env: Env) -> StdResult { })); } + // burn the left amount if !left_amount.is_zero() { messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: deps.api.addr_humanize(&config.anchor_token)?.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: deps - .api - .addr_humanize(&config.distributor_contract)? - .to_string(), + msg: to_binary(&Cw20ExecuteMsg::Burn { amount: left_amount, })?, funds: vec![], diff --git a/contracts/collector/src/testing.rs b/contracts/collector/src/testing.rs index f2b3605..39ed01c 100644 --- a/contracts/collector/src/testing.rs +++ b/contracts/collector/src/testing.rs @@ -179,8 +179,7 @@ fn test_distribute() { })), SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "tokenANC".to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { - recipient: "distributor".to_string(), + msg: to_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::from(10u128), }) .unwrap(), From 9cfc769729bf18905c0829f264cdecd8c5a2a92a Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Tue, 21 Dec 2021 00:19:45 +0900 Subject: [PATCH 04/17] feat: add more logic to update config add logic to be able to change gov contract, distributor_contract and terraswap factory --- contracts/collector/src/contract.rs | 27 +++++++++++++++++++++++++- contracts/collector/src/testing.rs | 12 ++++++++++++ packages/anchor_token/src/collector.rs | 7 ++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index 30f52ef..a968341 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -38,7 +38,19 @@ pub fn instantiate( #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { - ExecuteMsg::UpdateConfig { reward_factor } => update_config(deps, info, reward_factor), + ExecuteMsg::UpdateConfig { + reward_factor, + gov_contract, + terraswap_factory, + distributor_contract, + } => update_config( + deps, + info, + reward_factor, + gov_contract, + terraswap_factory, + distributor_contract, + ), ExecuteMsg::Sweep { denom } => sweep(deps, env, denom), } } @@ -47,6 +59,9 @@ pub fn update_config( deps: DepsMut, info: MessageInfo, reward_factor: Option, + gov_contract: Option, + terraswap_factory: Option, + distributor_contract: Option, ) -> StdResult { let mut config: Config = read_config(deps.storage)?; if deps.api.addr_canonicalize(info.sender.as_str())? != config.gov_contract { @@ -57,6 +72,16 @@ pub fn update_config( config.reward_factor = reward_factor; } + if let Some(gov_contract) = gov_contract { + config.gov_contract = deps.api.addr_canonicalize(gov_contract.as_str())?; + } + if let Some(distributor_contract) = distributor_contract { + config.distributor_contract = deps.api.addr_canonicalize(distributor_contract.as_str())?; + } + if let Some(terraswap_factory) = terraswap_factory { + config.terraswap_factory = deps.api.addr_canonicalize(terraswap_factory.as_str())?; + } + store_config(deps.storage, &config)?; Ok(Response::default()) } diff --git a/contracts/collector/src/testing.rs b/contracts/collector/src/testing.rs index 39ed01c..413181a 100644 --- a/contracts/collector/src/testing.rs +++ b/contracts/collector/src/testing.rs @@ -51,6 +51,9 @@ fn update_config() { let info = mock_info("gov", &[]); let msg = ExecuteMsg::UpdateConfig { reward_factor: Some(Decimal::percent(80)), + gov_contract: Some("new_gov".to_string()), + terraswap_factory: Some("new_terraswap_factory".to_string()), + distributor_contract: Some("new_distributor_contract".to_string()), }; let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); @@ -59,11 +62,20 @@ fn update_config() { // it worked, let's query the state let value = query_config(deps.as_ref()).unwrap(); assert_eq!(Decimal::percent(80), value.reward_factor); + assert_eq!(value.terraswap_factory, "new_terraswap_factory".to_string()); + assert_eq!(value.gov_contract, "new_gov".to_string()); + assert_eq!( + value.distributor_contract, + "new_distributor_contract".to_string() + ); // Unauthorized err let info = mock_info("addr0000", &[]); let msg = ExecuteMsg::UpdateConfig { reward_factor: None, + gov_contract: Some("new_gov".to_string()), + terraswap_factory: Some("new_terraswap_factory".to_string()), + distributor_contract: Some("new_distributor_contract".to_string()), }; let res = execute(deps.as_mut(), mock_env(), info, msg); diff --git a/packages/anchor_token/src/collector.rs b/packages/anchor_token/src/collector.rs index aa6e89e..fc50076 100644 --- a/packages/anchor_token/src/collector.rs +++ b/packages/anchor_token/src/collector.rs @@ -17,7 +17,12 @@ pub struct InstantiateMsg { pub enum ExecuteMsg { /// Update config interface /// to enable reward_factor update - UpdateConfig { reward_factor: Option }, + UpdateConfig { + reward_factor: Option, + gov_contract: Option, + terraswap_factory: Option, + distributor_contract: Option, + }, /// Public Message /// Sweep all given denom balance to ANC token /// and execute Distribute message From c12acb77f8dfe2f32857fde389b2cbd78600942f Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Thu, 23 Dec 2021 15:56:47 +0900 Subject: [PATCH 05/17] fix: change naming to astroport --- contracts/collector/src/contract.rs | 20 ++++++++++---------- contracts/collector/src/mock_querier.rs | 18 +++++++++--------- contracts/collector/src/state.rs | 2 +- contracts/collector/src/testing.rs | 18 +++++++++--------- packages/anchor_token/src/collector.rs | 6 +++--- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index a968341..8c8beb7 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -25,7 +25,7 @@ pub fn instantiate( deps.storage, &Config { gov_contract: deps.api.addr_canonicalize(&msg.gov_contract)?, - terraswap_factory: deps.api.addr_canonicalize(&msg.terraswap_factory)?, + astroport_factory: deps.api.addr_canonicalize(&msg.astroport_factory)?, anchor_token: deps.api.addr_canonicalize(&msg.anchor_token)?, distributor_contract: deps.api.addr_canonicalize(&msg.distributor_contract)?, reward_factor: msg.reward_factor, @@ -41,14 +41,14 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S ExecuteMsg::UpdateConfig { reward_factor, gov_contract, - terraswap_factory, + astroport_factory, distributor_contract, } => update_config( deps, info, reward_factor, gov_contract, - terraswap_factory, + astroport_factory, distributor_contract, ), ExecuteMsg::Sweep { denom } => sweep(deps, env, denom), @@ -60,7 +60,7 @@ pub fn update_config( info: MessageInfo, reward_factor: Option, gov_contract: Option, - terraswap_factory: Option, + astroport_factory: Option, distributor_contract: Option, ) -> StdResult { let mut config: Config = read_config(deps.storage)?; @@ -78,8 +78,8 @@ pub fn update_config( if let Some(distributor_contract) = distributor_contract { config.distributor_contract = deps.api.addr_canonicalize(distributor_contract.as_str())?; } - if let Some(terraswap_factory) = terraswap_factory { - config.terraswap_factory = deps.api.addr_canonicalize(terraswap_factory.as_str())?; + if let Some(astroport_factory) = astroport_factory { + config.astroport_factory = deps.api.addr_canonicalize(astroport_factory.as_str())?; } store_config(deps.storage, &config)?; @@ -95,11 +95,11 @@ const SWEEP_REPLY_ID: u64 = 1; pub fn sweep(deps: DepsMut, env: Env, denom: String) -> StdResult { let config: Config = read_config(deps.storage)?; let anchor_token = deps.api.addr_humanize(&config.anchor_token)?; - let terraswap_factory_addr = deps.api.addr_humanize(&config.terraswap_factory)?; + let astroport_factory_addr = deps.api.addr_humanize(&config.astroport_factory)?; let pair_info: PairInfo = query_pair_info( &deps.querier, - terraswap_factory_addr, + astroport_factory_addr, &[ AssetInfo::NativeToken { denom: denom.to_string(), @@ -214,9 +214,9 @@ pub fn query_config(deps: Deps) -> StdResult { let state = read_config(deps.storage)?; let resp = ConfigResponse { gov_contract: deps.api.addr_humanize(&state.gov_contract)?.to_string(), - terraswap_factory: deps + astroport_factory: deps .api - .addr_humanize(&state.terraswap_factory)? + .addr_humanize(&state.astroport_factory)? .to_string(), anchor_token: deps.api.addr_humanize(&state.anchor_token)?.to_string(), distributor_contract: deps diff --git a/contracts/collector/src/mock_querier.rs b/contracts/collector/src/mock_querier.rs index f57fac1..2cb832d 100644 --- a/contracts/collector/src/mock_querier.rs +++ b/contracts/collector/src/mock_querier.rs @@ -32,7 +32,7 @@ pub struct WasmMockQuerier { base: MockQuerier, token_querier: TokenQuerier, tax_querier: TaxQuerier, - terraswap_factory_querier: TerraswapFactoryQuerier, + astroport_factory_querier: AstroportFactoryQuerier, } #[derive(Clone, Default)] @@ -89,13 +89,13 @@ pub(crate) fn caps_to_map(caps: &[(&String, &Uint128)]) -> HashMap, } -impl TerraswapFactoryQuerier { +impl AstroportFactoryQuerier { pub fn new(pairs: &[(&String, &String)]) -> Self { - TerraswapFactoryQuerier { + AstroportFactoryQuerier { pairs: pairs_to_map(pairs), } } @@ -162,7 +162,7 @@ impl WasmMockQuerier { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => match from_binary(msg) { Ok(QueryMsg::Pair { asset_infos }) => { let key = asset_infos[0].to_string() + asset_infos[1].to_string().as_str(); - match self.terraswap_factory_querier.pairs.get(&key) { + match self.astroport_factory_querier.pairs.get(&key) { Some(v) => SystemResult::Ok(ContractResult::from(to_binary(&PairInfo { contract_addr: v.to_string(), liquidity_token: "liquidity".to_string(), @@ -227,7 +227,7 @@ impl WasmMockQuerier { base, token_querier: TokenQuerier::default(), tax_querier: TaxQuerier::default(), - terraswap_factory_querier: TerraswapFactoryQuerier::default(), + astroport_factory_querier: AstroportFactoryQuerier::default(), } } @@ -241,8 +241,8 @@ impl WasmMockQuerier { self.tax_querier = TaxQuerier::new(rate, caps); } - // configure the terraswap pair - pub fn with_terraswap_pairs(&mut self, pairs: &[(&String, &String)]) { - self.terraswap_factory_querier = TerraswapFactoryQuerier::new(pairs); + // configure the astroport pair + pub fn with_astroport_pairs(&mut self, pairs: &[(&String, &String)]) { + self.astroport_factory_querier = AstroportFactoryQuerier::new(pairs); } } diff --git a/contracts/collector/src/state.rs b/contracts/collector/src/state.rs index e0d7087..4ae9d13 100644 --- a/contracts/collector/src/state.rs +++ b/contracts/collector/src/state.rs @@ -9,7 +9,7 @@ static KEY_CONFIG: &[u8] = b"config"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Config { pub gov_contract: CanonicalAddr, // collected rewards receiver - pub terraswap_factory: CanonicalAddr, // terraswap factory contract + pub astroport_factory: CanonicalAddr, // astroport factory contract pub anchor_token: CanonicalAddr, // anchor token address pub distributor_contract: CanonicalAddr, // distributor contract to sent back rewards pub reward_factor: Decimal, // reward distribution rate to gov contract, left rewards sent back to distributor contract diff --git a/contracts/collector/src/testing.rs b/contracts/collector/src/testing.rs index 413181a..d5d0c06 100644 --- a/contracts/collector/src/testing.rs +++ b/contracts/collector/src/testing.rs @@ -15,7 +15,7 @@ fn proper_initialization() { let mut deps = mock_dependencies(&[]); let msg = InstantiateMsg { - terraswap_factory: "terraswapfactory".to_string(), + astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), distributor_contract: "distributor".to_string(), @@ -29,7 +29,7 @@ fn proper_initialization() { // it worked, let's query the state let config: ConfigResponse = query_config(deps.as_ref()).unwrap(); - assert_eq!("terraswapfactory", config.terraswap_factory.as_str()); + assert_eq!("astroportfactory", config.astroport_factory.as_str()); } #[test] @@ -37,7 +37,7 @@ fn update_config() { let mut deps = mock_dependencies(&[]); let msg = InstantiateMsg { - terraswap_factory: "terraswapfactory".to_string(), + astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), distributor_contract: "distributor".to_string(), @@ -52,7 +52,7 @@ fn update_config() { let msg = ExecuteMsg::UpdateConfig { reward_factor: Some(Decimal::percent(80)), gov_contract: Some("new_gov".to_string()), - terraswap_factory: Some("new_terraswap_factory".to_string()), + astroport_factory: Some("new_astroport_factory".to_string()), distributor_contract: Some("new_distributor_contract".to_string()), }; @@ -62,7 +62,7 @@ fn update_config() { // it worked, let's query the state let value = query_config(deps.as_ref()).unwrap(); assert_eq!(Decimal::percent(80), value.reward_factor); - assert_eq!(value.terraswap_factory, "new_terraswap_factory".to_string()); + assert_eq!(value.astroport_factory, "new_astroport_factory".to_string()); assert_eq!(value.gov_contract, "new_gov".to_string()); assert_eq!( value.distributor_contract, @@ -74,7 +74,7 @@ fn update_config() { let msg = ExecuteMsg::UpdateConfig { reward_factor: None, gov_contract: Some("new_gov".to_string()), - terraswap_factory: Some("new_terraswap_factory".to_string()), + astroport_factory: Some("new_astroport_factory".to_string()), distributor_contract: Some("new_distributor_contract".to_string()), }; @@ -98,10 +98,10 @@ fn test_sweep() { ); deps.querier - .with_terraswap_pairs(&[(&"uusdtokenANC".to_string(), &"pairANC".to_string())]); + .with_astroport_pairs(&[(&"uusdtokenANC".to_string(), &"pairANC".to_string())]); let msg = InstantiateMsg { - terraswap_factory: "terraswapfactory".to_string(), + astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), distributor_contract: "distributor".to_string(), @@ -158,7 +158,7 @@ fn test_distribute() { )]); let msg = InstantiateMsg { - terraswap_factory: "terraswapfactory".to_string(), + astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), distributor_contract: "distributor".to_string(), diff --git a/packages/anchor_token/src/collector.rs b/packages/anchor_token/src/collector.rs index fc50076..51d3a6c 100644 --- a/packages/anchor_token/src/collector.rs +++ b/packages/anchor_token/src/collector.rs @@ -6,7 +6,7 @@ use cosmwasm_std::Decimal; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct InstantiateMsg { pub gov_contract: String, // collected rewards receiver - pub terraswap_factory: String, + pub astroport_factory: String, pub anchor_token: String, pub distributor_contract: String, pub reward_factor: Decimal, @@ -20,7 +20,7 @@ pub enum ExecuteMsg { UpdateConfig { reward_factor: Option, gov_contract: Option, - terraswap_factory: Option, + astroport_factory: Option, distributor_contract: Option, }, /// Public Message @@ -39,7 +39,7 @@ pub enum QueryMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct ConfigResponse { pub gov_contract: String, // collected rewards receiver - pub terraswap_factory: String, + pub astroport_factory: String, pub anchor_token: String, pub distributor_contract: String, pub reward_factor: Decimal, From 39e068d5c9c931c6bc064f30f9e52255ec1745fb Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Thu, 23 Dec 2021 15:57:40 +0900 Subject: [PATCH 06/17] fix: add vec to update config --- contracts/staking/src/contract.rs | 72 ++++++++----- contracts/staking/src/testing.rs | 150 ++++++++++++++++++++++++--- packages/anchor_token/src/staking.rs | 2 +- 3 files changed, 184 insertions(+), 40 deletions(-) diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 69d3ebb..8b5ea7a 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -202,7 +202,7 @@ pub fn update_config( deps: DepsMut, _env: Env, info: MessageInfo, - distribution_schedule: (u64, u64, Uint128), + distribution_schedule: Vec<(u64, u64, Uint128)>, ) -> StdResult { // get gov address by querying anc token minter let config: Config = read_config(deps.storage)?; @@ -218,34 +218,56 @@ pub fn update_config( } let mut new_distribution: Vec<(u64, u64, Uint128)> = vec![]; - for s in config.distribution_schedule { - if distribution_schedule.0 > s.0 && distribution_schedule.1 < s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); - } - if s.0 == distribution_schedule.0 && distribution_schedule.1 != s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); - } - if s.0 != distribution_schedule.0 && distribution_schedule.1 == s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); + + for s in config.distribution_schedule.clone().into_iter() { + let mut found = false; + for distribution in distribution_schedule.clone().into_iter() { + if distribution.0 > s.0 && distribution.1 < s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if s.0 == distribution.0 && distribution.1 != s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if s.0 != distribution.0 && distribution.1 == s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if distribution.0 <= state.last_distributed && state.last_distributed <= distribution.1 + { + return Err(StdError::generic_err("cannot update the ongoing schedule")); + } + if distribution.0 <= state.last_distributed && state.last_distributed >= distribution.1 + { + return Err(StdError::generic_err("cannot update a previous schedule")); + } + if s.0 == distribution.0 && distribution.1 == s.1 { + found = true; + new_distribution.push(distribution); + continue; + } } - if distribution_schedule.0 <= state.last_distributed && state.last_distributed <= s.1 { - return Err(StdError::generic_err("cannot update the ongoing schedule")); + if !found { + new_distribution.push(s); } - if distribution_schedule.0 <= state.last_distributed && state.last_distributed >= s.1 { - return Err(StdError::generic_err("cannot update a previous schedule")); + } + + for distribution in distribution_schedule { + let mut bigger = false; + for s in config.distribution_schedule.clone().into_iter() { + if distribution.0 >= s.1 { + bigger = true; + } else { + bigger = false; + } } - if s.0 == distribution_schedule.0 && distribution_schedule.1 == s.1 { - new_distribution.push(distribution_schedule); - continue; + if bigger { + new_distribution.push(distribution) } - - new_distribution.push(s) } let new_config = Config { diff --git a/contracts/staking/src/testing.rs b/contracts/staking/src/testing.rs index b89bb1e..1ad4db2 100644 --- a/contracts/staking/src/testing.rs +++ b/contracts/staking/src/testing.rs @@ -590,11 +590,11 @@ fn test_update_global_index() { let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds() + 300, mock_env().block.time.seconds() + 400, Uint128::from(10000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -608,11 +608,11 @@ fn test_update_global_index() { //update the overlapped schedule let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds() + 250, mock_env().block.time.seconds() + 300, Uint128::from(10000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -628,11 +628,11 @@ fn test_update_global_index() { //update the overlapped schedule let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds() + 250, mock_env().block.time.seconds() + 299, Uint128::from(10000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -677,11 +677,11 @@ fn test_update_global_index() { ); let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds(), mock_env().block.time.seconds() + 100, Uint128::from(10000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -716,11 +716,11 @@ fn test_update_global_index() { //cannot update previous scehdule let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds(), mock_env().block.time.seconds() + 100, Uint128::from(10000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -736,11 +736,11 @@ fn test_update_global_index() { //successful one let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds() + 300, mock_env().block.time.seconds() + 400, Uint128::from(20000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -786,11 +786,11 @@ fn test_update_global_index() { //successful one let update_config = UpdateConfig { - distribution_schedule: ( + distribution_schedule: vec![( mock_env().block.time.seconds() + 400, mock_env().block.time.seconds() + 500, Uint128::from(50000000u128), - ), + )], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -833,4 +833,126 @@ fn test_update_global_index() { ), ] ); + + let update_config = UpdateConfig { + distribution_schedule: vec![ + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(90000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(80000000u128), + ), + ], + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config).unwrap(); + + assert_eq!(res.attributes, vec![("action", "update_config")]); + + // query config + let res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); + let config: ConfigResponse = from_binary(&res).unwrap(); + assert_eq!( + config.distribution_schedule, + vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(90000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(80000000u128), + ), + ] + ); + + let update_config = UpdateConfig { + distribution_schedule: vec![ + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(90000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(80000000u128), + ), + ( + mock_env().block.time.seconds() + 500, + mock_env().block.time.seconds() + 600, + Uint128::from(60000000u128), + ), + ], + }; + + deps.querier.with_anc_minter("gov0000".to_string()); + + let info = mock_info("gov0000", &[]); + let res = execute(deps.as_mut(), mock_env(), info, update_config).unwrap(); + + assert_eq!(res.attributes, vec![("action", "update_config")]); + + // query config + let res = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); + let config: ConfigResponse = from_binary(&res).unwrap(); + assert_eq!( + config.distribution_schedule, + vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(90000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(80000000u128), + ), + ( + mock_env().block.time.seconds() + 500, + mock_env().block.time.seconds() + 600, + Uint128::from(60000000u128), + ) + ] + ); } diff --git a/packages/anchor_token/src/staking.rs b/packages/anchor_token/src/staking.rs index 4f73b29..60c200d 100644 --- a/packages/anchor_token/src/staking.rs +++ b/packages/anchor_token/src/staking.rs @@ -26,7 +26,7 @@ pub enum ExecuteMsg { new_staking_contract: String, }, UpdateConfig { - distribution_schedule: (u64, u64, Uint128), + distribution_schedule: Vec<(u64, u64, Uint128)>, }, } From f2dfc8d54044b85879dac210b4c1f0c752c39b9d Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Thu, 23 Dec 2021 17:09:27 +0900 Subject: [PATCH 07/17] chore: update dependencies to astroport --- contracts/collector/Cargo.toml | 2 +- contracts/collector/src/contract.rs | 16 ++++++++-------- contracts/collector/src/mock_querier.rs | 10 ++++++---- contracts/collector/src/testing.rs | 6 +++--- contracts/gov/Cargo.toml | 2 +- contracts/gov/src/contract.rs | 2 +- contracts/gov/src/staking.rs | 2 +- contracts/gov/src/tests.rs | 2 +- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/contracts/collector/Cargo.toml b/contracts/collector/Cargo.toml index 067f110..3e062aa 100644 --- a/contracts/collector/Cargo.toml +++ b/contracts/collector/Cargo.toml @@ -39,7 +39,7 @@ cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } terra-cosmwasm = "2.2.0" -terraswap = { version = "2.4.0" } +astroport = "0.3.1" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index 8c8beb7..fa1e854 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -2,17 +2,17 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, to_binary, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, - Response, StdError, StdResult, SubMsg, WasmMsg, + attr, to_binary, Addr, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, + Reply, Response, StdError, StdResult, SubMsg, WasmMsg, }; use crate::state::{read_config, store_config, Config}; use anchor_token::collector::{ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use astroport::asset::{Asset, AssetInfo, PairInfo}; +use astroport::pair::ExecuteMsg as AstroportExecuteMsg; +use astroport::querier::{query_balance, query_pair_info, query_token_balance}; use cw20::Cw20ExecuteMsg; -use terraswap::asset::{Asset, AssetInfo, PairInfo}; -use terraswap::pair::ExecuteMsg as TerraswapExecuteMsg; -use terraswap::querier::{query_balance, query_pair_info, query_token_balance}; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -105,7 +105,7 @@ pub fn sweep(deps: DepsMut, env: Env, denom: String) -> StdResult { denom: denom.to_string(), }, AssetInfo::Token { - contract_addr: anchor_token.to_string(), + contract_addr: Addr::unchecked(anchor_token), }, ], )?; @@ -124,8 +124,8 @@ pub fn sweep(deps: DepsMut, env: Env, denom: String) -> StdResult { Ok(Response::new() .add_submessage(SubMsg::reply_on_success( CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: pair_info.contract_addr, - msg: to_binary(&TerraswapExecuteMsg::Swap { + contract_addr: pair_info.contract_addr.into_string(), + msg: to_binary(&AstroportExecuteMsg::Swap { offer_asset: Asset { amount, ..swap_asset diff --git a/contracts/collector/src/mock_querier.rs b/contracts/collector/src/mock_querier.rs index 2cb832d..0bb3f7e 100644 --- a/contracts/collector/src/mock_querier.rs +++ b/contracts/collector/src/mock_querier.rs @@ -3,15 +3,16 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, from_slice, to_binary, Coin, ContractResult, Decimal, OwnedDeps, Querier, + from_binary, from_slice, to_binary, Addr, Coin, ContractResult, Decimal, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg}; use std::collections::HashMap; +use astroport::asset::{AssetInfo, PairInfo}; +use astroport::factory::PairType; use terra_cosmwasm::{TaxCapResponse, TaxRateResponse, TerraQuery, TerraQueryWrapper, TerraRoute}; -use terraswap::asset::{AssetInfo, PairInfo}; /// mock_dependencies is a drop-in replacement for cosmwasm_std::testing::mock_dependencies /// this uses our CustomQuerier. @@ -164,8 +165,8 @@ impl WasmMockQuerier { let key = asset_infos[0].to_string() + asset_infos[1].to_string().as_str(); match self.astroport_factory_querier.pairs.get(&key) { Some(v) => SystemResult::Ok(ContractResult::from(to_binary(&PairInfo { - contract_addr: v.to_string(), - liquidity_token: "liquidity".to_string(), + contract_addr: Addr::unchecked(v.to_string()), + liquidity_token: Addr::unchecked("liquidity".to_string()), asset_infos: [ AssetInfo::NativeToken { denom: "uusd".to_string(), @@ -174,6 +175,7 @@ impl WasmMockQuerier { denom: "uusd".to_string(), }, ], + pair_type: PairType::Stable {}, }))), None => SystemResult::Err(SystemError::InvalidRequest { error: "No pair info exists".to_string(), diff --git a/contracts/collector/src/testing.rs b/contracts/collector/src/testing.rs index d5d0c06..e5daf71 100644 --- a/contracts/collector/src/testing.rs +++ b/contracts/collector/src/testing.rs @@ -1,14 +1,14 @@ use crate::contract::{execute, instantiate, query_config, reply}; use crate::mock_querier::mock_dependencies; use anchor_token::collector::{ConfigResponse, ExecuteMsg, InstantiateMsg}; +use astroport::asset::{Asset, AssetInfo}; +use astroport::pair::ExecuteMsg as AstroportExecuteMsg; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ to_binary, Coin, ContractResult, CosmosMsg, Decimal, Reply, ReplyOn, StdError, SubMsg, SubMsgExecutionResponse, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; -use terraswap::asset::{Asset, AssetInfo}; -use terraswap::pair::ExecuteMsg as TerraswapExecuteMsg; #[test] fn proper_initialization() { @@ -123,7 +123,7 @@ fn test_sweep() { vec![SubMsg { msg: WasmMsg::Execute { contract_addr: "pairANC".to_string(), - msg: to_binary(&TerraswapExecuteMsg::Swap { + msg: to_binary(&AstroportExecuteMsg::Swap { offer_asset: Asset { info: AssetInfo::NativeToken { denom: "uusd".to_string() diff --git a/contracts/gov/Cargo.toml b/contracts/gov/Cargo.toml index 72f4700..2a08d7f 100644 --- a/contracts/gov/Cargo.toml +++ b/contracts/gov/Cargo.toml @@ -41,7 +41,7 @@ cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -terraswap = { version = "2.4.0" } +astroport = "0.3.1" thiserror = { version = "1.0.20" } hex = "0.4" diff --git a/contracts/gov/src/contract.rs b/contracts/gov/src/contract.rs index e3d9621..2abc4c6 100644 --- a/contracts/gov/src/contract.rs +++ b/contracts/gov/src/contract.rs @@ -6,6 +6,7 @@ use crate::state::{ state_store, store_tmp_poll_id, Config, ExecuteData, Poll, State, }; +use astroport::querier::query_token_balance; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -13,7 +14,6 @@ use cosmwasm_std::{ MessageInfo, Reply, Response, StdError, StdResult, SubMsg, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; -use terraswap::querier::query_token_balance; use anchor_token::common::OrderBy; use anchor_token::gov::{ diff --git a/contracts/gov/src/staking.rs b/contracts/gov/src/staking.rs index c619842..a59a88d 100644 --- a/contracts/gov/src/staking.rs +++ b/contracts/gov/src/staking.rs @@ -5,12 +5,12 @@ use crate::state::{ }; use anchor_token::gov::{PollStatus, StakerResponse}; +use astroport::querier::query_token_balance; use cosmwasm_std::{ to_binary, Addr, CanonicalAddr, CosmosMsg, Deps, DepsMut, MessageInfo, Response, StdResult, Storage, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; -use terraswap::querier::query_token_balance; pub fn stake_voting_tokens( deps: DepsMut, diff --git a/contracts/gov/src/tests.rs b/contracts/gov/src/tests.rs index e85bfd3..c87a6ca 100644 --- a/contracts/gov/src/tests.rs +++ b/contracts/gov/src/tests.rs @@ -12,13 +12,13 @@ use anchor_token::gov::{ PollStatus, PollsResponse, QueryMsg, StakerResponse, VoteOption, VoterInfo, VotersResponse, VotersResponseItem, }; +use astroport::querier::query_token_balance; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ attr, coins, from_binary, to_binary, Addr, Api, CanonicalAddr, ContractResult, CosmosMsg, Decimal, Deps, DepsMut, Env, Reply, Response, StdError, SubMsg, Timestamp, Uint128, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; -use terraswap::querier::query_token_balance; const VOTING_TOKEN: &str = "voting_token"; const TEST_CREATOR: &str = "creator"; From 3052d01aab19ad986190fe79bb1854d962960cf7 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Thu, 23 Dec 2021 19:31:36 +0900 Subject: [PATCH 08/17] feat: add migration to collector contract --- contracts/collector/Cargo.toml | 2 +- contracts/collector/src/contract.rs | 6 ++++- contracts/collector/src/lib.rs | 1 + contracts/collector/src/migration.rs | 34 ++++++++++++++++++++++++++ contracts/collector/src/state.rs | 2 +- packages/anchor_token/Cargo.toml | 2 +- packages/anchor_token/src/collector.rs | 4 ++- 7 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 contracts/collector/src/migration.rs diff --git a/contracts/collector/Cargo.toml b/contracts/collector/Cargo.toml index 3e062aa..48b6abd 100644 --- a/contracts/collector/Cargo.toml +++ b/contracts/collector/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.2.1", path = "../../packages/anchor_token" } terra-cosmwasm = "2.2.0" astroport = "0.3.1" schemars = "0.8.1" diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index fa1e854..a56c618 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -8,6 +8,7 @@ use cosmwasm_std::{ use crate::state::{read_config, store_config, Config}; +use crate::migration::migrate_config; use anchor_token::collector::{ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use astroport::asset::{Asset, AssetInfo, PairInfo}; use astroport::pair::ExecuteMsg as AstroportExecuteMsg; @@ -230,6 +231,9 @@ pub fn query_config(deps: Deps) -> StdResult { } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { + //migrate config + migrate_config(deps.storage, deps.api.addr_canonicalize(&msg.astroport_factory)?)?; + Ok(Response::default()) } diff --git a/contracts/collector/src/lib.rs b/contracts/collector/src/lib.rs index 68e2087..c89e271 100644 --- a/contracts/collector/src/lib.rs +++ b/contracts/collector/src/lib.rs @@ -1,4 +1,5 @@ pub mod contract; +pub mod migration; pub mod state; #[cfg(test)] diff --git a/contracts/collector/src/migration.rs b/contracts/collector/src/migration.rs new file mode 100644 index 0000000..f1058cc --- /dev/null +++ b/contracts/collector/src/migration.rs @@ -0,0 +1,34 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::state::{store_config, Config, KEY_CONFIG}; +use cosmwasm_std::{CanonicalAddr, Decimal, StdResult, Storage}; +use cosmwasm_storage::ReadonlySingleton; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct LegacyConfig { + pub gov_contract: CanonicalAddr, // collected rewards receiver + pub terraswap_factory: CanonicalAddr, // astroport factory contract + pub anchor_token: CanonicalAddr, // anchor token address + pub distributor_contract: CanonicalAddr, // distributor contract to sent back rewards + pub reward_factor: Decimal, // reward distribution rate to gov contract, left rewards sent back to distributor contract +} + +fn read_legacy_config(storage: &dyn Storage) -> StdResult { + ReadonlySingleton::new(storage, KEY_CONFIG).load() +} + +pub fn migrate_config(storage: &mut dyn Storage, astroport_factory: CanonicalAddr) -> StdResult<()> { + let legacy_config: LegacyConfig = read_legacy_config(storage)?; + + store_config( + storage, + &Config { + gov_contract: legacy_config.gov_contract, + astroport_factory, + anchor_token: legacy_config.anchor_token, + distributor_contract: legacy_config.distributor_contract, + reward_factor: legacy_config.reward_factor, + }, + ) +} diff --git a/contracts/collector/src/state.rs b/contracts/collector/src/state.rs index 4ae9d13..a93d833 100644 --- a/contracts/collector/src/state.rs +++ b/contracts/collector/src/state.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use cosmwasm_std::{CanonicalAddr, Decimal, StdResult, Storage}; use cosmwasm_storage::{singleton, singleton_read}; -static KEY_CONFIG: &[u8] = b"config"; +pub static KEY_CONFIG: &[u8] = b"config"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Config { diff --git a/packages/anchor_token/Cargo.toml b/packages/anchor_token/Cargo.toml index 42702ab..a75b43c 100644 --- a/packages/anchor_token/Cargo.toml +++ b/packages/anchor_token/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-token" -version = "0.2.0" +version = "0.2.1" authors = ["Terraform Labs, PTE."] edition = "2018" description = "Common helpers for other anchor-token specs" diff --git a/packages/anchor_token/src/collector.rs b/packages/anchor_token/src/collector.rs index 51d3a6c..7f98eb3 100644 --- a/packages/anchor_token/src/collector.rs +++ b/packages/anchor_token/src/collector.rs @@ -47,4 +47,6 @@ pub struct ConfigResponse { /// We currently take no arguments for migrations #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MigrateMsg {} +pub struct MigrateMsg { + pub astroport_factory: String +} From 22d350456e1346d7388965c3488cd11aabe9e265 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Mon, 27 Dec 2021 18:53:35 +0900 Subject: [PATCH 09/17] fix: fix format issue --- contracts/collector/src/contract.rs | 5 ++++- contracts/collector/src/migration.rs | 5 ++++- packages/anchor_token/src/collector.rs | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index a56c618..f56e03d 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -233,7 +233,10 @@ pub fn query_config(deps: Deps) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { //migrate config - migrate_config(deps.storage, deps.api.addr_canonicalize(&msg.astroport_factory)?)?; + migrate_config( + deps.storage, + deps.api.addr_canonicalize(&msg.astroport_factory)?, + )?; Ok(Response::default()) } diff --git a/contracts/collector/src/migration.rs b/contracts/collector/src/migration.rs index f1058cc..d4c15cd 100644 --- a/contracts/collector/src/migration.rs +++ b/contracts/collector/src/migration.rs @@ -18,7 +18,10 @@ fn read_legacy_config(storage: &dyn Storage) -> StdResult { ReadonlySingleton::new(storage, KEY_CONFIG).load() } -pub fn migrate_config(storage: &mut dyn Storage, astroport_factory: CanonicalAddr) -> StdResult<()> { +pub fn migrate_config( + storage: &mut dyn Storage, + astroport_factory: CanonicalAddr, +) -> StdResult<()> { let legacy_config: LegacyConfig = read_legacy_config(storage)?; store_config( diff --git a/packages/anchor_token/src/collector.rs b/packages/anchor_token/src/collector.rs index 7f98eb3..7bd60ab 100644 --- a/packages/anchor_token/src/collector.rs +++ b/packages/anchor_token/src/collector.rs @@ -48,5 +48,5 @@ pub struct ConfigResponse { /// We currently take no arguments for migrations #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct MigrateMsg { - pub astroport_factory: String + pub astroport_factory: String, } From bf84043e9a21b4e253e1fc13592cfe6247bf8836 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Tue, 28 Dec 2021 16:09:29 +0900 Subject: [PATCH 10/17] fix: update the update-config logic of staking contracts --- contracts/staking/src/contract.rs | 131 +++++----------- contracts/staking/src/testing.rs | 224 +++++++++++++++++++++++---- packages/anchor_token/src/staking.rs | 4 +- 3 files changed, 233 insertions(+), 126 deletions(-) diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 8b5ea7a..3e8acc3 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -217,63 +217,12 @@ pub fn update_config( return Err(StdError::generic_err("unauthorized")); } - let mut new_distribution: Vec<(u64, u64, Uint128)> = vec![]; - - for s in config.distribution_schedule.clone().into_iter() { - let mut found = false; - for distribution in distribution_schedule.clone().into_iter() { - if distribution.0 > s.0 && distribution.1 < s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); - } - if s.0 == distribution.0 && distribution.1 != s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); - } - if s.0 != distribution.0 && distribution.1 == s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); - } - if distribution.0 <= state.last_distributed && state.last_distributed <= distribution.1 - { - return Err(StdError::generic_err("cannot update the ongoing schedule")); - } - if distribution.0 <= state.last_distributed && state.last_distributed >= distribution.1 - { - return Err(StdError::generic_err("cannot update a previous schedule")); - } - if s.0 == distribution.0 && distribution.1 == s.1 { - found = true; - new_distribution.push(distribution); - continue; - } - } - if !found { - new_distribution.push(s); - } - } - - for distribution in distribution_schedule { - let mut bigger = false; - for s in config.distribution_schedule.clone().into_iter() { - if distribution.0 >= s.1 { - bigger = true; - } else { - bigger = false; - } - } - if bigger { - new_distribution.push(distribution) - } - } + assert_new_schedules(&config, &state, distribution_schedule.clone())?; let new_config = Config { anchor_token: config.anchor_token, staking_token: config.staking_token, - distribution_schedule: new_distribution, + distribution_schedule, }; store_config(deps.storage, &new_config)?; @@ -467,45 +416,43 @@ pub fn query_staker_info( }) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { - let mut config = read_config(deps.storage)?; - config.distribution_schedule = msg.distribution_schedule; - store_config(deps.storage, &config)?; - - Ok(Response::default()) +pub fn assert_new_schedules( + config: &Config, + state: &State, + distribution_schedule: Vec<(u64, u64, Uint128)>, +) -> StdResult<()> { + if distribution_schedule.len() < config.distribution_schedule.len() { + return Err(StdError::generic_err( + "cannot update; the new schedule must support all of the previous schedule", + )); + } + for schedule in distribution_schedule { + for s in config.distribution_schedule.clone() { + if schedule.0 > s.0 && schedule.1 < s.1 { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if (s.0 == schedule.0 && schedule.1 != s.1) || (s.0 != schedule.0 && schedule.1 == s.1) + { + return Err(StdError::generic_err( + "cannot update the overlapped distribution", + )); + } + if schedule.0 == s.0 && schedule.1 == s.1 && schedule.2 != s.2 { + if schedule.0 <= state.last_distributed && state.last_distributed <= schedule.1 { + return Err(StdError::generic_err("cannot update the ongoing schedule")); + } + if schedule.0 <= state.last_distributed && state.last_distributed >= schedule.1 { + return Err(StdError::generic_err("cannot update a previous schedule")); + } + } + } + } + Ok(()) } -#[cfg(test)] -mod test { - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - - #[test] - fn proper_migrate() { - let mut deps = mock_dependencies(&[]); - - // init the contract - let init_msg = InstantiateMsg { - anchor_token: "anchor_token".to_string(), - staking_token: "staking".to_string(), - distribution_schedule: vec![(50, 1000, Uint128::new(50000000u128))], - }; - - let info = mock_info("sender", &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, init_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - let distribution_schedule = vec![(300000, 800000, Uint128::new(50000000u128))]; - - // migrate - let migrate_msg = MigrateMsg { - distribution_schedule: distribution_schedule.clone(), - }; - let res = migrate(deps.as_mut(), mock_env(), migrate_msg).unwrap(); - assert_eq!(res, Response::default()); - - let config = read_config(&deps.storage).unwrap(); - assert_eq!(config.distribution_schedule, distribution_schedule); - } +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { + Ok(Response::default()) } diff --git a/contracts/staking/src/testing.rs b/contracts/staking/src/testing.rs index 1ad4db2..ad9380a 100644 --- a/contracts/staking/src/testing.rs +++ b/contracts/staking/src/testing.rs @@ -551,7 +551,7 @@ fn test_migrate_staking() { } #[test] -fn test_update_global_index() { +fn test_update_config() { let mut deps = mock_dependencies(&[]); let msg = InstantiateMsg { @@ -608,11 +608,33 @@ fn test_update_global_index() { //update the overlapped schedule let update_config = UpdateConfig { - distribution_schedule: vec![( - mock_env().block.time.seconds() + 250, - mock_env().block.time.seconds() + 300, - Uint128::from(10000000u128), - )], + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 250, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -628,11 +650,33 @@ fn test_update_global_index() { //update the overlapped schedule let update_config = UpdateConfig { - distribution_schedule: vec![( - mock_env().block.time.seconds() + 250, - mock_env().block.time.seconds() + 299, - Uint128::from(10000000u128), - )], + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 250, + mock_env().block.time.seconds() + 299, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -677,11 +721,33 @@ fn test_update_global_index() { ); let update_config = UpdateConfig { - distribution_schedule: vec![( - mock_env().block.time.seconds(), - mock_env().block.time.seconds() + 100, - Uint128::from(10000000u128), - )], + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(5000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -716,11 +782,33 @@ fn test_update_global_index() { //cannot update previous scehdule let update_config = UpdateConfig { - distribution_schedule: vec![( - mock_env().block.time.seconds(), - mock_env().block.time.seconds() + 100, - Uint128::from(10000000u128), - )], + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(5000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -736,11 +824,33 @@ fn test_update_global_index() { //successful one let update_config = UpdateConfig { - distribution_schedule: vec![( - mock_env().block.time.seconds() + 300, - mock_env().block.time.seconds() + 400, - Uint128::from(20000000u128), - )], + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(20000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(10000000u128), + ), + ], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -786,11 +896,33 @@ fn test_update_global_index() { //successful one let update_config = UpdateConfig { - distribution_schedule: vec![( - mock_env().block.time.seconds() + 400, - mock_env().block.time.seconds() + 500, - Uint128::from(50000000u128), - )], + distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 300, + mock_env().block.time.seconds() + 400, + Uint128::from(20000000u128), + ), + ( + mock_env().block.time.seconds() + 400, + mock_env().block.time.seconds() + 500, + Uint128::from(50000000u128), + ), + ], }; deps.querier.with_anc_minter("gov0000".to_string()); @@ -836,6 +968,21 @@ fn test_update_global_index() { let update_config = UpdateConfig { distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), ( mock_env().block.time.seconds() + 300, mock_env().block.time.seconds() + 400, @@ -892,6 +1039,21 @@ fn test_update_global_index() { let update_config = UpdateConfig { distribution_schedule: vec![ + ( + mock_env().block.time.seconds(), + mock_env().block.time.seconds() + 100, + Uint128::from(1000000u128), + ), + ( + mock_env().block.time.seconds() + 100, + mock_env().block.time.seconds() + 200, + Uint128::from(10000000u128), + ), + ( + mock_env().block.time.seconds() + 200, + mock_env().block.time.seconds() + 300, + Uint128::from(10000000u128), + ), ( mock_env().block.time.seconds() + 300, mock_env().block.time.seconds() + 400, diff --git a/packages/anchor_token/src/staking.rs b/packages/anchor_token/src/staking.rs index 60c200d..f3089f5 100644 --- a/packages/anchor_token/src/staking.rs +++ b/packages/anchor_token/src/staking.rs @@ -39,9 +39,7 @@ pub enum Cw20HookMsg { /// migrate struct for distribution schedule /// block-based schedule to a time-based schedule #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MigrateMsg { - pub distribution_schedule: Vec<(u64, u64, Uint128)>, -} +pub struct MigrateMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] From 735c91fbed458900938533f1c599c40697e84474 Mon Sep 17 00:00:00 2001 From: Alwin Peng Date: Tue, 28 Dec 2021 03:12:28 -0500 Subject: [PATCH 11/17] upd assert_new_schedules --- contracts/staking/src/contract.rs | 47 +++++++++++++++++++------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 3e8acc3..e8f44aa 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -20,6 +20,7 @@ use crate::{ }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; +use std::collections::BTreeMap; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -426,27 +427,37 @@ pub fn assert_new_schedules( "cannot update; the new schedule must support all of the previous schedule", )); } - for schedule in distribution_schedule { - for s in config.distribution_schedule.clone() { - if schedule.0 > s.0 && schedule.1 < s.1 { - return Err(StdError::generic_err( - "cannot update the overlapped distribution", - )); - } - if (s.0 == schedule.0 && schedule.1 != s.1) || (s.0 != schedule.0 && schedule.1 == s.1) - { + + let mut existing_counts: BTreeMap<(u64, u64, Uint128), u32> = BTreeMap::new(); + for schedule in config.distribution_schedule.clone() { + let counter = existing_counts.entry(schedule).or_insert(0); + *counter += 1; + } + + let mut new_counts: BTreeMap<(u64, u64, Uint128), u32> = BTreeMap::new(); + for schedule in distribution_schedule.clone() { + let counter = new_counts.entry(schedule).or_insert(0); + *counter += 1; + } + + for (schedule, count) in existing_counts.into_iter() { + // if began ensure its in the new schedule + if schedule.0 <= state.last_distributed { + if count > *new_counts.get(&schedule).unwrap_or(&0u32) { return Err(StdError::generic_err( - "cannot update the overlapped distribution", + "new schedule removes already started distribution", )); } - if schedule.0 == s.0 && schedule.1 == s.1 && schedule.2 != s.2 { - if schedule.0 <= state.last_distributed && state.last_distributed <= schedule.1 { - return Err(StdError::generic_err("cannot update the ongoing schedule")); - } - if schedule.0 <= state.last_distributed && state.last_distributed >= schedule.1 { - return Err(StdError::generic_err("cannot update a previous schedule")); - } - } + // after this new_counts will only contain the newly added schedules + *new_counts.get_mut(&schedule).unwrap() -= count; + } + } + + for (schedule, count) in new_counts.into_iter() { + if count > 0 && schedule.0 <= state.last_distributed { + return Err(StdError::generic_err( + "new schedule adds an already started distribution", + )); } } Ok(()) From 160e8b5d1fb49cdb19fda2cbf989d142f0f539be Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Tue, 28 Dec 2021 17:45:38 +0900 Subject: [PATCH 12/17] fix: change tests to new logic --- contracts/staking/src/testing.rs | 87 +------------------------------- 1 file changed, 2 insertions(+), 85 deletions(-) diff --git a/contracts/staking/src/testing.rs b/contracts/staking/src/testing.rs index ad9380a..f75bdaf 100644 --- a/contracts/staking/src/testing.rs +++ b/contracts/staking/src/testing.rs @@ -606,89 +606,6 @@ fn test_update_config() { _ => panic!("Must return unauthorized error"), } - //update the overlapped schedule - let update_config = UpdateConfig { - distribution_schedule: vec![ - ( - mock_env().block.time.seconds(), - mock_env().block.time.seconds() + 100, - Uint128::from(1000000u128), - ), - ( - mock_env().block.time.seconds() + 100, - mock_env().block.time.seconds() + 200, - Uint128::from(10000000u128), - ), - ( - mock_env().block.time.seconds() + 250, - mock_env().block.time.seconds() + 300, - Uint128::from(10000000u128), - ), - ( - mock_env().block.time.seconds() + 300, - mock_env().block.time.seconds() + 400, - Uint128::from(10000000u128), - ), - ( - mock_env().block.time.seconds() + 400, - mock_env().block.time.seconds() + 500, - Uint128::from(10000000u128), - ), - ], - }; - - deps.querier.with_anc_minter("gov0000".to_string()); - - let info = mock_info("gov0000", &[]); - let res = execute(deps.as_mut(), mock_env(), info, update_config); - match res { - Err(StdError::GenericErr { msg, .. }) => { - assert_eq!(msg, "cannot update the overlapped distribution") - } - _ => panic!("Must return unauthorized error"), - } - - //update the overlapped schedule - let update_config = UpdateConfig { - distribution_schedule: vec![ - ( - mock_env().block.time.seconds(), - mock_env().block.time.seconds() + 100, - Uint128::from(1000000u128), - ), - ( - mock_env().block.time.seconds() + 100, - mock_env().block.time.seconds() + 200, - Uint128::from(10000000u128), - ), - ( - mock_env().block.time.seconds() + 250, - mock_env().block.time.seconds() + 299, - Uint128::from(10000000u128), - ), - ( - mock_env().block.time.seconds() + 300, - mock_env().block.time.seconds() + 400, - Uint128::from(10000000u128), - ), - ( - mock_env().block.time.seconds() + 400, - mock_env().block.time.seconds() + 500, - Uint128::from(10000000u128), - ), - ], - }; - - deps.querier.with_anc_minter("gov0000".to_string()); - - let info = mock_info("gov0000", &[]); - let res = execute(deps.as_mut(), mock_env(), info, update_config); - match res { - Err(StdError::GenericErr { msg, .. }) => { - assert_eq!(msg, "cannot update the overlapped distribution") - } - _ => panic!("Must return unauthorized error"), - } // do some bond and update rewards // bond 100 tokens let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { @@ -756,7 +673,7 @@ fn test_update_config() { let res = execute(deps.as_mut(), mock_env(), info, update_config); match res { Err(StdError::GenericErr { msg, .. }) => { - assert_eq!(msg, "cannot update the ongoing schedule") + assert_eq!(msg, "new schedule removes already started distribution") } _ => panic!("Must return unauthorized error"), } @@ -817,7 +734,7 @@ fn test_update_config() { let res = execute(deps.as_mut(), mock_env(), info, update_config); match res { Err(StdError::GenericErr { msg, .. }) => { - assert_eq!(msg, "cannot update a previous schedule") + assert_eq!(msg, "new schedule removes already started distribution") } _ => panic!("Must return unauthorized error"), } From 766393fa3f0659b048401debb3bcf6a4f5d0dc8a Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Fri, 31 Dec 2021 14:10:40 +0900 Subject: [PATCH 13/17] fix: remove unnecessary distributer address from collector contract --- contracts/collector/src/contract.rs | 19 +------------------ contracts/collector/src/migration.rs | 1 - contracts/collector/src/state.rs | 7 +++---- contracts/collector/src/testing.rs | 10 ---------- packages/anchor_token/src/collector.rs | 3 --- 5 files changed, 4 insertions(+), 36 deletions(-) diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index f56e03d..0329d27 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -28,7 +28,6 @@ pub fn instantiate( gov_contract: deps.api.addr_canonicalize(&msg.gov_contract)?, astroport_factory: deps.api.addr_canonicalize(&msg.astroport_factory)?, anchor_token: deps.api.addr_canonicalize(&msg.anchor_token)?, - distributor_contract: deps.api.addr_canonicalize(&msg.distributor_contract)?, reward_factor: msg.reward_factor, }, )?; @@ -43,15 +42,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S reward_factor, gov_contract, astroport_factory, - distributor_contract, - } => update_config( - deps, - info, - reward_factor, - gov_contract, - astroport_factory, - distributor_contract, - ), + } => update_config(deps, info, reward_factor, gov_contract, astroport_factory), ExecuteMsg::Sweep { denom } => sweep(deps, env, denom), } } @@ -62,7 +53,6 @@ pub fn update_config( reward_factor: Option, gov_contract: Option, astroport_factory: Option, - distributor_contract: Option, ) -> StdResult { let mut config: Config = read_config(deps.storage)?; if deps.api.addr_canonicalize(info.sender.as_str())? != config.gov_contract { @@ -76,9 +66,6 @@ pub fn update_config( if let Some(gov_contract) = gov_contract { config.gov_contract = deps.api.addr_canonicalize(gov_contract.as_str())?; } - if let Some(distributor_contract) = distributor_contract { - config.distributor_contract = deps.api.addr_canonicalize(distributor_contract.as_str())?; - } if let Some(astroport_factory) = astroport_factory { config.astroport_factory = deps.api.addr_canonicalize(astroport_factory.as_str())?; } @@ -220,10 +207,6 @@ pub fn query_config(deps: Deps) -> StdResult { .addr_humanize(&state.astroport_factory)? .to_string(), anchor_token: deps.api.addr_humanize(&state.anchor_token)?.to_string(), - distributor_contract: deps - .api - .addr_humanize(&state.distributor_contract)? - .to_string(), reward_factor: state.reward_factor, }; diff --git a/contracts/collector/src/migration.rs b/contracts/collector/src/migration.rs index d4c15cd..fb57638 100644 --- a/contracts/collector/src/migration.rs +++ b/contracts/collector/src/migration.rs @@ -30,7 +30,6 @@ pub fn migrate_config( gov_contract: legacy_config.gov_contract, astroport_factory, anchor_token: legacy_config.anchor_token, - distributor_contract: legacy_config.distributor_contract, reward_factor: legacy_config.reward_factor, }, ) diff --git a/contracts/collector/src/state.rs b/contracts/collector/src/state.rs index a93d833..b637db6 100644 --- a/contracts/collector/src/state.rs +++ b/contracts/collector/src/state.rs @@ -8,10 +8,9 @@ pub static KEY_CONFIG: &[u8] = b"config"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Config { - pub gov_contract: CanonicalAddr, // collected rewards receiver - pub astroport_factory: CanonicalAddr, // astroport factory contract - pub anchor_token: CanonicalAddr, // anchor token address - pub distributor_contract: CanonicalAddr, // distributor contract to sent back rewards + pub gov_contract: CanonicalAddr, // collected rewards receiver + pub astroport_factory: CanonicalAddr, // astroport factory contract + pub anchor_token: CanonicalAddr, // anchor token address pub reward_factor: Decimal, // reward distribution rate to gov contract, left rewards sent back to distributor contract } diff --git a/contracts/collector/src/testing.rs b/contracts/collector/src/testing.rs index e5daf71..a040f09 100644 --- a/contracts/collector/src/testing.rs +++ b/contracts/collector/src/testing.rs @@ -18,7 +18,6 @@ fn proper_initialization() { astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), - distributor_contract: "distributor".to_string(), reward_factor: Decimal::percent(90), }; @@ -40,7 +39,6 @@ fn update_config() { astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), - distributor_contract: "distributor".to_string(), reward_factor: Decimal::percent(90), }; @@ -53,7 +51,6 @@ fn update_config() { reward_factor: Some(Decimal::percent(80)), gov_contract: Some("new_gov".to_string()), astroport_factory: Some("new_astroport_factory".to_string()), - distributor_contract: Some("new_distributor_contract".to_string()), }; let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); @@ -64,10 +61,6 @@ fn update_config() { assert_eq!(Decimal::percent(80), value.reward_factor); assert_eq!(value.astroport_factory, "new_astroport_factory".to_string()); assert_eq!(value.gov_contract, "new_gov".to_string()); - assert_eq!( - value.distributor_contract, - "new_distributor_contract".to_string() - ); // Unauthorized err let info = mock_info("addr0000", &[]); @@ -75,7 +68,6 @@ fn update_config() { reward_factor: None, gov_contract: Some("new_gov".to_string()), astroport_factory: Some("new_astroport_factory".to_string()), - distributor_contract: Some("new_distributor_contract".to_string()), }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -104,7 +96,6 @@ fn test_sweep() { astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), - distributor_contract: "distributor".to_string(), reward_factor: Decimal::percent(90), }; @@ -161,7 +152,6 @@ fn test_distribute() { astroport_factory: "astroportfactory".to_string(), gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), - distributor_contract: "distributor".to_string(), reward_factor: Decimal::percent(90), }; diff --git a/packages/anchor_token/src/collector.rs b/packages/anchor_token/src/collector.rs index 7bd60ab..bdfdb80 100644 --- a/packages/anchor_token/src/collector.rs +++ b/packages/anchor_token/src/collector.rs @@ -8,7 +8,6 @@ pub struct InstantiateMsg { pub gov_contract: String, // collected rewards receiver pub astroport_factory: String, pub anchor_token: String, - pub distributor_contract: String, pub reward_factor: Decimal, } @@ -21,7 +20,6 @@ pub enum ExecuteMsg { reward_factor: Option, gov_contract: Option, astroport_factory: Option, - distributor_contract: Option, }, /// Public Message /// Sweep all given denom balance to ANC token @@ -41,7 +39,6 @@ pub struct ConfigResponse { pub gov_contract: String, // collected rewards receiver pub astroport_factory: String, pub anchor_token: String, - pub distributor_contract: String, pub reward_factor: Decimal, } From 0130f7474254ec44fb242101704ea89ee85ac83f Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Wed, 5 Jan 2022 16:45:59 +0900 Subject: [PATCH 14/17] feat: add max_spread to swap function of collector --- .../collector/schema/config_response.json | 20 ++++++---- contracts/collector/schema/execute_msg.json | 39 ++++++++++++++++++- .../collector/schema/instantiate_msg.json | 20 ++++++---- contracts/collector/schema/query_msg.json | 2 +- contracts/collector/src/contract.rs | 20 +++++++++- contracts/collector/src/migration.rs | 2 + contracts/collector/src/state.rs | 1 + contracts/collector/src/testing.rs | 28 ++++++++++++- packages/anchor_token/src/collector.rs | 9 +++++ 9 files changed, 121 insertions(+), 20 deletions(-) diff --git a/contracts/collector/schema/config_response.json b/contracts/collector/schema/config_response.json index d90a5f3..ca829f4 100644 --- a/contracts/collector/schema/config_response.json +++ b/contracts/collector/schema/config_response.json @@ -4,26 +4,32 @@ "type": "object", "required": [ "anchor_token", - "distributor_contract", + "astroport_factory", "gov_contract", - "reward_factor", - "terraswap_factory" + "reward_factor" ], "properties": { "anchor_token": { "type": "string" }, - "distributor_contract": { + "astroport_factory": { "type": "string" }, "gov_contract": { "type": "string" }, + "max_spread": { + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, "reward_factor": { "$ref": "#/definitions/Decimal" - }, - "terraswap_factory": { - "type": "string" } }, "definitions": { diff --git a/contracts/collector/schema/execute_msg.json b/contracts/collector/schema/execute_msg.json index a378a88..5252e5f 100644 --- a/contracts/collector/schema/execute_msg.json +++ b/contracts/collector/schema/execute_msg.json @@ -1,9 +1,9 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "ExecuteMsg", - "anyOf": [ + "oneOf": [ { - "description": "Update config interface to enable reward_factor update", + "description": "Update config interface to enable reward_factor update ## NOTE: for updating `max spread` it should be either (true, none) or (true, \"0.1\") if we do not want to update it it should be (false, none)", "type": "object", "required": [ "update_config" @@ -11,7 +11,42 @@ "properties": { "update_config": { "type": "object", + "required": [ + "max_spread" + ], "properties": { + "astroport_factory": { + "type": [ + "string", + "null" + ] + }, + "gov_contract": { + "type": [ + "string", + "null" + ] + }, + "max_spread": { + "type": "array", + "items": [ + { + "type": "boolean" + }, + { + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + } + ], + "maxItems": 2, + "minItems": 2 + }, "reward_factor": { "anyOf": [ { diff --git a/contracts/collector/schema/instantiate_msg.json b/contracts/collector/schema/instantiate_msg.json index dc63611..d649f7a 100644 --- a/contracts/collector/schema/instantiate_msg.json +++ b/contracts/collector/schema/instantiate_msg.json @@ -4,26 +4,32 @@ "type": "object", "required": [ "anchor_token", - "distributor_contract", + "astroport_factory", "gov_contract", - "reward_factor", - "terraswap_factory" + "reward_factor" ], "properties": { "anchor_token": { "type": "string" }, - "distributor_contract": { + "astroport_factory": { "type": "string" }, "gov_contract": { "type": "string" }, + "max_spread": { + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, "reward_factor": { "$ref": "#/definitions/Decimal" - }, - "terraswap_factory": { - "type": "string" } }, "definitions": { diff --git a/contracts/collector/schema/query_msg.json b/contracts/collector/schema/query_msg.json index 6392c2a..3df1ec1 100644 --- a/contracts/collector/schema/query_msg.json +++ b/contracts/collector/schema/query_msg.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "QueryMsg", - "anyOf": [ + "oneOf": [ { "type": "object", "required": [ diff --git a/contracts/collector/src/contract.rs b/contracts/collector/src/contract.rs index 0329d27..ac21c11 100644 --- a/contracts/collector/src/contract.rs +++ b/contracts/collector/src/contract.rs @@ -29,6 +29,7 @@ pub fn instantiate( astroport_factory: deps.api.addr_canonicalize(&msg.astroport_factory)?, anchor_token: deps.api.addr_canonicalize(&msg.anchor_token)?, reward_factor: msg.reward_factor, + max_spread: msg.max_spread, }, )?; @@ -42,7 +43,15 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S reward_factor, gov_contract, astroport_factory, - } => update_config(deps, info, reward_factor, gov_contract, astroport_factory), + max_spread, + } => update_config( + deps, + info, + reward_factor, + gov_contract, + astroport_factory, + max_spread, + ), ExecuteMsg::Sweep { denom } => sweep(deps, env, denom), } } @@ -53,6 +62,7 @@ pub fn update_config( reward_factor: Option, gov_contract: Option, astroport_factory: Option, + max_spread: (bool, Option), ) -> StdResult { let mut config: Config = read_config(deps.storage)?; if deps.api.addr_canonicalize(info.sender.as_str())? != config.gov_contract { @@ -70,6 +80,10 @@ pub fn update_config( config.astroport_factory = deps.api.addr_canonicalize(astroport_factory.as_str())?; } + if max_spread.0 { + config.max_spread = max_spread.1 + } + store_config(deps.storage, &config)?; Ok(Response::default()) } @@ -118,7 +132,7 @@ pub fn sweep(deps: DepsMut, env: Env, denom: String) -> StdResult { amount, ..swap_asset }, - max_spread: None, + max_spread: config.max_spread, belief_price: None, to: None, })?, @@ -208,6 +222,7 @@ pub fn query_config(deps: Deps) -> StdResult { .to_string(), anchor_token: deps.api.addr_humanize(&state.anchor_token)?.to_string(), reward_factor: state.reward_factor, + max_spread: state.max_spread, }; Ok(resp) @@ -219,6 +234,7 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult migrate_config( deps.storage, deps.api.addr_canonicalize(&msg.astroport_factory)?, + msg.max_spread, )?; Ok(Response::default()) diff --git a/contracts/collector/src/migration.rs b/contracts/collector/src/migration.rs index fb57638..cbfb7cb 100644 --- a/contracts/collector/src/migration.rs +++ b/contracts/collector/src/migration.rs @@ -21,6 +21,7 @@ fn read_legacy_config(storage: &dyn Storage) -> StdResult { pub fn migrate_config( storage: &mut dyn Storage, astroport_factory: CanonicalAddr, + max_spread: Decimal, ) -> StdResult<()> { let legacy_config: LegacyConfig = read_legacy_config(storage)?; @@ -31,6 +32,7 @@ pub fn migrate_config( astroport_factory, anchor_token: legacy_config.anchor_token, reward_factor: legacy_config.reward_factor, + max_spread: Some(max_spread), }, ) } diff --git a/contracts/collector/src/state.rs b/contracts/collector/src/state.rs index b637db6..9de01a8 100644 --- a/contracts/collector/src/state.rs +++ b/contracts/collector/src/state.rs @@ -12,6 +12,7 @@ pub struct Config { pub astroport_factory: CanonicalAddr, // astroport factory contract pub anchor_token: CanonicalAddr, // anchor token address pub reward_factor: Decimal, // reward distribution rate to gov contract, left rewards sent back to distributor contract + pub max_spread: Option, // max spread for buybacks } pub fn store_config(storage: &mut dyn Storage, config: &Config) -> StdResult<()> { diff --git a/contracts/collector/src/testing.rs b/contracts/collector/src/testing.rs index a040f09..5fc2996 100644 --- a/contracts/collector/src/testing.rs +++ b/contracts/collector/src/testing.rs @@ -19,6 +19,7 @@ fn proper_initialization() { gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), reward_factor: Decimal::percent(90), + max_spread: Default::default(), }; let info = mock_info("addr0000", &[]); @@ -40,6 +41,7 @@ fn update_config() { gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), reward_factor: Decimal::percent(90), + max_spread: Default::default(), }; let info = mock_info("addr0000", &[]); @@ -51,6 +53,7 @@ fn update_config() { reward_factor: Some(Decimal::percent(80)), gov_contract: Some("new_gov".to_string()), astroport_factory: Some("new_astroport_factory".to_string()), + max_spread: (true, Some(Decimal::percent(10))), }; let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); @@ -61,6 +64,26 @@ fn update_config() { assert_eq!(Decimal::percent(80), value.reward_factor); assert_eq!(value.astroport_factory, "new_astroport_factory".to_string()); assert_eq!(value.gov_contract, "new_gov".to_string()); + assert_eq!(value.max_spread, Some(Decimal::percent(10))); + + // test max spread update + let info = mock_info("new_gov", &[]); + let msg = ExecuteMsg::UpdateConfig { + reward_factor: None, + gov_contract: None, + astroport_factory: None, + max_spread: (true, None), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // it worked, let's query the state + let value = query_config(deps.as_ref()).unwrap(); + assert_eq!(Decimal::percent(80), value.reward_factor); + assert_eq!(value.astroport_factory, "new_astroport_factory".to_string()); + assert_eq!(value.gov_contract, "new_gov".to_string()); + assert_eq!(value.max_spread, None); // Unauthorized err let info = mock_info("addr0000", &[]); @@ -68,6 +91,7 @@ fn update_config() { reward_factor: None, gov_contract: Some("new_gov".to_string()), astroport_factory: Some("new_astroport_factory".to_string()), + max_spread: (false, None), }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -97,6 +121,7 @@ fn test_sweep() { gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), reward_factor: Decimal::percent(90), + max_spread: Some(Decimal::percent(10)), }; let info = mock_info("addr0000", &[]); @@ -121,7 +146,7 @@ fn test_sweep() { }, amount: Uint128::from(99u128), }, - max_spread: None, + max_spread: Some(Decimal::percent(10)), belief_price: None, to: None, }) @@ -153,6 +178,7 @@ fn test_distribute() { gov_contract: "gov".to_string(), anchor_token: "tokenANC".to_string(), reward_factor: Decimal::percent(90), + max_spread: Some(Decimal::percent(10)), }; let info = mock_info("addr0000", &[]); diff --git a/packages/anchor_token/src/collector.rs b/packages/anchor_token/src/collector.rs index bdfdb80..5ee85ce 100644 --- a/packages/anchor_token/src/collector.rs +++ b/packages/anchor_token/src/collector.rs @@ -9,6 +9,7 @@ pub struct InstantiateMsg { pub astroport_factory: String, pub anchor_token: String, pub reward_factor: Decimal, + pub max_spread: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -16,10 +17,16 @@ pub struct InstantiateMsg { pub enum ExecuteMsg { /// Update config interface /// to enable reward_factor update + /// ## NOTE: + /// for updating `max spread` + /// it should be either (true, none) or (true, "0.1") + /// if we do not want to update it + /// it should be (false, none) UpdateConfig { reward_factor: Option, gov_contract: Option, astroport_factory: Option, + max_spread: (bool, Option), }, /// Public Message /// Sweep all given denom balance to ANC token @@ -40,10 +47,12 @@ pub struct ConfigResponse { pub astroport_factory: String, pub anchor_token: String, pub reward_factor: Decimal, + pub max_spread: Option, } /// We currently take no arguments for migrations #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct MigrateMsg { pub astroport_factory: String, + pub max_spread: Decimal, } From e78f2571d390bcc7bdc1688973df9fcffcabb66f Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Fri, 7 Jan 2022 16:11:57 +0900 Subject: [PATCH 15/17] release: release 0.3.0 alpha --- packages/anchor_token/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/anchor_token/Cargo.toml b/packages/anchor_token/Cargo.toml index a75b43c..a73c12b 100644 --- a/packages/anchor_token/Cargo.toml +++ b/packages/anchor_token/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-token" -version = "0.2.1" +version = "0.3.0-alpha.1" authors = ["Terraform Labs, PTE."] edition = "2018" description = "Common helpers for other anchor-token specs" From 5e11ce0e6ac7e0b2821572f9ba4a96f4af065183 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Fri, 7 Jan 2022 16:25:09 +0900 Subject: [PATCH 16/17] fix: fix the version of anchor token in all contracts --- contracts/airdrop/Cargo.toml | 2 +- contracts/collector/Cargo.toml | 2 +- contracts/community/Cargo.toml | 2 +- contracts/distributor/Cargo.toml | 2 +- contracts/gov/Cargo.toml | 2 +- contracts/staking/Cargo.toml | 2 +- contracts/vesting/Cargo.toml | 2 +- packages/anchor_token/Cargo.toml | 1 + 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/contracts/airdrop/Cargo.toml b/contracts/airdrop/Cargo.toml index 60d62b3..454ebbe 100644 --- a/contracts/airdrop/Cargo.toml +++ b/contracts/airdrop/Cargo.toml @@ -34,7 +34,7 @@ overflow-checks = true backtraces = ["cosmwasm-std/backtraces"] [dependencies] -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } cw20 = { version = "0.8.0" } diff --git a/contracts/collector/Cargo.toml b/contracts/collector/Cargo.toml index 48b6abd..0358a0c 100644 --- a/contracts/collector/Cargo.toml +++ b/contracts/collector/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.2.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } terra-cosmwasm = "2.2.0" astroport = "0.3.1" schemars = "0.8.1" diff --git a/contracts/community/Cargo.toml b/contracts/community/Cargo.toml index 847e810..176cf0f 100644 --- a/contracts/community/Cargo.toml +++ b/contracts/community/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/distributor/Cargo.toml b/contracts/distributor/Cargo.toml index 84abef6..66b0ace 100644 --- a/contracts/distributor/Cargo.toml +++ b/contracts/distributor/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/gov/Cargo.toml b/contracts/gov/Cargo.toml index 2a08d7f..a582e9b 100644 --- a/contracts/gov/Cargo.toml +++ b/contracts/gov/Cargo.toml @@ -38,7 +38,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0", features = ["iterator"] } cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } astroport = "0.3.1" diff --git a/contracts/staking/Cargo.toml b/contracts/staking/Cargo.toml index 18414a1..0645fd2 100644 --- a/contracts/staking/Cargo.toml +++ b/contracts/staking/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0", features = ["iterator"] } cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/vesting/Cargo.toml b/contracts/vesting/Cargo.toml index 972c508..2bd7a95 100644 --- a/contracts/vesting/Cargo.toml +++ b/contracts/vesting/Cargo.toml @@ -29,7 +29,7 @@ cosmwasm-std = { version = "0.16.0", features = ["iterator"] } cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -anchor-token = { version = "0.2.0", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } [dev-dependencies] cosmwasm-schema = { version = "0.16.0", default-features = false } diff --git a/packages/anchor_token/Cargo.toml b/packages/anchor_token/Cargo.toml index a73c12b..0aa3e41 100644 --- a/packages/anchor_token/Cargo.toml +++ b/packages/anchor_token/Cargo.toml @@ -21,6 +21,7 @@ cw20 = { version = "0.8.0" } cosmwasm-bignumber = "2.2.0" cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } +anchor-token = "0.3.0-alpha.1" terra-cosmwasm = "2.2.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } From a7fb3f9177aae4fed8f3c9bab6370fbd5e6896d7 Mon Sep 17 00:00:00 2001 From: MSNTCS Date: Wed, 12 Jan 2022 15:22:41 +0900 Subject: [PATCH 17/17] chore: update changelog --- CHANGELOG.md | 4 +++- contracts/airdrop/Cargo.toml | 2 +- contracts/collector/Cargo.toml | 2 +- contracts/community/Cargo.toml | 2 +- contracts/distributor/Cargo.toml | 2 +- contracts/gov/Cargo.toml | 2 +- contracts/staking/Cargo.toml | 2 +- contracts/vesting/Cargo.toml | 2 +- packages/anchor_token/Cargo.toml | 5 ++--- 9 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83ab984..770b7e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ -## 0.2.0 +## 0.3.0 +Astroport support for collector and staking contracts. +## 0.2.0 Columbus-5 upgrade compatible version release. diff --git a/contracts/airdrop/Cargo.toml b/contracts/airdrop/Cargo.toml index 454ebbe..f03fbfb 100644 --- a/contracts/airdrop/Cargo.toml +++ b/contracts/airdrop/Cargo.toml @@ -34,7 +34,7 @@ overflow-checks = true backtraces = ["cosmwasm-std/backtraces"] [dependencies] -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } cw20 = { version = "0.8.0" } diff --git a/contracts/collector/Cargo.toml b/contracts/collector/Cargo.toml index 0358a0c..240e563 100644 --- a/contracts/collector/Cargo.toml +++ b/contracts/collector/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } terra-cosmwasm = "2.2.0" astroport = "0.3.1" schemars = "0.8.1" diff --git a/contracts/community/Cargo.toml b/contracts/community/Cargo.toml index 176cf0f..9950cbf 100644 --- a/contracts/community/Cargo.toml +++ b/contracts/community/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/distributor/Cargo.toml b/contracts/distributor/Cargo.toml index 66b0ace..8176096 100644 --- a/contracts/distributor/Cargo.toml +++ b/contracts/distributor/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/gov/Cargo.toml b/contracts/gov/Cargo.toml index a582e9b..4426d09 100644 --- a/contracts/gov/Cargo.toml +++ b/contracts/gov/Cargo.toml @@ -38,7 +38,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0", features = ["iterator"] } cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } astroport = "0.3.1" diff --git a/contracts/staking/Cargo.toml b/contracts/staking/Cargo.toml index 0645fd2..30aa628 100644 --- a/contracts/staking/Cargo.toml +++ b/contracts/staking/Cargo.toml @@ -37,7 +37,7 @@ backtraces = ["cosmwasm-std/backtraces"] cw20 = { version = "0.8.0" } cosmwasm-std = { version = "0.16.0", features = ["iterator"] } cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/vesting/Cargo.toml b/contracts/vesting/Cargo.toml index 2bd7a95..cc0f297 100644 --- a/contracts/vesting/Cargo.toml +++ b/contracts/vesting/Cargo.toml @@ -29,7 +29,7 @@ cosmwasm-std = { version = "0.16.0", features = ["iterator"] } cosmwasm-storage = { version = "0.16.0", features = ["iterator"] } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -anchor-token = { version = "0.3.0-alpha.1", path = "../../packages/anchor_token" } +anchor-token = { version = "0.3.0", path = "../../packages/anchor_token" } [dev-dependencies] cosmwasm-schema = { version = "0.16.0", default-features = false } diff --git a/packages/anchor_token/Cargo.toml b/packages/anchor_token/Cargo.toml index 0aa3e41..e0bf0cd 100644 --- a/packages/anchor_token/Cargo.toml +++ b/packages/anchor_token/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-token" -version = "0.3.0-alpha.1" +version = "0.3.0" authors = ["Terraform Labs, PTE."] edition = "2018" description = "Common helpers for other anchor-token specs" @@ -21,8 +21,7 @@ cw20 = { version = "0.8.0" } cosmwasm-bignumber = "2.2.0" cosmwasm-std = { version = "0.16.0" } cosmwasm-storage = { version = "0.16.0" } -anchor-token = "0.3.0-alpha.1" -terra-cosmwasm = "2.2.0" +terra-cosmwasm = "2.2.0" schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] }