From 5990598905405b9e239eb3785d0c90d0ece506dc Mon Sep 17 00:00:00 2001 From: codchen Date: Wed, 20 Nov 2024 15:04:47 +0800 Subject: [PATCH] update --- src/contract.rs | 209 ++++++++++++++++++++++++++++++------------ src/data_structure.rs | 113 ++++++++++++++--------- src/vesting.rs | 47 +++++++--- 3 files changed, 257 insertions(+), 112 deletions(-) diff --git a/src/contract.rs b/src/contract.rs index 97ff3e0..f9ea0b1 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -1,7 +1,9 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - coins, to_binary, Addr, BankMsg, Binary, BlockInfo, CosmosMsg, Decimal, Delegation, Deps, DepsMut, Empty, Env, GovMsg, MessageInfo, Order, Response, StdError, StdResult, Timestamp, VoteOption, WasmMsg + coins, to_binary, Addr, BankMsg, Binary, BlockInfo, CosmosMsg, Decimal, Delegation, Deps, + DepsMut, Empty, Env, GovMsg, MessageInfo, Order, Response, StdError, StdResult, Timestamp, + VoteOption, WasmMsg, }; use cw2::set_contract_version; use cw3::{ @@ -13,8 +15,8 @@ use cw_utils::{Threshold, ThresholdError}; use crate::data_structure::EmptyStruct; use crate::error::ContractError; use crate::msg::{ - AdminListResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, OpListResponse, QueryMsg, ShowConfigResponse, - ShowInfoResponse, ShowTotalVestedResponse + AdminListResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, OpListResponse, QueryMsg, + ShowConfigResponse, ShowInfoResponse, ShowTotalVestedResponse, }; use crate::permission::{authorize_admin, authorize_op, authorize_self_call}; use crate::staking::{ @@ -23,9 +25,9 @@ use crate::staking::{ }; use crate::state::{ get_number_of_admins, next_proposal_id, ADMINS, ADMIN_VOTING_THRESHOLD, BALLOTS, DENOM, - MAX_VOTING_PERIOD, OPS, PROPOSALS, STAKING_REWARD_ADDRESS, UNLOCK_DISTRIBUTION_ADDRESS, - VESTING_AMOUNTS, VESTING_TIMESTAMPS, WITHDRAWN_LOCKED, WITHDRAWN_STAKING_REWARDS, - WITHDRAWN_UNLOCKED, TOTAL_AMOUNT, + MAX_VOTING_PERIOD, OPS, PROPOSALS, STAKING_REWARD_ADDRESS, TOTAL_AMOUNT, + UNLOCK_DISTRIBUTION_ADDRESS, VESTING_AMOUNTS, VESTING_TIMESTAMPS, WITHDRAWN_LOCKED, + WITHDRAWN_STAKING_REWARDS, WITHDRAWN_UNLOCKED, }; use crate::vesting::{collect_vested, distribute_vested, total_vested_amount}; use semver::Version; @@ -55,11 +57,7 @@ pub fn validate_migration( // NOTE: New migrations may need store migrations if store changes are being made #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate( - deps: DepsMut, - env: Env, - _msg: MigrateMsg, -) -> Result { +pub fn migrate(deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result { validate_migration(deps.as_ref(), CONTRACT_NAME, CONTRACT_VERSION)?; // set the new version @@ -77,7 +75,9 @@ pub fn migrate( } fn migrate_105_handler(deps: DepsMut, env: Env) -> Result { - if env.contract.address.as_str() == "sei1w0fvamykx7v2e6n5x0e2s39m0jz3krejjkpmgc3tmnqdf8p9fy5syg05yv" { + if env.contract.address.as_str() + == "sei1w0fvamykx7v2e6n5x0e2s39m0jz3krejjkpmgc3tmnqdf8p9fy5syg05yv" + { let timestamps: Vec = vec![ Timestamp::from_nanos(1726358400000000000), Timestamp::from_nanos(1728950400000000000), @@ -120,7 +120,9 @@ fn migrate_105_handler(deps: DepsMut, env: Env) -> Result = vec![ Timestamp::from_nanos(1726358400000000000), Timestamp::from_nanos(1728950400000000000), @@ -194,9 +196,11 @@ fn migrate_105_handler(deps: DepsMut, env: Env) -> Result Result { // foundation - if env.contract.address.as_str() == "sei19se8ass0qvpa2cc60ehnv5dtccznnn5m505cug5tg2gwsjqw5drqm5ptnx" { + if env.contract.address.as_str() + == "sei19se8ass0qvpa2cc60ehnv5dtccznnn5m505cug5tg2gwsjqw5drqm5ptnx" + { let total_amount = 700_000_000_000_000_u128; // 700M SEI - TOTAL_AMOUNT.save(deps.storage, &total_amount)?; + TOTAL_AMOUNT.save(deps.storage, &total_amount)?; let total_delegations = 530871446501692_u128; let withdrawn_unlocked = 139962026461886_u128; let principal_in_bank = total_amount - withdrawn_unlocked - total_delegations; @@ -210,6 +214,21 @@ fn migrate_109_handler(deps: DepsMut, env: Env) -> Result Result { Ok(old + delta) })?; + } else if env.contract.address.as_str() + == "sei18qgau4n88tdaxu9y2t2y2px29yvwp50mk4xctp7grwfj7fkcdn8qvs9ry8" + { + let total_amount = 1_700_000_000_000_000_u128; // 1700M SEI + TOTAL_AMOUNT.save(deps.storage, &total_amount)?; + } else if env.contract.address.as_str() + == "sei1w0fvamykx7v2e6n5x0e2s39m0jz3krejjkpmgc3tmnqdf8p9fy5syg05yv" + { + let total_amount = 800_000_000_000_000_u128; // 800M SEI + TOTAL_AMOUNT.save(deps.storage, &total_amount)?; + } else if env.contract.address.as_str() + == "sei1letzrrlgdlrpxj6z279fx85hn5u34mm9nrc9hq4e6wxz5c79je2swt6x4a" + { + let total_amount = 1_200_000_000_000_000_u128; // 1200M SEI + TOTAL_AMOUNT.save(deps.storage, &total_amount)?; } Ok(Response::default()) } @@ -244,7 +263,8 @@ pub fn instantiate( DENOM.save(deps.storage, &msg.tranche.denom)?; VESTING_TIMESTAMPS.save(deps.storage, &msg.tranche.vesting_timestamps)?; VESTING_AMOUNTS.save(deps.storage, &msg.tranche.vesting_amounts)?; - TOTAL_AMOUNT.save(deps.storage, msg.tranche.vesting_amounts.iter().sum())?; + let total: u128 = msg.tranche.vesting_amounts.iter().sum(); + TOTAL_AMOUNT.save(deps.storage, &total)?; UNLOCK_DISTRIBUTION_ADDRESS.save( deps.storage, &msg.tranche.unlocked_token_distribution_address, @@ -293,18 +313,29 @@ pub fn execute( ExecuteMsg::ProposeUpdateAdmin { admin, remove } => { execute_propose_update_admin(deps, env, info, admin, remove) } - ExecuteMsg::ProposeUpdateUnlockedDistributionAddress {unlocked_distribution_address } => { - execute_propose_update_unlocked_distribution_address(deps, env, info, unlocked_distribution_address) - } - ExecuteMsg::ProposeUpdateStakingRewardDistributionAddress {staking_reward_distribution_address } => { - execute_propose_update_staking_reward_distribution_address(deps, env, info, staking_reward_distribution_address) - } + ExecuteMsg::ProposeUpdateUnlockedDistributionAddress { + unlocked_distribution_address, + } => execute_propose_update_unlocked_distribution_address( + deps, + env, + info, + unlocked_distribution_address, + ), + ExecuteMsg::ProposeUpdateStakingRewardDistributionAddress { + staking_reward_distribution_address, + } => execute_propose_update_staking_reward_distribution_address( + deps, + env, + info, + staking_reward_distribution_address, + ), ExecuteMsg::ProposeEmergencyWithdraw { dst } => { execute_propose_emergency_withdraw(deps, env, info, dst) } - ExecuteMsg::ProposeGovVote { gov_proposal_id, gov_vote } => { - execute_propose_gov_vote(deps, env, info, gov_proposal_id, gov_vote) - } + ExecuteMsg::ProposeGovVote { + gov_proposal_id, + gov_vote, + } => execute_propose_gov_vote(deps, env, info, gov_proposal_id, gov_vote), ExecuteMsg::VoteProposal { proposal_id } => execute_vote(deps, env, info, proposal_id), ExecuteMsg::ProcessProposal { proposal_id } => { execute_process_proposal(deps, env, info, proposal_id) @@ -312,12 +343,22 @@ pub fn execute( ExecuteMsg::InternalUpdateAdmin { admin, remove } => { execute_internal_update_admin(deps, env, info, admin, remove) } - ExecuteMsg::InternalUpdateUnlockedDistributionAddress { unlocked_distribution_address } => { - execute_internal_update_unlocked_distribution_address(deps, env, info, unlocked_distribution_address) - } - ExecuteMsg::InternalUpdateStakingRewardDistributionAddress {staking_reward_distribution_address } => { - execute_internal_update_staking_reward_distribution_address(deps, env, info, staking_reward_distribution_address) - } + ExecuteMsg::InternalUpdateUnlockedDistributionAddress { + unlocked_distribution_address, + } => execute_internal_update_unlocked_distribution_address( + deps, + env, + info, + unlocked_distribution_address, + ), + ExecuteMsg::InternalUpdateStakingRewardDistributionAddress { + staking_reward_distribution_address, + } => execute_internal_update_staking_reward_distribution_address( + deps, + env, + info, + staking_reward_distribution_address, + ), ExecuteMsg::InternalWithdrawLocked { dst } => { execute_internal_withdraw_locked(deps, env, info, dst) } @@ -413,15 +454,25 @@ fn execute_initiate_withdraw_reward( // To avoid under-withdraw, the operator can wait till there is no unbonding amount for the contract when executing // rewards withdrawal. fn calculate_withdrawn_rewards(deps: Deps, env: Env) -> Result { - let bank_balance = deps.querier.query_balance(env.contract.address.clone(), DENOM.load(deps.storage)?)?.amount.u128(); + let bank_balance = deps + .querier + .query_balance(env.contract.address.clone(), DENOM.load(deps.storage)?)? + .amount + .u128(); let total_locked: u128 = TOTAL_AMOUNT.load(deps.storage)?; - let withdrawn_principal = WITHDRAWN_LOCKED.load(deps.storage)? + WITHDRAWN_UNLOCKED.load(deps.storage)?; - let staked: u128 = deps.querier.query_all_delegations(env.contract.address)?.iter().map(|del: &Delegation| -> u128 { - if del.amount.clone().denom != DENOM.load(deps.storage).unwrap() { - return 0; - } - del.amount.amount.u128() - }).sum(); + let withdrawn_principal = + WITHDRAWN_LOCKED.load(deps.storage)? + WITHDRAWN_UNLOCKED.load(deps.storage)?; + let staked: u128 = deps + .querier + .query_all_delegations(env.contract.address)? + .iter() + .map(|del: &Delegation| -> u128 { + if del.amount.clone().denom != DENOM.load(deps.storage).unwrap() { + return 0; + } + del.amount.amount.u128() + }) + .sum(); let mut principal_in_bank: u128 = 0; if withdrawn_principal + staked < total_locked { principal_in_bank = total_locked - withdrawn_principal - staked; @@ -486,7 +537,10 @@ fn execute_propose_update_unlocked_distribution_address( let msg = ExecuteMsg::InternalUpdateUnlockedDistributionAddress { unlocked_distribution_address: unlocked_distribution_address.clone(), }; - let title = format!("updating unlocked distribution address {}", unlocked_distribution_address.to_string()); + let title = format!( + "updating unlocked distribution address {}", + unlocked_distribution_address.to_string() + ); execute_propose( deps, env.clone(), @@ -509,7 +563,10 @@ fn execute_propose_update_staking_reward_distribution_address( let msg = ExecuteMsg::InternalUpdateStakingRewardDistributionAddress { staking_reward_distribution_address: staking_reward_distribution_address.clone(), }; - let title = format!("updating staking reward distribution address {}", staking_reward_distribution_address.to_string()); + let title = format!( + "updating staking reward distribution address {}", + staking_reward_distribution_address.to_string() + ); execute_propose( deps, env.clone(), @@ -552,7 +609,10 @@ fn execute_propose_gov_vote( gov_vote: VoteOption, ) -> Result, ContractError> { let title = format!("voting {:?} for {}", gov_vote, gov_proposal_id); - let msg = GovMsg::Vote { proposal_id: gov_proposal_id, vote: gov_vote }; + let msg = GovMsg::Vote { + proposal_id: gov_proposal_id, + vote: gov_vote, + }; execute_propose( deps, env.clone(), @@ -828,7 +888,7 @@ fn query_total_vested(deps: Deps, env: Env) -> StdResult Ok(()), Err(_) => Err(ContractError::Unauthorized {}), @@ -1238,11 +1307,22 @@ mod tests { // Verify address has updated after internal call let internal_update = ExecuteMsg::InternalUpdateUnlockedDistributionAddress { - unlocked_distribution_address: new_addr.clone() + unlocked_distribution_address: new_addr.clone(), }; let internal_info = mock_info(MOCK_CONTRACT_ADDR, &[]); - execute(deps.as_mut(), mock_env(), internal_info, internal_update.clone()).unwrap(); - assert_eq!(UNLOCK_DISTRIBUTION_ADDRESS.load(deps.as_ref().storage).unwrap(), new_addr); + execute( + deps.as_mut(), + mock_env(), + internal_info, + internal_update.clone(), + ) + .unwrap(); + assert_eq!( + UNLOCK_DISTRIBUTION_ADDRESS + .load(deps.as_ref().storage) + .unwrap(), + new_addr + ); } #[test] @@ -1271,11 +1351,20 @@ mod tests { // Verify address has updated after internal call let internal_update = ExecuteMsg::InternalUpdateStakingRewardDistributionAddress { - staking_reward_distribution_address: new_addr.clone() + staking_reward_distribution_address: new_addr.clone(), }; let internal_info = mock_info(MOCK_CONTRACT_ADDR, &[]); - execute(deps.as_mut(), mock_env(), internal_info, internal_update.clone()).unwrap(); - assert_eq!(STAKING_REWARD_ADDRESS.load(deps.as_ref().storage).unwrap(), new_addr); + execute( + deps.as_mut(), + mock_env(), + internal_info, + internal_update.clone(), + ) + .unwrap(); + assert_eq!( + STAKING_REWARD_ADDRESS.load(deps.as_ref().storage).unwrap(), + new_addr + ); } #[test] @@ -1325,7 +1414,10 @@ mod tests { setup_test_case(deps.as_mut(), info.clone()).unwrap(); let info = mock_info(VOTER1, &[]); - let proposal = ExecuteMsg::ProposeGovVote { gov_proposal_id: 1, gov_vote: VoteOption::Yes }; + let proposal = ExecuteMsg::ProposeGovVote { + gov_proposal_id: 1, + gov_vote: VoteOption::Yes, + }; let res = execute(deps.as_mut(), mock_env(), info, proposal.clone()).unwrap(); // Verify @@ -1481,7 +1573,10 @@ mod tests { setup_test_case(deps.as_mut(), info.clone()).unwrap(); let info = mock_info(VOTER1, &[]); - let proposal = ExecuteMsg::ProposeGovVote { gov_proposal_id: 1, gov_vote: VoteOption::Yes }; + let proposal = ExecuteMsg::ProposeGovVote { + gov_proposal_id: 1, + gov_vote: VoteOption::Yes, + }; execute(deps.as_mut(), mock_env(), info, proposal.clone()).unwrap(); let info = mock_info(VOTER2, &[]); @@ -1834,8 +1929,8 @@ mod tests { let info = mock_info(OWNER, &[Coin::new(48000000, "usei".to_string())]); setup_test_case(deps.as_mut(), info.clone()).unwrap(); - let msg = QueryMsg::TotalVested{}; - let vesting_timestamps= VESTING_TIMESTAMPS.load(deps.as_ref().storage); + let msg = QueryMsg::TotalVested {}; + let vesting_timestamps = VESTING_TIMESTAMPS.load(deps.as_ref().storage); let mut env = mock_env(); env.block.time = *(vesting_timestamps.unwrap().first().unwrap()); let bin = query(deps.as_ref(), env, msg).unwrap(); diff --git a/src/data_structure.rs b/src/data_structure.rs index b8fca6b..ba14755 100644 --- a/src/data_structure.rs +++ b/src/data_structure.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Coin, Timestamp, Env}; +use cosmwasm_std::{Addr, Coin, Env, Timestamp}; use crate::ContractError; @@ -80,13 +80,12 @@ impl Tranche { Ok(()) } - } #[cfg(test)] mod tests { - use cosmwasm_std::{Uint128, testing::mock_env}; use super::*; + use cosmwasm_std::{testing::mock_env, Uint128}; const UNLOCK_ADDR1: &str = "unlock0001"; @@ -104,9 +103,10 @@ mod tests { denom: "token".to_string(), staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![ - Coin { denom: "token".to_string(), amount: Uint128::from(600u128) }, - ]; + let funds = vec![Coin { + denom: "token".to_string(), + amount: Uint128::from(600u128), + }]; assert!(tranche.validate(env, funds).is_ok()); } @@ -122,10 +122,9 @@ mod tests { Timestamp::from_seconds(3).plus_nanos(env.block.time.nanos()), ], denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![ - ]; + let funds = vec![]; assert!(matches!( tranche.validate(env, funds), Err(ContractError::InvalidTranche(msg)) if msg.contains("mismatched vesting amounts and schedule") @@ -140,10 +139,9 @@ mod tests { unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), vesting_timestamps: vec![], denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![ - ]; + let funds = vec![]; assert!(matches!( tranche.validate(env, funds), Err(ContractError::InvalidTranche(msg)) if msg.contains("nothing to vest") @@ -156,11 +154,17 @@ mod tests { let tranche = Tranche { vesting_amounts: vec![0, 100], unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), - vesting_timestamps: vec![Timestamp::from_seconds(1).plus_nanos(env.block.time.nanos()), Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos())], + vesting_timestamps: vec![ + Timestamp::from_seconds(1).plus_nanos(env.block.time.nanos()), + Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos()), + ], denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![Coin { denom: "token".to_string(), amount: Uint128::new(100) }]; + let funds = vec![Coin { + denom: "token".to_string(), + amount: Uint128::new(100), + }]; let result = tranche.validate(env, funds); assert!(matches!( result, @@ -174,11 +178,17 @@ mod tests { let tranche = Tranche { vesting_amounts: vec![200, 200], unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), - vesting_timestamps: vec![Timestamp::from_seconds(1).plus_nanos(env.block.time.nanos()), Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos())], + vesting_timestamps: vec![ + Timestamp::from_seconds(1).plus_nanos(env.block.time.nanos()), + Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos()), + ], denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![Coin { denom: "token".to_string(), amount: Uint128::new(300) }]; + let funds = vec![Coin { + denom: "token".to_string(), + amount: Uint128::new(300), + }]; let result = tranche.validate(env, funds); assert!(matches!( result, @@ -192,11 +202,17 @@ mod tests { let tranche = Tranche { vesting_amounts: vec![100, 100], unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), - vesting_timestamps: vec![Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos()), Timestamp::from_seconds(1).plus_nanos(env.block.time.nanos())], + vesting_timestamps: vec![ + Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos()), + Timestamp::from_seconds(1).plus_nanos(env.block.time.nanos()), + ], denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![Coin { denom: "token".to_string(), amount: Uint128::new(200) }]; + let funds = vec![Coin { + denom: "token".to_string(), + amount: Uint128::new(200), + }]; let result = tranche.validate(env, funds); assert!(matches!( result, @@ -210,33 +226,42 @@ mod tests { let tranche = Tranche { vesting_amounts: vec![100], unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), - vesting_timestamps: vec![Timestamp::from_seconds(2).plus_nanos(env.block.time.nanos()).minus_seconds(3)], + vesting_timestamps: vec![Timestamp::from_seconds(2) + .plus_nanos(env.block.time.nanos()) + .minus_seconds(3)], denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), }; - let funds = vec![Coin { denom: "token".to_string(), amount: Uint128::new(200) }]; + let funds = vec![Coin { + denom: "token".to_string(), + amount: Uint128::new(200), + }]; let result = tranche.validate(env, funds); assert!(matches!( result, Err(ContractError::InvalidTranche(msg)) if msg.contains("Timestamp nanoseconds are out of range") )); - } - - #[test] - fn test_validate_timestamps_too_late() { - let env = mock_env(); - let tranche = Tranche { - vesting_amounts: vec![100], - unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), - vesting_timestamps: vec![Timestamp::from_seconds(HUNDRED_YEARS_IN_SECONDS+1).plus_nanos(env.block.time.nanos())], - denom: "token".to_string(), - staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1) - }; - let funds = vec![Coin { denom: "token".to_string(), amount: Uint128::new(200) }]; - let result = tranche.validate(env, funds); - assert!(matches!( - result, - Err(ContractError::InvalidTranche(msg)) if msg.contains("Timestamp is too far in the future") - )); - } -} \ No newline at end of file + } + + #[test] + fn test_validate_timestamps_too_late() { + let env = mock_env(); + let tranche = Tranche { + vesting_amounts: vec![100], + unlocked_token_distribution_address: Addr::unchecked(UNLOCK_ADDR1), + vesting_timestamps: vec![Timestamp::from_seconds(HUNDRED_YEARS_IN_SECONDS + 1) + .plus_nanos(env.block.time.nanos())], + denom: "token".to_string(), + staking_reward_distribution_address: Addr::unchecked(UNLOCK_ADDR1), + }; + let funds = vec![Coin { + denom: "token".to_string(), + amount: Uint128::new(200), + }]; + let result = tranche.validate(env, funds); + assert!(matches!( + result, + Err(ContractError::InvalidTranche(msg)) if msg.contains("Timestamp is too far in the future") + )); + } +} diff --git a/src/vesting.rs b/src/vesting.rs index fa0c08a..09115f0 100644 --- a/src/vesting.rs +++ b/src/vesting.rs @@ -1,11 +1,15 @@ -use cosmwasm_std::{coins, BankMsg, Response, Storage, Timestamp, StdResult}; +use cosmwasm_std::{coins, BankMsg, Response, StdResult, Storage, Timestamp}; use crate::{ state::{DENOM, UNLOCK_DISTRIBUTION_ADDRESS, VESTING_AMOUNTS, VESTING_TIMESTAMPS}, ContractError, }; -pub fn collect_vested(storage: &mut dyn Storage, now: Timestamp, requested_amount: u128) -> Result { +pub fn collect_vested( + storage: &mut dyn Storage, + now: Timestamp, + requested_amount: u128, +) -> Result { let vesting_ts = VESTING_TIMESTAMPS.load(storage)?; let vesting_amounts = VESTING_AMOUNTS.load(storage)?; let mut vested_amount = 0u128; @@ -28,7 +32,7 @@ pub fn collect_vested(storage: &mut dyn Storage, now: Timestamp, requested_amoun remaining_first_idx = i + 1; } if vested_amount < requested_amount { - return Err(ContractError::NoSufficientUnlockedTokens{}); + return Err(ContractError::NoSufficientUnlockedTokens {}); } if remaining_first_idx >= vesting_amounts.len() { VESTING_AMOUNTS.save(storage, &vec![])?; @@ -47,7 +51,7 @@ pub fn collect_vested(storage: &mut dyn Storage, now: Timestamp, requested_amoun } pub fn total_vested_amount(storage: &dyn Storage, now: Timestamp) -> StdResult { - let vesting_timestamps= VESTING_TIMESTAMPS.load(storage)?; + let vesting_timestamps = VESTING_TIMESTAMPS.load(storage)?; let vesting_amounts = VESTING_AMOUNTS.load(storage)?; let mut total_vested_amount = 0u128; for i in 0..vesting_timestamps.len() { @@ -96,7 +100,10 @@ mod tests { VESTING_AMOUNTS.save(deps_mut.storage, &vec![]).unwrap(); assert_eq!(0, collect_vested(deps_mut.storage, now, 0).unwrap()); - assert_eq!(ContractError::NoSufficientUnlockedTokens {}, collect_vested(deps_mut.storage, now, 10).expect_err("should error")); + assert_eq!( + ContractError::NoSufficientUnlockedTokens {}, + collect_vested(deps_mut.storage, now, 10).expect_err("should error") + ); } #[test] @@ -124,8 +131,14 @@ mod tests { .unwrap(); VESTING_AMOUNTS.save(deps_mut.storage, &vec![10]).unwrap(); - assert_eq!(ContractError::NoSufficientUnlockedTokens {}, collect_vested(deps_mut.storage, now, 15).expect_err("should error")); - assert_eq!(VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), vec![now]); + assert_eq!( + ContractError::NoSufficientUnlockedTokens {}, + collect_vested(deps_mut.storage, now, 15).expect_err("should error") + ); + assert_eq!( + VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), + vec![now] + ); assert_eq!(VESTING_AMOUNTS.load(deps_mut.storage).unwrap(), vec![10]); } @@ -140,7 +153,10 @@ mod tests { VESTING_AMOUNTS.save(deps_mut.storage, &vec![10]).unwrap(); assert_eq!(5, collect_vested(deps_mut.storage, now, 5).unwrap()); - assert_eq!(VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), vec![now]); + assert_eq!( + VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), + vec![now] + ); assert_eq!(VESTING_AMOUNTS.load(deps_mut.storage).unwrap(), vec![5]); } @@ -154,7 +170,10 @@ mod tests { .unwrap(); VESTING_AMOUNTS.save(deps_mut.storage, &vec![10]).unwrap(); - assert_eq!(ContractError::NoSufficientUnlockedTokens {}, collect_vested(deps_mut.storage, now, 10).expect_err("should error")); + assert_eq!( + ContractError::NoSufficientUnlockedTokens {}, + collect_vested(deps_mut.storage, now, 10).expect_err("should error") + ); assert_eq!( VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), vec![now.plus_seconds(1)] @@ -187,7 +206,10 @@ mod tests { vec![1u128, 11u128] ); - assert_eq!(2, collect_vested(deps_mut.storage, now.plus_seconds(1), 2).unwrap()); + assert_eq!( + 2, + collect_vested(deps_mut.storage, now.plus_seconds(1), 2).unwrap() + ); assert_eq!( VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), vec![now.plus_seconds(1)] @@ -237,7 +259,10 @@ mod tests { .save(deps_mut.storage, &vec![10, 9, 11]) .unwrap(); - assert_eq!(ContractError::NoSufficientUnlockedTokens {}, collect_vested(deps_mut.storage, now, 30).expect_err("should error")); + assert_eq!( + ContractError::NoSufficientUnlockedTokens {}, + collect_vested(deps_mut.storage, now, 30).expect_err("should error") + ); assert_eq!( VESTING_TIMESTAMPS.load(deps_mut.storage).unwrap(), vec![