From 9453c84eb57bb77c455d6fe879d6178ae414f010 Mon Sep 17 00:00:00 2001 From: Kevin Yang <5478483+k-yang@users.noreply.github.com> Date: Sun, 10 Mar 2024 11:24:37 -0500 Subject: [PATCH] feat(core-token-vesting-v2): add query for multiple vesting accounts (#137) * refactor(core-token-vesting-v2): use references instead of clone * chore: run linter * refactor: use move instead of clone * refactor: don't use StdResult when unneeded * refactor: create better error messages * feat(core-token-vesting): add query for multiple vesting accounts and tests --- .../core-token-vesting-v2/src/contract.rs | 29 ++++++-- contracts/core-token-vesting-v2/src/msg.rs | 3 + .../core-token-vesting-v2/src/testing.rs | 69 ++++++++++++++++++- 3 files changed, 92 insertions(+), 9 deletions(-) diff --git a/contracts/core-token-vesting-v2/src/contract.rs b/contracts/core-token-vesting-v2/src/contract.rs index a0cfc75..f342676 100644 --- a/contracts/core-token-vesting-v2/src/contract.rs +++ b/contracts/core-token-vesting-v2/src/contract.rs @@ -1,7 +1,9 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Attribute, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Storage, Timestamp, Uint128 + to_json_binary, Attribute, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, + Env, MessageInfo, Response, StdError, StdResult, Storage, Timestamp, + Uint128, }; use std::cmp::min; @@ -430,17 +432,31 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { address, start_after: _start_after, limit: _limit, - } => to_json_binary(&vesting_account(deps, env, address)?), + } => to_json_binary(&vesting_account(deps, &env, address)?), + QueryMsg::VestingAccounts { address } => { + to_json_binary(&vesting_accounts(deps, &env, address)?) + } } } +// query multiple vesting accounts, with the provided vec of addresses +fn vesting_accounts( + deps: Deps, + env: &Env, + addresses: Vec, +) -> StdResult> { + let mut res = vec![]; + for address in addresses { + res.push(vesting_account(deps, env, address)?); + } + Ok(res) +} + /// address: Bech 32 address for the owner of the vesting accounts. This will be /// the prefix we filter by in state. -/// limit: Maximum number of vesting accounts to retrieve when reading the -/// VESTING_ACCOUNTs store. fn vesting_account( deps: Deps, - env: Env, + env: &Env, address: String, ) -> StdResult { let account = VESTING_ACCOUNTS.may_load(deps.storage, address.as_str())?; @@ -453,8 +469,7 @@ fn vesting_account( vestings: vec![], }), Some(account) => { - let vested_amount = - account.vested_amount(env.block.time)?; + let vested_amount = account.vested_amount(env.block.time)?; let vesting_schedule_query = from_vesting_to_query_output( &account.vesting_schedule, diff --git a/contracts/core-token-vesting-v2/src/msg.rs b/contracts/core-token-vesting-v2/src/msg.rs index 7b0194f..25f2255 100644 --- a/contracts/core-token-vesting-v2/src/msg.rs +++ b/contracts/core-token-vesting-v2/src/msg.rs @@ -91,6 +91,9 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + VestingAccounts { + address: Vec, + } } #[cw_serde] diff --git a/contracts/core-token-vesting-v2/src/testing.rs b/contracts/core-token-vesting-v2/src/testing.rs index 4cd33cf..f4a07c0 100644 --- a/contracts/core-token-vesting-v2/src/testing.rs +++ b/contracts/core-token-vesting-v2/src/testing.rs @@ -297,7 +297,10 @@ fn register_cliff_vesting_account_with_native_token() -> TestResult { &env, mock_info("addr0042", &[]), msg, - StdError::generic_err("Sender addr0042 is unauthorized to reward users.").into(), + StdError::generic_err( + "Sender addr0042 is unauthorized to reward users.", + ) + .into(), ); // zero amount vesting token @@ -932,7 +935,10 @@ fn deregister_err_unauthorized_vesting_account() -> TestResult { &env, mock_info("addr0042", &[]), msg, - StdError::generic_err("Sender addr0042 is not authorized to deregister vesting accounts.").into(), + StdError::generic_err( + "Sender addr0042 is not authorized to deregister vesting accounts.", + ) + .into(), ); Ok(()) } @@ -975,3 +981,62 @@ fn deregister_successful() -> TestResult { )?; Ok(()) } + +#[test] +fn query_vesting_accounts() -> TestResult { + // Set up the environment with a block time before the vesting start time + let (mut deps, env) = setup_with_block_time(105)?; + + let register_msg = ExecuteMsg::RewardUsers { + rewards: vec![RewardUserRequest { + user_address: "addr0001".to_string(), + vesting_amount: Uint128::new(5000u128), + cliff_amount: Uint128::new(1250u128), + }], + vesting_schedule: VestingSchedule::LinearVestingWithCliff { + start_time: Uint64::new(100), + end_time: Uint64::new(110), + cliff_time: Uint64::new(105), + }, + }; + + execute( + deps.as_mut(), + env.clone(), // Use the custom environment with the adjusted block time + testing::mock_info("admin-sender", &[]), + register_msg, + )?; + + let res = query( + deps.as_ref(), + env, + QueryMsg::VestingAccounts { + address: vec!["addr0001".to_string()], + }, + )?; + + let response_items: Vec = from_json(res).unwrap(); + assert_eq!( + response_items[0], + VestingAccountResponse { + address: "addr0001".to_string(), + vestings: vec![VestingData { + master_address: Some("admin-sender".to_string()), + vesting_amount: Uint128::new(5000u128), + vesting_schedule: + VestingScheduleQueryOutput::LinearVestingWithCliff { + start_time: Uint64::new(100), + end_time: Uint64::new(110), + cliff_time: Uint64::new(105), + vesting_amount: Uint128::new(5000u128), + cliff_amount: Uint128::new(1250u128), + }, + vesting_denom: cw20::Denom::Native("token".to_string()), + vested_amount: Uint128::new(1250u128), + claimable_amount: Uint128::new(1250u128), + }] + } + ); + + Ok(()) +}