From fda6019a64a3c1eeea9034e48e285f55fa012cbe Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Tue, 16 Jan 2024 18:12:31 +0300 Subject: [PATCH 01/28] shorten lockdrop_pcl contract --- Cargo.lock | 2 +- contracts/lockdrop-pcl/Cargo.toml | 6 +- contracts/lockdrop-pcl/README.md | 62 +- contracts/lockdrop-pcl/src/contract.rs | 752 +----------------- contracts/lockdrop-pcl/src/state.rs | 19 +- .../astroport_periphery/src/lockdrop_pcl.rs | 83 +- 6 files changed, 50 insertions(+), 874 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cca8d87b..6d6ea2b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -995,7 +995,7 @@ dependencies = [ [[package]] name = "neutron-lockdrop-pcl" -version = "1.2.1" +version = "1.0.0" dependencies = [ "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?tag=v2.5.0)", "astroport-periphery", diff --git a/contracts/lockdrop-pcl/Cargo.toml b/contracts/lockdrop-pcl/Cargo.toml index d3167f93..15c4a7cb 100644 --- a/contracts/lockdrop-pcl/Cargo.toml +++ b/contracts/lockdrop-pcl/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "neutron-lockdrop" -version = "1.2.1" -authors = ["_astromartian"] +name = "neutron-lockdrop-pcl" +version = "1.0.0" +authors = ["_astromartian", "sotnikov-s"] edition = "2021" diff --git a/contracts/lockdrop-pcl/README.md b/contracts/lockdrop-pcl/README.md index 0bc572b1..8a969628 100644 --- a/contracts/lockdrop-pcl/README.md +++ b/contracts/lockdrop-pcl/README.md @@ -1,61 +1,3 @@ -# Lockdrop +# Lockdrop for PCL pools -The lockdrop contract allows users to lock any of the supported Terraswap LP tokens locked for a selected duration against which they will receive ASTRO tokens pro-rata to their weighted share of the LP tokens to the total deposited LP tokens for that particular pool in the contract. - -- Upon lockup expiration, users will receive Astroport LP tokens on an equivalent weight basis as per their initial Terraswap LP token deposits. - -Note - Users can open muliple lockup positions with different lockup duration for each LP Token pool - -## Contract Design - -### Handle Messages - -| Message | Description | -|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ExecuteMsg::UpdateConfig` | Can only be called by the admin. Facilitates updating configuration parameters | -| `ExecuteMsg::EnableClaims` | Executed by the Bootstrap auction contract when liquidity is added to the ASTRO-UST pool. Enables ASTRO withdrawals by the lockdrop recipients. | -| `ExecuteMsg::InitializePool` | Admin function. Facilitates addition of new Pool (Terraswap Pools) whose LP tokens can then be locked in the lockdrop contract | -| `ExecuteMsg::UpdatePool` | Admin function to update any configuraton parameter for a terraswap pool whose LP tokens are currently accepted for the lockdrop | -| `ExecuteMsg::IncreaseLockup` | Facilitates opening a new user position or adding to an existing position | -| `ExecuteMsg::IncreaseAstroIncentives` | Admin function to increase the ASTRO incentives that are to be distributed | -| `ExecuteMsg::WithdrawFromLockup` | Facilitates LP token withdrawals from lockup positions by users. 100% amount can be withdrawn during deposit window, which is then limited to 50% during 1st half of deposit window which then decreases linearly during 2nd half of deposit window. Only 1 withdrawal can be made by a user during the withdrawal windows | -| `ExecuteMsg::MigrateLiquidity` | Admin function. Facilitates migration of liquidity (locked terraswap LP tokens) from Terraswap to Astroport (Astroport LP tokens) | -| `ExecuteMsg::StakeLpTokens` | Admin function. Facilitates staking of Astroport LP tokens for a particular LP pool with the generator contract | -| `ExecuteMsg::DelegateAstroToAuction` | This function facilitates ASTRO tokens delegation to the Bootstrap auction contract during the bootstrap auction phase. Delegated ASTRO tokens are added to the user's position in the bootstrap auction contract | -| `ExecuteMsg::ClaimRewardsAndOptionallyUnlock` | Facilitates rewards claim by users for a particular lockup position along with unlock when possible | -| `ExecuteMsg::ClaimAssetReward` | Collects assets reward from LP and distribute reward to user if all requirements are met | -| `ExecuteMsg::TogglePoolRewards` | Admin function. Enables assets reward for specified LP | -| `ExecuteMsg::ProposeNewOwner` | Admin function. Creates an offer to change the contract ownership. The validity period of the offer is set in the `expires_in` variable. After `expires_in` seconds pass, the proposal expires and cannot be accepted anymore. | -| `ExecuteMsg::DropOwnershipProposal` | Admin function. Removes an existing offer to change the contract owner. | -| `ExecuteMsg::ClaimOwnership` | Admin function. Used to claim contract ownership. | - -### Handle Messages :: Callback - -| Message | Description | -|-------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| `CallbackMsg::UpdatePoolOnDualRewardsClaim` | Callback function to update contract state after pending dual staking rewards are claimed from the generator contract | -| `CallbackMsg::WithdrawUserLockupRewardsCallback` | Callback function to withdraw user rewards for a particular lockcup position along with optional LP tokens withdrawal (upon lockup duration expiration) | -| `CallbackMsg::WithdrawLiquidityFromTerraswapCallback` | Callback function used during liquidity migration to update state after liquidity is removed from terraswap | -| `CallbackMsg::DistributeAssetReward` | Callback function used for assets reward distribution after rewards claiming from LP | - -### Query Messages - -| Message | Description | -|---------------------------------|------------------------------------------------------------------------------------------------------------------| -| `QueryMsg::Config` | Returns the config info | -| `QueryMsg::State` | Returns the contract's global state | -| `QueryMsg::Pool` | Returns info regarding a certain supported LP token pool | -| `QueryMsg::UserInfo` | Returns info regarding a user (total ASTRO rewards, list of lockup positions) | -| `QueryMsg::LockUpInfo` | Returns info regarding a particular lockup position with a given duration and identifer for the LP tokens locked | -| `QueryMsg::PendingAssetReward` | Returns the amount of pending asset rewards for the specified recipient and for a specific lockup position | - -## Build schema and run unit-tests - -``` -cargo schema -cargo test -``` - -## License - -TBD +A shortened, simplified copy of the [Neutron lockdrop contract](https://github.com/neutron-org/neutron-tge-contracts/tree/main/contracts/lockdrop) extended with an entry point to receive lockdrop liquidity from the original contract in order to move it from XYK pools to PCL ones. \ No newline at end of file diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 50aee229..5d0cd2f1 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -12,18 +12,18 @@ use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; use astroport_periphery::utils::Decimal256CheckedOps; use cosmwasm_std::{ - attr, coins, entry_point, from_binary, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, - Decimal, Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, - Uint128, Uint256, WasmMsg, + attr, coins, entry_point, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, + Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, + Uint256, WasmMsg, }; use cw2::set_contract_version; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg}; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use crate::raw_queries::{raw_balance, raw_generator_deposit}; -use astroport_periphery::lockdrop::{ - CallbackMsg, Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, - LockUpInfoSummary, LockupInfoV2, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, - StateResponse, UpdateConfigMsg, UserInfoResponse, UserInfoWithListResponse, +use astroport_periphery::lockdrop_pcl::{ + CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, + MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + UserInfoResponse, UserInfoWithListResponse, }; use crate::state::{ @@ -36,43 +36,19 @@ const AIRDROP_REWARDS_MULTIPLIER: &str = "1.0"; pub const UNTRN_DENOM: &str = "untrn"; /// Contract name that is used for migration. -const CONTRACT_NAME: &str = "neutron_lockdrop"; +const CONTRACT_NAME: &str = "neutron_lockdrop_pcl"; /// Contract version that is used for migration. const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -/// Minimum lockup positions for user. -const MIN_POSITIONS_PER_USER: u32 = 1; - /// Creates a new contract with the specified parameters packed in the `msg` variable. -/// Returns a [`Response`] with the specified attributes if the operation was successful, or a [`ContractError`] if the contract was not created -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **msg** is a message of type [`InstantiateMsg`] which contains the parameters used for creating the contract. #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - env: Env, + _env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> StdResult { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // CHECK :: init_timestamp needs to be valid - if env.block.time.seconds() > msg.init_timestamp { - return Err(StdError::generic_err(format!( - "Invalid init_timestamp. Current timestamp : {}", - env.block.time.seconds() - ))); - } - - // CHECK :: min_lock_duration , max_lock_duration need to be valid (min_lock_duration < max_lock_duration) - if msg.max_lock_duration < msg.min_lock_duration || msg.min_lock_duration == 0u64 { - return Err(StdError::generic_err("Invalid Lockup durations")); - } if msg.lockup_rewards_info.is_empty() { return Err(StdError::generic_err("Invalid lockup rewards info")); @@ -85,29 +61,17 @@ pub fn instantiate( } } - if msg.max_positions_per_user < MIN_POSITIONS_PER_USER { - return Err(StdError::generic_err( - "The maximum number of locked positions per user cannot be lower than a minimum acceptable value." - )); - } - let config = Config { owner: msg .owner .map(|v| deps.api.addr_validate(&v)) .transpose()? .unwrap_or(info.sender), - token_info_manager: deps.api.addr_validate(&msg.token_info_manager)?, + xyk_lockdrop_contract: deps.api.addr_validate(&msg.xyk_lockdrop_contract)?, credits_contract: deps.api.addr_validate(&msg.credits_contract)?, auction_contract: deps.api.addr_validate(&msg.auction_contract)?, - generator: None, - init_timestamp: msg.init_timestamp, - lock_window: msg.lock_window, - withdrawal_window: msg.withdrawal_window, - min_lock_duration: msg.min_lock_duration, - max_lock_duration: msg.max_lock_duration, + generator: deps.api.addr_validate(&msg.generator)?, lockdrop_incentives: Uint128::zero(), - max_positions_per_user: msg.max_positions_per_user, lockup_rewards_info: msg.lockup_rewards_info, }; @@ -116,43 +80,10 @@ pub fn instantiate( Ok(Response::default()) } -/// ## Description /// Exposes all the execute functions available in the contract. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **msg** is an object of type [`ExecuteMsg`]. -/// -/// ## Execute messages -/// -/// * **ExecuteMsg::Receive(msg)** Parse incoming messages from the cNTRN token. -/// -/// * **ExecuteMsg::UpdateConfig { new_config }** Admin function to update configuration parameters. -/// -/// * **ExecuteMsg::InitializePool { -/// pool_type, -/// incentives_share, -/// }** Facilitates addition of new Pool (axlrUSDC/NTRN or ATOM/NTRN) whose LP tokens can then be locked in the lockdrop contract. -/// -/// * **ExecuteMsg::ClaimRewardsAndOptionallyUnlock { -/// terraswap_lp_token, -/// duration, -/// withdraw_lp_stake, -/// }** Claims user Rewards for a particular Lockup position. -/// -/// * **ExecuteMsg::ProposeNewOwner { owner, expires_in }** Creates a request to change contract ownership. -/// -/// * **ExecuteMsg::DropOwnershipProposal {}** Removes a request to change contract ownership. -/// -/// * **ExecuteMsg::ClaimOwnership {}** Claims contract ownership. #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { - ExecuteMsg::Receive(msg) => receive_cw20(deps, env, info, msg), ExecuteMsg::ClaimRewardsAndOptionallyUnlock { pool_type, duration, @@ -191,81 +122,11 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S Ok(()) }) } - ExecuteMsg::IncreaseNTRNIncentives {} => handle_increasing_ntrn_incentives(deps, env, info), - ExecuteMsg::IncreaseLockupFor { - user_address, - pool_type, - amount, - duration, - } => handle_increase_lockup(deps, env, info, user_address, pool_type, duration, amount), - ExecuteMsg::WithdrawFromLockup { - user_address, - pool_type, - duration, - amount, - } => { - handle_withdraw_from_lockup(deps, env, info, user_address, pool_type, duration, amount) - } ExecuteMsg::UpdateConfig { new_config } => handle_update_config(deps, info, new_config), - ExecuteMsg::SetTokenInfo { - usdc_token, - atom_token, - generator, - } => handle_set_token_info(deps, env, info, usdc_token, atom_token, generator), } } -/// Receives a message of type [`Cw20ReceiveMsg`] and processes it depending on the received template. -/// If the template is not found in the received message, then an [`StdError`] is returned, -/// otherwise it returns the [`Response`] with the specified attributes if the operation was successful. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **cw20_msg** is an object of type [`Cw20ReceiveMsg`]. This is the CW20 message that has to be processed. -pub fn receive_cw20( - deps: DepsMut, - env: Env, - info: MessageInfo, - cw20_msg: Cw20ReceiveMsg, -) -> Result { - let cw20_sender_addr = deps.api.addr_validate(&cw20_msg.sender)?; - // CHECK :: Tokens sent > 0 - if cw20_msg.amount == Uint128::zero() { - return Err(StdError::generic_err( - "Number of tokens sent should be > 0 ", - )); - } - - match from_binary(&cw20_msg.msg)? { - Cw20HookMsg::InitializePool { - pool_type, - incentives_share, - } => handle_initialize_pool( - deps, - env, - info, - pool_type, - cw20_sender_addr, - incentives_share, - cw20_msg.amount, - ), - } -} - -/// ## Description -/// Handles callback. Returns a [`ContractError`] on failure. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **msg** is an object of type [`CallbackMsg`]. +/// Handles callback. fn _handle_callback( deps: DepsMut, env: Env, @@ -307,46 +168,6 @@ fn _handle_callback( } /// Exposes all the queries available in the contract. -/// ## Params -/// * **deps** is an object of type [`Deps`]. -/// -/// * **_env** is an object of type [`Env`]. -/// -/// * **msg** is an object of type [`QueryMsg`]. -/// -/// ## Queries -/// * **QueryMsg::Config {}** Returns the config info. -/// -/// * **QueryMsg::State {}** Returns the contract's state info. -/// -/// * **QueryMsg::Pool { terraswap_lp_token }** Returns info regarding a certain supported LP token pool. -/// -/// * **QueryMsg::UserInfo { address }** Returns info regarding a user (total NTRN rewards, list of lockup positions). -/// -/// * **QueryMsg::UserInfoWithLockupsList { address }** Returns info regarding a user with lockups. -/// -/// * **QueryMsg::LockUpInfo { -/// user_address, -/// terraswap_lp_token, -/// duration, -/// }** Returns info regarding a particular lockup position with a given duration and identifer for the LP tokens locked. -/// -/// * **QueryMsg::PendingAssetReward { -/// user_address, -/// terraswap_lp_token, -/// duration, -/// }** Returns the amount of pending asset rewards for the specified recipient and for a specific lockup position. -/// -/// * **QueryUserLockupTotalAtHeight { -/// pool_type: PoolType, -/// user_address: String, -/// height: u64, -/// }** Returns locked amount of LP tokens for the specified user for the specified pool at a specific height. -/// -/// * **QueryLockupTotalAtHeight { -/// pool_type: PoolType, -/// height: u64, -/// }** Returns a total amount of LP tokens for the specified pool at a specific height. #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { @@ -384,13 +205,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } } -/// Used for contract migration. Returns a default object of type [`Response`]. -/// ## Params -/// * **_deps** is an object of type [`DepsMut`]. -/// -/// * **_env** is an object of type [`Env`]. -/// -/// * **_msg** is an object of type [`MigrateMsg`]. +/// Used for contract migration. #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { Ok(Response::default()) @@ -416,29 +231,22 @@ pub fn handle_update_config( return Err(StdError::generic_err("Unauthorized")); } - if let Some(auction) = new_config.auction_contract_address { - config.auction_contract = deps.api.addr_validate(&auction)?; - attributes.push(attr("auction_contract", auction)); - }; - if let Some(generator) = new_config.generator_address { // If generator is set, we check is any LP tokens are currently staked before updating generator address - if config.generator.is_some() { - for pool_type in ASSET_POOLS - .keys(deps.storage, None, None, Order::Ascending) - .collect::, StdError>>()? - { - let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - if pool_info.is_staked { - return Err(StdError::generic_err(format!( - "{:?} astro LP tokens already staked. Unstake them before updating generator", - pool_type - ))); - } + for pool_type in ASSET_POOLS + .keys(deps.storage, None, None, Order::Ascending) + .collect::, StdError>>()? + { + let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + if pool_info.is_staked { + return Err(StdError::generic_err(format!( + "{:?} astro LP tokens already staked. Unstake them before updating generator", + pool_type + ))); } } - config.generator = Some(deps.api.addr_validate(&generator)?); + config.generator = deps.api.addr_validate(&generator)?; attributes.push(attr("new_generator", generator)) } @@ -446,478 +254,6 @@ pub fn handle_update_config( Ok(Response::new().add_attributes(attributes)) } -pub fn handle_set_token_info( - deps: DepsMut, - env: Env, - info: MessageInfo, - usdc_token: String, - atom_token: String, - generator: String, -) -> Result { - let mut config = CONFIG.load(deps.storage)?; - - // CHECK :: Only owner and token info manager can call this function - if info.sender != config.owner && info.sender != config.token_info_manager { - return Err(StdError::generic_err("Unauthorized")); - } - - // POOL INFO :: Initialize new pool - let pool_info = PoolInfo { - lp_token: deps.api.addr_validate(&atom_token)?, - amount_in_lockups: Default::default(), - incentives_share: Uint128::zero(), - weighted_amount: Default::default(), - generator_ntrn_per_share: Default::default(), - generator_proxy_per_share: RestrictedVector::default(), - is_staked: false, - }; - ASSET_POOLS.save(deps.storage, PoolType::ATOM, &pool_info, env.block.height)?; - - // POOL INFO :: Initialize new pool - let pool_info = PoolInfo { - lp_token: deps.api.addr_validate(&usdc_token)?, - amount_in_lockups: Default::default(), - incentives_share: Uint128::zero(), - weighted_amount: Default::default(), - generator_ntrn_per_share: Default::default(), - generator_proxy_per_share: RestrictedVector::default(), - is_staked: false, - }; - ASSET_POOLS.save(deps.storage, PoolType::USDC, &pool_info, env.block.height)?; - - config.generator = Some(deps.api.addr_validate(&generator)?); - CONFIG.save(deps.storage, &config)?; - - let attributes = vec![ - attr("action", "update_config"), - attr("usdc_token", usdc_token), - attr("atom_token", atom_token), - attr("generator", generator), - ]; - - Ok(Response::new().add_attributes(attributes)) -} - -/// Facilitates increasing NTRN incentives that are to be distributed as Lockdrop participation reward. Returns a default object of type [`Response`]. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -pub fn handle_increasing_ntrn_incentives( - deps: DepsMut, - env: Env, - info: MessageInfo, -) -> Result { - let mut config = CONFIG.load(deps.storage)?; - - if env.block.time.seconds() - >= config.init_timestamp + config.lock_window + config.withdrawal_window - { - return Err(StdError::generic_err("Lock window is closed")); - }; - - let incentive = info.funds.iter().find(|c| c.denom == UNTRN_DENOM); - let amount = if let Some(coin) = incentive { - coin.amount - } else { - return Err(StdError::generic_err(format!( - "{} is not found", - UNTRN_DENOM - ))); - }; - // Anyone can increase ntrn incentives - config.lockdrop_incentives = config.lockdrop_incentives.checked_add(amount)?; - - CONFIG.save(deps.storage, &config)?; - Ok(Response::new() - .add_attribute("action", "ntrn_incentives_increased") - .add_attribute("amount", amount)) -} - -/// Admin function to initialize new LP Pool. Returns a default object of type [`Response`]. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **pool_type** is an object of type [`PoolType`]. LiquidPool type - USDC or ATOM -/// -/// * **cw20_sender_addr** is an object of type [`Addr`]. Address caller cw20 contract -/// -/// * **incentives_share** is an object of type [`u64`]. Parameter defining share of total NTRN incentives are allocated for this pool -/// -/// * **amount** amount of LP tokens of `pool_type` to be staked in the Generator Contract. -pub fn handle_initialize_pool( - deps: DepsMut, - env: Env, - info: MessageInfo, - pool_type: PoolType, - cw20_sender_addr: Addr, - incentives_share: Uint128, - amount: Uint128, -) -> StdResult { - let config = CONFIG.load(deps.storage)?; - let mut state = STATE.load(deps.storage)?; - - // CHECK ::: Only auction can call this function - if cw20_sender_addr != config.auction_contract { - return Err(StdError::generic_err("Unauthorized")); - } - - // CHECK ::: Is LP Token Pool initialized - let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - - if info.sender != pool_info.lp_token { - return Err(StdError::generic_err("Unknown cw20 token address")); - } - - // Set Pool Incentives - pool_info.incentives_share = incentives_share; - - let stake_msgs = stake_messages( - config, - env.block.height + 1u64, - pool_info.lp_token.clone(), - amount, - )?; - pool_info.is_staked = true; - - ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; - - state.total_incentives_share = state.total_incentives_share.checked_add(incentives_share)?; - STATE.save(deps.storage, &state)?; - - Ok(Response::new() - .add_messages(stake_msgs) - .add_attributes(vec![ - attr("action", "initialize_pool"), - attr("pool_type", format!("{:?}", pool_type)), - attr("lp_token", info.sender), - attr("lp_amount", amount), - attr("incentives_share", incentives_share.to_string()), - ])) -} - -fn stake_messages( - config: Config, - height: u64, - lp_token_address: Addr, - amount: Uint128, -) -> StdResult> { - let mut cosmos_msgs = vec![]; - - let generator = config - .generator - .as_ref() - .ok_or_else(|| StdError::generic_err("Generator address hasn't set yet!"))?; - - // TODO: why do we need allowance here, when next message is "send" to a pool - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: lp_token_address.to_string(), - funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::IncreaseAllowance { - spender: generator.to_string(), - amount, - expires: Some(cw20::Expiration::AtHeight(height)), - })?, - })); - - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: lp_token_address.to_string(), - funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { - contract: generator.to_string(), - msg: to_binary(&astroport::generator::Cw20HookMsg::Deposit {})?, - amount, - })?, - })); - - Ok(cosmos_msgs) -} - -/// Hook function to increase Lockup position size when any of the supported LP Tokens are sent to the contract by the user. Returns a default object of type [`Response`]. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **user_address_raw** is an object of type [`Addr`]. User we increase lockup position for -/// -/// * **pool_type** is an object of type [`PoolType`]. LiquidPool type - USDC or ATOM -/// -/// * **duration** is an object of type [`u64`]. Number of seconds the LP token is locked for (lockup period begins post the withdrawal window closure). -/// -/// * **amount** is an object of type [`Uint128`]. Number of LP tokens sent by the user. -pub fn handle_increase_lockup( - deps: DepsMut, - env: Env, - info: MessageInfo, - user_address_raw: String, - pool_type: PoolType, - duration: u64, - amount: Uint128, -) -> StdResult { - let config = CONFIG.load(deps.storage)?; - - if info.sender != config.auction_contract { - return Err(StdError::generic_err("Unauthorized")); - } - - if env.block.time.seconds() >= config.init_timestamp + config.lock_window { - return Err(StdError::generic_err("Lock window is closed")); - }; - - let user_address = deps.api.addr_validate(&user_address_raw)?; - - if !config - .lockup_rewards_info - .iter() - .any(|i| i.duration == duration) - { - return Err(StdError::generic_err("invalid duration")); - } - - // CHECK ::: LP Token supported or not ? - let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - let mut user_info = USER_INFO - .may_load(deps.storage, &user_address)? - .unwrap_or_default(); - - // CHECK :: Valid Lockup Duration - if duration > config.max_lock_duration || duration < config.min_lock_duration { - return Err(StdError::generic_err(format!( - "Lockup duration needs to be between {} and {}", - config.min_lock_duration, config.max_lock_duration - ))); - } - - pool_info.weighted_amount = pool_info - .weighted_amount - .checked_add(calculate_weight(amount, duration, &config)?)?; - pool_info.amount_in_lockups = pool_info.amount_in_lockups.checked_add(amount)?; - - let lockup_key = (pool_type, &user_address, duration); - - let lockup_info = - match LOCKUP_INFO.compatible_may_load(deps.as_ref(), lockup_key, &config.generator)? { - Some(mut li) => { - li.lp_units_locked = li.lp_units_locked.checked_add(amount)?; - li - } - None => { - if config.max_positions_per_user == user_info.lockup_positions_index { - return Err(StdError::generic_err(format!( - "Users can only have max {} lockup positions", - config.max_positions_per_user - ))); - } - // Update number of lockup positions the user is having - user_info.lockup_positions_index += 1; - - LockupInfoV2 { - lp_units_locked: amount, - astroport_lp_transferred: None, - ntrn_rewards: Uint128::zero(), - unlock_timestamp: config.init_timestamp - + config.lock_window - + duration - + config.withdrawal_window, - generator_ntrn_debt: Uint128::zero(), - generator_proxy_debt: Default::default(), - withdrawal_flag: false, - } - } - }; - - // SAVE UPDATED STATE - LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; - - TOTAL_USER_LOCKUP_AMOUNT.update( - deps.storage, - (pool_type, &user_address), - env.block.height, - |lockup_amount| -> StdResult { - if let Some(la) = lockup_amount { - Ok(la.checked_add(amount)?) - } else { - Ok(amount) - } - }, - )?; - - ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; - USER_INFO.save(deps.storage, &user_address, &user_info)?; - - Ok(Response::new().add_attributes(vec![ - attr("action", "increase_lockup_position"), - attr("pool_type", format!("{:?}", pool_type)), - attr("user", user_address), - attr("duration", duration.to_string()), - attr("amount", amount), - ])) -} - -/// Withdraws LP Tokens from an existing Lockup position. Returns a default object of type [`Response`]. -/// ## Params -/// * **deps** is an object of type [`DepsMut`]. -/// -/// * **env** is an object of type [`Env`]. -/// -/// * **info** is an object of type [`MessageInfo`]. -/// -/// * **pool_type** is an object of type [`PoolType`]. LiquidPool type - USDC or ATOM -/// -/// * **duration** is an object of type [`u64`]. Duration of the lockup position from which withdrawal is to be made. -/// -/// * **amount** is an object of type [`Uint128`]. Number of LP tokens to be withdrawn. -pub fn handle_withdraw_from_lockup( - deps: DepsMut, - env: Env, - info: MessageInfo, - user_address: String, - pool_type: PoolType, - duration: u64, - amount: Uint128, -) -> StdResult { - let config = CONFIG.load(deps.storage)?; - - if info.sender != config.auction_contract { - return Err(StdError::generic_err("Unauthorized")); - } - - if env.block.time.seconds() - >= config.init_timestamp + config.lock_window + config.withdrawal_window - { - return Err(StdError::generic_err("Withdrawal window is closed")); - }; - - // CHECK :: Valid Withdraw Amount - if amount.is_zero() { - return Err(StdError::generic_err("Invalid withdrawal request")); - } - - let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - - let user_address = deps.api.addr_validate(&user_address)?; - - // Retrieve Lockup position - let lockup_key = (pool_type, &user_address, duration); - let mut lockup_info = - LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; - - // CHECK :: Has user already withdrawn LP tokens once post the deposit window closure state - if lockup_info.withdrawal_flag { - return Err(StdError::generic_err( - "Withdrawal already happened. No more withdrawals accepted", - )); - } - - // Check :: Amount should be within the allowed withdrawal limit bounds - let max_withdrawal_percent = - calculate_max_withdrawal_percent_allowed(env.block.time.seconds(), &config); - let max_withdrawal_allowed = lockup_info - .lp_units_locked - .to_decimal() - .checked_mul(max_withdrawal_percent)? - .to_uint_floor(); - if amount > max_withdrawal_allowed { - return Err(StdError::generic_err(format!( - "Amount exceeds maximum allowed withdrawal limit of {}", - max_withdrawal_allowed - ))); - } - - // Update withdrawal flag after the deposit window - if env.block.time.seconds() >= config.init_timestamp + config.lock_window { - lockup_info.withdrawal_flag = true; - } - - // STATE :: RETRIEVE --> UPDATE - lockup_info.lp_units_locked = lockup_info.lp_units_locked.checked_sub(amount)?; - pool_info.weighted_amount = pool_info - .weighted_amount - .checked_sub(calculate_weight(amount, duration, &config)?)?; - pool_info.amount_in_lockups = pool_info.amount_in_lockups.checked_sub(amount)?; - - // Remove Lockup position from the list of user positions if Lp_Locked balance == 0 - if lockup_info.lp_units_locked.is_zero() { - LOCKUP_INFO.remove(deps.storage, lockup_key); - // decrement number of user's lockup positions - let mut user_info = USER_INFO - .may_load(deps.storage, &user_address)? - .unwrap_or_default(); - user_info.lockup_positions_index -= 1; - USER_INFO.save(deps.storage, &user_address, &user_info)?; - } else { - LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; - } - TOTAL_USER_LOCKUP_AMOUNT.update( - deps.storage, - (pool_type, &user_address), - env.block.height, - |lockup_amount| -> StdResult { - if let Some(la) = lockup_amount { - Ok(la.checked_sub(amount)?) - } else { - Ok(Uint128::zero()) - } - }, - )?; - - // SAVE Updated States - ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; - - Ok(Response::new().add_attributes(vec![ - attr("action", "withdraw_from_lockup"), - attr("pool_type", pool_type), - attr("user_address", user_address), - attr("duration", duration.to_string()), - attr("amount", amount), - ])) -} - -/// Calculates maximum % of LP balances deposited that can be withdrawn -/// ## Params -/// * **current_timestamp** is an object of type [`u64`]. Current block timestamp -/// -/// * **config** is an object of type [`Config`]. Contract configuration -fn calculate_max_withdrawal_percent_allowed(current_timestamp: u64, config: &Config) -> Decimal { - let withdrawal_cutoff_init_point = config.init_timestamp + config.lock_window; - - // Deposit window :: 100% withdrawals allowed - if current_timestamp < withdrawal_cutoff_init_point { - return Decimal::from_ratio(100u32, 100u32); - } - - let withdrawal_cutoff_second_point = - withdrawal_cutoff_init_point + (config.withdrawal_window / 2u64); - // Deposit window closed, 1st half of withdrawal window :: 50% withdrawals allowed - if current_timestamp <= withdrawal_cutoff_second_point { - return Decimal::from_ratio(50u32, 100u32); - } - - // max withdrawal allowed decreasing linearly from 50% to 0% vs time elapsed - let withdrawal_cutoff_final = withdrawal_cutoff_init_point + config.withdrawal_window; - // Deposit window closed, 2nd half of withdrawal window :: max withdrawal allowed decreases linearly from 50% to 0% vs time elapsed - if current_timestamp < withdrawal_cutoff_final { - let time_left = withdrawal_cutoff_final - current_timestamp; - Decimal::from_ratio( - 50u64 * time_left, - 100u64 * (withdrawal_cutoff_final - withdrawal_cutoff_second_point), - ) - } - // Withdrawals not allowed - else { - Decimal::from_ratio(0u32, 100u32) - } -} - /// Claims user Rewards for a particular Lockup position. Returns a default object of type [`Response`]. /// ## Params /// * **deps** is an object of type [`DepsMut`]. @@ -942,14 +278,6 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let config = CONFIG.load(deps.storage)?; let state = STATE.load(deps.storage)?; - if env.block.time.seconds() - < config.init_timestamp + config.lock_window + config.withdrawal_window - { - return Err(StdError::generic_err( - "Lock/withdrawal window is still open", - )); - } - let user_address = info.sender; // CHECK ::: Is LP Token Pool supported or not ? @@ -994,10 +322,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let astroport_lp_token = pool_info.lp_token; if pool_info.is_staked { - let generator = config - .generator - .as_ref() - .ok_or_else(|| StdError::generic_err("Generator should be set at this moment!"))?; + let generator = &config.generator; // QUERY :: Check if there are any pending staking rewards let pending_rewards: PendingTokenResponse = deps.querier.query_wasm_smart( @@ -1151,11 +476,7 @@ pub fn update_pool_on_dual_rewards_claim( ) -> StdResult { let config = CONFIG.load(deps.storage)?; let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - - let generator = config - .generator - .as_ref() - .ok_or_else(|| StdError::generic_err("Generator hasn't been set yet!"))?; + let generator = &config.generator; let astroport_lp_token = pool_info.lp_token.clone(); let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( @@ -1253,11 +574,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( ]; let astroport_lp_token = pool_info.lp_token.clone(); - - let generator = config - .generator - .as_ref() - .ok_or_else(|| StdError::generic_err("Generator should be set"))?; + let generator = &config.generator; // Calculate Astro LP share for the lockup position let astroport_lp_amount: Uint128 = { @@ -1631,10 +948,7 @@ pub fn query_lockup_info( pool_astroport_lp_units = if pool_info.is_staked { raw_generator_deposit( deps.querier, - config - .generator - .as_ref() - .ok_or_else(|| StdError::generic_err("Should be set!"))?, + &config.generator, astroport_lp_token.as_bytes(), env.contract.address.as_bytes(), )? @@ -1656,14 +970,10 @@ pub fn query_lockup_info( astroport_lp_token_opt = astroport_lp_token.clone(); // If LP tokens are staked, calculate the rewards claimable by the user for this lockup position if pool_info.is_staked && !lockup_astroport_lp_units.is_zero() { - let generator = config - .generator - .clone() - .ok_or_else(|| StdError::generic_err("Generator should be set at this moment!"))?; - + let generator = &config.generator; // QUERY :: Check if there are any pending staking rewards let pending_rewards: PendingTokenResponse = deps.querier.query_wasm_smart( - &generator, + generator, &GenQueryMsg::PendingToken { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), diff --git a/contracts/lockdrop-pcl/src/state.rs b/contracts/lockdrop-pcl/src/state.rs index 5b817721..e54e857c 100644 --- a/contracts/lockdrop-pcl/src/state.rs +++ b/contracts/lockdrop-pcl/src/state.rs @@ -2,9 +2,8 @@ use astroport::common::OwnershipProposal; use astroport::generator::PoolInfoResponse; use astroport::generator::QueryMsg as GenQueryMsg; use astroport::restricted_vector::RestrictedVector; -use astroport_periphery::lockdrop::PoolType; -use astroport_periphery::lockdrop::{ - Config, LockupInfoV1, LockupInfoV2, PoolInfo, State, UserInfo, +use astroport_periphery::lockdrop_pcl::{ + Config, LockupInfoV1, LockupInfoV2, PoolInfo, PoolType, State, UserInfo, }; use astroport_periphery::U64Key; use cosmwasm_std::{Addr, Deps, StdError, StdResult, Uint128}; @@ -39,14 +38,9 @@ pub const OLD_LOCKUP_INFO: Map<(PoolType, &Addr, U64Key), LockupInfoV1> = Map::new("lockup_position"); pub trait CompatibleLoader { - fn compatible_load(&self, deps: Deps, key: K, generator: &Option) -> StdResult; + fn compatible_load(&self, deps: Deps, key: K, generator: &Addr) -> StdResult; - fn compatible_may_load( - &self, - deps: Deps, - key: K, - generator: &Option, - ) -> StdResult>; + fn compatible_may_load(&self, deps: Deps, key: K, generator: &Addr) -> StdResult>; } impl CompatibleLoader<(PoolType, &Addr, U64Key), LockupInfoV2> @@ -56,12 +50,11 @@ impl CompatibleLoader<(PoolType, &Addr, U64Key), LockupInfoV2> &self, deps: Deps, key: (PoolType, &Addr, U64Key), - generator: &Option, + generator: &Addr, ) -> StdResult { self.load(deps.storage, key).or_else(|_| { let old_lockup_info = OLD_LOCKUP_INFO.load(deps.storage, key)?; let mut generator_proxy_debt = RestrictedVector::default(); - let generator = generator.as_ref().expect("Generator should be set!"); if !old_lockup_info.generator_proxy_debt.is_zero() { let asset = ASSET_POOLS.load(deps.storage, key.0)?; @@ -101,7 +94,7 @@ impl CompatibleLoader<(PoolType, &Addr, U64Key), LockupInfoV2> &self, deps: Deps, key: (PoolType, &Addr, U64Key), - generator: &Option, + generator: &Addr, ) -> StdResult> { if !OLD_LOCKUP_INFO.has(deps.storage, key) { return Ok(None); diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 6dcbd342..cfc27bfd 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -5,7 +5,6 @@ use cosmwasm_std::{ to_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, WasmMsg, }; -use cw20::Cw20ReceiveMsg; use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -70,32 +69,20 @@ impl<'a> Prefixer<'a> for PoolType { pub struct InstantiateMsg { /// Account which can update config pub owner: Option, - /// Account which can update token addresses and generator - pub token_info_manager: String, + /// Original XYK lockdrop contract address + pub xyk_lockdrop_contract: String, /// Credits contract address pub credits_contract: String, /// Auction contract address pub auction_contract: String, - /// Timestamp when Contract will start accepting LP Token deposits - pub init_timestamp: u64, - /// Number of seconds during which lockup deposits will be accepted - pub lock_window: u64, - /// Withdrawal Window Length :: Post the deposit window - pub withdrawal_window: u64, - /// Min. no. of weeks allowed for lockup - pub min_lock_duration: u64, - /// Max. no. of weeks allowed for lockup - pub max_lock_duration: u64, - /// Max lockup positions a user can have - pub max_positions_per_user: u32, + /// Generator (Staking for dual rewards) contract address + pub generator: String, /// Describes rewards coefficients for each lockup duration pub lockup_rewards_info: Vec, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct UpdateConfigMsg { - /// Bootstrap Auction contract address - pub auction_contract_address: Option, /// Generator (Staking for dual rewards) contract address pub generator_address: Option, } @@ -103,43 +90,10 @@ pub struct UpdateConfigMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { - IncreaseLockupFor { - user_address: String, - pool_type: PoolType, - amount: Uint128, - duration: u64, - }, - // Receive hook used to accept LP Token deposits - Receive(Cw20ReceiveMsg), - #[serde(rename = "increase_ntrn_incentives")] - IncreaseNTRNIncentives {}, // ADMIN Function ::: To update configuration UpdateConfig { new_config: UpdateConfigMsg, }, - SetTokenInfo { - atom_token: String, - usdc_token: String, - generator: String, - }, - // Function to facilitate LP Token withdrawals from lockups - WithdrawFromLockup { - user_address: String, - pool_type: PoolType, - duration: u64, - amount: Uint128, - }, - - // ADMIN Function ::: To Migrate liquidity from terraswap to astroport - // MigrateLiquidity { - // terraswap_lp_token: String, - // astroport_pool_addr: String, - // slippage_tolerance: Option, - // }, - // ADMIN Function ::: To stake LP Tokens with the generator contract - // StakeLpTokens { - // pool_type: PoolType, - // }, // Facilitates ASTRO reward withdrawal which have not been delegated to bootstrap auction along with optional Unlock (can be forceful) // If withdraw_lp_stake is true and force_unlock is false, it Unlocks the lockup position if its lockup duration has concluded // If both withdraw_lp_stake and force_unlock are true, it forcefully unlocks the positon. user needs to approve ASTRO Token to @@ -244,12 +198,6 @@ pub enum QueryMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct MigrateMsg {} -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] -pub struct MigrationInfo { - pub terraswap_migrated_amount: Uint128, - pub astroport_lp_token: Addr, -} - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct LockupRewardsInfo { pub duration: u64, @@ -260,28 +208,16 @@ pub struct LockupRewardsInfo { pub struct Config { /// Account which can update the config pub owner: Addr, - /// Account which can update the generator and token addresses - pub token_info_manager: Addr, + /// Original XYK lockdrop contract address + pub xyk_lockdrop_contract: Addr, /// Credits contract address pub credits_contract: Addr, /// Bootstrap Auction contract address pub auction_contract: Addr, /// Generator (Staking for dual rewards) contract address - pub generator: Option, - /// Timestamp when Contract will start accepting LP Token deposits - pub init_timestamp: u64, - /// Number of seconds during which lockup positions be accepted - pub lock_window: u64, - /// Withdrawal Window Length :: Post the deposit window - pub withdrawal_window: u64, - /// Min. no. of weeks allowed for lockup - pub min_lock_duration: u64, - /// Max. no. of weeks allowed for lockup - pub max_lock_duration: u64, + pub generator: Addr, /// Total NTRN lockdrop incentives to be distributed among the users pub lockdrop_incentives: Uint128, - /// Max lockup positions a user can have - pub max_positions_per_user: u32, /// Describes rewards coefficients for each lockup duration pub lockup_rewards_info: Vec, } @@ -419,8 +355,3 @@ pub struct LockUpInfoResponse { pub astroport_lp_token: Addr, pub astroport_lp_transferred: Option, } - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct PendingAssetRewardResponse { - pub amount: Uint128, -} From 795ef424077384bda9318b65eaef8cb3861f355d Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 25 Jan 2024 13:08:20 +0300 Subject: [PATCH 02/28] add init version of lockdrop liquidity migration to PCL --- contracts/lockdrop-pcl/src/contract.rs | 230 +++++++- contracts/lockdrop/src/contract.rs | 515 +++++++++++++++++- contracts/lockdrop/src/state.rs | 3 + packages/astroport_periphery/src/lockdrop.rs | 55 +- .../astroport_periphery/src/lockdrop_pcl.rs | 119 +++- 5 files changed, 884 insertions(+), 38 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 5d0cd2f1..3dbc4737 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -1,5 +1,6 @@ use std::cmp::min; use std::convert::TryInto; +use std::ops::Sub; use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; @@ -8,22 +9,27 @@ use astroport::cosmwasm_ext::IntegerToDecimal; use astroport::generator::{ ExecuteMsg as GenExecuteMsg, PendingTokenResponse, QueryMsg as GenQueryMsg, RewardInfoResponse, }; +use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; use astroport_periphery::utils::Decimal256CheckedOps; use cosmwasm_std::{ attr, coins, entry_point, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, - Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, - Uint256, WasmMsg, + Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, + Uint128, Uint256, WasmMsg, }; use cw2::set_contract_version; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use crate::raw_queries::{raw_balance, raw_generator_deposit}; +use astroport_periphery::lockdrop::{ + LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, + UserInfo as LockdropXYKUserInfo, +}; use astroport_periphery::lockdrop_pcl::{ CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, - MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, - UserInfoResponse, UserInfoWithListResponse, + LockupInfoV2, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + UserInfo, UserInfoResponse, UserInfoWithListResponse, }; use crate::state::{ @@ -44,7 +50,7 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> StdResult { @@ -71,11 +77,35 @@ pub fn instantiate( credits_contract: deps.api.addr_validate(&msg.credits_contract)?, auction_contract: deps.api.addr_validate(&msg.auction_contract)?, generator: deps.api.addr_validate(&msg.generator)?, - lockdrop_incentives: Uint128::zero(), + lockdrop_incentives: msg.lockdrop_incentives, lockup_rewards_info: msg.lockup_rewards_info, }; - CONFIG.save(deps.storage, &config)?; + + // Initialize NTRN/ATOM pool + let pool_info = PoolInfo { + lp_token: deps.api.addr_validate(&msg.atom_token)?, + amount_in_lockups: Default::default(), + incentives_share: msg.atom_incentives_share, + weighted_amount: msg.atom_weighted_amount, + generator_ntrn_per_share: Default::default(), + generator_proxy_per_share: RestrictedVector::default(), + is_staked: true, + }; + ASSET_POOLS.save(deps.storage, PoolType::ATOM, &pool_info, env.block.height)?; + + // Initialize NTRN/USDC pool + let pool_info = PoolInfo { + lp_token: deps.api.addr_validate(&msg.usdc_token)?, + amount_in_lockups: Default::default(), + incentives_share: msg.usdc_incentives_share, + weighted_amount: msg.usdc_weighted_amount, + generator_ntrn_per_share: Default::default(), + generator_proxy_per_share: RestrictedVector::default(), + is_staked: true, + }; + ASSET_POOLS.save(deps.storage, PoolType::USDC, &pool_info, env.block.height)?; + STATE.save(deps.storage, &State::default())?; Ok(Response::default()) } @@ -123,6 +153,22 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S }) } ExecuteMsg::UpdateConfig { new_config } => handle_update_config(deps, info, new_config), + ExecuteMsg::MigrateXYKLiquidity { + pool_type, + user_address_raw, + duration, + user_info, + lockup_info, + } => handle_migrate_xyk_liquidity( + deps, + env, + info, + pool_type, + user_address_raw, + duration, + user_info, + lockup_info, + ), } } @@ -164,6 +210,25 @@ fn _handle_callback( duration, withdraw_lp_stake, ), + CallbackMsg::FinishLockupMigrationCallback { + pool_type, + user_address, + duration, + lp_token, + lp_token_balance, + user_info, + lockup_info, + } => callback_finish_lockup_migration( + deps, + env, + pool_type, + user_address, + duration, + lp_token, + lp_token_balance, + user_info, + lockup_info, + ), } } @@ -254,6 +319,93 @@ pub fn handle_update_config( Ok(Response::new().add_attributes(attributes)) } +#[allow(clippy::too_many_arguments)] +/// Creates a lockup position based on the provided parameters and XYK lockdrop contract's state. No +/// validation is performed on the lockup parameters, they are expected to be valid ones because the +/// only valid sender of the message is the XYK lockdrop contract which has already validated them +/// in the beginning of the TGE. +/// +/// Exactly two **Coin**s are expected to be attached to the message as funds. These **Coin**s are +/// used in ProvideLiquidity message sent to the PCL pool, the minted LP tokens are staked to the +/// generator. +pub fn handle_migrate_xyk_liquidity( + deps: DepsMut, + env: Env, + info: MessageInfo, + pool_type: LockdropXYKPoolType, + user_address_raw: String, + duration: u64, + user_info: LockdropXYKUserInfo, + lockup_info: LockdropXYKLockupInfoV2, +) -> StdResult { + let config = CONFIG.load(deps.storage)?; + if info.sender != config.xyk_lockdrop_contract { + return Err(StdError::generic_err( + "only the XYK lockdrop contract is authorized to call the liquidity migration handler", + )); + } + if info.funds.len() != 2 { + return Err(StdError::generic_err( + "exactly two assets are expected to be attached to the message", + )); + } + + // determine the PCL pool address and the current lp token balance + let pool_info = ASSET_POOLS.load(deps.storage, pool_type.into())?; + let astroport_pool: String = deps + .querier + .query_wasm_smart::( + pool_info.lp_token.to_string(), + &cw20::Cw20QueryMsg::Minter {}, + )? + .minter; + let astroport_lp_token_balance = deps + .querier + .query_wasm_smart::( + pool_info.lp_token.to_string(), + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )? + .balance; + + // provide the transferred liquidity to the PCL pool + let mut cosmos_msgs: Vec> = vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: astroport_pool.to_string(), + funds: info.funds.clone(), + msg: to_binary(&ProvideLiquidity { + assets: info + .funds + .iter() + .map(|f| Asset { + info: AssetInfo::NativeToken { + denom: f.denom.clone(), + }, + amount: f.amount, + }) + .collect(), + slippage_tolerance: None, + auto_stake: Some(true), + receiver: None, + })?, + })]; + // invoke callback that creates a lockup entry for the provided liquidity + cosmos_msgs.push( + CallbackMsg::FinishLockupMigrationCallback { + pool_type: pool_type.into(), + user_address: deps.api.addr_validate(&user_address_raw)?, + duration, + lp_token: pool_info.lp_token.to_string(), + lp_token_balance: astroport_lp_token_balance, + user_info, + lockup_info, + } + .to_cosmos_msg(&env)?, + ); + + Ok(Response::default().add_messages(cosmos_msgs)) +} + /// Claims user Rewards for a particular Lockup position. Returns a default object of type [`Response`]. /// ## Params /// * **deps** is an object of type [`DepsMut`]. @@ -760,6 +912,68 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .add_attributes(attributes)) } +#[allow(clippy::too_many_arguments)] +/// Completes the liquidity migration process by making all necessary state updates for the lockup +/// position. +pub fn callback_finish_lockup_migration( + deps: DepsMut, + env: Env, + pool_type: PoolType, + user_address: Addr, + duration: u64, + lp_token: String, + lp_token_balance: Uint128, + user_info: LockdropXYKUserInfo, + lockup_info: LockdropXYKLockupInfoV2, +) -> StdResult { + let astroport_lp_tokens_minted = deps + .querier + .query_wasm_smart::( + lp_token, + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )? + .balance + .sub(lp_token_balance); + + let user_info: UserInfo = user_info.into(); + let lockup_info: LockupInfoV2 = + LockupInfoV2::from_xyk_lockup_info(lockup_info, astroport_lp_tokens_minted); + let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + let config = CONFIG.load(deps.storage)?; + + pool_info.weighted_amount = pool_info.weighted_amount.checked_add(calculate_weight( + astroport_lp_tokens_minted, + duration, + &config, + )?)?; + pool_info.amount_in_lockups = pool_info + .amount_in_lockups + .checked_add(astroport_lp_tokens_minted)?; + + let lockup_key = (pool_type, &user_address, duration); + LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; + + TOTAL_USER_LOCKUP_AMOUNT.update( + deps.storage, + (pool_type, &user_address), + env.block.height, + |lockup_amount| -> StdResult { + if let Some(la) = lockup_amount { + Ok(la.checked_add(astroport_lp_tokens_minted)?) + } else { + Ok(astroport_lp_tokens_minted) + } + }, + )?; + + ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; + USER_INFO.save(deps.storage, &user_address, &user_info)?; + + Ok(Response::default()) +} + /// Returns the contract's State. /// ## Params /// * **deps** is an object of type [`Deps`]. diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index 50aee229..109a737d 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -1,5 +1,6 @@ use std::cmp::min; use std::convert::TryInto; +use std::ops::Sub; use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; @@ -17,7 +18,7 @@ use cosmwasm_std::{ Uint128, Uint256, WasmMsg, }; use cw2::set_contract_version; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg}; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg, MinterResponse}; use crate::raw_queries::{raw_balance, raw_generator_deposit}; use astroport_periphery::lockdrop::{ @@ -25,10 +26,11 @@ use astroport_periphery::lockdrop::{ LockUpInfoSummary, LockupInfoV2, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfoResponse, UserInfoWithListResponse, }; +use astroport_periphery::lockdrop_pcl::ExecuteMsg as LockdropPCLExecuteMsg; use crate::state::{ - CompatibleLoader, ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, STATE, - TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, + CompatibleLoader, ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, PCL_LOCKDROP_CONTRACT, + STATE, TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, }; const AIRDROP_REWARDS_MULTIPLIER: &str = "1.0"; @@ -212,6 +214,9 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S atom_token, generator, } => handle_set_token_info(deps, env, info, usdc_token, atom_token, generator), + ExecuteMsg::MigrateLiquidityToPCLPools { user_address_raw } => { + handle_migrate_liquidity_to_pcl_pools(deps, info, env, user_address_raw) + } } } @@ -303,6 +308,28 @@ fn _handle_callback( duration, withdraw_lp_stake, ), + CallbackMsg::WithdrawUserLockupCallback { + pool_type, + user_address, + duration, + } => callback_withdraw_user_lockup(deps, env, pool_type, user_address, duration), + CallbackMsg::MigrateUserLockupToPCLPairCallback { + pool_type, + user_address, + duration, + ntrn_balance, + paired_asset_denom, + paired_asset_balance, + } => callback_migrate_user_lockup_to_pcl_pair( + deps, + env, + pool_type, + user_address, + duration, + ntrn_balance, + paired_asset_denom, + paired_asset_balance, + ), } } @@ -392,7 +419,11 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { /// /// * **_msg** is an object of type [`MigrateMsg`]. #[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 { + PCL_LOCKDROP_CONTRACT.save( + deps.storage, + &deps.api.addr_validate(&msg.pcl_lockdrop_contract)?, + )?; Ok(Response::default()) } @@ -446,6 +477,182 @@ pub fn handle_update_config( Ok(Response::new().add_attributes(attributes)) } +/// Liquidity migration entry point. Starts the locked liquidity migration from this lockdrop contract +/// which stores the liquidity in XYK pools to another lockdrop contract which works with PCL pools. +/// A single call to this handler migrates all lockup positions of a single user. If user is not +/// specified, the caller's address is used to determine the lockup positions to migrate. +/// +/// Liquidity migration process consists of several sequential messages invocation and mostly mimics +/// (and clones code of) the **ClaimRewardsAndOptionallyUnlock** called with **withdraw_lp_stake=true** +/// for each lockup position. So, for this contract's state, liquidity migration looks like lockup +/// positions unlock by the user. +pub fn handle_migrate_liquidity_to_pcl_pools( + mut deps: DepsMut, + info: MessageInfo, + env: Env, + user_address_raw: Option, +) -> StdResult { + let user_address = match user_address_raw { + Some(addr) => deps.api.addr_validate(&addr)?, + None => info.sender, + }; + + let config = CONFIG.load(deps.storage)?; + let state = STATE.load(deps.storage)?; + + let mut user_info = USER_INFO + .may_load(deps.storage, &user_address)? + .unwrap_or_default(); + // If user's total NTRN rewards == 0 :: We update all of the user's lockup positions to + // calculate NTRN rewards and for each alongwith their equivalent Astroport LP Shares + if user_info.total_ntrn_rewards == Uint128::zero() { + user_info.total_ntrn_rewards = update_user_lockup_positions_and_calc_rewards( + deps.branch(), + &config, + &state, + &user_address, + )?; + USER_INFO.save(deps.storage, &user_address, &user_info)?; + } + + // collect all user's lockups + let mut user_lockups: Vec<(PoolType, u64)> = vec![]; + for pool_type in ASSET_POOLS + .keys(deps.storage, None, None, Order::Ascending) + .collect::, StdError>>()? + { + for duration in LOCKUP_INFO + .prefix((pool_type, &user_address)) + .keys(deps.storage, None, None, Order::Ascending) + .collect::, StdError>>()? + { + user_lockups.push((pool_type, duration)); + } + } + + let mut resp: Response = Response::default(); + // migrate all user lockups sequentially + for (pool_type, duration) in user_lockups { + let iter_resp = migrate_lockup_to_pcl_pool( + &mut deps, + env.clone(), + pool_type, + user_address.clone(), + duration, + )?; + resp.attributes.extend(iter_resp.attributes); + resp.events.extend(iter_resp.events); + resp.messages.extend(iter_resp.messages); + } + Ok(resp) +} + +/// Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator +/// rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the +/// respective callback message. +fn migrate_lockup_to_pcl_pool( + deps: &mut DepsMut, + env: Env, + pool_type: PoolType, + user_address: Addr, + duration: u64, +) -> Result { + let lockup_info = query_lockup_info( + deps.as_ref(), + &env, + user_address.as_str(), + pool_type, + duration, + )?; + + if lockup_info.astroport_lp_transferred.is_some() { + return Ok(Response::default().add_attribute( + format!("{:?}_for_{}", pool_type, duration), + "already_been_claimed", + )); + } + + let config = CONFIG.load(deps.storage)?; + let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + let astroport_lp_token = pool_info.lp_token; + let generator = config + .generator + .as_ref() + .ok_or_else(|| StdError::generic_err("Generator should be set at this moment!"))?; + + // QUERY :: Check if there are any pending staking rewards + let pending_rewards: PendingTokenResponse = deps.querier.query_wasm_smart( + generator, + &GenQueryMsg::PendingToken { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; + let pending_on_proxy = &pending_rewards.pending_on_proxy.unwrap_or_default(); + let mut cosmos_msgs = vec![]; + if !pending_rewards.pending.is_zero() + || pending_on_proxy.iter().any(|asset| !asset.amount.is_zero()) + { + let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( + generator, + &GenQueryMsg::RewardInfo { + lp_token: astroport_lp_token.to_string(), + }, + )?; + + let reward_token_balance = deps + .querier + .query_balance( + env.contract.address.clone(), + rwi.base_reward_token.to_string(), + )? + .amount; + + let prev_proxy_reward_balances: Vec = pending_on_proxy + .iter() + .map(|asset| { + let balance = asset + .info + .query_pool(&deps.querier, env.contract.address.clone()) + .unwrap_or_default(); + + Asset { + info: asset.info.clone(), + amount: balance, + } + }) + .collect(); + + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: generator.to_string(), + funds: vec![], + msg: to_binary(&GenExecuteMsg::ClaimRewards { + lp_tokens: vec![astroport_lp_token.to_string()], + })?, + })); + + cosmos_msgs.push( + CallbackMsg::UpdatePoolOnDualRewardsClaim { + pool_type, + prev_ntrn_balance: reward_token_balance, + prev_proxy_reward_balances, + } + .to_cosmos_msg(&env)?, + ); + } + + cosmos_msgs.push( + CallbackMsg::WithdrawUserLockupCallback { + pool_type, + user_address, + duration, + } + .to_cosmos_msg(&env)?, + ); + + Ok(Response::default().add_messages(cosmos_msgs)) +} + pub fn handle_set_token_info( deps: DepsMut, env: Env, @@ -1443,6 +1650,306 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .add_attributes(attributes)) } +/// Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the +/// PCL lockdrop contract, and claims all possible rewards for the user. The claimed user's rewards +/// are generator staking rewards and proxy rewards, one time NTRN rewards and rewards for airdrop +/// participants. This makes sure the XYK lockdrop contract has no obligations once the liquidity +/// is migrated, and the only obligations the PCL lockdrop contract will have are the LP tokens, +/// generator staking rewards and proxy rewards. +pub fn callback_withdraw_user_lockup( + deps: DepsMut, + env: Env, + pool_type: PoolType, + user_address: Addr, + duration: u64, +) -> StdResult { + let config = CONFIG.load(deps.storage)?; + let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + let lockup_key = (pool_type, &user_address, duration); + let mut lockup_info = + LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; + + let mut user_info = USER_INFO + .may_load(deps.storage, &user_address)? + .unwrap_or_default(); + + let mut cosmos_msgs = vec![]; + + let astroport_lp_token = pool_info.lp_token.clone(); + + let generator = config + .generator + .as_ref() + .ok_or_else(|| StdError::generic_err("Generator should be set"))?; + + // Calculate Astro LP share for the lockup position + let astroport_lp_amount: Uint128 = { + let balance: Uint128 = if pool_info.is_staked { + deps.querier.query_wasm_smart( + generator, + &GenQueryMsg::Deposit { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )? + } else { + let res: BalanceResponse = deps.querier.query_wasm_smart( + astroport_lp_token.clone(), + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )?; + res.balance + }; + + (lockup_info + .lp_units_locked + .full_mul(balance) + .checked_div(Uint256::from(pool_info.amount_in_lockups))?) + .try_into()? + }; + + let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( + generator, + &GenQueryMsg::RewardInfo { + lp_token: astroport_lp_token.to_string(), + }, + )?; + + // Calculate claimable staking rewards for this lockup + let total_lockup_astro_rewards = pool_info + .generator_ntrn_per_share + .checked_mul(astroport_lp_amount.to_decimal())? + .to_uint_floor(); + let pending_astro_rewards = + total_lockup_astro_rewards.checked_sub(lockup_info.generator_ntrn_debt)?; + lockup_info.generator_ntrn_debt = total_lockup_astro_rewards; + + // If claimable staking rewards > 0, claim them and send to the user + if pending_astro_rewards > Uint128::zero() { + cosmos_msgs.push(CosmosMsg::Bank(BankMsg::Send { + to_address: user_address.to_string(), + amount: vec![Coin { + denom: rwi.base_reward_token.to_string(), + amount: pending_astro_rewards, + }], + })); + } + + let mut pending_proxy_rewards: Vec = vec![]; + // If this LP token is getting dual incentives + // Calculate claimable proxy staking rewards for this lockup + lockup_info.generator_proxy_debt = lockup_info + .generator_proxy_debt + .inner_ref() + .iter() + .map(|(asset, debt)| { + let generator_proxy_per_share = pool_info + .generator_proxy_per_share + .load(asset) + .unwrap_or_default(); + let total_lockup_proxy_reward = + generator_proxy_per_share.checked_mul_uint128(astroport_lp_amount)?; + let pending_proxy_reward: Uint128 = total_lockup_proxy_reward.checked_sub(*debt)?; + + if !pending_proxy_reward.is_zero() { + pending_proxy_rewards.push(Asset { + info: asset.clone(), + amount: pending_proxy_reward, + }); + } + Ok((asset.clone(), total_lockup_proxy_reward)) + }) + .collect::>>()? + .into(); + + // If claimable proxy staking rewards > 0, claim them + for pending_proxy_reward in pending_proxy_rewards { + cosmos_msgs.push(pending_proxy_reward.into_msg(&deps.querier, user_address.clone())?); + } + + pool_info.amount_in_lockups = pool_info + .amount_in_lockups + .checked_sub(lockup_info.lp_units_locked)?; + ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; + + lockup_info.astroport_lp_transferred = Some(astroport_lp_amount); + TOTAL_USER_LOCKUP_AMOUNT.update( + deps.storage, + (pool_type, &user_address), + env.block.height, + |lockup_amount| -> StdResult { + if let Some(la) = lockup_amount { + Ok(la.checked_sub(lockup_info.lp_units_locked)?) + } else { + Ok(Uint128::zero()) + } + }, + )?; + LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; + + // Transfers claimable one time NTRN rewards to the user that the user gets for all his lock + if !user_info.ntrn_transferred { + // Calculating how much NTRN user can claim (from total one time reward) + let total_claimable_ntrn_rewards = user_info.total_ntrn_rewards; + if total_claimable_ntrn_rewards > Uint128::zero() { + cosmos_msgs.push(CosmosMsg::Bank(BankMsg::Send { + to_address: user_address.to_string(), + amount: coins(total_claimable_ntrn_rewards.u128(), UNTRN_DENOM), + })) + } + + // claim airdrop rewards for airdrop participants + let res: BalanceResponse = deps.querier.query_wasm_smart( + config.credits_contract.clone(), + &Cw20QueryMsg::Balance { + address: user_address.to_string(), + }, + )?; + if res.balance > Uint128::zero() { + cosmos_msgs.push(claim_airdrop_tokens_with_multiplier_msg( + deps.as_ref(), + config.credits_contract, + user_address.clone(), + total_claimable_ntrn_rewards, + )?); + } + + user_info.ntrn_transferred = true; + USER_INFO.save(deps.storage, &user_address, &user_info)?; + } + + // below we unstake the staked LP amount, withdraw it from the pool and invoke callback that will + // send the withdrawn assets to the PCL lockdrop contract + + // withdraw the staked lp tokens from the generator + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: generator.to_string(), + funds: vec![], + msg: to_binary(&GenExecuteMsg::Withdraw { + lp_token: astroport_lp_token.to_string(), + amount: astroport_lp_amount, + })?, + })); + + // determine the pool address and the denom of the second (not untrn) token in the pool + let astroport_pool: String = deps + .querier + .query_wasm_smart::( + astroport_lp_token.to_string(), + &cw20::Cw20QueryMsg::Minter {}, + )? + .minter; + let astroport_pool_info: astroport::pair::PoolResponse = deps + .querier + .query_wasm_smart(astroport_pool.clone(), &astroport::pair::QueryMsg::Pool {})?; + let paired_asset_denom = astroport_pool_info + .assets + .iter() + .find_map(|x| match &x.info { + AssetInfo::NativeToken { denom } if denom != UNTRN_DENOM => Some(denom.clone()), + _ => None, + }) + .ok_or_else(|| StdError::generic_err("No second leg of pair found"))?; + + // determine contract balances before withdrawal + let ntrn_balance = deps + .querier + .query_balance(&env.contract.address, UNTRN_DENOM)? + .amount; + let paired_asset_balance = deps + .querier + .query_balance(&env.contract.address, paired_asset_denom.clone())? + .amount; + + // withdraw liquidity from the XYK pool + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: astroport_lp_token.to_string(), + funds: vec![], + msg: to_binary(&Cw20ExecuteMsg::Send { + contract: astroport_pool, + amount: astroport_lp_amount, + msg: to_binary(&astroport::pair::Cw20HookMsg::WithdrawLiquidity { assets: vec![] })?, + })?, + })); + + // invoke callback that transfers the liquidity to the PCL lockdrop + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.to_string(), + funds: vec![], + msg: to_binary(&CallbackMsg::MigrateUserLockupToPCLPairCallback { + pool_type, + user_address: user_address.clone(), + duration, + ntrn_balance, + paired_asset_denom, + paired_asset_balance, + })?, + })); + + Ok(Response::new().add_messages(cosmos_msgs)) +} + +#[allow(clippy::too_many_arguments)] +/// Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in +/// the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's +/// lockup position. The funds attached to the MigrateXYKLiquidity message are calculated based on +/// the balance differences of the assets from the WithdrawLiquidity made at the previous step of the +/// migration process. +pub fn callback_migrate_user_lockup_to_pcl_pair( + deps: DepsMut, + env: Env, + pool_type: PoolType, + user_address: Addr, + duration: u64, + ntrn_balance: Uint128, + paired_asset_denom: String, + paired_asset_balance: Uint128, +) -> StdResult { + let config = CONFIG.load(deps.storage)?; + let lockup_key = (pool_type, &user_address, duration); + let lockup_info = LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; + let user_info = USER_INFO + .may_load(deps.storage, &user_address)? + .unwrap_or_default(); + + // determine withdrawn amounts + let ntrn_withdrawn = deps + .querier + .query_balance(&env.contract.address, UNTRN_DENOM)? + .amount + .sub(ntrn_balance); + let paired_asset_withdrawn = deps + .querier + .query_balance(&env.contract.address, paired_asset_denom.clone())? + .amount + .sub(paired_asset_balance); + + let pcl_lockdrop = PCL_LOCKDROP_CONTRACT.load(deps.storage)?; + Ok( + Response::default().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: pcl_lockdrop.to_string(), + funds: vec![ + Coin { + denom: UNTRN_DENOM.to_string(), + amount: ntrn_withdrawn, + }, + Coin { + denom: paired_asset_denom.to_string(), + amount: paired_asset_withdrawn, + }, + ], + msg: to_binary(&LockdropPCLExecuteMsg::MigrateXYKLiquidity { + pool_type, + user_address_raw: user_address.to_string(), + duration, + user_info, + lockup_info, + })?, + })), + ) +} + /// Returns the contract's State. /// ## Params /// * **deps** is an object of type [`Deps`]. diff --git a/contracts/lockdrop/src/state.rs b/contracts/lockdrop/src/state.rs index 5b817721..9eab8c25 100644 --- a/contracts/lockdrop/src/state.rs +++ b/contracts/lockdrop/src/state.rs @@ -14,6 +14,9 @@ use crate::raw_queries::raw_proxy_asset; pub const CONFIG: Item = Item::new("config"); pub const STATE: Item = Item::new("state"); +/// The address of the lockdrop contract working with PCL pools. Used in users' locked liquidity +/// migration from XYK pools to PCL ones. +pub const PCL_LOCKDROP_CONTRACT: Item = Item::new("pcl_lockdrop_contract"); /// Key is an Terraswap LP token address pub const ASSET_POOLS: SnapshotMap = SnapshotMap::new( diff --git a/packages/astroport_periphery/src/lockdrop.rs b/packages/astroport_periphery/src/lockdrop.rs index 6dcbd342..0e0cfedb 100644 --- a/packages/astroport_periphery/src/lockdrop.rs +++ b/packages/astroport_periphery/src/lockdrop.rs @@ -163,6 +163,14 @@ pub enum ExecuteMsg { DropOwnershipProposal {}, /// Used to claim contract ownership. ClaimOwnership {}, + /// Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation + /// rewards to the address which liquidity has been migrated. + #[serde(rename = "migrate_liquidity_to_pcl_pools")] + MigrateLiquidityToPCLPools { + /// The address which liquidity is supposed to be transferred. If no user address is + /// provided, the message sender's address is used. + user_address_raw: Option, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] @@ -181,23 +189,52 @@ pub enum Cw20HookMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum CallbackMsg { + /// Updates contract state after dual staking rewards are claimed from the generator contract. UpdatePoolOnDualRewardsClaim { pool_type: PoolType, prev_ntrn_balance: Uint128, prev_proxy_reward_balances: Vec, }, + /// Withdraws user rewards and LP Tokens after claims / unlocks. WithdrawUserLockupRewardsCallback { pool_type: PoolType, user_address: Addr, duration: u64, withdraw_lp_stake: bool, }, - // WithdrawLiquidityFromTerraswapCallback { - // terraswap_lp_token: Addr, - // astroport_pool: Addr, - // prev_assets: [terraswap::asset::Asset; 2], - // slippage_tolerance: Option, - // }, + /// The first step in the lockup's XYK -> PCL liquidity migration process. + /// Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to + /// the PCL lockdrop contract, and claims all possible rewards for the user. + WithdrawUserLockupCallback { + /// The type of the pool the lockup is related to. + pool_type: PoolType, + /// The address of the user which owns the lockup. + user_address: Addr, + /// The duration of the lock period. + duration: u64, + }, + /// The second step in the lockup's XYK -> PCL liquidity migration process. + /// Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position + /// in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn + /// user's lockup position. + #[serde(rename = "migrate_user_lockup_to_pcl_pair_callback")] + MigrateUserLockupToPCLPairCallback { + /// The type of the pool the lockup is related to. + pool_type: PoolType, + /// The address of the user which owns the lockup. + user_address: Addr, + /// The duration of the lock period. + duration: u64, + /// The balance in untrn of the XYK lockdrop contract at the first migration step. Is used + /// in the callback to calculate the amount of untrn been withdrawn from the XYK pool. + ntrn_balance: Uint128, + /// The denom of the paired asset (the asset paired with untrn in the pool). + paired_asset_denom: String, + /// The balance in the paired denom of the XYK lockdrop contract at the first migration step. + /// Is used in the callback to calculate the amount of the paired asset been withdrawn + /// from the XYK pool. + paired_asset_balance: Uint128, + }, } // Modified from @@ -242,7 +279,11 @@ pub enum QueryMsg { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct MigrateMsg {} +pub struct MigrateMsg { + /// The address of the lockdrop contract working with PCL pools. Used to transfer + /// the lockdrop's liquidity locked in XYK pools to more efficient pools. + pub pcl_lockdrop_contract: String, +} #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] pub struct MigrationInfo { diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index cfc27bfd..eb8e90a6 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -1,3 +1,7 @@ +use crate::lockdrop::{ + LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, + UserInfo as LockdropXYKUserInfo, +}; use astroport::asset::{Asset, AssetInfo}; use astroport::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; @@ -16,6 +20,15 @@ pub enum PoolType { ATOM, } +impl From for PoolType { + fn from(t: LockdropXYKPoolType) -> PoolType { + match t { + LockdropXYKPoolType::USDC => PoolType::USDC, + LockdropXYKPoolType::ATOM => PoolType::ATOM, + } + } +} + #[allow(clippy::from_over_into)] impl Into for PoolType { fn into(self) -> String { @@ -79,6 +92,28 @@ pub struct InstantiateMsg { pub generator: String, /// Describes rewards coefficients for each lockup duration pub lockup_rewards_info: Vec, + /// Address of the LP token of the NTRN/USDC PCL pool + pub usdc_token: String, + /// Address of the LP token of the NTRN/ATOM PCL pool + pub atom_token: String, + + /* + Since no NTRN rewards are distributed from the PCL lockdrop contract, the fields below are + just used to fill the contract's state with the same values as it is in the XYK lockdrop + contract. So the values should be just copied from the XYK lockdrop contract's state. + */ + /// Total NTRN lockdrop incentives distributed among the users. + pub lockdrop_incentives: Uint128, + /// Share of total NTRN incentives allocated to the NTRN/USDC PCL pool + pub usdc_incentives_share: Uint128, + /// Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/USDC pool + /// depositor can claim + pub usdc_weighted_amount: Uint256, + /// Share of total NTRN incentives allocated to the NTRN/ATOM PCL pool + pub atom_incentives_share: Uint128, + /// Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/ATOM pool + /// depositor can claim + pub atom_weighted_amount: Uint256, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] @@ -117,18 +152,22 @@ pub enum ExecuteMsg { DropOwnershipProposal {}, /// Used to claim contract ownership. ClaimOwnership {}, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum Cw20HookMsg { - // Called by the bootstrap auction contract when liquidity is added to the - // Pool to enable ASTRO withdrawals by users - // EnableClaims {}, - // ADMIN Function ::: Add new Pool (Only Terraswap Pools) - InitializePool { - pool_type: PoolType, - incentives_share: Uint128, + /// A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable + /// by the original lockdrop contract. + #[serde(rename = "migrate_xyk_liquidity")] + MigrateXYKLiquidity { + /// The type of the pool the lockup is related to. + pool_type: LockdropXYKPoolType, + /// The address of the user which owns the lockup. + user_address_raw: String, + /// The duration of the lock period. + duration: u64, + /// The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo + /// entry on the PCL lockdrop contract's side. + user_info: LockdropXYKUserInfo, + /// The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry + /// on the PCL lockdrop contract's side. + lockup_info: LockdropXYKLockupInfoV2, }, } @@ -146,12 +185,26 @@ pub enum CallbackMsg { duration: u64, withdraw_lp_stake: bool, }, - // WithdrawLiquidityFromTerraswapCallback { - // terraswap_lp_token: Addr, - // astroport_pool: Addr, - // prev_assets: [terraswap::asset::Asset; 2], - // slippage_tolerance: Option, - // }, + /// Completes the liquidity migration process by making all necessary state updates for the lockup + /// position. + FinishLockupMigrationCallback { + /// The type of the pool the lockup is related to. + pool_type: PoolType, + /// The address of the user which owns the lockup. + user_address: Addr, + /// The duration of the lock period. + duration: u64, + /// The address of the LP token of the pool. + lp_token: String, + /// The balance in the LP token of the PCL lockdrop contract before liquidity provision. + lp_token_balance: Uint128, + /// The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo + /// entry on the PCL lockdrop contract's side. + user_info: LockdropXYKUserInfo, + /// The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry + /// on the PCL lockdrop contract's side. + lockup_info: LockdropXYKLockupInfoV2, + }, } // Modified from @@ -232,7 +285,6 @@ pub struct State { pub struct PoolInfo { pub lp_token: Addr, pub amount_in_lockups: Uint128, - // pub migration_info: Option, /// Share of total NTRN incentives allocated to this pool pub incentives_share: Uint128, /// Weighted LP Token balance used to calculate NTRN rewards a particular user can claim @@ -255,6 +307,16 @@ pub struct UserInfo { pub lockup_positions_index: u32, } +impl From for UserInfo { + fn from(i: LockdropXYKUserInfo) -> UserInfo { + UserInfo { + total_ntrn_rewards: i.total_ntrn_rewards, + ntrn_transferred: i.ntrn_transferred, + lockup_positions_index: i.lockup_positions_index, + } + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct LockupInfoV1 { /// Terraswap LP units locked by the user @@ -289,6 +351,25 @@ pub struct LockupInfoV2 { pub unlock_timestamp: u64, } +impl LockupInfoV2 { + /// Creates a lockup entry for PCL lockdrop contract based on a lockup entry for XYK lockdrop + /// contract. The **lp_units_locked** field is the amount of lp tokens minted by the PCL pool. + pub fn from_xyk_lockup_info( + i: LockdropXYKLockupInfoV2, + lp_units_locked: Uint128, + ) -> LockupInfoV2 { + LockupInfoV2 { + lp_units_locked, + astroport_lp_transferred: None, + withdrawal_flag: i.withdrawal_flag, + ntrn_rewards: i.ntrn_rewards, + generator_ntrn_debt: Uint128::zero(), + generator_proxy_debt: Default::default(), + unlock_timestamp: i.unlock_timestamp, + } + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct StateResponse { /// Total NTRN incentives share From ec50f680344ba307171fa39b15be15ba71ab684c Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Fri, 2 Feb 2024 14:07:39 +0300 Subject: [PATCH 03/28] refine liquidity migration steps, add comments --- contracts/lockdrop-pcl/src/contract.rs | 57 +++--- contracts/lockdrop/src/contract.rs | 173 ++++++++++++------ packages/astroport_periphery/src/lockdrop.rs | 38 +++- .../astroport_periphery/src/lockdrop_pcl.rs | 8 +- 4 files changed, 184 insertions(+), 92 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 3dbc4737..647d9890 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -215,7 +215,7 @@ fn _handle_callback( user_address, duration, lp_token, - lp_token_balance, + staked_lp_token_amount, user_info, lockup_info, } => callback_finish_lockup_migration( @@ -225,7 +225,7 @@ fn _handle_callback( user_address, duration, lp_token, - lp_token_balance, + staked_lp_token_amount, user_info, lockup_info, ), @@ -328,6 +328,12 @@ pub fn handle_update_config( /// Exactly two **Coin**s are expected to be attached to the message as funds. These **Coin**s are /// used in ProvideLiquidity message sent to the PCL pool, the minted LP tokens are staked to the /// generator. +/// +/// Liquidity migration process consists of several sequential messages invocation and from this +/// contract's point of view it mostly mimics (and clones code of) the **IncreaseLockupFor** exec +/// handler of the XYK lockdrop contract called for each lockup position. So, for this contract's +/// state, liquidity migration looks like lockups creation just like it happened in the beginning +/// of the token generation event (TGE). pub fn handle_migrate_xyk_liquidity( deps: DepsMut, env: Env, @@ -350,7 +356,7 @@ pub fn handle_migrate_xyk_liquidity( )); } - // determine the PCL pool address and the current lp token balance + // determine the PCL pool info and the current staked lp token amount let pool_info = ASSET_POOLS.load(deps.storage, pool_type.into())?; let astroport_pool: String = deps .querier @@ -359,15 +365,13 @@ pub fn handle_migrate_xyk_liquidity( &cw20::Cw20QueryMsg::Minter {}, )? .minter; - let astroport_lp_token_balance = deps - .querier - .query_wasm_smart::( - pool_info.lp_token.to_string(), - &Cw20QueryMsg::Balance { - address: env.contract.address.to_string(), - }, - )? - .balance; + let staked_lp_token_amount = deps.querier.query_wasm_smart::( + config.generator.to_string(), + &GenQueryMsg::Deposit { + lp_token: pool_info.lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; // provide the transferred liquidity to the PCL pool let mut cosmos_msgs: Vec> = vec![CosmosMsg::Wasm(WasmMsg::Execute { @@ -396,7 +400,7 @@ pub fn handle_migrate_xyk_liquidity( user_address: deps.api.addr_validate(&user_address_raw)?, duration, lp_token: pool_info.lp_token.to_string(), - lp_token_balance: astroport_lp_token_balance, + staked_lp_token_amount, user_info, lockup_info, } @@ -922,35 +926,36 @@ pub fn callback_finish_lockup_migration( user_address: Addr, duration: u64, lp_token: String, - lp_token_balance: Uint128, + staked_lp_token_amount: Uint128, user_info: LockdropXYKUserInfo, lockup_info: LockdropXYKLockupInfoV2, ) -> StdResult { - let astroport_lp_tokens_minted = deps + let config = CONFIG.load(deps.storage)?; + let staked_lp_token_amount_diff = deps .querier - .query_wasm_smart::( - lp_token, - &Cw20QueryMsg::Balance { - address: env.contract.address.to_string(), + .query_wasm_smart::( + config.generator.to_string(), + &GenQueryMsg::Deposit { + lp_token, + user: env.contract.address.to_string(), }, )? - .balance - .sub(lp_token_balance); + .sub(staked_lp_token_amount); let user_info: UserInfo = user_info.into(); let lockup_info: LockupInfoV2 = - LockupInfoV2::from_xyk_lockup_info(lockup_info, astroport_lp_tokens_minted); + LockupInfoV2::from_xyk_lockup_info(lockup_info, staked_lp_token_amount_diff); let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let config = CONFIG.load(deps.storage)?; pool_info.weighted_amount = pool_info.weighted_amount.checked_add(calculate_weight( - astroport_lp_tokens_minted, + staked_lp_token_amount_diff, duration, &config, )?)?; pool_info.amount_in_lockups = pool_info .amount_in_lockups - .checked_add(astroport_lp_tokens_minted)?; + .checked_add(staked_lp_token_amount_diff)?; let lockup_key = (pool_type, &user_address, duration); LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; @@ -961,9 +966,9 @@ pub fn callback_finish_lockup_migration( env.block.height, |lockup_amount| -> StdResult { if let Some(la) = lockup_amount { - Ok(la.checked_add(astroport_lp_tokens_minted)?) + Ok(la.checked_add(staked_lp_token_amount_diff)?) } else { - Ok(astroport_lp_tokens_minted) + Ok(staked_lp_token_amount_diff) } }, )?; diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index 109a737d..0300f5b3 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -308,11 +308,41 @@ fn _handle_callback( duration, withdraw_lp_stake, ), + CallbackMsg::InitMigrateLockupToPCLPoolsCallback { + pool_type, + user_address, + duration, + } => { + callback_init_migrate_lockup_to_pcl_pools(deps, env, pool_type, user_address, duration) + } + CallbackMsg::TransferAllRewardsBeforeMigrationCallback { + pool_type, + user_address, + duration, + } => callback_transfer_all_rewards_before_migration( + deps, + env, + pool_type, + user_address, + duration, + ), CallbackMsg::WithdrawUserLockupCallback { pool_type, user_address, duration, - } => callback_withdraw_user_lockup(deps, env, pool_type, user_address, duration), + generator, + astroport_lp_token, + astroport_lp_amount, + } => callback_withdraw_user_lockup( + deps, + env, + pool_type, + user_address, + duration, + generator, + astroport_lp_token, + astroport_lp_amount, + ), CallbackMsg::MigrateUserLockupToPCLPairCallback { pool_type, user_address, @@ -482,10 +512,10 @@ pub fn handle_update_config( /// A single call to this handler migrates all lockup positions of a single user. If user is not /// specified, the caller's address is used to determine the lockup positions to migrate. /// -/// Liquidity migration process consists of several sequential messages invocation and mostly mimics -/// (and clones code of) the **ClaimRewardsAndOptionallyUnlock** called with **withdraw_lp_stake=true** -/// for each lockup position. So, for this contract's state, liquidity migration looks like lockup -/// positions unlock by the user. +/// Liquidity migration process consists of several sequential messages invocation and from this +/// contract's point of view it mostly mimics (and clones code of) the **ClaimRewardsAndOptionallyUnlock** +/// called with **withdraw_lp_stake=true** for each lockup position. So, for this contract's state, +/// liquidity migration looks like lockup positions unlock by the user. pub fn handle_migrate_liquidity_to_pcl_pools( mut deps: DepsMut, info: MessageInfo, @@ -530,28 +560,26 @@ pub fn handle_migrate_liquidity_to_pcl_pools( } } - let mut resp: Response = Response::default(); + let mut cosmos_msgs = vec![]; // migrate all user lockups sequentially for (pool_type, duration) in user_lockups { - let iter_resp = migrate_lockup_to_pcl_pool( - &mut deps, - env.clone(), - pool_type, - user_address.clone(), - duration, - )?; - resp.attributes.extend(iter_resp.attributes); - resp.events.extend(iter_resp.events); - resp.messages.extend(iter_resp.messages); + cosmos_msgs.push( + CallbackMsg::InitMigrateLockupToPCLPoolsCallback { + pool_type, + user_address: user_address.clone(), + duration, + } + .to_cosmos_msg(&env)?, + ); } - Ok(resp) + Ok(Response::default().add_messages(cosmos_msgs)) } /// Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator /// rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the /// respective callback message. -fn migrate_lockup_to_pcl_pool( - deps: &mut DepsMut, +fn callback_init_migrate_lockup_to_pcl_pools( + deps: DepsMut, env: Env, pool_type: PoolType, user_address: Addr, @@ -568,7 +596,7 @@ fn migrate_lockup_to_pcl_pool( if lockup_info.astroport_lp_transferred.is_some() { return Ok(Response::default().add_attribute( format!("{:?}_for_{}", pool_type, duration), - "already_been_claimed", + "already_been_withdrawn", )); } @@ -642,7 +670,7 @@ fn migrate_lockup_to_pcl_pool( } cosmos_msgs.push( - CallbackMsg::WithdrawUserLockupCallback { + CallbackMsg::TransferAllRewardsBeforeMigrationCallback { pool_type, user_address, duration, @@ -1650,13 +1678,12 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .add_attributes(attributes)) } -/// Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the -/// PCL lockdrop contract, and claims all possible rewards for the user. The claimed user's rewards -/// are generator staking rewards and proxy rewards, one time NTRN rewards and rewards for airdrop -/// participants. This makes sure the XYK lockdrop contract has no obligations once the liquidity -/// is migrated, and the only obligations the PCL lockdrop contract will have are the LP tokens, -/// generator staking rewards and proxy rewards. -pub fn callback_withdraw_user_lockup( +/// Claims all possible rewards for the user. The claimed user's rewards are generator staking +/// rewards and proxy rewards, one time NTRN rewards and rewards for airdrop participants. This +/// makes sure the XYK lockdrop contract has no obligations once the liquidity is migrated, and +/// the only obligations the PCL lockdrop contract will have are the minted LP tokens and further +/// generator staking rewards and proxy rewards associated with the LP tokens. +pub fn callback_transfer_all_rewards_before_migration( deps: DepsMut, env: Env, pool_type: PoolType, @@ -1664,7 +1691,7 @@ pub fn callback_withdraw_user_lockup( duration: u64, ) -> StdResult { let config = CONFIG.load(deps.storage)?; - let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let lockup_key = (pool_type, &user_address, duration); let mut lockup_info = LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; @@ -1768,26 +1795,6 @@ pub fn callback_withdraw_user_lockup( cosmos_msgs.push(pending_proxy_reward.into_msg(&deps.querier, user_address.clone())?); } - pool_info.amount_in_lockups = pool_info - .amount_in_lockups - .checked_sub(lockup_info.lp_units_locked)?; - ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; - - lockup_info.astroport_lp_transferred = Some(astroport_lp_amount); - TOTAL_USER_LOCKUP_AMOUNT.update( - deps.storage, - (pool_type, &user_address), - env.block.height, - |lockup_amount| -> StdResult { - if let Some(la) = lockup_amount { - Ok(la.checked_sub(lockup_info.lp_units_locked)?) - } else { - Ok(Uint128::zero()) - } - }, - )?; - LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; - // Transfers claimable one time NTRN rewards to the user that the user gets for all his lock if !user_info.ntrn_transferred { // Calculating how much NTRN user can claim (from total one time reward) @@ -1819,8 +1826,35 @@ pub fn callback_withdraw_user_lockup( USER_INFO.save(deps.storage, &user_address, &user_info)?; } - // below we unstake the staked LP amount, withdraw it from the pool and invoke callback that will - // send the withdrawn assets to the PCL lockdrop contract + cosmos_msgs.push( + CallbackMsg::WithdrawUserLockupCallback { + pool_type, + user_address: user_address.clone(), + duration, + generator: generator.clone(), + astroport_lp_token, + astroport_lp_amount, + } + .to_cosmos_msg(&env)?, + ); + + Ok(Response::new().add_messages(cosmos_msgs)) +} + +#[allow(clippy::too_many_arguments)] +// Unstakes the staked LP amount, withdraws it from the pool and invokes callback that will +// send the withdrawn assets to the PCL lockdrop contract +pub fn callback_withdraw_user_lockup( + deps: DepsMut, + env: Env, + pool_type: PoolType, + user_address: Addr, + duration: u64, + generator: Addr, + astroport_lp_token: Addr, + astroport_lp_amount: Uint128, +) -> StdResult { + let mut cosmos_msgs = vec![]; // withdraw the staked lp tokens from the generator cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { @@ -1873,19 +1907,42 @@ pub fn callback_withdraw_user_lockup( })?, })); - // invoke callback that transfers the liquidity to the PCL lockdrop - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: env.contract.address.to_string(), - funds: vec![], - msg: to_binary(&CallbackMsg::MigrateUserLockupToPCLPairCallback { + // update contract's state in accordance with the just made withdrawal + let config = CONFIG.load(deps.storage)?; + let lockup_key = (pool_type, &user_address, duration); + let mut lockup_info = + LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; + let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + pool_info.amount_in_lockups = pool_info + .amount_in_lockups + .checked_sub(lockup_info.lp_units_locked)?; + ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; + lockup_info.astroport_lp_transferred = Some(astroport_lp_amount); + TOTAL_USER_LOCKUP_AMOUNT.update( + deps.storage, + (pool_type, &user_address), + env.block.height, + |lockup_amount| -> StdResult { + if let Some(la) = lockup_amount { + Ok(la.checked_sub(lockup_info.lp_units_locked)?) + } else { + Ok(Uint128::zero()) + } + }, + )?; + LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; + + cosmos_msgs.push( + CallbackMsg::MigrateUserLockupToPCLPairCallback { pool_type, user_address: user_address.clone(), duration, ntrn_balance, paired_asset_denom, paired_asset_balance, - })?, - })); + } + .to_cosmos_msg(&env)?, + ); Ok(Response::new().add_messages(cosmos_msgs)) } diff --git a/packages/astroport_periphery/src/lockdrop.rs b/packages/astroport_periphery/src/lockdrop.rs index 0e0cfedb..7476789c 100644 --- a/packages/astroport_periphery/src/lockdrop.rs +++ b/packages/astroport_periphery/src/lockdrop.rs @@ -202,9 +202,31 @@ pub enum CallbackMsg { duration: u64, withdraw_lp_stake: bool, }, - /// The first step in the lockup's XYK -> PCL liquidity migration process. + /// Entry point for a single lockup position migration to PCL lockdrop contract. Performs + /// generator rewards claiming and initializes liquidity withdrawal+transfer process by + /// invocation of the respective callback message. + #[serde(rename = "init_migrate_lockup_to_pcl_pools_callback")] + InitMigrateLockupToPCLPoolsCallback { + /// The type of the pool the lockup is related to. + pool_type: PoolType, + /// The address of the user which owns the lockup. + user_address: Addr, + /// The duration of the lock period. + duration: u64, + }, + /// The second step in the lockup's XYK -> PCL liquidity migration process. + /// Claims all possible rewards that the user is eligible of and transfers them to the user. + TransferAllRewardsBeforeMigrationCallback { + /// The type of the pool the lockup is related to. + pool_type: PoolType, + /// The address of the user which owns the lockup. + user_address: Addr, + /// The duration of the lock period. + duration: u64, + }, + /// The third step in the lockup's XYK -> PCL liquidity migration process. /// Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to - /// the PCL lockdrop contract, and claims all possible rewards for the user. + /// the PCL lockdrop contract. WithdrawUserLockupCallback { /// The type of the pool the lockup is related to. pool_type: PoolType, @@ -212,8 +234,14 @@ pub enum CallbackMsg { user_address: Addr, /// The duration of the lock period. duration: u64, + /// The address of the generator which possesses the staked liquidity. + generator: Addr, + /// The address of the pool's liquidity token. + astroport_lp_token: Addr, + /// The amount of LP token to be unstaked and withdrawn. + astroport_lp_amount: Uint128, }, - /// The second step in the lockup's XYK -> PCL liquidity migration process. + /// The fourth step in the lockup's XYK -> PCL liquidity migration process. /// Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position /// in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn /// user's lockup position. @@ -225,12 +253,12 @@ pub enum CallbackMsg { user_address: Addr, /// The duration of the lock period. duration: u64, - /// The balance in untrn of the XYK lockdrop contract at the first migration step. Is used + /// The balance in untrn of the XYK lockdrop contract at the third migration step. Is used /// in the callback to calculate the amount of untrn been withdrawn from the XYK pool. ntrn_balance: Uint128, /// The denom of the paired asset (the asset paired with untrn in the pool). paired_asset_denom: String, - /// The balance in the paired denom of the XYK lockdrop contract at the first migration step. + /// The balance in the paired denom of the XYK lockdrop contract at the third migration step. /// Is used in the callback to calculate the amount of the paired asset been withdrawn /// from the XYK pool. paired_asset_balance: Uint128, diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index eb8e90a6..367f97a9 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -153,7 +153,7 @@ pub enum ExecuteMsg { /// Used to claim contract ownership. ClaimOwnership {}, /// A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable - /// by the original lockdrop contract. + /// by the original lockdrop contract. Expects two **Coin**s to be attached as funds. #[serde(rename = "migrate_xyk_liquidity")] MigrateXYKLiquidity { /// The type of the pool the lockup is related to. @@ -196,8 +196,10 @@ pub enum CallbackMsg { duration: u64, /// The address of the LP token of the pool. lp_token: String, - /// The balance in the LP token of the PCL lockdrop contract before liquidity provision. - lp_token_balance: Uint128, + /// The amount of staked LP token the PCL lockdrop contract possesses of before liquidity + /// provision and staking to the generator. Used to calculate LP token amount received for + /// liquidity provision. + staked_lp_token_amount: Uint128, /// The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo /// entry on the PCL lockdrop contract's side. user_info: LockdropXYKUserInfo, From 5019e46bb5dbb063bf0733e6476001a995b3c6fb Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Mon, 5 Feb 2024 07:42:02 +0300 Subject: [PATCH 04/28] rm pcl lockdrop unit tests --- contracts/lockdrop-pcl/src/lib.rs | 3 - contracts/lockdrop-pcl/src/testing.rs | 149 -------------------------- 2 files changed, 152 deletions(-) delete mode 100644 contracts/lockdrop-pcl/src/testing.rs diff --git a/contracts/lockdrop-pcl/src/lib.rs b/contracts/lockdrop-pcl/src/lib.rs index 43f4f742..127e2860 100644 --- a/contracts/lockdrop-pcl/src/lib.rs +++ b/contracts/lockdrop-pcl/src/lib.rs @@ -1,6 +1,3 @@ pub mod contract; pub mod raw_queries; pub mod state; - -#[cfg(test)] -mod testing; diff --git a/contracts/lockdrop-pcl/src/testing.rs b/contracts/lockdrop-pcl/src/testing.rs deleted file mode 100644 index 526c0362..00000000 --- a/contracts/lockdrop-pcl/src/testing.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::contract::{execute, instantiate, query, UNTRN_DENOM}; -use astroport_periphery::lockdrop::{ - Config, ExecuteMsg, InstantiateMsg, LockupRewardsInfo, QueryMsg, -}; -use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{coin, from_binary, Addr, Decimal256, StdError, Uint128}; - -#[test] -fn update_owner() { - let mut deps = mock_dependencies(); - let info = mock_info("addr0000", &[]); - - let owner = Addr::unchecked("owner"); - let token_info_manager = Addr::unchecked("token_info_manager"); - - let env = mock_env(); - - let msg = InstantiateMsg { - owner: Some(owner.to_string()), - token_info_manager: token_info_manager.to_string(), - init_timestamp: env.block.time.seconds(), - lock_window: 10_000_000, - withdrawal_window: 500_000, - min_lock_duration: 1u64, - max_lock_duration: 52u64, - max_positions_per_user: 14, - credits_contract: "credit_contract".to_string(), - lockup_rewards_info: vec![LockupRewardsInfo { - duration: 1, - coefficient: Decimal256::zero(), - }], - auction_contract: "auction_contract".to_string(), - }; - - // We can just call .unwrap() to assert this was a success - instantiate(deps.as_mut(), env, info, msg).unwrap(); - - let new_owner = String::from("new_owner"); - - // BNew owner - let env = mock_env(); - let msg = ExecuteMsg::ProposeNewOwner { - owner: new_owner.clone(), - expires_in: 100, // seconds - }; - - let info = mock_info(new_owner.as_str(), &[]); - - // Unauthorized check - let err = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap_err(); - assert_eq!(err.to_string(), "Generic error: Unauthorized"); - - // Claim before a proposal - let info = mock_info(new_owner.as_str(), &[]); - execute( - deps.as_mut(), - env.clone(), - info, - ExecuteMsg::ClaimOwnership {}, - ) - .unwrap_err(); - - // Propose new owner - let info = mock_info(owner.as_str(), &[]); - let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // Unauthorized ownership claim - let info = mock_info("invalid_addr", &[]); - let err = execute( - deps.as_mut(), - env.clone(), - info, - ExecuteMsg::ClaimOwnership {}, - ) - .unwrap_err(); - assert_eq!(err.to_string(), "Generic error: Unauthorized"); - - // Claim ownership - let info = mock_info(new_owner.as_str(), &[]); - let res = execute( - deps.as_mut(), - env.clone(), - info, - ExecuteMsg::ClaimOwnership {}, - ) - .unwrap(); - assert_eq!(0, res.messages.len()); - - // Let's query the state - let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); - assert_eq!(new_owner, config.owner); -} - -#[test] -fn increase_ntrn_incentives() { - let mut deps = mock_dependencies(); - let info = mock_info("addr0000", &[]); - - let owner = Addr::unchecked("owner"); - let token_info_manager = Addr::unchecked("token_info_manager"); - - let env = mock_env(); - - let msg = InstantiateMsg { - owner: Some(owner.to_string()), - token_info_manager: token_info_manager.to_string(), - init_timestamp: env.block.time.seconds(), - lock_window: 10_000_000, - withdrawal_window: 500_000, - min_lock_duration: 1u64, - max_lock_duration: 52u64, - max_positions_per_user: 14, - credits_contract: "credit_contract".to_string(), - auction_contract: "auction_contract".to_string(), - lockup_rewards_info: vec![LockupRewardsInfo { - duration: 1, - coefficient: Decimal256::zero(), - }], - }; - - // We can just call .unwrap() to assert this was a success - instantiate(deps.as_mut(), env, info, msg).unwrap(); - - let env = mock_env(); - let msg = ExecuteMsg::IncreaseNTRNIncentives {}; - - let info = mock_info(owner.as_str(), &[coin(100u128, UNTRN_DENOM)]); - - let res = execute(deps.as_mut(), env.clone(), info, msg); - assert!(res.is_ok()); - - let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); - assert_eq!(Uint128::new(100u128), config.lockdrop_incentives); - - // invalid coin - let env = mock_env(); - let msg = ExecuteMsg::IncreaseNTRNIncentives {}; - - let info = mock_info(owner.as_str(), &[coin(100u128, "DENOM")]); - - let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!( - err, - StdError::generic_err(format!("{} is not found", UNTRN_DENOM)) - ); -} From ee21daff134b8dc8e08ff89f689a6d27a3dd5f77 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 8 Feb 2024 08:31:02 +0300 Subject: [PATCH 05/28] generate schema for lockdrop and lockdrop_pcl --- ...ockdrop.json => neutron-lockdrop-pcl.json} | 257 +++++++++++++++++- .../lockdrop-pcl/schema/raw/execute.json | 242 +++++++++++++++++ .../lockdrop-pcl/schema/raw/migrate.json | 11 +- .../lockdrop/schema/neutron-lockdrop.json | 253 ++++++++++++++++- contracts/lockdrop/schema/raw/execute.json | 242 +++++++++++++++++ contracts/lockdrop/schema/raw/migrate.json | 11 +- 6 files changed, 1010 insertions(+), 6 deletions(-) rename contracts/lockdrop-pcl/schema/{neutron-lockdrop.json => neutron-lockdrop-pcl.json} (84%) diff --git a/contracts/lockdrop-pcl/schema/neutron-lockdrop.json b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json similarity index 84% rename from contracts/lockdrop-pcl/schema/neutron-lockdrop.json rename to contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json index cf59d5f9..5ec78b28 100644 --- a/contracts/lockdrop-pcl/schema/neutron-lockdrop.json +++ b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json @@ -1,6 +1,6 @@ { - "contract_name": "neutron-lockdrop", - "contract_version": "1.2.1", + "contract_name": "neutron-lockdrop-pcl", + "contract_version": "1.0.0", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", @@ -347,6 +347,28 @@ } }, "additionalProperties": false + }, + { + "description": "Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation rewards to the address which liquidity has been migrated.", + "type": "object", + "required": [ + "migrate_liquidity_to_pcl_pools" + ], + "properties": { + "migrate_liquidity_to_pcl_pools": { + "type": "object", + "properties": { + "user_address_raw": { + "description": "The address which liquidity is supposed to be transferred. If no user address is provided, the message sender's address is used.", + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false } ], "definitions": { @@ -437,6 +459,7 @@ "CallbackMsg": { "oneOf": [ { + "description": "Updates contract state after dual staking rewards are claimed from the generator contract.", "type": "object", "required": [ "update_pool_on_dual_rewards_claim" @@ -468,6 +491,7 @@ "additionalProperties": false }, { + "description": "Withdraws user rewards and LP Tokens after claims / unlocks.", "type": "object", "required": [ "withdraw_user_lockup_rewards_callback" @@ -500,6 +524,224 @@ } }, "additionalProperties": false + }, + { + "description": "Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the respective callback message.", + "type": "object", + "required": [ + "init_migrate_lockup_to_pcl_pools_callback" + ], + "properties": { + "init_migrate_lockup_to_pcl_pools_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The second step in the lockup's XYK -> PCL liquidity migration process. Claims all possible rewards that the user is eligible of and transfers them to the user.", + "type": "object", + "required": [ + "transfer_all_rewards_before_migration_callback" + ], + "properties": { + "transfer_all_rewards_before_migration_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The third step in the lockup's XYK -> PCL liquidity migration process. Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the PCL lockdrop contract.", + "type": "object", + "required": [ + "withdraw_user_lockup_callback" + ], + "properties": { + "withdraw_user_lockup_callback": { + "type": "object", + "required": [ + "astroport_lp_amount", + "astroport_lp_token", + "duration", + "generator", + "pool_type", + "user_address" + ], + "properties": { + "astroport_lp_amount": { + "description": "The amount of LP token to be unstaked and withdrawn.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "astroport_lp_token": { + "description": "The address of the pool's liquidity token.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "generator": { + "description": "The address of the generator which possesses the staked liquidity.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The fourth step in the lockup's XYK -> PCL liquidity migration process. Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's lockup position.", + "type": "object", + "required": [ + "migrate_user_lockup_to_pcl_pair_callback" + ], + "properties": { + "migrate_user_lockup_to_pcl_pair_callback": { + "type": "object", + "required": [ + "duration", + "ntrn_balance", + "paired_asset_balance", + "paired_asset_denom", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "ntrn_balance": { + "description": "The balance in untrn of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of untrn been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_balance": { + "description": "The balance in the paired denom of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of the paired asset been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_denom": { + "description": "The denom of the paired asset (the asset paired with untrn in the pool).", + "type": "string" + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false } ] }, @@ -752,7 +994,16 @@ "migrate": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", - "type": "object" + "type": "object", + "required": [ + "pcl_lockdrop_contract" + ], + "properties": { + "pcl_lockdrop_contract": { + "description": "The address of the lockdrop contract working with PCL pools. Used to transfer the lockdrop's liquidity locked in XYK pools to more efficient pools.", + "type": "string" + } + } }, "sudo": null, "responses": { diff --git a/contracts/lockdrop-pcl/schema/raw/execute.json b/contracts/lockdrop-pcl/schema/raw/execute.json index 97932b6d..b0e991e6 100644 --- a/contracts/lockdrop-pcl/schema/raw/execute.json +++ b/contracts/lockdrop-pcl/schema/raw/execute.json @@ -239,6 +239,28 @@ } }, "additionalProperties": false + }, + { + "description": "Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation rewards to the address which liquidity has been migrated.", + "type": "object", + "required": [ + "migrate_liquidity_to_pcl_pools" + ], + "properties": { + "migrate_liquidity_to_pcl_pools": { + "type": "object", + "properties": { + "user_address_raw": { + "description": "The address which liquidity is supposed to be transferred. If no user address is provided, the message sender's address is used.", + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false } ], "definitions": { @@ -329,6 +351,7 @@ "CallbackMsg": { "oneOf": [ { + "description": "Updates contract state after dual staking rewards are claimed from the generator contract.", "type": "object", "required": [ "update_pool_on_dual_rewards_claim" @@ -360,6 +383,7 @@ "additionalProperties": false }, { + "description": "Withdraws user rewards and LP Tokens after claims / unlocks.", "type": "object", "required": [ "withdraw_user_lockup_rewards_callback" @@ -392,6 +416,224 @@ } }, "additionalProperties": false + }, + { + "description": "Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the respective callback message.", + "type": "object", + "required": [ + "init_migrate_lockup_to_pcl_pools_callback" + ], + "properties": { + "init_migrate_lockup_to_pcl_pools_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The second step in the lockup's XYK -> PCL liquidity migration process. Claims all possible rewards that the user is eligible of and transfers them to the user.", + "type": "object", + "required": [ + "transfer_all_rewards_before_migration_callback" + ], + "properties": { + "transfer_all_rewards_before_migration_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The third step in the lockup's XYK -> PCL liquidity migration process. Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the PCL lockdrop contract.", + "type": "object", + "required": [ + "withdraw_user_lockup_callback" + ], + "properties": { + "withdraw_user_lockup_callback": { + "type": "object", + "required": [ + "astroport_lp_amount", + "astroport_lp_token", + "duration", + "generator", + "pool_type", + "user_address" + ], + "properties": { + "astroport_lp_amount": { + "description": "The amount of LP token to be unstaked and withdrawn.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "astroport_lp_token": { + "description": "The address of the pool's liquidity token.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "generator": { + "description": "The address of the generator which possesses the staked liquidity.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The fourth step in the lockup's XYK -> PCL liquidity migration process. Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's lockup position.", + "type": "object", + "required": [ + "migrate_user_lockup_to_pcl_pair_callback" + ], + "properties": { + "migrate_user_lockup_to_pcl_pair_callback": { + "type": "object", + "required": [ + "duration", + "ntrn_balance", + "paired_asset_balance", + "paired_asset_denom", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "ntrn_balance": { + "description": "The balance in untrn of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of untrn been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_balance": { + "description": "The balance in the paired denom of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of the paired asset been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_denom": { + "description": "The denom of the paired asset (the asset paired with untrn in the pool).", + "type": "string" + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false } ] }, diff --git a/contracts/lockdrop-pcl/schema/raw/migrate.json b/contracts/lockdrop-pcl/schema/raw/migrate.json index 87b18ea7..1efd732d 100644 --- a/contracts/lockdrop-pcl/schema/raw/migrate.json +++ b/contracts/lockdrop-pcl/schema/raw/migrate.json @@ -1,5 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", - "type": "object" + "type": "object", + "required": [ + "pcl_lockdrop_contract" + ], + "properties": { + "pcl_lockdrop_contract": { + "description": "The address of the lockdrop contract working with PCL pools. Used to transfer the lockdrop's liquidity locked in XYK pools to more efficient pools.", + "type": "string" + } + } } diff --git a/contracts/lockdrop/schema/neutron-lockdrop.json b/contracts/lockdrop/schema/neutron-lockdrop.json index cf59d5f9..09c431a1 100644 --- a/contracts/lockdrop/schema/neutron-lockdrop.json +++ b/contracts/lockdrop/schema/neutron-lockdrop.json @@ -347,6 +347,28 @@ } }, "additionalProperties": false + }, + { + "description": "Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation rewards to the address which liquidity has been migrated.", + "type": "object", + "required": [ + "migrate_liquidity_to_pcl_pools" + ], + "properties": { + "migrate_liquidity_to_pcl_pools": { + "type": "object", + "properties": { + "user_address_raw": { + "description": "The address which liquidity is supposed to be transferred. If no user address is provided, the message sender's address is used.", + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false } ], "definitions": { @@ -437,6 +459,7 @@ "CallbackMsg": { "oneOf": [ { + "description": "Updates contract state after dual staking rewards are claimed from the generator contract.", "type": "object", "required": [ "update_pool_on_dual_rewards_claim" @@ -468,6 +491,7 @@ "additionalProperties": false }, { + "description": "Withdraws user rewards and LP Tokens after claims / unlocks.", "type": "object", "required": [ "withdraw_user_lockup_rewards_callback" @@ -500,6 +524,224 @@ } }, "additionalProperties": false + }, + { + "description": "Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the respective callback message.", + "type": "object", + "required": [ + "init_migrate_lockup_to_pcl_pools_callback" + ], + "properties": { + "init_migrate_lockup_to_pcl_pools_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The second step in the lockup's XYK -> PCL liquidity migration process. Claims all possible rewards that the user is eligible of and transfers them to the user.", + "type": "object", + "required": [ + "transfer_all_rewards_before_migration_callback" + ], + "properties": { + "transfer_all_rewards_before_migration_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The third step in the lockup's XYK -> PCL liquidity migration process. Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the PCL lockdrop contract.", + "type": "object", + "required": [ + "withdraw_user_lockup_callback" + ], + "properties": { + "withdraw_user_lockup_callback": { + "type": "object", + "required": [ + "astroport_lp_amount", + "astroport_lp_token", + "duration", + "generator", + "pool_type", + "user_address" + ], + "properties": { + "astroport_lp_amount": { + "description": "The amount of LP token to be unstaked and withdrawn.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "astroport_lp_token": { + "description": "The address of the pool's liquidity token.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "generator": { + "description": "The address of the generator which possesses the staked liquidity.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The fourth step in the lockup's XYK -> PCL liquidity migration process. Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's lockup position.", + "type": "object", + "required": [ + "migrate_user_lockup_to_pcl_pair_callback" + ], + "properties": { + "migrate_user_lockup_to_pcl_pair_callback": { + "type": "object", + "required": [ + "duration", + "ntrn_balance", + "paired_asset_balance", + "paired_asset_denom", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "ntrn_balance": { + "description": "The balance in untrn of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of untrn been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_balance": { + "description": "The balance in the paired denom of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of the paired asset been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_denom": { + "description": "The denom of the paired asset (the asset paired with untrn in the pool).", + "type": "string" + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false } ] }, @@ -752,7 +994,16 @@ "migrate": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", - "type": "object" + "type": "object", + "required": [ + "pcl_lockdrop_contract" + ], + "properties": { + "pcl_lockdrop_contract": { + "description": "The address of the lockdrop contract working with PCL pools. Used to transfer the lockdrop's liquidity locked in XYK pools to more efficient pools.", + "type": "string" + } + } }, "sudo": null, "responses": { diff --git a/contracts/lockdrop/schema/raw/execute.json b/contracts/lockdrop/schema/raw/execute.json index 97932b6d..b0e991e6 100644 --- a/contracts/lockdrop/schema/raw/execute.json +++ b/contracts/lockdrop/schema/raw/execute.json @@ -239,6 +239,28 @@ } }, "additionalProperties": false + }, + { + "description": "Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation rewards to the address which liquidity has been migrated.", + "type": "object", + "required": [ + "migrate_liquidity_to_pcl_pools" + ], + "properties": { + "migrate_liquidity_to_pcl_pools": { + "type": "object", + "properties": { + "user_address_raw": { + "description": "The address which liquidity is supposed to be transferred. If no user address is provided, the message sender's address is used.", + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false } ], "definitions": { @@ -329,6 +351,7 @@ "CallbackMsg": { "oneOf": [ { + "description": "Updates contract state after dual staking rewards are claimed from the generator contract.", "type": "object", "required": [ "update_pool_on_dual_rewards_claim" @@ -360,6 +383,7 @@ "additionalProperties": false }, { + "description": "Withdraws user rewards and LP Tokens after claims / unlocks.", "type": "object", "required": [ "withdraw_user_lockup_rewards_callback" @@ -392,6 +416,224 @@ } }, "additionalProperties": false + }, + { + "description": "Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the respective callback message.", + "type": "object", + "required": [ + "init_migrate_lockup_to_pcl_pools_callback" + ], + "properties": { + "init_migrate_lockup_to_pcl_pools_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The second step in the lockup's XYK -> PCL liquidity migration process. Claims all possible rewards that the user is eligible of and transfers them to the user.", + "type": "object", + "required": [ + "transfer_all_rewards_before_migration_callback" + ], + "properties": { + "transfer_all_rewards_before_migration_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The third step in the lockup's XYK -> PCL liquidity migration process. Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the PCL lockdrop contract.", + "type": "object", + "required": [ + "withdraw_user_lockup_callback" + ], + "properties": { + "withdraw_user_lockup_callback": { + "type": "object", + "required": [ + "astroport_lp_amount", + "astroport_lp_token", + "duration", + "generator", + "pool_type", + "user_address" + ], + "properties": { + "astroport_lp_amount": { + "description": "The amount of LP token to be unstaked and withdrawn.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "astroport_lp_token": { + "description": "The address of the pool's liquidity token.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "generator": { + "description": "The address of the generator which possesses the staked liquidity.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "The fourth step in the lockup's XYK -> PCL liquidity migration process. Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's lockup position.", + "type": "object", + "required": [ + "migrate_user_lockup_to_pcl_pair_callback" + ], + "properties": { + "migrate_user_lockup_to_pcl_pair_callback": { + "type": "object", + "required": [ + "duration", + "ntrn_balance", + "paired_asset_balance", + "paired_asset_denom", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "ntrn_balance": { + "description": "The balance in untrn of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of untrn been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_balance": { + "description": "The balance in the paired denom of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of the paired asset been withdrawn from the XYK pool.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "paired_asset_denom": { + "description": "The denom of the paired asset (the asset paired with untrn in the pool).", + "type": "string" + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + } + } + }, + "additionalProperties": false } ] }, diff --git a/contracts/lockdrop/schema/raw/migrate.json b/contracts/lockdrop/schema/raw/migrate.json index 87b18ea7..1efd732d 100644 --- a/contracts/lockdrop/schema/raw/migrate.json +++ b/contracts/lockdrop/schema/raw/migrate.json @@ -1,5 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", - "type": "object" + "type": "object", + "required": [ + "pcl_lockdrop_contract" + ], + "properties": { + "pcl_lockdrop_contract": { + "description": "The address of the lockdrop contract working with PCL pools. Used to transfer the lockdrop's liquidity locked in XYK pools to more efficient pools.", + "type": "string" + } + } } From 19c6f84a45a57172e2054c125463684108d6c428 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 8 Feb 2024 16:21:48 +0200 Subject: [PATCH 06/28] WIP: incentives contract instead of generator --- Cargo.lock | 371 ++++++++++-------- contracts/astroport/oracle/src/contract.rs | 10 +- .../astroport/oracle/src/mock_querier.rs | 24 +- contracts/astroport/oracle/src/testing.rs | 14 +- .../astroport/oracle/tests/integration.rs | 62 +-- contracts/auction/Cargo.toml | 2 +- contracts/auction/src/contract.rs | 34 +- contracts/credits/src/contract.rs | 26 +- contracts/credits/src/testing/tests.rs | 4 +- contracts/cw20-merkle-airdrop/src/contract.rs | 20 +- contracts/cw20-merkle-airdrop/src/msg.rs | 4 +- contracts/cw20-merkle-airdrop/src/tests.rs | 30 +- contracts/lockdrop-pcl/Cargo.toml | 2 +- contracts/lockdrop-pcl/src/contract.rs | 243 ++++-------- contracts/lockdrop-pcl/src/raw_queries.rs | 8 +- contracts/lockdrop/Cargo.toml | 2 +- contracts/lockdrop/src/contract.rs | 48 +-- contracts/lockdrop/src/raw_queries.rs | 8 +- contracts/lockdrop/src/testing.rs | 6 +- contracts/price-feed/src/contract.rs | 10 +- contracts/price-feed/src/ibc.rs | 6 +- .../src/tests/integration.rs | 22 +- contracts/vesting-lp/src/tests/integration.rs | 18 +- .../vesting-lti/src/tests/integration.rs | 22 +- packages/astroport/src/asset.rs | 4 +- packages/astroport/src/generator.rs | 4 +- packages/astroport/src/mock_querier.rs | 14 +- packages/astroport/src/pair.rs | 18 +- packages/astroport/src/testing.rs | 4 +- packages/astroport_periphery/Cargo.toml | 2 +- packages/astroport_periphery/src/auction.rs | 4 +- packages/astroport_periphery/src/helpers.rs | 10 +- packages/astroport_periphery/src/lockdrop.rs | 4 +- .../astroport_periphery/src/lockdrop_pcl.rs | 9 +- packages/vesting-base/src/ext_historical.rs | 6 +- .../vesting-base/src/ext_with_managers.rs | 4 +- packages/vesting-base/src/handlers.rs | 16 +- packages/vesting-base/src/testing.rs | 22 +- 38 files changed, 544 insertions(+), 573 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d6ea2b4..4aee2278 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "astroport" @@ -25,8 +25,8 @@ version = "2.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw20 1.1.1", + "cw-storage-plus 1.2.0", + "cw20 1.1.2", "itertools 0.11.0", "uint", ] @@ -34,7 +34,7 @@ dependencies = [ [[package]] name = "astroport" version = "2.5.0" -source = "git+https://github.com/astroport-fi/astroport-core.git?tag=v2.5.0#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" +source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -47,24 +47,38 @@ dependencies = [ [[package]] name = "astroport" -version = "2.5.0" -source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" +version = "3.11.0" +source = "git+https://github.com/astroport-fi/astroport-core.git?tag=v3.11.0#d6adad9bcbf5df75ea503601115de7a1aed501db" dependencies = [ + "astroport-circular-buffer", "cosmwasm-schema", "cosmwasm-std", + "cw-asset", "cw-storage-plus 0.15.1", - "cw-utils 0.15.1", + "cw-utils 1.0.3", "cw20 0.15.1", + "cw3", "itertools 0.10.5", "uint", ] +[[package]] +name = "astroport-circular-buffer" +version = "0.1.0" +source = "git+https://github.com/astroport-fi/astroport-core.git?tag=v3.11.0#d6adad9bcbf5df75ea503601115de7a1aed501db" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 0.15.1", + "thiserror", +] + [[package]] name = "astroport-factory" version = "1.5.0" source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e)", + "astroport 2.5.0", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 0.15.1", @@ -79,7 +93,7 @@ name = "astroport-native-coin-registry" version = "1.0.1" source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e)", + "astroport 2.5.0", "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", @@ -102,9 +116,9 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", - "cw2 1.1.1", - "cw20 1.1.1", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", "itertools 0.11.0", "thiserror", ] @@ -114,7 +128,7 @@ name = "astroport-pair" version = "1.2.0" source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e)", + "astroport 2.5.0", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 0.15.1", @@ -130,11 +144,11 @@ name = "astroport-pair-stable" version = "2.1.1" source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e)", + "astroport 2.5.0", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 0.15.1", - "cw-utils 1.0.2", + "cw-utils 1.0.3", "cw2 0.15.1", "cw20 0.15.1", "itertools 0.10.5", @@ -145,11 +159,11 @@ dependencies = [ name = "astroport-periphery" version = "1.1.0" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?tag=v2.5.0)", + "astroport 3.11.0", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 0.15.1", - "cw20 1.1.1", + "cw20 1.1.2", "schemars", "serde", ] @@ -159,7 +173,7 @@ name = "astroport-token" version = "1.1.1" source = "git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e#65ce7d1879cc5d95b09fa14202f0423bba52ae0e" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?rev=65ce7d1879cc5d95b09fa14202f0423bba52ae0e)", + "astroport 2.5.0", "cosmwasm-schema", "cosmwasm-std", "cw2 0.15.1", @@ -188,9 +202,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -224,9 +238,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" [[package]] name = "byteorder" @@ -248,17 +262,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cosmwasm-crypto" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fb22494cf7d23d0c348740e06e5c742070b2991fd41db77bba0bcfbae1a723" +checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ "digest 0.10.7", + "ecdsa 0.16.9", "ed25519-zebra", "k256 0.13.1", "rand_core 0.6.4", @@ -267,18 +282,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e199424486ea97d6b211db6387fd72e26b4a439d40cc23140b2d8305728055b" +checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef683a9c1c4eabd6d31515719d0d2cc66952c4c87f7eb192bfc90384517dc34" +checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -289,22 +304,23 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9567025acbb4c0c008178393eb53b3ac3c2e492c25949d3bf415b9cbe80772d8" +checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "syn 1.0.109", ] [[package]] name = "cosmwasm-std" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d89d680fb60439b7c5947b15f9c84b961b88d1f8a3b20c4bd178a3f87db8bae" +checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" dependencies = [ "base64", + "bech32", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -315,14 +331,15 @@ dependencies = [ "serde", "serde-json-wasm", "sha2 0.10.8", + "static_assertions", "thiserror", ] [[package]] name = "cosmwasm-storage" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1c574d30feffe4b8121e61e839c231a5ce21901221d2fb4d5c945968a4f00" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -330,9 +347,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -343,9 +360,9 @@ version = "0.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw2 1.1.1", - "cw20 1.1.1", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", "cw20-base 0.13.4", "schemars", "serde", @@ -372,9 +389,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -405,6 +422,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cw-address-like" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" +dependencies = [ + "cosmwasm-std", +] + +[[package]] +name = "cw-asset" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "431e57314dceabd29a682c78bb3ff7c641f8bdc8b915400bb9956cb911e8e571" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-address-like", + "cw-storage-plus 1.2.0", + "cw20 1.1.2", + "thiserror", +] + [[package]] name = "cw-band" version = "0.1.1" @@ -424,8 +464,8 @@ checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" dependencies = [ "anyhow", "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw-utils 1.0.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", "derivative", "itertools 0.10.5", "k256 0.11.6", @@ -458,9 +498,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -495,13 +535,13 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9f351a4e4d81ef7c890e44d903f8c0bdcdc00f094fd3a181eaf70c0eec7a3a" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.1", + "cw2 1.1.2", "schemars", "semver", "serde", @@ -534,14 +574,15 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9431d14f64f49e41c6ef5561ed11a5391c417d0cb16455dea8cdcb9037a8d197" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "schemars", + "semver", "serde", "thiserror", ] @@ -572,13 +613,13 @@ dependencies = [ [[package]] name = "cw20" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786e9da5e937f473cecd2463e81384c1af65d0f6398bbd851be7655487c55492" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-utils 1.0.2", + "cw-utils 1.0.3", "schemars", "serde", ] @@ -618,16 +659,15 @@ dependencies = [ [[package]] name = "cw20-base" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09558f87fd3d5e4a479761051b3f98ee2fa723d9e484b5679b6058ad0eadf8f1" +checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw-utils 1.0.2", - "cw2 1.1.1", - "cw20 1.1.1", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", "schemars", "semver", "serde", @@ -643,10 +683,10 @@ dependencies = [ "cosmwasm-std", "credits", "cw-multi-test", - "cw-storage-plus 1.1.0", - "cw2 1.1.1", - "cw20 1.1.1", - "cw20-base 1.1.1", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", "hex", "ripemd", "schemars", @@ -656,6 +696,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw3" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", + "cw20 1.1.2", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "der" version = "0.6.1" @@ -683,7 +738,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "syn 1.0.109", ] @@ -716,9 +771,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "ecdsa" @@ -734,16 +789,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.8", "digest 0.10.7", - "elliptic-curve 0.13.6", + "elliptic-curve 0.13.8", "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -789,12 +844,12 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.3", + "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", "generic-array", @@ -845,9 +900,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -929,9 +984,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "k256" @@ -952,44 +1007,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.8", - "elliptic-curve 0.13.6", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "sha2 0.10.8", - "signature 2.1.0", + "signature 2.2.0", ] [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "neutron-auction" version = "1.0.0" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?tag=v2.5.0)", + "astroport 3.11.0", "astroport-periphery", "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", - "cw2 1.1.1", - "cw20 1.1.1", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", ] [[package]] name = "neutron-lockdrop" version = "1.2.1" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?tag=v2.5.0)", + "astroport 3.11.0", "astroport-periphery", "cosmwasm-schema", "cosmwasm-std", "credits", "cw-storage-plus 0.15.1", - "cw2 1.1.1", - "cw20 1.1.1", + "cw2 1.1.2", + "cw20 1.1.2", "serde", ] @@ -997,14 +1052,14 @@ dependencies = [ name = "neutron-lockdrop-pcl" version = "1.0.0" dependencies = [ - "astroport 2.5.0 (git+https://github.com/astroport-fi/astroport-core.git?tag=v2.5.0)", + "astroport 3.11.0", "astroport-periphery", "cosmwasm-schema", "cosmwasm-std", "credits", "cw-storage-plus 0.15.1", - "cw2 1.1.1", - "cw20 1.1.1", + "cw2 1.1.2", + "cw20 1.1.2", "serde", ] @@ -1016,17 +1071,17 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-band", - "cw-storage-plus 1.1.0", - "cw2 1.1.1", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", "obi", "thiserror", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -1058,15 +1113,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b00664fdffd7558a47a4c106c446104af3e789b740d7740885660c371eb0d09d" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "syn 1.0.109", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -1091,14 +1146,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.8", - "spki 0.7.2", + "spki 0.7.3", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1122,7 +1177,7 @@ dependencies = [ "anyhow", "itertools 0.10.5", "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "syn 1.0.109", ] @@ -1143,9 +1198,9 @@ checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1197,15 +1252,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -1215,12 +1270,12 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "serde_derive_internals", "syn 1.0.109", ] @@ -1255,37 +1310,37 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", - "quote 1.0.33", - "syn 2.0.38", + "quote 1.0.35", + "syn 2.0.48", ] [[package]] @@ -1295,15 +1350,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -1346,9 +1401,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -1371,7 +1426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "syn 1.0.109", ] @@ -1387,9 +1442,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der 0.7.8", @@ -1414,39 +1469,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.38" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", - "quote 1.0.33", + "quote 1.0.35", "unicode-ident", ] [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", - "quote 1.0.33", - "syn 2.0.38", + "quote 1.0.35", + "syn 2.0.48", ] [[package]] @@ -1486,9 +1541,9 @@ dependencies = [ "astroport 2.0.0", "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "cw-utils 0.15.1", - "cw20 1.1.1", + "cw20 1.1.2", "thiserror", ] @@ -1502,8 +1557,8 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-utils 0.15.1", - "cw2 1.1.1", - "cw20 1.1.1", + "cw2 1.1.2", + "cw20 1.1.2", "vesting-base", ] @@ -1517,8 +1572,8 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-utils 0.15.1", - "cw2 1.1.1", - "cw20 1.1.1", + "cw2 1.1.2", + "cw20 1.1.2", "vesting-base", ] @@ -1532,8 +1587,8 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-utils 0.15.1", - "cw2 1.1.1", - "cw20 1.1.1", + "cw2 1.1.2", + "cw20 1.1.2", "vesting-base", ] @@ -1545,6 +1600,6 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/contracts/astroport/oracle/src/contract.rs b/contracts/astroport/oracle/src/contract.rs index 756eae51..72eb2c97 100644 --- a/contracts/astroport/oracle/src/contract.rs +++ b/contracts/astroport/oracle/src/contract.rs @@ -7,7 +7,7 @@ use astroport::oracle::{Config, ExecuteMsg, InstantiateMsg, QueryMsg}; use astroport::pair::TWAP_PRECISION; use astroport::querier::query_pair_info; use cosmwasm_std::{ - entry_point, to_binary, Binary, Decimal256, Deps, DepsMut, Env, MessageInfo, Response, Uint128, + entry_point, to_json_binary, Binary, Decimal256, Deps, DepsMut, Env, MessageInfo, Response, Uint128, Uint256, Uint64, }; use cw2::set_contract_version; @@ -181,12 +181,12 @@ pub fn update(deps: DepsMut, env: Env) -> Result { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::Consult { token, amount } => Ok(to_binary(&consult(deps, token, amount)?)?), + QueryMsg::Consult { token, amount } => Ok(to_json_binary(&consult(deps, token, amount)?)?), QueryMsg::TWAPAtHeight { token, height } => { - Ok(to_binary(&twap_at_height(deps, token, height)?)?) + Ok(to_json_binary(&twap_at_height(deps, token, height)?)?) } - QueryMsg::Config {} => Ok(to_binary(&query_config(deps)?)?), - QueryMsg::LastUpdateTimestamp {} => Ok(to_binary(&query_last_update_ts(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&query_config(deps)?)?), + QueryMsg::LastUpdateTimestamp {} => Ok(to_json_binary(&query_last_update_ts(deps)?)?), } } diff --git a/contracts/astroport/oracle/src/mock_querier.rs b/contracts/astroport/oracle/src/mock_querier.rs index 0bbf558f..90a6a2b6 100644 --- a/contracts/astroport/oracle/src/mock_querier.rs +++ b/contracts/astroport/oracle/src/mock_querier.rs @@ -5,7 +5,7 @@ use astroport::pair::QueryMsg::{self, CumulativePrices}; use astroport::pair::{CumulativePricesResponse, SimulationResponse}; use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, from_slice, to_binary, Addr, Coin, Empty, OwnedDeps, Querier, QuerierResult, + from_json, to_json_binary, Addr, Coin, Empty, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; @@ -82,7 +82,7 @@ pub(crate) fn balances_to_map( impl Querier for WasmMockQuerier { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -100,9 +100,9 @@ impl WasmMockQuerier { match &request { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { if contract_addr == "factory" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Pair { asset_infos } => SystemResult::Ok( - to_binary(&PairInfo { + to_json_binary(&PairInfo { asset_infos, contract_addr: Addr::unchecked("pair"), liquidity_token: Addr::unchecked("lp_token"), @@ -113,9 +113,9 @@ impl WasmMockQuerier { _ => panic!("DO NOT ENTER HERE"), } } else if contract_addr == "astro-token" || contract_addr == "usdc-token" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => SystemResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: contract_addr.to_string(), symbol: contract_addr.to_string(), decimals: 6u8, @@ -126,7 +126,7 @@ impl WasmMockQuerier { _ => panic!("DO NOT ENTER HERE"), } } else if contract_addr == "pair" { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { CumulativePrices { .. } => { let balance = match self.token_querier.pairs.get(contract_addr) { Some(v) => v, @@ -134,13 +134,13 @@ impl WasmMockQuerier { return SystemResult::Err(SystemError::Unknown {}); } }; - SystemResult::Ok(to_binary(&balance).into()) + SystemResult::Ok(to_json_binary(&balance).into()) } QueryMsg::Simulation { offer_asset, ask_asset_info: _, } => SystemResult::Ok( - to_binary(&SimulationResponse { + to_json_binary(&SimulationResponse { return_amount: offer_asset.amount, spread_amount: Uint128::zero(), commission_amount: Uint128::zero(), @@ -150,7 +150,7 @@ impl WasmMockQuerier { _ => panic!("DO NOT ENTER HERE"), } } else { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { let balances: &HashMap = match self.token_querier.balances.get(contract_addr) { @@ -167,7 +167,7 @@ impl WasmMockQuerier { } SystemResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: "mAPPL".to_string(), symbol: "mAPPL".to_string(), decimals: 6, @@ -193,7 +193,7 @@ impl WasmMockQuerier { }; SystemResult::Ok( - to_binary(&BalanceResponse { balance: *balance }).into(), + to_json_binary(&BalanceResponse { balance: *balance }).into(), ) } _ => panic!("DO NOT ENTER HERE"), diff --git a/contracts/astroport/oracle/src/testing.rs b/contracts/astroport/oracle/src/testing.rs index beffe17a..4cf01b11 100644 --- a/contracts/astroport/oracle/src/testing.rs +++ b/contracts/astroport/oracle/src/testing.rs @@ -5,7 +5,7 @@ use astroport::asset::{Asset, AssetInfo, PairInfo}; use astroport::oracle::{Config, ExecuteMsg, InstantiateMsg, QueryMsg}; use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, Addr, Decimal256, DepsMut, Env, MessageInfo, Uint128, Uint256, Uint64, + from_json, Addr, Decimal256, DepsMut, Env, MessageInfo, Uint128, Uint256, Uint64, }; use std::ops::{Add, Mul}; @@ -205,7 +205,7 @@ fn cfg_and_last_update_ts() { // make sure config query works as expected let cfg: Config = - from_binary(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!( cfg, Config { @@ -249,7 +249,7 @@ fn cfg_and_last_update_ts() { ) .unwrap(); let last_update_ts: u64 = - from_binary(&query(deps.as_ref(), env.clone(), QueryMsg::LastUpdateTimestamp {}).unwrap()) + from_json(query(deps.as_ref(), env.clone(), QueryMsg::LastUpdateTimestamp {}).unwrap()) .unwrap(); assert_eq!(last_update_ts, first_update_ts); env.block.time = env.block.time.plus_seconds(100); @@ -261,7 +261,7 @@ fn cfg_and_last_update_ts() { ) .unwrap(); let last_update_ts: u64 = - from_binary(&query(deps.as_ref(), env.clone(), QueryMsg::LastUpdateTimestamp {}).unwrap()) + from_json(query(deps.as_ref(), env.clone(), QueryMsg::LastUpdateTimestamp {}).unwrap()) .unwrap(); assert_eq!(last_update_ts, first_update_ts.add(100)); @@ -274,12 +274,12 @@ fn cfg_and_last_update_ts() { ) .unwrap(); let cfg: Config = - from_binary(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(cfg.period, 500u64); // make sure premature update doesn't work let last_update_ts: u64 = - from_binary(&query(deps.as_ref(), env.clone(), QueryMsg::LastUpdateTimestamp {}).unwrap()) + from_json(query(deps.as_ref(), env.clone(), QueryMsg::LastUpdateTimestamp {}).unwrap()) .unwrap(); assert_eq!(last_update_ts, first_update_ts.add(100)); env.block.time = env.block.time.plus_seconds(100); @@ -295,7 +295,7 @@ fn cfg_and_last_update_ts() { env.block.time = env.block.time.plus_seconds(500); execute(deps.as_mut(), env.clone(), info, ExecuteMsg::Update {}).unwrap(); let last_update_ts: u64 = - from_binary(&query(deps.as_ref(), env, QueryMsg::LastUpdateTimestamp {}).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env, QueryMsg::LastUpdateTimestamp {}).unwrap()).unwrap(); assert_eq!(last_update_ts, first_update_ts.add(700)); } diff --git a/contracts/astroport/oracle/tests/integration.rs b/contracts/astroport/oracle/tests/integration.rs index 9e0c5040..ba5c544b 100644 --- a/contracts/astroport/oracle/tests/integration.rs +++ b/contracts/astroport/oracle/tests/integration.rs @@ -1,6 +1,6 @@ use anyhow::Result; use cosmwasm_std::{ - attr, to_binary, Addr, BlockInfo, Coin, Decimal, Decimal256, QueryRequest, StdResult, Uint128, + attr, to_json_binary, Addr, BlockInfo, Coin, Decimal, Decimal256, QueryRequest, StdResult, Uint128, Uint64, WasmQuery, }; use cw20::{BalanceResponse, Cw20QueryMsg, MinterResponse}; @@ -258,7 +258,7 @@ fn check_balance(router: &mut App, user: Addr, token: Addr, expected_amount: Uin let res: Result = router.wrap().query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: token.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })); let balance = res.unwrap(); @@ -364,7 +364,7 @@ fn create_pair( .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { asset_infos }).unwrap(), + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos }).unwrap(), })) .unwrap(); @@ -401,7 +401,7 @@ fn create_pair_stable( pair_type: PairType::Stable {}, asset_infos: asset_infos.clone(), init_params: Some( - to_binary(&StablePoolParams { + to_json_binary(&StablePoolParams { amp: 100, owner: None, }) @@ -423,7 +423,7 @@ fn create_pair_stable( .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { asset_infos }).unwrap(), + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos }).unwrap(), })) .unwrap(); @@ -575,7 +575,7 @@ fn consult() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -668,7 +668,7 @@ fn consult() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount); @@ -724,7 +724,7 @@ fn twap_at_height() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -825,7 +825,7 @@ fn twap_at_height() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, price); @@ -876,7 +876,7 @@ fn consult_pair_stable() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -981,7 +981,7 @@ fn consult_pair_stable() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount); @@ -1032,7 +1032,7 @@ fn twap_at_height_pair_stable() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -1137,7 +1137,7 @@ fn twap_at_height_pair_stable() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount); @@ -1363,7 +1363,7 @@ fn consult2() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount_exp); @@ -1416,7 +1416,7 @@ fn consult2() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount_exp); @@ -1570,7 +1570,7 @@ fn consult_zero_price() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount_out); @@ -1736,7 +1736,7 @@ fn consult_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -1917,7 +1917,7 @@ fn consult_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amounts_exp); @@ -2028,7 +2028,7 @@ fn consult_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2096,7 +2096,7 @@ fn twap_at_height_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -2319,7 +2319,7 @@ fn twap_at_height_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2388,7 +2388,7 @@ fn twap_at_height_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2457,7 +2457,7 @@ fn twap_at_height_multiple_assets() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2525,7 +2525,7 @@ fn twap_at_height_multiple_assets_non_accurate_heights() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -2753,7 +2753,7 @@ fn twap_at_height_multiple_assets_non_accurate_heights() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2823,7 +2823,7 @@ fn twap_at_height_multiple_assets_non_accurate_heights() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2894,7 +2894,7 @@ fn twap_at_height_multiple_assets_non_accurate_heights() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res, amount_exp); @@ -2949,7 +2949,7 @@ fn contract_works_after_pair_info_is_set() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -3042,7 +3042,7 @@ fn contract_works_after_pair_info_is_set() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: oracle_instance.to_string(), - msg: to_binary(&msg).unwrap(), + msg: to_json_binary(&msg).unwrap(), })) .unwrap(); assert_eq!(res[0].1, amount); @@ -3097,7 +3097,7 @@ fn only_manager_can_set_pair_info() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), @@ -3202,7 +3202,7 @@ fn only_owner_can_change_manager() { .wrap() .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: factory_instance.clone().to_string(), - msg: to_binary(&astroport::factory::QueryMsg::Pair { + msg: to_json_binary(&astroport::factory::QueryMsg::Pair { asset_infos: asset_infos.clone(), }) .unwrap(), diff --git a/contracts/auction/Cargo.toml b/contracts/auction/Cargo.toml index 3b1d828d..d0f577b7 100644 --- a/contracts/auction/Cargo.toml +++ b/contracts/auction/Cargo.toml @@ -23,7 +23,7 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v2.5.0" } +astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v3.11.0" } astroport-periphery = { workspace = true } cw20 = { workspace = true } cw2 = { workspace = true } diff --git a/contracts/auction/src/contract.rs b/contracts/auction/src/contract.rs index 3e714122..adbef9d8 100644 --- a/contracts/auction/src/contract.rs +++ b/contracts/auction/src/contract.rs @@ -3,7 +3,7 @@ use astroport::U256; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, + attr, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, WasmMsg, }; use std::str::FromStr; @@ -239,9 +239,9 @@ pub fn execute_deposit(deps: DepsMut, env: Env, info: MessageInfo) -> Result StdResult { match msg { - QueryMsg::Config {} => to_binary(&CONFIG.load(deps.storage)?), - QueryMsg::State {} => to_binary(&STATE.load(deps.storage)?), - QueryMsg::UserInfo { address } => to_binary(&query_user_info(deps, _env, address)?), + QueryMsg::Config {} => to_json_binary(&CONFIG.load(deps.storage)?), + QueryMsg::State {} => to_json_binary(&STATE.load(deps.storage)?), + QueryMsg::UserInfo { address } => to_json_binary(&query_user_info(deps, _env, address)?), } } @@ -720,7 +720,7 @@ pub fn execute_finalize_init_pool( CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: ntrn_usdc_lp_token_address.to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: config.reserve_contract_address.to_string(), amount: usdc_lp_to_reserve, })?, @@ -728,7 +728,7 @@ pub fn execute_finalize_init_pool( CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: ntrn_atom_lp_token_address.to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: config.reserve_contract_address.to_string(), amount: atom_lp_to_reserve, })?, @@ -740,10 +740,10 @@ pub fn execute_finalize_init_pool( msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: ntrn_atom_lp_token_address, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: lockdrop_address.to_string(), amount: state.atom_lp_locked, - msg: to_binary(&LockDropCw20HookMsg::InitializePool { + msg: to_json_binary(&LockDropCw20HookMsg::InitializePool { pool_type: LockDropPoolType::ATOM, incentives_share: state.atom_ntrn_size, })?, @@ -754,10 +754,10 @@ pub fn execute_finalize_init_pool( msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: ntrn_usdc_lp_token_address, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: lockdrop_address.to_string(), amount: state.usdc_lp_locked, - msg: to_binary(&LockDropCw20HookMsg::InitializePool { + msg: to_json_binary(&LockDropCw20HookMsg::InitializePool { pool_type: LockDropPoolType::USDC, incentives_share: state.usdc_ntrn_size, })?, @@ -859,10 +859,10 @@ fn execute_migrate_to_vesting( msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: pool_info.ntrn_atom_lp_token_address, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: config.vesting_atom_contract_address.to_string(), amount: atom_lp_amount, - msg: to_binary(&VestingExecuteMsg::RegisterVestingAccounts { + msg: to_json_binary(&VestingExecuteMsg::RegisterVestingAccounts { vesting_accounts: atom_users, })?, })?, @@ -872,10 +872,10 @@ fn execute_migrate_to_vesting( msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: pool_info.ntrn_usdc_lp_token_address, funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: config.vesting_usdc_contract_address.to_string(), amount: usdc_lp_amount, - msg: to_binary(&VestingExecuteMsg::RegisterVestingAccounts { + msg: to_json_binary(&VestingExecuteMsg::RegisterVestingAccounts { vesting_accounts: usdc_users, })?, })?, @@ -932,7 +932,7 @@ fn build_provide_liquidity_to_lp_pool_msg( Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: pool_address, funds, - msg: to_binary(&astroport::pair::ExecuteMsg::ProvideLiquidity { + msg: to_json_binary(&astroport::pair::ExecuteMsg::ProvideLiquidity { assets: vec![base, other], slippage_tolerance: None, auto_stake: None, @@ -1033,7 +1033,7 @@ pub fn execute_lock_lp_tokens( let msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: lockdrop_address.to_string(), funds: vec![], - msg: to_binary(&LockDropExecuteMsg::IncreaseLockupFor { + msg: to_json_binary(&LockDropExecuteMsg::IncreaseLockupFor { user_address: info.sender.to_string(), pool_type: asset, amount, @@ -1098,7 +1098,7 @@ pub fn execute_withdraw_lp_tokens( let msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: lockdrop_address.to_string(), funds: vec![], - msg: to_binary(&LockDropExecuteMsg::WithdrawFromLockup { + msg: to_json_binary(&LockDropExecuteMsg::WithdrawFromLockup { user_address: info.sender.to_string(), pool_type: asset, amount, diff --git a/contracts/credits/src/contract.rs b/contracts/credits/src/contract.rs index 10f36e6b..bd852634 100644 --- a/contracts/credits/src/contract.rs +++ b/contracts/credits/src/contract.rs @@ -6,7 +6,7 @@ use ::cw20_base::ContractError as Cw20ContractError; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdError, + to_json_binary, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, }; use cw2::set_contract_version; @@ -392,38 +392,38 @@ pub fn execute_mint(deps: DepsMut, env: Env, info: MessageInfo) -> Result StdResult { match msg { QueryMsg::WithdrawableAmount { address } => { - to_binary(&query_withdrawable_amount(deps, env, address)?) + to_json_binary(&query_withdrawable_amount(deps, env, address)?) } - QueryMsg::VestedAmount { address } => to_binary(&query_vested_amount(deps, env, address)?), - QueryMsg::Allocation { address } => to_binary(&query_allocation(deps, address)?), + QueryMsg::VestedAmount { address } => to_json_binary(&query_vested_amount(deps, env, address)?), + QueryMsg::Allocation { address } => to_json_binary(&query_allocation(deps, address)?), QueryMsg::Balance { address } => { - to_binary(&::cw20_base::contract::query_balance(deps, address)?) + to_json_binary(&::cw20_base::contract::query_balance(deps, address)?) } QueryMsg::TotalSupplyAtHeight { height } => { - to_binary(&query_total_supply_at_height(deps, height)?) + to_json_binary(&query_total_supply_at_height(deps, height)?) } QueryMsg::BalanceAtHeight { address, height } => { - to_binary(&query_balance_at_height(deps, address, height)?) + to_json_binary(&query_balance_at_height(deps, address, height)?) } - QueryMsg::TokenInfo {} => to_binary(&::cw20_base::contract::query_token_info(deps)?), - QueryMsg::Minter {} => to_binary(&::cw20_base::contract::query_minter(deps)?), - QueryMsg::Allowance { owner, spender } => to_binary( + QueryMsg::TokenInfo {} => to_json_binary(&::cw20_base::contract::query_token_info(deps)?), + QueryMsg::Minter {} => to_json_binary(&::cw20_base::contract::query_minter(deps)?), + QueryMsg::Allowance { owner, spender } => to_json_binary( &::cw20_base::allowances::query_allowance(deps, owner, spender)?, ), QueryMsg::AllAllowances { owner, start_after, limit, - } => to_binary(&::cw20_base::enumerable::query_all_allowances( + } => to_json_binary(&::cw20_base::enumerable::query_all_allowances( deps, owner, start_after, limit, )?), - QueryMsg::AllAccounts { start_after, limit } => to_binary( + QueryMsg::AllAccounts { start_after, limit } => to_json_binary( &::cw20_base::enumerable::query_all_accounts(deps, start_after, limit)?, ), - QueryMsg::Config {} => to_binary(&query_config(deps)?), + QueryMsg::Config {} => to_json_binary(&query_config(deps)?), } } diff --git a/contracts/credits/src/testing/tests.rs b/contracts/credits/src/testing/tests.rs index 2ed19104..9d095dab 100644 --- a/contracts/credits/src/testing/tests.rs +++ b/contracts/credits/src/testing/tests.rs @@ -564,7 +564,7 @@ mod withdraw { let res = execute_withdraw(deps.as_mut(), env, somebody_info); assert_eq!( res, - Err(Std(StdError::not_found("credits::state::Allocation"))) + Err(Std(StdError::not_found("type: credits::state::Allocation; key: [00, 0B, 61, 6C, 6C, 6F, 63, 61, 74, 69, 6F, 6E, 73, 73, 6F, 6D, 65, 62, 6F, 64, 79]"))) ); } } @@ -858,7 +858,7 @@ mod query_vested_amount { let query_res = query_vested_amount(deps.as_ref(), env, "noname".to_string()); assert_eq!( query_res, - Err(StdError::not_found("credits::state::Allocation")) + Err(StdError::not_found( "type: credits::state::Allocation; key: [00, 0B, 61, 6C, 6C, 6F, 63, 61, 74, 69, 6F, 6E, 73, 6E, 6F, 6E, 61, 6D, 65]")) ); } diff --git a/contracts/cw20-merkle-airdrop/src/contract.rs b/contracts/cw20-merkle-airdrop/src/contract.rs index dfd7a200..4cd5f3ed 100644 --- a/contracts/cw20-merkle-airdrop/src/contract.rs +++ b/contracts/cw20-merkle-airdrop/src/contract.rs @@ -2,7 +2,7 @@ use crate::enumerable::query_all_address_map; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, coin, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, + attr, coin, to_json_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, WasmMsg, }; use cw2::set_contract_version; @@ -174,7 +174,7 @@ pub fn execute_claim( .map_err(ContractError::Std)?; let vesting_message = WasmMsg::Execute { contract_addr: config.credits_address.to_string(), - msg: to_binary(&AddVesting { + msg: to_json_binary(&AddVesting { address: info.sender.to_string(), amount, start_time: vesting_start, @@ -236,7 +236,7 @@ pub fn execute_withdraw_all( // Generate burn submessage and return a response let burn_message = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cfg.credits_address.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Burn { + msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: amount_to_withdraw, })?, funds: vec![], @@ -335,16 +335,16 @@ pub fn execute_resume( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => to_binary(&query_config(deps)?), - QueryMsg::MerkleRoot {} => to_binary(&query_merkle_root(deps)?), - QueryMsg::IsClaimed { address } => to_binary(&query_is_claimed(deps, address)?), - QueryMsg::IsPaused {} => to_binary(&query_is_paused(deps)?), - QueryMsg::TotalClaimed {} => to_binary(&query_total_claimed(deps)?), + QueryMsg::Config {} => to_json_binary(&query_config(deps)?), + QueryMsg::MerkleRoot {} => to_json_binary(&query_merkle_root(deps)?), + QueryMsg::IsClaimed { address } => to_json_binary(&query_is_claimed(deps, address)?), + QueryMsg::IsPaused {} => to_json_binary(&query_is_paused(deps)?), + QueryMsg::TotalClaimed {} => to_json_binary(&query_total_claimed(deps)?), QueryMsg::AccountMap { external_address } => { - to_binary(&query_address_map(deps, external_address)?) + to_json_binary(&query_address_map(deps, external_address)?) } QueryMsg::AllAccountMaps { start_after, limit } => { - to_binary(&query_all_address_map(deps, start_after, limit)?) + to_json_binary(&query_all_address_map(deps, start_after, limit)?) } } } diff --git a/contracts/cw20-merkle-airdrop/src/msg.rs b/contracts/cw20-merkle-airdrop/src/msg.rs index ffbe2e88..41f20b7c 100644 --- a/contracts/cw20-merkle-airdrop/src/msg.rs +++ b/contracts/cw20-merkle-airdrop/src/msg.rs @@ -1,6 +1,6 @@ use crate::ContractError; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{from_slice, Binary, Uint128}; +use cosmwasm_std::{from_json, Binary, Uint128}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -133,7 +133,7 @@ pub struct SignatureInfo { } impl SignatureInfo { pub fn extract_addr(&self) -> Result { - let claim_msg = from_slice::(&self.claim_msg)?; + let claim_msg = from_json::(&self.claim_msg)?; Ok(claim_msg.address) } } diff --git a/contracts/cw20-merkle-airdrop/src/tests.rs b/contracts/cw20-merkle-airdrop/src/tests.rs index 99865ab8..b910bbdd 100644 --- a/contracts/cw20-merkle-airdrop/src/tests.rs +++ b/contracts/cw20-merkle-airdrop/src/tests.rs @@ -7,9 +7,9 @@ use crate::{ }, }; use cosmwasm_std::{ - attr, coin, from_binary, from_slice, + attr, coin, from_json, testing::{mock_dependencies, mock_env, mock_info}, - to_binary, Addr, BlockInfo, CosmosMsg, Empty, SubMsg, Timestamp, Uint128, WasmMsg, + to_json_binary, Addr, BlockInfo, CosmosMsg, Empty, SubMsg, Timestamp, Uint128, WasmMsg, }; use credits::msg::ExecuteMsg::AddVesting; use cw20::{BalanceResponse, Cw20ExecuteMsg}; @@ -68,7 +68,7 @@ fn proper_instantiation() { ); let res = query(deps.as_ref(), env.clone(), QueryMsg::MerkleRoot {}).unwrap(); - let merkle_root: MerkleRootResponse = from_binary(&res).unwrap(); + let merkle_root: MerkleRootResponse = from_json(res).unwrap(); assert_eq!( merkle_root, MerkleRootResponse { @@ -82,7 +82,7 @@ fn proper_instantiation() { ); let res = query(deps.as_ref(), env, QueryMsg::Config {}).unwrap(); - let config: ConfigResponse = from_binary(&res).unwrap(); + let config: ConfigResponse = from_json(res).unwrap(); assert_eq!( config, ConfigResponse { @@ -113,7 +113,7 @@ fn claim() { let airdrop_start = env.block.time.minus_seconds(5_000).seconds(); let vesting_start = env.block.time.plus_seconds(10_000).seconds(); let vesting_duration_seconds = 20_000; - let test_data: Encoded = from_slice(TEST_DATA_1).unwrap(); + let test_data: Encoded = from_json(TEST_DATA_1).unwrap(); let msg = InstantiateMsg { credits_address: "credits0000".to_string(), @@ -141,7 +141,7 @@ fn claim() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "credits0000".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: test_data.account.clone(), amount: test_data.amount, }) @@ -149,7 +149,7 @@ fn claim() { })), SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "credits0000".to_string(), - msg: to_binary(&AddVesting { + msg: to_json_binary(&AddVesting { address: test_data.account.clone(), amount: test_data.amount, start_time: vesting_start, @@ -172,7 +172,7 @@ fn claim() { // Check total claimed assert_eq!( - from_binary::( + from_json::( &query(deps.as_ref(), env.clone(), QueryMsg::TotalClaimed {},).unwrap() ) .unwrap() @@ -182,7 +182,7 @@ fn claim() { // Check address is claimed assert!( - from_binary::( + from_json::( &query( deps.as_ref(), env.clone(), @@ -225,7 +225,7 @@ fn multiple_claim() { let airdrop_start = env.block.time.minus_seconds(5_000).seconds(); let vesting_start = env.block.time.plus_seconds(10_000).seconds(); let vesting_duration_seconds = 20_000; - let test_data: MultipleData = from_slice(TEST_DATA_1_MULTI).unwrap(); + let test_data: MultipleData = from_json(TEST_DATA_1_MULTI).unwrap(); let msg = InstantiateMsg { credits_address: "credits0000".to_string(), @@ -255,7 +255,7 @@ fn multiple_claim() { SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "credits0000".to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: account.account.clone(), amount: account.amount, }) @@ -263,7 +263,7 @@ fn multiple_claim() { })), SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "credits0000".to_string(), - msg: to_binary(&AddVesting { + msg: to_json_binary(&AddVesting { address: account.account.clone(), amount: account.amount, start_time: vesting_start, @@ -288,7 +288,7 @@ fn multiple_claim() { // Check total claimed let env = mock_env(); assert_eq!( - from_binary::( + from_json::( &query(deps.as_ref(), env, QueryMsg::TotalClaimed {}).unwrap() ) .unwrap() @@ -415,7 +415,7 @@ fn update_reserve_address() { ); assert_eq!( - from_binary::(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()) .unwrap() .reserve_address, "reserve0002" @@ -424,7 +424,7 @@ fn update_reserve_address() { #[test] fn withdraw_all() { - let test_data: Encoded = from_slice(TEST_DATA_1).unwrap(); + let test_data: Encoded = from_json(TEST_DATA_1).unwrap(); let mut router = mock_app(); router .init_modules(|router, _api, storage| { diff --git a/contracts/lockdrop-pcl/Cargo.toml b/contracts/lockdrop-pcl/Cargo.toml index 15c4a7cb..aa5eec51 100644 --- a/contracts/lockdrop-pcl/Cargo.toml +++ b/contracts/lockdrop-pcl/Cargo.toml @@ -26,7 +26,7 @@ library = [] [dependencies] # we have to keep it 0.15.1 because it is the same version as in astroport cw-storage-plus = { version = "0.15.1" } -astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v2.5.0" } +astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v3.11.0" } credits = { path = "../credits" } astroport-periphery = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 647d9890..ae9ded9c 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -6,15 +6,15 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; -use astroport::generator::{ - ExecuteMsg as GenExecuteMsg, PendingTokenResponse, QueryMsg as GenQueryMsg, RewardInfoResponse, +use astroport::incentives::{ + ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg, }; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; use astroport_periphery::utils::Decimal256CheckedOps; use cosmwasm_std::{ - attr, coins, entry_point, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, + attr, coins, entry_point, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, Uint256, WasmMsg, }; @@ -76,7 +76,7 @@ pub fn instantiate( xyk_lockdrop_contract: deps.api.addr_validate(&msg.xyk_lockdrop_contract)?, credits_contract: deps.api.addr_validate(&msg.credits_contract)?, auction_contract: deps.api.addr_validate(&msg.auction_contract)?, - generator: deps.api.addr_validate(&msg.generator)?, + incentives: deps.api.addr_validate(&msg.generator)?, lockdrop_incentives: msg.lockdrop_incentives, lockup_rewards_info: msg.lockup_rewards_info, }; @@ -188,13 +188,11 @@ fn _handle_callback( match msg { CallbackMsg::UpdatePoolOnDualRewardsClaim { pool_type, - prev_ntrn_balance, prev_proxy_reward_balances, } => update_pool_on_dual_rewards_claim( deps, env, pool_type, - prev_ntrn_balance, prev_proxy_reward_balances, ), CallbackMsg::WithdrawUserLockupRewardsCallback { @@ -236,18 +234,18 @@ fn _handle_callback( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => to_binary(&CONFIG.load(deps.storage)?), - QueryMsg::State {} => to_binary(&query_state(deps)?), - QueryMsg::Pool { pool_type } => to_binary(&query_pool(deps, pool_type)?), - QueryMsg::UserInfo { address } => to_binary(&query_user_info(deps, env, address)?), + QueryMsg::Config {} => to_json_binary(&CONFIG.load(deps.storage)?), + QueryMsg::State {} => to_json_binary(&query_state(deps)?), + QueryMsg::Pool { pool_type } => to_json_binary(&query_pool(deps, pool_type)?), + QueryMsg::UserInfo { address } => to_json_binary(&query_user_info(deps, env, address)?), QueryMsg::UserInfoWithLockupsList { address } => { - to_binary(&query_user_info_with_lockups_list(deps, env, address)?) + to_json_binary(&query_user_info_with_lockups_list(deps, env, address)?) } QueryMsg::LockUpInfo { user_address, pool_type, duration, - } => to_binary(&query_lockup_info( + } => to_json_binary(&query_lockup_info( deps, &env, &user_address, @@ -258,14 +256,14 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { pool_type, user_address, height, - } => to_binary(&query_user_lockup_total_at_height( + } => to_json_binary(&query_user_lockup_total_at_height( deps, pool_type, deps.api.addr_validate(&user_address)?, height, )?), QueryMsg::QueryLockupTotalAtHeight { pool_type, height } => { - to_binary(&query_lockup_total_at_height(deps, pool_type, height)?) + to_json_binary(&query_lockup_total_at_height(deps, pool_type, height)?) } } } @@ -311,7 +309,7 @@ pub fn handle_update_config( } } - config.generator = deps.api.addr_validate(&generator)?; + config.incentives = deps.api.addr_validate(&generator)?; attributes.push(attr("new_generator", generator)) } @@ -366,8 +364,8 @@ pub fn handle_migrate_xyk_liquidity( )? .minter; let staked_lp_token_amount = deps.querier.query_wasm_smart::( - config.generator.to_string(), - &GenQueryMsg::Deposit { + config.incentives.to_string(), + &IncentivesQueryMsg::Deposit { lp_token: pool_info.lp_token.to_string(), user: env.contract.address.to_string(), }, @@ -377,7 +375,7 @@ pub fn handle_migrate_xyk_liquidity( let mut cosmos_msgs: Vec> = vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: astroport_pool.to_string(), funds: info.funds.clone(), - msg: to_binary(&ProvideLiquidity { + msg: to_json_binary(&ProvideLiquidity { assets: info .funds .iter() @@ -457,7 +455,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( // Check is there lockup or not ? let lockup_key = (pool_type, &user_address, duration); - let lockup_info = LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; + let lockup_info = LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.incentives)?; // CHECK :: Can the Lockup position be unlocked or not ? if withdraw_lp_stake && env.block.time.seconds() < lockup_info.unlock_timestamp { @@ -478,38 +476,20 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let astroport_lp_token = pool_info.lp_token; if pool_info.is_staked { - let generator = &config.generator; + let generator = &config.incentives; // QUERY :: Check if there are any pending staking rewards - let pending_rewards: PendingTokenResponse = deps.querier.query_wasm_smart( + let pending_rewards_response: Vec = deps.querier.query_wasm_smart( generator, - &GenQueryMsg::PendingToken { + &IncentivesQueryMsg::PendingRewards { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), }, )?; - let pending_on_proxy = &pending_rewards.pending_on_proxy.unwrap_or_default(); - - if !pending_rewards.pending.is_zero() - || pending_on_proxy.iter().any(|asset| !asset.amount.is_zero()) + if pending_rewards_response.iter().any(|asset| !asset.amount.is_zero()) { - let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::RewardInfo { - lp_token: astroport_lp_token.to_string(), - }, - )?; - - let reward_token_balance = deps - .querier - .query_balance( - env.contract.address.clone(), - rwi.base_reward_token.to_string(), - )? - .amount; - - let prev_proxy_reward_balances: Vec = pending_on_proxy + let prev_pending_rewards_balances: Vec = pending_rewards_response .iter() .map(|asset| { let balance = asset @@ -527,7 +507,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: generator.to_string(), funds: vec![], - msg: to_binary(&GenExecuteMsg::ClaimRewards { + msg: to_json_binary(&IncentivesExecuteMsg::ClaimRewards { lp_tokens: vec![astroport_lp_token.to_string()], })?, })); @@ -535,8 +515,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( cosmos_msgs.push( CallbackMsg::UpdatePoolOnDualRewardsClaim { pool_type, - prev_ntrn_balance: reward_token_balance, - prev_proxy_reward_balances, + prev_proxy_reward_balances: prev_pending_rewards_balances, } .to_cosmos_msg(&env)?, ); @@ -604,7 +583,7 @@ pub fn claim_airdrop_tokens_with_multiplier_msg( Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: credits_contract.to_string(), - msg: to_binary(&Cw20ExecuteMsg::BurnFrom { + msg: to_json_binary(&Cw20ExecuteMsg::BurnFrom { owner: user_addr.to_string(), amount: claimable_vested_amount.checked_add(unvested_tokens_amount.amount)?, })?, @@ -620,52 +599,28 @@ pub fn claim_airdrop_tokens_with_multiplier_msg( /// /// * **pool_type** is an object of type [`PoolType`]. LiquidPool type - USDC or ATOM /// -/// * **prev_ntrn_balance** is an object of type [`Uint128`]. Contract's NTRN token balance before claim. -/// -/// * **prev_proxy_reward_balances** is a vector of type [`Asset`]. Contract's Generator Proxy reward token balance before claim. +/// * **prev_pending_rewards_balances** is a vector of type [`Asset`]. Contract's Incentives reward token balance before claim. pub fn update_pool_on_dual_rewards_claim( deps: DepsMut, env: Env, pool_type: PoolType, - prev_ntrn_balance: Uint128, - prev_proxy_reward_balances: Vec, + prev_pending_rewards_balances: Vec, ) -> StdResult { let config = CONFIG.load(deps.storage)?; let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - let generator = &config.generator; + let incentives = &config.incentives; let astroport_lp_token = pool_info.lp_token.clone(); - let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::RewardInfo { - lp_token: astroport_lp_token.to_string(), - }, - )?; - let lp_balance: Uint128 = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::Deposit { + incentives, + &IncentivesQueryMsg::Deposit { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), }, )?; - let base_reward_received; - // Increment claimed rewards per LP share - pool_info.generator_ntrn_per_share = pool_info.generator_ntrn_per_share.checked_add({ - let reward_token_balance = deps - .querier - .query_balance( - env.contract.address.clone(), - rwi.base_reward_token.to_string(), - )? - .amount; - base_reward_received = reward_token_balance.checked_sub(prev_ntrn_balance)?; - Decimal::from_ratio(base_reward_received, lp_balance) - })?; - // Increment claimed Proxy rewards per LP share - for prev_balance in prev_proxy_reward_balances { + for prev_balance in prev_pending_rewards_balances { let current_balance = prev_balance .info .query_pool(&deps.querier, env.contract.address.clone())?; @@ -682,7 +637,6 @@ pub fn update_pool_on_dual_rewards_claim( Ok(Response::new().add_attributes(vec![ attr("action", "update_generator_dual_rewards"), attr("pool_type", format!("{:?}", pool_type)), - attr("NTRN_reward_received", base_reward_received), attr( "generator_ntrn_per_share", pool_info.generator_ntrn_per_share.to_string(), @@ -715,7 +669,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let lockup_key = (pool_type, &user_address, duration); let mut lockup_info = - LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; + LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.incentives)?; let mut user_info = USER_INFO .may_load(deps.storage, &user_address)? @@ -730,14 +684,14 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( ]; let astroport_lp_token = pool_info.lp_token.clone(); - let generator = &config.generator; + let incentives = &config.incentives; // Calculate Astro LP share for the lockup position let astroport_lp_amount: Uint128 = { let balance: Uint128 = if pool_info.is_staked { deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::Deposit { + incentives, + &IncentivesQueryMsg::Deposit { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), }, @@ -761,13 +715,6 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // If Astro LP tokens are staked with Astro generator if pool_info.is_staked { - let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::RewardInfo { - lp_token: astroport_lp_token.to_string(), - }, - )?; - // Calculate claimable staking rewards for this lockup let total_lockup_astro_rewards = pool_info .generator_ntrn_per_share @@ -777,21 +724,9 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( total_lockup_astro_rewards.checked_sub(lockup_info.generator_ntrn_debt)?; lockup_info.generator_ntrn_debt = total_lockup_astro_rewards; - // If claimable staking rewards > 0, claim them - if pending_astro_rewards > Uint128::zero() { - cosmos_msgs.push(CosmosMsg::Bank(BankMsg::Send { - to_address: user_address.to_string(), - amount: vec![Coin { - denom: rwi.base_reward_token.to_string(), - amount: pending_astro_rewards, - }], - })); - } - attributes.push(attr("generator_astro_reward", pending_astro_rewards)); - - let mut pending_proxy_rewards: Vec = vec![]; - // If this LP token is getting dual incentives - // Calculate claimable proxy staking rewards for this lockup + let mut pending_rewards: Vec = vec![]; + // If this LP token is getting incentives + // Calculate claimable staking rewards for this lockup lockup_info.generator_proxy_debt = lockup_info .generator_proxy_debt .inner_ref() @@ -801,42 +736,42 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .generator_proxy_per_share .load(asset) .unwrap_or_default(); - let total_lockup_proxy_reward = + let total_lockup_reward = generator_proxy_per_share.checked_mul_uint128(astroport_lp_amount)?; - let pending_proxy_reward: Uint128 = total_lockup_proxy_reward.checked_sub(*debt)?; + let pending_reward: Uint128 = total_lockup_reward.checked_sub(*debt)?; - if !pending_proxy_reward.is_zero() { - pending_proxy_rewards.push(Asset { + if !pending_reward.is_zero() { + pending_rewards.push(Asset { info: asset.clone(), - amount: pending_proxy_reward, + amount: pending_reward, }); } - Ok((asset.clone(), total_lockup_proxy_reward)) + Ok((asset.clone(), total_lockup_reward)) }) .collect::>>()? .into(); // If this is a void transaction (no state change), then return error. - // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending proxy rewards, not unlocking LP tokens in this tx + // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending rewards, not unlocking LP tokens in this tx if !withdraw_lp_stake && user_info.ntrn_transferred && pending_astro_rewards == Uint128::zero() - && pending_proxy_rewards.is_empty() + && pending_rewards.is_empty() { return Err(StdError::generic_err("No rewards available to claim!")); } // If claimable proxy staking rewards > 0, claim them - for pending_proxy_reward in pending_proxy_rewards { - cosmos_msgs.push(pending_proxy_reward.into_msg(&deps.querier, user_address.clone())?); + for pending_reward in pending_rewards { + cosmos_msgs.push(pending_reward.into_msg(user_address.clone())?); } // COSMOSMSG :: If LP Tokens are staked, we unstake the amount which needs to be returned to the user if withdraw_lp_stake { cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: generator.to_string(), + contract_addr: incentives.to_string(), funds: vec![], - msg: to_binary(&GenExecuteMsg::Withdraw { + msg: to_json_binary(&IncentivesExecuteMsg::Withdraw { lp_token: astroport_lp_token.to_string(), amount: astroport_lp_amount, })?, @@ -848,7 +783,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // COSMOSMSG :: Returns LP units locked by the user in the current lockup position cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: astroport_lp_token.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: user_address.to_string(), amount: astroport_lp_amount, })?, @@ -934,8 +869,8 @@ pub fn callback_finish_lockup_migration( let staked_lp_token_amount_diff = deps .querier .query_wasm_smart::( - config.generator.to_string(), - &GenQueryMsg::Deposit { + config.incentives.to_string(), + &IncentivesQueryMsg::Deposit { lp_token, user: env.contract.address.to_string(), }, @@ -1149,12 +1084,11 @@ pub fn query_lockup_info( let lockup_key = (pool_type, &user_address, duration); let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - let mut lockup_info = LOCKUP_INFO.compatible_load(deps, lockup_key, &config.generator)?; + let mut lockup_info = LOCKUP_INFO.compatible_load(deps, lockup_key, &config.incentives)?; let lockup_astroport_lp_units_opt: Option; let astroport_lp_token_opt: Addr; - let mut claimable_generator_astro_debt = Uint128::zero(); - let mut claimable_generator_proxy_debt: RestrictedVector = + let mut claimable_generator_rewards_debt: RestrictedVector = RestrictedVector::default(); if let Some(astroport_lp_transferred) = lockup_info.astroport_lp_transferred { lockup_astroport_lp_units_opt = Some(astroport_lp_transferred); @@ -1167,7 +1101,7 @@ pub fn query_lockup_info( pool_astroport_lp_units = if pool_info.is_staked { raw_generator_deposit( deps.querier, - &config.generator, + &config.incentives, astroport_lp_token.as_bytes(), env.contract.address.as_bytes(), )? @@ -1189,54 +1123,37 @@ pub fn query_lockup_info( astroport_lp_token_opt = astroport_lp_token.clone(); // If LP tokens are staked, calculate the rewards claimable by the user for this lockup position if pool_info.is_staked && !lockup_astroport_lp_units.is_zero() { - let generator = &config.generator; + let incentives = &config.incentives; // QUERY :: Check if there are any pending staking rewards - let pending_rewards: PendingTokenResponse = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::PendingToken { + let pending_rewards: Vec = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::PendingRewards { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), }, )?; - // Calculate claimable Astro staking rewards for this lockup - pool_info.generator_ntrn_per_share = - pool_info - .generator_ntrn_per_share - .checked_add(Decimal::from_ratio( - pending_rewards.pending, - pool_astroport_lp_units, - ))?; - - let total_lockup_astro_rewards = pool_info - .generator_ntrn_per_share - .checked_mul(lockup_astroport_lp_units.to_decimal())? - .to_uint_floor(); - claimable_generator_astro_debt = - total_lockup_astro_rewards.checked_sub(lockup_info.generator_ntrn_debt)?; - // Calculate claimable Proxy staking rewards for this lockup - if let Some(pending_on_proxy) = pending_rewards.pending_on_proxy { - for reward in pending_on_proxy { - let generator_proxy_per_share = pool_info.generator_proxy_per_share.update( - &reward.info, - Decimal::from_ratio(reward.amount, pool_astroport_lp_units), + for reward in pending_rewards { + let generator_proxy_per_share = pool_info.generator_proxy_per_share.update( + &reward.info, + Decimal::from_ratio(reward.amount, pool_astroport_lp_units), + )?; + + let debt = generator_proxy_per_share + .checked_mul_uint128(lockup_astroport_lp_units)? + .checked_sub( + lockup_info + .generator_proxy_debt + .inner_ref() + .iter() + .find_map(|a| if reward.info == a.0 { Some(a.1) } else { None }) + .unwrap_or_default(), )?; - let debt = generator_proxy_per_share - .checked_mul_uint128(lockup_astroport_lp_units)? - .checked_sub( - lockup_info - .generator_proxy_debt - .inner_ref() - .iter() - .find_map(|a| if reward.info == a.0 { Some(a.1) } else { None }) - .unwrap_or_default(), - )?; - - claimable_generator_proxy_debt.update(&reward.info, debt)?; - } + claimable_generator_rewards_debt.update(&reward.info, debt)?; } + } } // Calculate currently expected ASTRO Rewards if not finalized @@ -1258,9 +1175,9 @@ pub fn query_lockup_info( withdrawal_flag: lockup_info.withdrawal_flag, ntrn_rewards: lockup_info.ntrn_rewards, generator_ntrn_debt: lockup_info.generator_ntrn_debt, - claimable_generator_astro_debt, + claimable_generator_astro_debt: Uint128::zero(), generator_proxy_debt: lockup_info.generator_proxy_debt, - claimable_generator_proxy_debt, + claimable_generator_proxy_debt: claimable_generator_rewards_debt, unlock_timestamp: lockup_info.unlock_timestamp, astroport_lp_units: lockup_astroport_lp_units_opt, astroport_lp_token: astroport_lp_token_opt, @@ -1353,7 +1270,7 @@ fn update_user_lockup_positions_and_calc_rewards( let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let lockup_key = (pool_type, user_address, duration); let mut lockup_info = - LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.generator)?; + LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.incentives)?; if lockup_info.ntrn_rewards == Uint128::zero() { // Weighted lockup balance (using terraswap LP units to calculate as pool's total weighted balance is calculated on terraswap LP deposits summed over each deposit tx) diff --git a/contracts/lockdrop-pcl/src/raw_queries.rs b/contracts/lockdrop-pcl/src/raw_queries.rs index e491fdf4..fa8ead99 100644 --- a/contracts/lockdrop-pcl/src/raw_queries.rs +++ b/contracts/lockdrop-pcl/src/raw_queries.rs @@ -1,5 +1,5 @@ use astroport::asset::AssetInfo; -use cosmwasm_std::{from_slice, Addr, Empty, QuerierWrapper, StdError, StdResult, Uint128}; +use cosmwasm_std::{from_json, Addr, Empty, QuerierWrapper, StdError, StdResult, Uint128}; use cw_storage_plus::Path; use serde::Deserialize; @@ -17,7 +17,7 @@ pub fn raw_generator_deposit( let key: Path = Path::new(b"user_info", &[lp_token, address]); if let Some(res) = &querier.query_wasm_raw(generator, key.to_vec())? { - let UserInfo { amount } = from_slice(res)?; + let UserInfo { amount } = from_json(res)?; Ok(amount) } else { Ok(Uint128::zero()) @@ -28,7 +28,7 @@ pub fn raw_generator_deposit( pub fn raw_balance(querier: QuerierWrapper, token: &Addr, address: &[u8]) -> StdResult { let key: Path = Path::new(b"balance", &[address]); if let Some(res) = &querier.query_wasm_raw(token, key.to_vec())? { - let res: Uint128 = from_slice(res)?; + let res: Uint128 = from_json(res)?; Ok(res) } else { Ok(Uint128::zero()) @@ -43,7 +43,7 @@ pub fn raw_proxy_asset( ) -> StdResult { let key: Path = Path::new(b"proxy_reward_asset", &[address]); if let Some(res) = &querier.query_wasm_raw(generator, key.to_vec())? { - let res: AssetInfo = from_slice(res)?; + let res: AssetInfo = from_json(res)?; return Ok(res); } Err(StdError::generic_err(format!( diff --git a/contracts/lockdrop/Cargo.toml b/contracts/lockdrop/Cargo.toml index d3167f93..e98eceb1 100644 --- a/contracts/lockdrop/Cargo.toml +++ b/contracts/lockdrop/Cargo.toml @@ -26,7 +26,7 @@ library = [] [dependencies] # we have to keep it 0.15.1 because it is the same version as in astroport cw-storage-plus = { version = "0.15.1" } -astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v2.5.0" } +astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v3.11.0" } credits = { path = "../credits" } astroport-periphery = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index 0300f5b3..a25d2f51 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -13,7 +13,7 @@ use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; use astroport_periphery::utils::Decimal256CheckedOps; use cosmwasm_std::{ - attr, coins, entry_point, from_binary, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, + attr, coins, entry_point, from_json, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, Uint256, WasmMsg, }; @@ -245,7 +245,7 @@ pub fn receive_cw20( )); } - match from_binary(&cw20_msg.msg)? { + match from_json(&cw20_msg.msg)? { Cw20HookMsg::InitializePool { pool_type, incentives_share, @@ -407,18 +407,18 @@ fn _handle_callback( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => to_binary(&CONFIG.load(deps.storage)?), - QueryMsg::State {} => to_binary(&query_state(deps)?), - QueryMsg::Pool { pool_type } => to_binary(&query_pool(deps, pool_type)?), - QueryMsg::UserInfo { address } => to_binary(&query_user_info(deps, env, address)?), + QueryMsg::Config {} => to_json_binary(&CONFIG.load(deps.storage)?), + QueryMsg::State {} => to_json_binary(&query_state(deps)?), + QueryMsg::Pool { pool_type } => to_json_binary(&query_pool(deps, pool_type)?), + QueryMsg::UserInfo { address } => to_json_binary(&query_user_info(deps, env, address)?), QueryMsg::UserInfoWithLockupsList { address } => { - to_binary(&query_user_info_with_lockups_list(deps, env, address)?) + to_json_binary(&query_user_info_with_lockups_list(deps, env, address)?) } QueryMsg::LockUpInfo { user_address, pool_type, duration, - } => to_binary(&query_lockup_info( + } => to_json_binary(&query_lockup_info( deps, &env, &user_address, @@ -429,14 +429,14 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { pool_type, user_address, height, - } => to_binary(&query_user_lockup_total_at_height( + } => to_json_binary(&query_user_lockup_total_at_height( deps, pool_type, deps.api.addr_validate(&user_address)?, height, )?), QueryMsg::QueryLockupTotalAtHeight { pool_type, height } => { - to_binary(&query_lockup_total_at_height(deps, pool_type, height)?) + to_json_binary(&query_lockup_total_at_height(deps, pool_type, height)?) } } } @@ -654,7 +654,7 @@ fn callback_init_migrate_lockup_to_pcl_pools( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: generator.to_string(), funds: vec![], - msg: to_binary(&GenExecuteMsg::ClaimRewards { + msg: to_json_binary(&GenExecuteMsg::ClaimRewards { lp_tokens: vec![astroport_lp_token.to_string()], })?, })); @@ -854,7 +854,7 @@ fn stake_messages( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: lp_token_address.to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&Cw20ExecuteMsg::IncreaseAllowance { spender: generator.to_string(), amount, expires: Some(cw20::Expiration::AtHeight(height)), @@ -864,9 +864,9 @@ fn stake_messages( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: lp_token_address.to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: generator.to_string(), - msg: to_binary(&astroport::generator::Cw20HookMsg::Deposit {})?, + msg: to_json_binary(&astroport::generator::Cw20HookMsg::Deposit {})?, amount, })?, })); @@ -1281,7 +1281,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: generator.to_string(), funds: vec![], - msg: to_binary(&GenExecuteMsg::ClaimRewards { + msg: to_json_binary(&GenExecuteMsg::ClaimRewards { lp_tokens: vec![astroport_lp_token.to_string()], })?, })); @@ -1358,7 +1358,7 @@ pub fn claim_airdrop_tokens_with_multiplier_msg( Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: credits_contract.to_string(), - msg: to_binary(&Cw20ExecuteMsg::BurnFrom { + msg: to_json_binary(&Cw20ExecuteMsg::BurnFrom { owner: user_addr.to_string(), amount: claimable_vested_amount.checked_add(unvested_tokens_amount.amount)?, })?, @@ -1590,7 +1590,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // If claimable proxy staking rewards > 0, claim them for pending_proxy_reward in pending_proxy_rewards { - cosmos_msgs.push(pending_proxy_reward.into_msg(&deps.querier, user_address.clone())?); + cosmos_msgs.push(pending_proxy_reward.into_msg(user_address.clone())?); } // COSMOSMSG :: If LP Tokens are staked, we unstake the amount which needs to be returned to the user @@ -1598,7 +1598,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: generator.to_string(), funds: vec![], - msg: to_binary(&GenExecuteMsg::Withdraw { + msg: to_json_binary(&GenExecuteMsg::Withdraw { lp_token: astroport_lp_token.to_string(), amount: astroport_lp_amount, })?, @@ -1610,7 +1610,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // COSMOSMSG :: Returns LP units locked by the user in the current lockup position cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: astroport_lp_token.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: user_address.to_string(), amount: astroport_lp_amount, })?, @@ -1792,7 +1792,7 @@ pub fn callback_transfer_all_rewards_before_migration( // If claimable proxy staking rewards > 0, claim them for pending_proxy_reward in pending_proxy_rewards { - cosmos_msgs.push(pending_proxy_reward.into_msg(&deps.querier, user_address.clone())?); + cosmos_msgs.push(pending_proxy_reward.into_msg(user_address.clone())?); } // Transfers claimable one time NTRN rewards to the user that the user gets for all his lock @@ -1860,7 +1860,7 @@ pub fn callback_withdraw_user_lockup( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: generator.to_string(), funds: vec![], - msg: to_binary(&GenExecuteMsg::Withdraw { + msg: to_json_binary(&GenExecuteMsg::Withdraw { lp_token: astroport_lp_token.to_string(), amount: astroport_lp_amount, })?, @@ -1900,10 +1900,10 @@ pub fn callback_withdraw_user_lockup( cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: astroport_lp_token.to_string(), funds: vec![], - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: astroport_pool, amount: astroport_lp_amount, - msg: to_binary(&astroport::pair::Cw20HookMsg::WithdrawLiquidity { assets: vec![] })?, + msg: to_json_binary(&astroport::pair::Cw20HookMsg::WithdrawLiquidity { assets: vec![] })?, })?, })); @@ -1996,7 +1996,7 @@ pub fn callback_migrate_user_lockup_to_pcl_pair( amount: paired_asset_withdrawn, }, ], - msg: to_binary(&LockdropPCLExecuteMsg::MigrateXYKLiquidity { + msg: to_json_binary(&LockdropPCLExecuteMsg::MigrateXYKLiquidity { pool_type, user_address_raw: user_address.to_string(), duration, diff --git a/contracts/lockdrop/src/raw_queries.rs b/contracts/lockdrop/src/raw_queries.rs index e491fdf4..fa8ead99 100644 --- a/contracts/lockdrop/src/raw_queries.rs +++ b/contracts/lockdrop/src/raw_queries.rs @@ -1,5 +1,5 @@ use astroport::asset::AssetInfo; -use cosmwasm_std::{from_slice, Addr, Empty, QuerierWrapper, StdError, StdResult, Uint128}; +use cosmwasm_std::{from_json, Addr, Empty, QuerierWrapper, StdError, StdResult, Uint128}; use cw_storage_plus::Path; use serde::Deserialize; @@ -17,7 +17,7 @@ pub fn raw_generator_deposit( let key: Path = Path::new(b"user_info", &[lp_token, address]); if let Some(res) = &querier.query_wasm_raw(generator, key.to_vec())? { - let UserInfo { amount } = from_slice(res)?; + let UserInfo { amount } = from_json(res)?; Ok(amount) } else { Ok(Uint128::zero()) @@ -28,7 +28,7 @@ pub fn raw_generator_deposit( pub fn raw_balance(querier: QuerierWrapper, token: &Addr, address: &[u8]) -> StdResult { let key: Path = Path::new(b"balance", &[address]); if let Some(res) = &querier.query_wasm_raw(token, key.to_vec())? { - let res: Uint128 = from_slice(res)?; + let res: Uint128 = from_json(res)?; Ok(res) } else { Ok(Uint128::zero()) @@ -43,7 +43,7 @@ pub fn raw_proxy_asset( ) -> StdResult { let key: Path = Path::new(b"proxy_reward_asset", &[address]); if let Some(res) = &querier.query_wasm_raw(generator, key.to_vec())? { - let res: AssetInfo = from_slice(res)?; + let res: AssetInfo = from_json(res)?; return Ok(res); } Err(StdError::generic_err(format!( diff --git a/contracts/lockdrop/src/testing.rs b/contracts/lockdrop/src/testing.rs index 526c0362..97d8c772 100644 --- a/contracts/lockdrop/src/testing.rs +++ b/contracts/lockdrop/src/testing.rs @@ -3,7 +3,7 @@ use astroport_periphery::lockdrop::{ Config, ExecuteMsg, InstantiateMsg, LockupRewardsInfo, QueryMsg, }; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{coin, from_binary, Addr, Decimal256, StdError, Uint128}; +use cosmwasm_std::{coin, from_json, Addr, Decimal256, StdError, Uint128}; #[test] fn update_owner() { @@ -89,7 +89,7 @@ fn update_owner() { // Let's query the state let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(new_owner, config.owner); } @@ -132,7 +132,7 @@ fn increase_ntrn_incentives() { assert!(res.is_ok()); let config: Config = - from_binary(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(Uint128::new(100u128), config.lockdrop_incentives); // invalid coin diff --git a/contracts/price-feed/src/contract.rs b/contracts/price-feed/src/contract.rs index 9e3630b6..deecc189 100644 --- a/contracts/price-feed/src/contract.rs +++ b/contracts/price-feed/src/contract.rs @@ -6,7 +6,7 @@ use astroport_periphery::pricefeed::{ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Empty, Env, IbcMsg, IbcTimeout, MessageInfo, Response, + to_json_binary, Binary, Deps, DepsMut, Empty, Env, IbcMsg, IbcTimeout, MessageInfo, Response, StdResult, }; use cw2::set_contract_version; @@ -105,7 +105,7 @@ pub fn try_request(deps: DepsMut, env: Env) -> Result { let msg = IbcMsg::SendPacket { channel_id: endpoint.channel_id, - data: to_binary(&packet)?, + data: to_json_binary(&packet)?, timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(60)), }; LAST_UPDATE.save(deps.storage, &env.block.time.seconds())?; @@ -180,9 +180,9 @@ pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetRate {} => to_binary(&query_rate(deps)?), - QueryMsg::GetError {} => to_binary(&query_error(deps)?), - QueryMsg::GetConfig {} => to_binary(&query_config(deps)?), + QueryMsg::GetRate {} => to_json_binary(&query_rate(deps)?), + QueryMsg::GetError {} => to_json_binary(&query_error(deps)?), + QueryMsg::GetConfig {} => to_json_binary(&query_config(deps)?), } } diff --git a/contracts/price-feed/src/ibc.rs b/contracts/price-feed/src/ibc.rs index b1ac0349..c0a72b05 100644 --- a/contracts/price-feed/src/ibc.rs +++ b/contracts/price-feed/src/ibc.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, from_slice, Binary, DepsMut, Env, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannel, + attr, from_json, Binary, DepsMut, Env, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, StdResult, Uint64, @@ -95,7 +95,7 @@ fn do_ibc_packet_receive( env: Env, packet: &IbcPacket, ) -> Result { - let resp: OracleResponsePacketData = from_slice(&packet.data)?; + let resp: OracleResponsePacketData = from_json(&packet.data)?; let config = CONFIG.load(deps.storage)?; let symbols = config.symbols; deps.api @@ -153,6 +153,6 @@ fn ttt() { let res: Vec = OBIDecode::decode(&mut b.as_slice()).unwrap(); println!("{:?}\n{:?}", res, b.len()); - // let result: Result, _> = from_slice(b.as_slice()); + // let result: Result, _> = from_json(b.as_slice()); // println!("{:?}", result); } diff --git a/contracts/vesting-investors/src/tests/integration.rs b/contracts/vesting-investors/src/tests/integration.rs index c971d6c6..e101baf5 100644 --- a/contracts/vesting-investors/src/tests/integration.rs +++ b/contracts/vesting-investors/src/tests/integration.rs @@ -2,7 +2,7 @@ use crate::msg::InstantiateMsg; use astroport::asset::{native_asset_info, token_asset_info}; use astroport::querier::query_balance; use astroport::token::InstantiateMsg as TokenInstantiateMsg; -use cosmwasm_std::{coin, coins, to_binary, Addr, StdResult, Timestamp, Uint128}; +use cosmwasm_std::{coin, coins, to_json_binary, Addr, StdResult, Timestamp, Uint128}; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use cw_multi_test::{App, ContractWrapper, Executor}; use cw_utils::PaymentError; @@ -37,7 +37,7 @@ fn claim() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![ @@ -85,7 +85,7 @@ fn claim() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![ @@ -213,7 +213,7 @@ fn claim_native() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -383,7 +383,7 @@ fn register_vesting_accounts() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -409,7 +409,7 @@ fn register_vesting_accounts() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -495,7 +495,7 @@ fn register_vesting_accounts() { // Let's check user1's final vesting amount after add schedule for a new one let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user2.to_string(), schedules: vec![VestingSchedule { @@ -542,7 +542,7 @@ fn register_vesting_accounts() { // Add one more vesting schedule; final amount to vest must increase let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -636,7 +636,7 @@ fn register_vesting_accounts_native() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -1142,7 +1142,7 @@ fn remove_vesting_accounts() { let res: StdResult = app.wrap().query_wasm_smart(vesting_instance.clone(), &msg); assert_eq!( res.unwrap_err().to_string(), - "Generic error: Querier contract error: vesting_base::types::VestingInfo not found" + "Generic error: Querier contract error: type: vesting_base::types::VestingInfo; key: [00, 0C, 76, 65, 73, 74, 69, 6E, 67, 5F, 69, 6E, 66, 6F, 75, 73, 65, 72, 31] not found" ); // Check vesting balance @@ -1281,7 +1281,7 @@ fn remove_vesting_accounts() { let res: StdResult = app.wrap().query_wasm_smart(vesting_instance.clone(), &msg); assert_eq!( res.unwrap_err().to_string(), - "Generic error: Querier contract error: vesting_base::types::VestingInfo not found" + "Generic error: Querier contract error: type: vesting_base::types::VestingInfo; key: [00, 0C, 76, 65, 73, 74, 69, 6E, 67, 5F, 69, 6E, 66, 6F, 75, 73, 65, 72, 31] not found" ); // Check vesting balance diff --git a/contracts/vesting-lp/src/tests/integration.rs b/contracts/vesting-lp/src/tests/integration.rs index 5a150e97..311bf01b 100644 --- a/contracts/vesting-lp/src/tests/integration.rs +++ b/contracts/vesting-lp/src/tests/integration.rs @@ -2,7 +2,7 @@ use crate::msg::InstantiateMsg; use astroport::asset::{native_asset_info, token_asset_info}; use astroport::querier::query_balance; use astroport::token::InstantiateMsg as TokenInstantiateMsg; -use cosmwasm_std::{coin, coins, to_binary, Addr, StdResult, Timestamp, Uint128}; +use cosmwasm_std::{coin, coins, to_json_binary, Addr, StdResult, Timestamp, Uint128}; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use cw_multi_test::{App, ContractWrapper, Executor}; use cw_utils::PaymentError; @@ -39,7 +39,7 @@ fn claim() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![ @@ -87,7 +87,7 @@ fn claim() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![ @@ -215,7 +215,7 @@ fn claim_native() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -385,7 +385,7 @@ fn register_vesting_accounts() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -411,7 +411,7 @@ fn register_vesting_accounts() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -497,7 +497,7 @@ fn register_vesting_accounts() { // Let's check user1's final vesting amount after add schedule for a new one let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user2.to_string(), schedules: vec![VestingSchedule { @@ -544,7 +544,7 @@ fn register_vesting_accounts() { // Add one more vesting schedule; final amount to vest must increase let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -638,7 +638,7 @@ fn register_vesting_accounts_native() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { diff --git a/contracts/vesting-lti/src/tests/integration.rs b/contracts/vesting-lti/src/tests/integration.rs index dd94da54..529ca1b4 100644 --- a/contracts/vesting-lti/src/tests/integration.rs +++ b/contracts/vesting-lti/src/tests/integration.rs @@ -2,7 +2,7 @@ use crate::msg::InstantiateMsg; use astroport::asset::{native_asset_info, token_asset_info}; use astroport::querier::query_balance; use astroport::token::InstantiateMsg as TokenInstantiateMsg; -use cosmwasm_std::{coin, coins, to_binary, Addr, StdResult, Timestamp, Uint128}; +use cosmwasm_std::{coin, coins, to_json_binary, Addr, StdResult, Timestamp, Uint128}; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use cw_multi_test::{App, ContractWrapper, Executor}; use cw_utils::PaymentError; @@ -40,7 +40,7 @@ fn claim() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![ @@ -88,7 +88,7 @@ fn claim() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![ @@ -217,7 +217,7 @@ fn claim_native() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -391,7 +391,7 @@ fn register_vesting_accounts() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -417,7 +417,7 @@ fn register_vesting_accounts() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -503,7 +503,7 @@ fn register_vesting_accounts() { // Let's check user1's final vesting amount after add schedule for a new one let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user2.to_string(), schedules: vec![VestingSchedule { @@ -550,7 +550,7 @@ fn register_vesting_accounts() { // Add one more vesting schedule; final amount to vest must increase let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -644,7 +644,7 @@ fn register_vesting_accounts_native() { let msg = Cw20ExecuteMsg::Send { contract: vesting_instance.to_string(), - msg: to_binary(&Cw20HookMsg::RegisterVestingAccounts { + msg: to_json_binary(&Cw20HookMsg::RegisterVestingAccounts { vesting_accounts: vec![VestingAccount { address: user1.to_string(), schedules: vec![VestingSchedule { @@ -974,7 +974,7 @@ fn remove_vesting_accounts() { let res: StdResult = app.wrap().query_wasm_smart(vesting_instance.clone(), &msg); assert_eq!( res.unwrap_err().to_string(), - "Generic error: Querier contract error: vesting_base::types::VestingInfo not found" + "Generic error: Querier contract error: type: vesting_base::types::VestingInfo; key: [00, 0C, 76, 65, 73, 74, 69, 6E, 67, 5F, 69, 6E, 66, 6F, 75, 73, 65, 72, 31] not found" ); // Check vesting balance @@ -1113,7 +1113,7 @@ fn remove_vesting_accounts() { let res: StdResult = app.wrap().query_wasm_smart(vesting_instance.clone(), &msg); assert_eq!( res.unwrap_err().to_string(), - "Generic error: Querier contract error: vesting_base::types::VestingInfo not found" + "Generic error: Querier contract error: type: vesting_base::types::VestingInfo; key: [00, 0C, 76, 65, 73, 74, 69, 6E, 67, 5F, 69, 6E, 66, 6F, 75, 73, 65, 72, 31] not found" ); // Check vesting balance diff --git a/packages/astroport/src/asset.rs b/packages/astroport/src/asset.rs index 60a029ce..c0bba3c5 100644 --- a/packages/astroport/src/asset.rs +++ b/packages/astroport/src/asset.rs @@ -7,7 +7,7 @@ use crate::querier::{ query_balance, query_token_balance, query_token_precision, query_token_symbol, }; use cosmwasm_std::{ - to_binary, Addr, Api, BankMsg, Coin, ConversionOverflowError, CosmosMsg, Decimal256, Fraction, + to_json_binary, Addr, Api, BankMsg, Coin, ConversionOverflowError, CosmosMsg, Decimal256, Fraction, MessageInfo, QuerierWrapper, StdError, StdResult, Uint128, Uint256, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; @@ -79,7 +79,7 @@ impl Asset { match &self.info { AssetInfo::Token { contract_addr } => Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient, amount: self.amount, })?, diff --git a/packages/astroport/src/generator.rs b/packages/astroport/src/generator.rs index 998adf2d..4872012d 100644 --- a/packages/astroport/src/generator.rs +++ b/packages/astroport/src/generator.rs @@ -2,7 +2,7 @@ use crate::asset::{Asset, AssetInfo}; use crate::factory::PairType; use crate::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_binary, Addr, Decimal, Env, StdResult, SubMsg, Uint128, Uint64, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, Decimal, Env, StdResult, SubMsg, Uint128, Uint64, WasmMsg}; use cw20::Cw20ReceiveMsg; /// This structure describes the parameters used for creating a contract. @@ -201,7 +201,7 @@ impl ExecuteOnReply { pub fn into_submsg(self, env: &Env) -> StdResult { let msg = SubMsg::new(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), - msg: to_binary(&ExecuteMsg::Callback { action: self })?, + msg: to_json_binary(&ExecuteMsg::Callback { action: self })?, funds: vec![], }); diff --git a/packages/astroport/src/mock_querier.rs b/packages/astroport/src/mock_querier.rs index 528fc737..7a815bf6 100644 --- a/packages/astroport/src/mock_querier.rs +++ b/packages/astroport/src/mock_querier.rs @@ -1,6 +1,6 @@ use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_binary, from_slice, to_binary, Coin, Empty, OwnedDeps, Querier, QuerierResult, + from_json, to_json_binary, Coin, Empty, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, }; @@ -89,7 +89,7 @@ pub(crate) fn pairs_to_map(pairs: &[(&String, &PairInfo)]) -> HashMap QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_json(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -119,7 +119,7 @@ impl CW20QueryHandler { pub fn execute(&self, request: &QueryRequest) -> QuerierResult { match &request { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match from_binary(msg).unwrap() { + match from_json(msg).unwrap() { Cw20QueryMsg::TokenInfo {} => { let balances: &HashMap = match self.token_querier.balances.get(contract_addr) { @@ -136,7 +136,7 @@ impl CW20QueryHandler { } SystemResult::Ok( - to_binary(&TokenInfoResponse { + to_json_binary(&TokenInfoResponse { name: "mAPPL".to_string(), symbol: "mAPPL".to_string(), decimals: 6, @@ -161,7 +161,7 @@ impl CW20QueryHandler { } }; - SystemResult::Ok(to_binary(&BalanceResponse { balance: *balance }).into()) + SystemResult::Ok(to_json_binary(&BalanceResponse { balance: *balance }).into()) } _ => panic!("DO NOT ENTER HERE"), } @@ -182,11 +182,11 @@ impl DefaultQueryHandler { QueryRequest::Wasm(WasmQuery::Smart { contract_addr: _, msg, - }) => match from_binary(msg).unwrap() { + }) => match from_json(msg).unwrap() { FactoryQueryMsg::Pair { asset_infos } => { 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(to_binary(&v).into()), + Some(v) => SystemResult::Ok(to_json_binary(&v).into()), None => SystemResult::Err(SystemError::InvalidRequest { error: "No pair info exists".to_string(), request: msg.as_slice().into(), diff --git a/packages/astroport/src/pair.rs b/packages/astroport/src/pair.rs index 3900ecce..ff34845d 100644 --- a/packages/astroport/src/pair.rs +++ b/packages/astroport/src/pair.rs @@ -2,7 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use crate::asset::{Asset, AssetInfo, PairInfo}; -use cosmwasm_std::{from_slice, Addr, Binary, Decimal, QuerierWrapper, StdResult, Uint128}; +use cosmwasm_std::{Addr, Binary, Decimal, from_json, QuerierWrapper, StdResult, Uint128}; use cw20::Cw20ReceiveMsg; /// The default swap slippage @@ -208,7 +208,7 @@ pub fn migration_check( pair_addr: &Addr, ) -> StdResult { if let Some(res) = querier.query_wasm_raw(factory, b"pairs_to_migrate".as_slice())? { - let res: Vec = from_slice(&res)?; + let res: Vec = from_json(res)?; Ok(res.contains(pair_addr)) } else { Ok(false) @@ -219,7 +219,7 @@ pub fn migration_check( mod tests { use super::*; use crate::asset::native_asset_info; - use cosmwasm_std::{from_binary, to_binary}; + use cosmwasm_std::{from_json, to_json_binary}; #[cw_serde] pub struct LegacyInstantiateMsg { @@ -247,17 +247,17 @@ mod tests { init_params: None, }; - let ser_msg = to_binary(&inst_msg).unwrap(); + let ser_msg = to_json_binary(&inst_msg).unwrap(); // This .unwrap() is enough to make sure that [AssetInfo; 2] and Vec are compatible. - let _: InstantiateMsg = from_binary(&ser_msg).unwrap(); + let _: InstantiateMsg = from_json(ser_msg).unwrap(); } #[test] fn test_config_response_compatability() { - let ser_msg = to_binary(&LegacyConfigResponse { + let ser_msg = to_json_binary(&LegacyConfigResponse { block_time_last: 12, params: Some( - to_binary(&StablePoolConfig { + to_json_binary(&StablePoolConfig { amp: Decimal::one(), }) .unwrap(), @@ -265,12 +265,12 @@ mod tests { }) .unwrap(); - let _: ConfigResponse = from_binary(&ser_msg).unwrap(); + let _: ConfigResponse = from_json(ser_msg).unwrap(); } #[test] fn check_empty_vec_deserialization() { - let variant: Cw20HookMsg = from_slice(br#"{"withdraw_liquidity": {} }"#).unwrap(); + let variant: Cw20HookMsg = from_json(br#"{"withdraw_liquidity": {} }"#).unwrap(); assert_eq!(variant, Cw20HookMsg::WithdrawLiquidity { assets: vec![] }); } } diff --git a/packages/astroport/src/testing.rs b/packages/astroport/src/testing.rs index 0a197683..2b4c6953 100644 --- a/packages/astroport/src/testing.rs +++ b/packages/astroport/src/testing.rs @@ -7,7 +7,7 @@ use crate::querier::{ use crate::factory::PairType; use crate::DecimalCheckedOps; use cosmwasm_std::testing::MOCK_CONTRACT_ADDR; -use cosmwasm_std::{to_binary, Addr, BankMsg, Coin, CosmosMsg, Decimal, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, BankMsg, Coin, CosmosMsg, Decimal, Uint128, WasmMsg}; use cw20::Cw20ExecuteMsg; #[test] @@ -209,7 +209,7 @@ fn test_asset() { .unwrap(), CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: String::from("asset0000"), - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: String::from("addr0000"), amount: Uint128::new(123123u128), }) diff --git a/packages/astroport_periphery/Cargo.toml b/packages/astroport_periphery/Cargo.toml index 14843f44..f3ff340e 100644 --- a/packages/astroport_periphery/Cargo.toml +++ b/packages/astroport_periphery/Cargo.toml @@ -17,6 +17,6 @@ cw20 = { workspace = true } cw-storage-plus = "0.15.1" cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } -astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v2.5.0" } +astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v3.11.0" } schemars = { workspace = true } serde = { workspace = true } diff --git a/packages/astroport_periphery/src/auction.rs b/packages/astroport_periphery/src/auction.rs index 525abbc3..a76dab9c 100644 --- a/packages/astroport_periphery/src/auction.rs +++ b/packages/astroport_periphery/src/auction.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, Env, StdResult, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, Env, StdResult, Uint128, WasmMsg}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -90,7 +90,7 @@ impl CallbackMsg { pub fn to_cosmos_msg(&self, env: &Env) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), - msg: to_binary(&ExecuteMsg::Callback(self.clone()))?, + msg: to_json_binary(&ExecuteMsg::Callback(self.clone()))?, funds: vec![], })) } diff --git a/packages/astroport_periphery/src/helpers.rs b/packages/astroport_periphery/src/helpers.rs index 15c53fd6..c811a8cf 100644 --- a/packages/astroport_periphery/src/helpers.rs +++ b/packages/astroport_periphery/src/helpers.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_binary, Addr, Binary, CosmosMsg, QuerierWrapper, QueryRequest, StdResult, Uint128, WasmMsg, + to_json_binary, Addr, Binary, CosmosMsg, QuerierWrapper, QueryRequest, StdResult, Uint128, WasmMsg, WasmQuery, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; @@ -15,7 +15,7 @@ pub fn build_transfer_cw20_token_msg( ) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: token_contract_address, - msg: to_binary(&Cw20ExecuteMsg::Transfer { + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: recipient.into(), amount, })?, @@ -36,7 +36,7 @@ pub fn build_send_cw20_token_msg( ) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: token_contract_address, - msg: to_binary(&Cw20ExecuteMsg::Send { + msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: recipient_contract_addr, amount, msg: msg_, @@ -59,7 +59,7 @@ pub fn cntrn_get_balance( ) -> StdResult { let query: BalanceResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: token_address.into(), - msg: to_binary(&Cw20QueryMsg::Balance { + msg: to_json_binary(&Cw20QueryMsg::Balance { address: account_addr.into(), })?, }))?; @@ -82,7 +82,7 @@ pub fn build_approve_cntrn_msg( ) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: token_contract_address, - msg: to_binary(&Cw20ExecuteMsg::IncreaseAllowance { + msg: to_json_binary(&Cw20ExecuteMsg::IncreaseAllowance { spender: spender_address, amount: allowance_amount, expires: Some(cw20::Expiration::AtHeight(expiration_block)), diff --git a/packages/astroport_periphery/src/lockdrop.rs b/packages/astroport_periphery/src/lockdrop.rs index 7476789c..91ee879a 100644 --- a/packages/astroport_periphery/src/lockdrop.rs +++ b/packages/astroport_periphery/src/lockdrop.rs @@ -2,7 +2,7 @@ use astroport::asset::{Asset, AssetInfo}; use astroport::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, + to_json_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, WasmMsg, }; use cw20::Cw20ReceiveMsg; @@ -271,7 +271,7 @@ impl CallbackMsg { pub fn to_cosmos_msg(self, env: &Env) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), - msg: to_binary(&ExecuteMsg::Callback(self))?, + msg: to_json_binary(&ExecuteMsg::Callback(self))?, funds: vec![], })) } diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 367f97a9..0827d693 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -6,7 +6,7 @@ use astroport::asset::{Asset, AssetInfo}; use astroport::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, + to_json_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, WasmMsg, }; use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; @@ -176,7 +176,6 @@ pub enum ExecuteMsg { pub enum CallbackMsg { UpdatePoolOnDualRewardsClaim { pool_type: PoolType, - prev_ntrn_balance: Uint128, prev_proxy_reward_balances: Vec, }, WithdrawUserLockupRewardsCallback { @@ -215,7 +214,7 @@ impl CallbackMsg { pub fn to_cosmos_msg(self, env: &Env) -> StdResult { Ok(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: env.contract.address.to_string(), - msg: to_binary(&ExecuteMsg::Callback(self))?, + msg: to_json_binary(&ExecuteMsg::Callback(self))?, funds: vec![], })) } @@ -269,8 +268,8 @@ pub struct Config { pub credits_contract: Addr, /// Bootstrap Auction contract address pub auction_contract: Addr, - /// Generator (Staking for dual rewards) contract address - pub generator: Addr, + /// Incentives contract address + pub incentives: Addr, /// Total NTRN lockdrop incentives to be distributed among the users pub lockdrop_incentives: Uint128, /// Describes rewards coefficients for each lockup duration diff --git a/packages/vesting-base/src/ext_historical.rs b/packages/vesting-base/src/ext_historical.rs index d494adf6..fffb3008 100644 --- a/packages/vesting-base/src/ext_historical.rs +++ b/packages/vesting-base/src/ext_historical.rs @@ -3,7 +3,7 @@ use crate::msg::{ExecuteMsgHistorical, QueryMsgHistorical}; use crate::state::{vesting_info, vesting_state, CONFIG}; use crate::types::VestingInfo; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, }; /// Contains the historical extension check and routing of the message. @@ -35,10 +35,10 @@ pub(crate) fn handle_query_historical_msg( match msg { QueryMsgHistorical::UnclaimedAmountAtHeight { address, height } => { - to_binary(&query_unclaimed_amount_at_height(deps, address, height)?) + to_json_binary(&query_unclaimed_amount_at_height(deps, address, height)?) } QueryMsgHistorical::UnclaimedTotalAmountAtHeight { height } => { - to_binary(&query_total_unclaimed_amount_at_height(deps, height)?) + to_json_binary(&query_total_unclaimed_amount_at_height(deps, height)?) } } } diff --git a/packages/vesting-base/src/ext_with_managers.rs b/packages/vesting-base/src/ext_with_managers.rs index 56573188..bbbdaae9 100644 --- a/packages/vesting-base/src/ext_with_managers.rs +++ b/packages/vesting-base/src/ext_with_managers.rs @@ -2,7 +2,7 @@ use crate::error::{ext_unsupported_err, ContractError}; use crate::msg::{ExecuteMsgWithManagers, QueryMsgWithManagers}; use crate::state::{CONFIG, VESTING_MANAGERS}; use cosmwasm_std::{ - attr, to_binary, Addr, Attribute, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, + attr, to_json_binary, Addr, Attribute, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, }; @@ -40,7 +40,7 @@ pub(crate) fn handle_query_managers_msg( } match msg { - QueryMsgWithManagers::VestingManagers {} => to_binary(&query_vesting_managers(deps)?), + QueryMsgWithManagers::VestingManagers {} => to_json_binary(&query_vesting_managers(deps)?), } } diff --git a/packages/vesting-base/src/handlers.rs b/packages/vesting-base/src/handlers.rs index 7797db28..a51d4089 100644 --- a/packages/vesting-base/src/handlers.rs +++ b/packages/vesting-base/src/handlers.rs @@ -12,7 +12,7 @@ use crate::types::{ use astroport::asset::{addr_opt_validate, token_asset_info, AssetInfo, AssetInfoExt}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use cosmwasm_std::{ - attr, from_binary, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, + attr, from_json, to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Storage, SubMsg, Uint128, }; use cw20::Cw20ReceiveMsg; @@ -108,7 +108,7 @@ fn receive_cw20( return Err(ContractError::Unauthorized {}); } - match from_binary(&cw20_msg.msg)? { + match from_json(&cw20_msg.msg)? { Cw20HookMsg::RegisterVestingAccounts { vesting_accounts } => { register_vesting_accounts(deps, vesting_accounts, cw20_msg.amount, env.block.height) } @@ -285,25 +285,25 @@ pub(crate) fn get_vesting_token(config: &Config) -> Result StdResult { match msg { - QueryMsg::Config {} => Ok(to_binary(&query_config(deps)?)?), + QueryMsg::Config {} => Ok(to_json_binary(&query_config(deps)?)?), QueryMsg::VestingAccount { address } => { - Ok(to_binary(&query_vesting_account(deps, address)?)?) + Ok(to_json_binary(&query_vesting_account(deps, address)?)?) } QueryMsg::VestingAccounts { start_after, limit, order_by, - } => Ok(to_binary(&query_vesting_accounts( + } => Ok(to_json_binary(&query_vesting_accounts( deps, start_after, limit, order_by, )?)?), - QueryMsg::AvailableAmount { address } => Ok(to_binary(&query_vesting_available_amount( + QueryMsg::AvailableAmount { address } => Ok(to_json_binary(&query_vesting_available_amount( deps, env, address, )?)?), - QueryMsg::VestingState {} => Ok(to_binary(&query_vesting_state(deps)?)?), - QueryMsg::Timestamp {} => Ok(to_binary(&query_timestamp(env)?)?), + QueryMsg::VestingState {} => Ok(to_json_binary(&query_vesting_state(deps)?)?), + QueryMsg::Timestamp {} => Ok(to_json_binary(&query_timestamp(env)?)?), QueryMsg::ManagedExtension { msg } => handle_query_managed_msg(deps, env, msg), QueryMsg::WithManagersExtension { msg } => handle_query_managers_msg(deps, env, msg), QueryMsg::HistoricalExtension { msg } => handle_query_historical_msg(deps, env, msg), diff --git a/packages/vesting-base/src/testing.rs b/packages/vesting-base/src/testing.rs index 3d11af41..094ddebe 100644 --- a/packages/vesting-base/src/testing.rs +++ b/packages/vesting-base/src/testing.rs @@ -7,7 +7,7 @@ use crate::msg::{ use crate::types::{Config, Extensions}; use astroport::asset::token_asset_info; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{from_binary, Addr}; +use cosmwasm_std::{from_json, Addr}; #[test] fn set_vesting_token() { @@ -21,7 +21,7 @@ fn set_vesting_token() { // check initialisation assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -63,7 +63,7 @@ fn set_vesting_token() { .unwrap(); assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -92,7 +92,7 @@ fn set_vesting_token() { ); assert_eq!( - from_binary::(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(), + from_json::(&query(deps.as_ref(), env, QueryMsg::Config {}).unwrap()).unwrap(), Config { owner: Addr::unchecked("owner"), token_info_manager: Addr::unchecked(token_info_manager), @@ -119,7 +119,7 @@ fn proper_building_standard() { // check initialisation assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -192,7 +192,7 @@ fn proper_building_managers() { // check initialisation assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -208,7 +208,7 @@ fn proper_building_managers() { // make sure with_managers extension is enabled assert_eq!( - from_binary::>( + from_json::>( &query( deps.as_ref(), env.clone(), @@ -267,7 +267,7 @@ fn proper_building_historical() { // check initialisation assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -335,7 +335,7 @@ fn proper_building_managed() { // check initialisation and set vesting token assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -417,7 +417,7 @@ fn proper_building_all_extensions() { // check initialisation and set vesting token assert_eq!( - from_binary::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) + from_json::(&query(deps.as_ref(), env.clone(), QueryMsg::Config {}).unwrap()) .unwrap(), Config { owner: Addr::unchecked("owner"), @@ -443,7 +443,7 @@ fn proper_building_all_extensions() { // make sure with_managers extension is enabled assert_eq!( - from_binary::>( + from_json::>( &query( deps.as_ref(), env.clone(), From 123b378b6499170edd3d2fa74b52c913d6cabb57 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 8 Feb 2024 16:23:34 +0200 Subject: [PATCH 07/28] fmt --- contracts/astroport/oracle/src/contract.rs | 4 ++-- contracts/astroport/oracle/src/mock_querier.rs | 4 ++-- contracts/astroport/oracle/tests/integration.rs | 4 ++-- contracts/credits/src/contract.rs | 4 +++- contracts/cw20-merkle-airdrop/src/contract.rs | 4 ++-- contracts/lockdrop-pcl/src/contract.rs | 16 +++++----------- contracts/lockdrop/src/contract.rs | 4 +++- packages/astroport/src/asset.rs | 4 ++-- packages/astroport/src/generator.rs | 4 +++- packages/astroport/src/mock_querier.rs | 8 +++++--- packages/astroport/src/pair.rs | 2 +- packages/astroport_periphery/src/helpers.rs | 4 ++-- packages/astroport_periphery/src/lockdrop.rs | 4 ++-- packages/astroport_periphery/src/lockdrop_pcl.rs | 4 ++-- packages/vesting-base/src/ext_with_managers.rs | 4 ++-- packages/vesting-base/src/handlers.rs | 6 +++--- 16 files changed, 41 insertions(+), 39 deletions(-) diff --git a/contracts/astroport/oracle/src/contract.rs b/contracts/astroport/oracle/src/contract.rs index 72eb2c97..0368e1cb 100644 --- a/contracts/astroport/oracle/src/contract.rs +++ b/contracts/astroport/oracle/src/contract.rs @@ -7,8 +7,8 @@ use astroport::oracle::{Config, ExecuteMsg, InstantiateMsg, QueryMsg}; use astroport::pair::TWAP_PRECISION; use astroport::querier::query_pair_info; use cosmwasm_std::{ - entry_point, to_json_binary, Binary, Decimal256, Deps, DepsMut, Env, MessageInfo, Response, Uint128, - Uint256, Uint64, + entry_point, to_json_binary, Binary, Decimal256, Deps, DepsMut, Env, MessageInfo, Response, + Uint128, Uint256, Uint64, }; use cw2::set_contract_version; use std::ops::Div; diff --git a/contracts/astroport/oracle/src/mock_querier.rs b/contracts/astroport/oracle/src/mock_querier.rs index 90a6a2b6..2ddbe4d4 100644 --- a/contracts/astroport/oracle/src/mock_querier.rs +++ b/contracts/astroport/oracle/src/mock_querier.rs @@ -5,8 +5,8 @@ use astroport::pair::QueryMsg::{self, CumulativePrices}; use astroport::pair::{CumulativePricesResponse, SimulationResponse}; use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_json, to_json_binary, Addr, Coin, Empty, OwnedDeps, Querier, QuerierResult, - QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, + from_json, to_json_binary, Addr, Coin, Empty, OwnedDeps, Querier, QuerierResult, QueryRequest, + SystemError, SystemResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; use std::collections::HashMap; diff --git a/contracts/astroport/oracle/tests/integration.rs b/contracts/astroport/oracle/tests/integration.rs index ba5c544b..5e91d8ac 100644 --- a/contracts/astroport/oracle/tests/integration.rs +++ b/contracts/astroport/oracle/tests/integration.rs @@ -1,7 +1,7 @@ use anyhow::Result; use cosmwasm_std::{ - attr, to_json_binary, Addr, BlockInfo, Coin, Decimal, Decimal256, QueryRequest, StdResult, Uint128, - Uint64, WasmQuery, + attr, to_json_binary, Addr, BlockInfo, Coin, Decimal, Decimal256, QueryRequest, StdResult, + Uint128, Uint64, WasmQuery, }; use cw20::{BalanceResponse, Cw20QueryMsg, MinterResponse}; use cw_multi_test::{App, AppResponse, ContractWrapper, Executor}; diff --git a/contracts/credits/src/contract.rs b/contracts/credits/src/contract.rs index bd852634..7d167ebd 100644 --- a/contracts/credits/src/contract.rs +++ b/contracts/credits/src/contract.rs @@ -394,7 +394,9 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::WithdrawableAmount { address } => { to_json_binary(&query_withdrawable_amount(deps, env, address)?) } - QueryMsg::VestedAmount { address } => to_json_binary(&query_vested_amount(deps, env, address)?), + QueryMsg::VestedAmount { address } => { + to_json_binary(&query_vested_amount(deps, env, address)?) + } QueryMsg::Allocation { address } => to_json_binary(&query_allocation(deps, address)?), QueryMsg::Balance { address } => { to_json_binary(&::cw20_base::contract::query_balance(deps, address)?) diff --git a/contracts/cw20-merkle-airdrop/src/contract.rs b/contracts/cw20-merkle-airdrop/src/contract.rs index 4cd5f3ed..d30baa1d 100644 --- a/contracts/cw20-merkle-airdrop/src/contract.rs +++ b/contracts/cw20-merkle-airdrop/src/contract.rs @@ -2,8 +2,8 @@ use crate::enumerable::query_all_address_map; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, coin, to_json_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, - StdResult, Uint128, WasmMsg, + attr, coin, to_json_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, + Response, StdResult, Uint128, WasmMsg, }; use cw2::set_contract_version; use cw20::{BalanceResponse, Cw20Contract, Cw20ExecuteMsg, Cw20QueryMsg}; diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index ae9ded9c..53147d19 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -6,9 +6,7 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; -use astroport::incentives::{ - ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg, -}; +use astroport::incentives::{ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg}; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; @@ -189,12 +187,7 @@ fn _handle_callback( CallbackMsg::UpdatePoolOnDualRewardsClaim { pool_type, prev_proxy_reward_balances, - } => update_pool_on_dual_rewards_claim( - deps, - env, - pool_type, - prev_proxy_reward_balances, - ), + } => update_pool_on_dual_rewards_claim(deps, env, pool_type, prev_proxy_reward_balances), CallbackMsg::WithdrawUserLockupRewardsCallback { pool_type, user_address, @@ -487,7 +480,9 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( }, )?; - if pending_rewards_response.iter().any(|asset| !asset.amount.is_zero()) + if pending_rewards_response + .iter() + .any(|asset| !asset.amount.is_zero()) { let prev_pending_rewards_balances: Vec = pending_rewards_response .iter() @@ -1153,7 +1148,6 @@ pub fn query_lockup_info( claimable_generator_rewards_debt.update(&reward.info, debt)?; } - } } // Calculate currently expected ASTRO Rewards if not finalized diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index a25d2f51..a275602f 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -1903,7 +1903,9 @@ pub fn callback_withdraw_user_lockup( msg: to_json_binary(&Cw20ExecuteMsg::Send { contract: astroport_pool, amount: astroport_lp_amount, - msg: to_json_binary(&astroport::pair::Cw20HookMsg::WithdrawLiquidity { assets: vec![] })?, + msg: to_json_binary(&astroport::pair::Cw20HookMsg::WithdrawLiquidity { + assets: vec![], + })?, })?, })); diff --git a/packages/astroport/src/asset.rs b/packages/astroport/src/asset.rs index c0bba3c5..cff5ca2a 100644 --- a/packages/astroport/src/asset.rs +++ b/packages/astroport/src/asset.rs @@ -7,8 +7,8 @@ use crate::querier::{ query_balance, query_token_balance, query_token_precision, query_token_symbol, }; use cosmwasm_std::{ - to_json_binary, Addr, Api, BankMsg, Coin, ConversionOverflowError, CosmosMsg, Decimal256, Fraction, - MessageInfo, QuerierWrapper, StdError, StdResult, Uint128, Uint256, WasmMsg, + to_json_binary, Addr, Api, BankMsg, Coin, ConversionOverflowError, CosmosMsg, Decimal256, + Fraction, MessageInfo, QuerierWrapper, StdError, StdResult, Uint128, Uint256, WasmMsg, }; use cw20::{Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use itertools::Itertools; diff --git a/packages/astroport/src/generator.rs b/packages/astroport/src/generator.rs index 4872012d..bf52fc92 100644 --- a/packages/astroport/src/generator.rs +++ b/packages/astroport/src/generator.rs @@ -2,7 +2,9 @@ use crate::asset::{Asset, AssetInfo}; use crate::factory::PairType; use crate::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_json_binary, Addr, Decimal, Env, StdResult, SubMsg, Uint128, Uint64, WasmMsg}; +use cosmwasm_std::{ + to_json_binary, Addr, Decimal, Env, StdResult, SubMsg, Uint128, Uint64, WasmMsg, +}; use cw20::Cw20ReceiveMsg; /// This structure describes the parameters used for creating a contract. diff --git a/packages/astroport/src/mock_querier.rs b/packages/astroport/src/mock_querier.rs index 7a815bf6..d8ad0342 100644 --- a/packages/astroport/src/mock_querier.rs +++ b/packages/astroport/src/mock_querier.rs @@ -1,7 +1,7 @@ use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_json, to_json_binary, Coin, Empty, OwnedDeps, Querier, QuerierResult, - QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, + from_json, to_json_binary, Coin, Empty, OwnedDeps, Querier, QuerierResult, QueryRequest, + SystemError, SystemResult, Uint128, WasmQuery, }; use std::collections::HashMap; @@ -161,7 +161,9 @@ impl CW20QueryHandler { } }; - SystemResult::Ok(to_json_binary(&BalanceResponse { balance: *balance }).into()) + SystemResult::Ok( + to_json_binary(&BalanceResponse { balance: *balance }).into(), + ) } _ => panic!("DO NOT ENTER HERE"), } diff --git a/packages/astroport/src/pair.rs b/packages/astroport/src/pair.rs index ff34845d..cfcbc706 100644 --- a/packages/astroport/src/pair.rs +++ b/packages/astroport/src/pair.rs @@ -2,7 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use crate::asset::{Asset, AssetInfo, PairInfo}; -use cosmwasm_std::{Addr, Binary, Decimal, from_json, QuerierWrapper, StdResult, Uint128}; +use cosmwasm_std::{from_json, Addr, Binary, Decimal, QuerierWrapper, StdResult, Uint128}; use cw20::Cw20ReceiveMsg; /// The default swap slippage diff --git a/packages/astroport_periphery/src/helpers.rs b/packages/astroport_periphery/src/helpers.rs index c811a8cf..36ef76a7 100644 --- a/packages/astroport_periphery/src/helpers.rs +++ b/packages/astroport_periphery/src/helpers.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ - to_json_binary, Addr, Binary, CosmosMsg, QuerierWrapper, QueryRequest, StdResult, Uint128, WasmMsg, - WasmQuery, + to_json_binary, Addr, Binary, CosmosMsg, QuerierWrapper, QueryRequest, StdResult, Uint128, + WasmMsg, WasmQuery, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; diff --git a/packages/astroport_periphery/src/lockdrop.rs b/packages/astroport_periphery/src/lockdrop.rs index 91ee879a..47f6fa8a 100644 --- a/packages/astroport_periphery/src/lockdrop.rs +++ b/packages/astroport_periphery/src/lockdrop.rs @@ -2,8 +2,8 @@ use astroport::asset::{Asset, AssetInfo}; use astroport::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - to_json_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, - WasmMsg, + to_json_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, + Uint256, WasmMsg, }; use cw20::Cw20ReceiveMsg; use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 0827d693..878db4a0 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -6,8 +6,8 @@ use astroport::asset::{Asset, AssetInfo}; use astroport::restricted_vector::RestrictedVector; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - to_json_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, Uint256, - WasmMsg, + to_json_binary, Addr, CosmosMsg, Decimal, Decimal256, Env, StdError, StdResult, Uint128, + Uint256, WasmMsg, }; use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; use schemars::JsonSchema; diff --git a/packages/vesting-base/src/ext_with_managers.rs b/packages/vesting-base/src/ext_with_managers.rs index bbbdaae9..6d0f4feb 100644 --- a/packages/vesting-base/src/ext_with_managers.rs +++ b/packages/vesting-base/src/ext_with_managers.rs @@ -2,8 +2,8 @@ use crate::error::{ext_unsupported_err, ContractError}; use crate::msg::{ExecuteMsgWithManagers, QueryMsgWithManagers}; use crate::state::{CONFIG, VESTING_MANAGERS}; use cosmwasm_std::{ - attr, to_json_binary, Addr, Attribute, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, - StdError, StdResult, + attr, to_json_binary, Addr, Attribute, Binary, Deps, DepsMut, Env, MessageInfo, Order, + Response, StdError, StdResult, }; /// Contains the with_managers extension check and routing of the message. diff --git a/packages/vesting-base/src/handlers.rs b/packages/vesting-base/src/handlers.rs index a51d4089..b85929ad 100644 --- a/packages/vesting-base/src/handlers.rs +++ b/packages/vesting-base/src/handlers.rs @@ -299,9 +299,9 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { limit, order_by, )?)?), - QueryMsg::AvailableAmount { address } => Ok(to_json_binary(&query_vesting_available_amount( - deps, env, address, - )?)?), + QueryMsg::AvailableAmount { address } => Ok(to_json_binary( + &query_vesting_available_amount(deps, env, address)?, + )?), QueryMsg::VestingState {} => Ok(to_json_binary(&query_vesting_state(deps)?)?), QueryMsg::Timestamp {} => Ok(to_json_binary(&query_timestamp(env)?)?), QueryMsg::ManagedExtension { msg } => handle_query_managed_msg(deps, env, msg), From 082e44a035bdc4eb94abae391dffbf9c374069b4 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Mon, 12 Feb 2024 18:36:51 +0300 Subject: [PATCH 08/28] adjust lockdrop pcl to incentives contract rewards --- contracts/lockdrop-pcl/src/contract.rs | 151 +++++++++++------- contracts/lockdrop-pcl/src/state.rs | 83 +--------- .../astroport_periphery/src/lockdrop_pcl.rs | 58 ++----- 3 files changed, 109 insertions(+), 183 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 53147d19..3544607e 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -1,5 +1,4 @@ use std::cmp::min; -use std::convert::TryInto; use std::ops::Sub; use std::str::FromStr; @@ -26,13 +25,13 @@ use astroport_periphery::lockdrop::{ }; use astroport_periphery::lockdrop_pcl::{ CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, - LockupInfoV2, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + LockupInfo, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfo, UserInfoResponse, UserInfoWithListResponse, }; use crate::state::{ - CompatibleLoader, ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, STATE, - TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, + ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, STATE, TOTAL_USER_LOCKUP_AMOUNT, + USER_INFO, }; const AIRDROP_REWARDS_MULTIPLIER: &str = "1.0"; @@ -86,8 +85,7 @@ pub fn instantiate( amount_in_lockups: Default::default(), incentives_share: msg.atom_incentives_share, weighted_amount: msg.atom_weighted_amount, - generator_ntrn_per_share: Default::default(), - generator_proxy_per_share: RestrictedVector::default(), + generator_rewards_per_share: RestrictedVector::default(), is_staked: true, }; ASSET_POOLS.save(deps.storage, PoolType::ATOM, &pool_info, env.block.height)?; @@ -98,8 +96,7 @@ pub fn instantiate( amount_in_lockups: Default::default(), incentives_share: msg.usdc_incentives_share, weighted_amount: msg.usdc_weighted_amount, - generator_ntrn_per_share: Default::default(), - generator_proxy_per_share: RestrictedVector::default(), + generator_rewards_per_share: RestrictedVector::default(), is_staked: true, }; ASSET_POOLS.save(deps.storage, PoolType::USDC, &pool_info, env.block.height)?; @@ -186,8 +183,8 @@ fn _handle_callback( match msg { CallbackMsg::UpdatePoolOnDualRewardsClaim { pool_type, - prev_proxy_reward_balances, - } => update_pool_on_dual_rewards_claim(deps, env, pool_type, prev_proxy_reward_balances), + prev_reward_balances, + } => update_pool_on_dual_rewards_claim(deps, env, pool_type, prev_reward_balances), CallbackMsg::WithdrawUserLockupRewardsCallback { pool_type, user_address, @@ -448,7 +445,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( // Check is there lockup or not ? let lockup_key = (pool_type, &user_address, duration); - let lockup_info = LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.incentives)?; + let lockup_info = LOCKUP_INFO.load(deps.storage, lockup_key)?; // CHECK :: Can the Lockup position be unlocked or not ? if withdraw_lp_stake && env.block.time.seconds() < lockup_info.unlock_timestamp { @@ -510,7 +507,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( cosmos_msgs.push( CallbackMsg::UpdatePoolOnDualRewardsClaim { pool_type, - prev_proxy_reward_balances: prev_pending_rewards_balances, + prev_reward_balances: prev_pending_rewards_balances, } .to_cosmos_msg(&env)?, ); @@ -614,13 +611,18 @@ pub fn update_pool_on_dual_rewards_claim( }, )?; - // Increment claimed Proxy rewards per LP share + // Increment claimed rewards per LP share for prev_balance in prev_pending_rewards_balances { let current_balance = prev_balance .info .query_pool(&deps.querier, env.contract.address.clone())?; let received_amount = current_balance.checked_sub(prev_balance.amount)?; - pool_info.generator_proxy_per_share.update( + deps.api.debug(&format!( + "WASMDEBUG: set gen rewards per share for {:?}: {}", + prev_balance.info, + Decimal::from_ratio(received_amount, lp_balance) + )); + pool_info.generator_rewards_per_share.update( &prev_balance.info, Decimal::from_ratio(received_amount, lp_balance), )?; @@ -632,10 +634,6 @@ pub fn update_pool_on_dual_rewards_claim( Ok(Response::new().add_attributes(vec![ attr("action", "update_generator_dual_rewards"), attr("pool_type", format!("{:?}", pool_type)), - attr( - "generator_ntrn_per_share", - pool_info.generator_ntrn_per_share.to_string(), - ), ])) } @@ -663,8 +661,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( let config = CONFIG.load(deps.storage)?; let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let lockup_key = (pool_type, &user_address, duration); - let mut lockup_info = - LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.incentives)?; + let mut lockup_info = LOCKUP_INFO.load(deps.storage, lockup_key)?; let mut user_info = USER_INFO .may_load(deps.storage, &user_address)? @@ -710,33 +707,71 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // If Astro LP tokens are staked with Astro generator if pool_info.is_staked { - // Calculate claimable staking rewards for this lockup - let total_lockup_astro_rewards = pool_info - .generator_ntrn_per_share - .checked_mul(astroport_lp_amount.to_decimal())? - .to_uint_floor(); - let pending_astro_rewards = - total_lockup_astro_rewards.checked_sub(lockup_info.generator_ntrn_debt)?; - lockup_info.generator_ntrn_debt = total_lockup_astro_rewards; - - let mut pending_rewards: Vec = vec![]; // If this LP token is getting incentives // Calculate claimable staking rewards for this lockup - lockup_info.generator_proxy_debt = lockup_info - .generator_proxy_debt + let pending_rewards: Vec = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::PendingRewards { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; + for reward in pending_rewards { + let generator_rewards_per_share = pool_info.generator_rewards_per_share.update( + &reward.info, + Decimal::from_ratio(reward.amount, astroport_lp_amount), + )?; + + // Calculate Lockup Astro LP shares + let lockup_astroport_lp_units: Uint128 = lockup_info + .lp_units_locked + .full_mul(astroport_lp_amount) + .checked_div(Uint256::from(pool_info.amount_in_lockups))? + .try_into()?; + + let debt = generator_rewards_per_share + .checked_mul_uint128(lockup_astroport_lp_units)? + .checked_sub( + lockup_info + .generator_debt + .inner_ref() + .iter() + .find_map(|a| if reward.info == a.0 { Some(a.1) } else { None }) + .unwrap_or_default(), + )?; + + lockup_info.generator_debt.update(&reward.info, debt)?; + deps.api.debug(&format!( + "WASMDEBUG: found pending rewards debt: {} {}", + reward.info.clone(), + debt, + )); + } + + let mut pending_reward_assets: Vec = vec![]; + lockup_info.generator_debt = lockup_info + .generator_debt .inner_ref() .iter() .map(|(asset, debt)| { - let generator_proxy_per_share = pool_info - .generator_proxy_per_share + let generator_rewards_per_share = pool_info + .generator_rewards_per_share .load(asset) .unwrap_or_default(); let total_lockup_reward = - generator_proxy_per_share.checked_mul_uint128(astroport_lp_amount)?; + generator_rewards_per_share.checked_mul_uint128(astroport_lp_amount)?; let pending_reward: Uint128 = total_lockup_reward.checked_sub(*debt)?; + deps.api.debug(&format!( + "WASMDEBUG: rewards for {} calculated: share {}, total {}, pending {}", + user_address.to_string(), + generator_rewards_per_share, + total_lockup_reward, + pending_reward + )); + if !pending_reward.is_zero() { - pending_rewards.push(Asset { + pending_reward_assets.push(Asset { info: asset.clone(), amount: pending_reward, }); @@ -748,16 +783,12 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // If this is a void transaction (no state change), then return error. // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending rewards, not unlocking LP tokens in this tx - if !withdraw_lp_stake - && user_info.ntrn_transferred - && pending_astro_rewards == Uint128::zero() - && pending_rewards.is_empty() - { + if !withdraw_lp_stake && user_info.ntrn_transferred && pending_reward_assets.is_empty() { return Err(StdError::generic_err("No rewards available to claim!")); } - // If claimable proxy staking rewards > 0, claim them - for pending_reward in pending_rewards { + // If claimable staking rewards > 0, claim them + for pending_reward in pending_reward_assets { cosmos_msgs.push(pending_reward.into_msg(user_address.clone())?); } @@ -873,8 +904,8 @@ pub fn callback_finish_lockup_migration( .sub(staked_lp_token_amount); let user_info: UserInfo = user_info.into(); - let lockup_info: LockupInfoV2 = - LockupInfoV2::from_xyk_lockup_info(lockup_info, staked_lp_token_amount_diff); + let lockup_info: LockupInfo = + LockupInfo::from_xyk_lockup_info(lockup_info, staked_lp_token_amount_diff); let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let config = CONFIG.load(deps.storage)?; @@ -947,8 +978,7 @@ pub fn query_user_info(deps: Deps, env: Env, user: String) -> StdResult = Default::default(); for pool_type in ASSET_POOLS .keys(deps.storage, None, None, Order::Ascending) .collect::, StdError>>()? @@ -960,8 +990,10 @@ pub fn query_user_info(deps: Deps, env: Env, user: String) -> StdResult StdResult; let astroport_lp_token_opt: Addr; @@ -1128,18 +1160,18 @@ pub fn query_lockup_info( }, )?; - // Calculate claimable Proxy staking rewards for this lockup + // Calculate claimable staking rewards for this lockup for reward in pending_rewards { - let generator_proxy_per_share = pool_info.generator_proxy_per_share.update( + let generator_rewards_per_share = pool_info.generator_rewards_per_share.update( &reward.info, Decimal::from_ratio(reward.amount, pool_astroport_lp_units), )?; - let debt = generator_proxy_per_share + let debt = generator_rewards_per_share .checked_mul_uint128(lockup_astroport_lp_units)? .checked_sub( lockup_info - .generator_proxy_debt + .generator_debt .inner_ref() .iter() .find_map(|a| if reward.info == a.0 { Some(a.1) } else { None }) @@ -1168,10 +1200,8 @@ pub fn query_lockup_info( lp_units_locked: lockup_info.lp_units_locked, withdrawal_flag: lockup_info.withdrawal_flag, ntrn_rewards: lockup_info.ntrn_rewards, - generator_ntrn_debt: lockup_info.generator_ntrn_debt, - claimable_generator_astro_debt: Uint128::zero(), - generator_proxy_debt: lockup_info.generator_proxy_debt, - claimable_generator_proxy_debt: claimable_generator_rewards_debt, + generator_debt: lockup_info.generator_debt, + claimable_generator_debt: claimable_generator_rewards_debt, unlock_timestamp: lockup_info.unlock_timestamp, astroport_lp_units: lockup_astroport_lp_units_opt, astroport_lp_token: astroport_lp_token_opt, @@ -1263,8 +1293,7 @@ fn update_user_lockup_positions_and_calc_rewards( for (pool_type, duration) in keys { let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let lockup_key = (pool_type, user_address, duration); - let mut lockup_info = - LOCKUP_INFO.compatible_load(deps.as_ref(), lockup_key, &config.incentives)?; + let mut lockup_info = LOCKUP_INFO.load(deps.storage, lockup_key)?; if lockup_info.ntrn_rewards == Uint128::zero() { // Weighted lockup balance (using terraswap LP units to calculate as pool's total weighted balance is calculated on terraswap LP deposits summed over each deposit tx) diff --git a/contracts/lockdrop-pcl/src/state.rs b/contracts/lockdrop-pcl/src/state.rs index e54e857c..2abdc0c2 100644 --- a/contracts/lockdrop-pcl/src/state.rs +++ b/contracts/lockdrop-pcl/src/state.rs @@ -1,16 +1,9 @@ use astroport::common::OwnershipProposal; -use astroport::generator::PoolInfoResponse; -use astroport::generator::QueryMsg as GenQueryMsg; -use astroport::restricted_vector::RestrictedVector; -use astroport_periphery::lockdrop_pcl::{ - Config, LockupInfoV1, LockupInfoV2, PoolInfo, PoolType, State, UserInfo, -}; +use astroport_periphery::lockdrop_pcl::{Config, LockupInfo, PoolInfo, PoolType, State, UserInfo}; use astroport_periphery::U64Key; -use cosmwasm_std::{Addr, Deps, StdError, StdResult, Uint128}; +use cosmwasm_std::{Addr, Uint128}; use cw_storage_plus::{Item, Map, SnapshotMap, Strategy}; -use crate::raw_queries::raw_proxy_asset; - pub const CONFIG: Item = Item::new("config"); pub const STATE: Item = Item::new("state"); @@ -24,7 +17,7 @@ pub const ASSET_POOLS: SnapshotMap = SnapshotMap::new( /// Key is an user address pub const USER_INFO: Map<&Addr, UserInfo> = Map::new("users"); /// Key consists of an Terraswap LP token address, an user address, and a duration -pub const LOCKUP_INFO: Map<(PoolType, &Addr, U64Key), LockupInfoV2> = Map::new("lockup_position"); +pub const LOCKUP_INFO: Map<(PoolType, &Addr, U64Key), LockupInfo> = Map::new("lockup_position"); pub const TOTAL_USER_LOCKUP_AMOUNT: SnapshotMap<(PoolType, &Addr), Uint128> = SnapshotMap::new( "total_user_lockup_info", @@ -33,74 +26,4 @@ pub const TOTAL_USER_LOCKUP_AMOUNT: SnapshotMap<(PoolType, &Addr), Uint128> = Sn Strategy::EveryBlock, ); -/// Old LOCKUP_INFO storage interface for backward compatibility -pub const OLD_LOCKUP_INFO: Map<(PoolType, &Addr, U64Key), LockupInfoV1> = - Map::new("lockup_position"); - -pub trait CompatibleLoader { - fn compatible_load(&self, deps: Deps, key: K, generator: &Addr) -> StdResult; - - fn compatible_may_load(&self, deps: Deps, key: K, generator: &Addr) -> StdResult>; -} - -impl CompatibleLoader<(PoolType, &Addr, U64Key), LockupInfoV2> - for Map<'_, (PoolType, &Addr, U64Key), LockupInfoV2> -{ - fn compatible_load( - &self, - deps: Deps, - key: (PoolType, &Addr, U64Key), - generator: &Addr, - ) -> StdResult { - self.load(deps.storage, key).or_else(|_| { - let old_lockup_info = OLD_LOCKUP_INFO.load(deps.storage, key)?; - let mut generator_proxy_debt = RestrictedVector::default(); - - if !old_lockup_info.generator_proxy_debt.is_zero() { - let asset = ASSET_POOLS.load(deps.storage, key.0)?; - let astro_lp = asset.lp_token; - let pool_info: PoolInfoResponse = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::PoolInfo { - lp_token: astro_lp.to_string(), - }, - )?; - let (proxy, _) = pool_info - .accumulated_proxy_rewards_per_share - .first() - .ok_or_else(|| { - StdError::generic_err(format!("Proxy rewards not found: {}", astro_lp)) - })?; - let reward_asset = raw_proxy_asset(deps.querier, generator, proxy.as_bytes())?; - - generator_proxy_debt.update(&reward_asset, old_lockup_info.generator_proxy_debt)?; - } - - let lockup_info = LockupInfoV2 { - lp_units_locked: old_lockup_info.lp_units_locked, - astroport_lp_transferred: old_lockup_info.astroport_lp_transferred, - withdrawal_flag: old_lockup_info.withdrawal_flag, - ntrn_rewards: old_lockup_info.ntrn_rewards, - generator_ntrn_debt: old_lockup_info.generator_ntrn_debt, - generator_proxy_debt, - unlock_timestamp: old_lockup_info.unlock_timestamp, - }; - - Ok(lockup_info) - }) - } - - fn compatible_may_load( - &self, - deps: Deps, - key: (PoolType, &Addr, U64Key), - generator: &Addr, - ) -> StdResult> { - if !OLD_LOCKUP_INFO.has(deps.storage, key) { - return Ok(None); - } - Some(self.compatible_load(deps, key, generator)).transpose() - } -} - pub const OWNERSHIP_PROPOSAL: Item = Item::new("ownership_proposal"); diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 878db4a0..42f2a13c 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -176,7 +176,7 @@ pub enum ExecuteMsg { pub enum CallbackMsg { UpdatePoolOnDualRewardsClaim { pool_type: PoolType, - prev_proxy_reward_balances: Vec, + prev_reward_balances: Vec, }, WithdrawUserLockupRewardsCallback { pool_type: PoolType, @@ -290,10 +290,8 @@ pub struct PoolInfo { pub incentives_share: Uint128, /// Weighted LP Token balance used to calculate NTRN rewards a particular user can claim pub weighted_amount: Uint256, - /// Ratio of Generator NTRN rewards accured to astroport pool share - pub generator_ntrn_per_share: Decimal, - /// Ratio of Generator Proxy rewards accured to astroport pool share - pub generator_proxy_per_share: RestrictedVector, + /// Ratio of Generator rewards accured to astroport pool share + pub generator_rewards_per_share: RestrictedVector, /// Boolean value indicating if the LP Tokens are staked with the Generator contract or not pub is_staked: bool, } @@ -318,25 +316,8 @@ impl From for UserInfo { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct LockupInfoV1 { - /// Terraswap LP units locked by the user - pub lp_units_locked: Uint128, - pub astroport_lp_transferred: Option, - /// Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff - pub withdrawal_flag: bool, - /// NTRN tokens received as rewards for participation in the lockdrop - pub ntrn_rewards: Uint128, - /// Generator NTRN tokens loockup received as generator rewards - pub generator_ntrn_debt: Uint128, - /// Generator Proxy tokens lockup received as generator rewards - pub generator_proxy_debt: Uint128, - /// Timestamp beyond which this position can be unlocked - pub unlock_timestamp: u64, -} - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct LockupInfoV2 { +pub struct LockupInfo { /// Terraswap LP units locked by the user pub lp_units_locked: Uint128, pub astroport_lp_transferred: Option, @@ -344,28 +325,25 @@ pub struct LockupInfoV2 { pub withdrawal_flag: bool, /// NTRN tokens received as rewards for participation in the lockdrop pub ntrn_rewards: Uint128, - /// Generator NTRN tokens loockup received as generator rewards - pub generator_ntrn_debt: Uint128, - /// Generator Proxy tokens lockup received as generator rewards - pub generator_proxy_debt: RestrictedVector, + /// Generator tokens lockup received as generator rewards + pub generator_debt: RestrictedVector, /// Timestamp beyond which this position can be unlocked pub unlock_timestamp: u64, } -impl LockupInfoV2 { +impl LockupInfo { /// Creates a lockup entry for PCL lockdrop contract based on a lockup entry for XYK lockdrop /// contract. The **lp_units_locked** field is the amount of lp tokens minted by the PCL pool. pub fn from_xyk_lockup_info( i: LockdropXYKLockupInfoV2, lp_units_locked: Uint128, - ) -> LockupInfoV2 { - LockupInfoV2 { + ) -> LockupInfo { + LockupInfo { lp_units_locked, astroport_lp_transferred: None, withdrawal_flag: i.withdrawal_flag, ntrn_rewards: i.ntrn_rewards, - generator_ntrn_debt: Uint128::zero(), - generator_proxy_debt: Default::default(), + generator_debt: Default::default(), unlock_timestamp: i.unlock_timestamp, } } @@ -387,8 +365,8 @@ pub struct UserInfoResponse { pub ntrn_transferred: bool, /// Lockup positions pub lockup_infos: Vec, - /// NTRN tokens receivable as generator rewards that user can claim - pub claimable_generator_ntrn_debt: Uint128, + /// Tokens receivable as generator rewards that user can claim + pub claimable_generator_debt: RestrictedVector, /// Number of lockup positions the user is having pub lockup_positions_index: u32, } @@ -422,14 +400,10 @@ pub struct LockUpInfoResponse { /// NTRN tokens received as rewards for participation in the lockdrop pub ntrn_rewards: Uint128, pub duration: u64, - /// Generator NTRN tokens lockup received as generator rewards - pub generator_ntrn_debt: Uint128, - /// ASTRO tokens receivable as generator rewards that user can claim - pub claimable_generator_astro_debt: Uint128, - /// Generator Proxy tokens lockup received as generator rewards - pub generator_proxy_debt: RestrictedVector, - /// Proxy tokens receivable as generator rewards that user can claim - pub claimable_generator_proxy_debt: RestrictedVector, + /// Generator tokens lockup received as generator rewards + pub generator_debt: RestrictedVector, + /// Tokens receivable as generator rewards that user can claim + pub claimable_generator_debt: RestrictedVector, /// Timestamp beyond which this position can be unlocked pub unlock_timestamp: u64, /// User's Astroport LP units, calculated as lp_units_locked (terraswap) / total LP units locked (terraswap) * Astroport LP units minted post migration From 9a2911b80f4c6f6e40b3ab5c71c40a77376c6cb6 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Tue, 13 Feb 2024 12:11:35 +0300 Subject: [PATCH 09/28] fix skate rewards calculation --- contracts/lockdrop-pcl/src/contract.rs | 92 ++++++++------------------ 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 3544607e..bf216b96 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -617,11 +617,7 @@ pub fn update_pool_on_dual_rewards_claim( .info .query_pool(&deps.querier, env.contract.address.clone())?; let received_amount = current_balance.checked_sub(prev_balance.amount)?; - deps.api.debug(&format!( - "WASMDEBUG: set gen rewards per share for {:?}: {}", - prev_balance.info, - Decimal::from_ratio(received_amount, lp_balance) - )); + pool_info.generator_rewards_per_share.update( &prev_balance.info, Decimal::from_ratio(received_amount, lp_balance), @@ -705,6 +701,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .try_into()? }; + let mut pending_reward_assets: Vec = vec![]; // If Astro LP tokens are staked with Astro generator if pool_info.is_staked { // If this LP token is getting incentives @@ -717,70 +714,35 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( }, )?; for reward in pending_rewards { - let generator_rewards_per_share = pool_info.generator_rewards_per_share.update( - &reward.info, - Decimal::from_ratio(reward.amount, astroport_lp_amount), - )?; + let generator_rewards_per_share = pool_info + .generator_rewards_per_share + .load(&reward.info) + .unwrap_or_default(); + if generator_rewards_per_share.is_zero() { + continue; + }; - // Calculate Lockup Astro LP shares - let lockup_astroport_lp_units: Uint128 = lockup_info - .lp_units_locked - .full_mul(astroport_lp_amount) - .checked_div(Uint256::from(pool_info.amount_in_lockups))? - .try_into()?; - - let debt = generator_rewards_per_share - .checked_mul_uint128(lockup_astroport_lp_units)? - .checked_sub( - lockup_info - .generator_debt - .inner_ref() - .iter() - .find_map(|a| if reward.info == a.0 { Some(a.1) } else { None }) - .unwrap_or_default(), - )?; + let total_lockup_rewards = generator_rewards_per_share + .checked_mul(astroport_lp_amount.to_decimal())? + .to_uint_floor(); + let debt = lockup_info + .generator_debt + .load(&reward.info) + .unwrap_or_default(); + let pending_reward = total_lockup_rewards.checked_sub(debt)?; + + if !pending_reward.is_zero() { + pending_reward_assets.push(Asset { + info: reward.info.clone(), + amount: pending_reward, + }); + } - lockup_info.generator_debt.update(&reward.info, debt)?; - deps.api.debug(&format!( - "WASMDEBUG: found pending rewards debt: {} {}", - reward.info.clone(), - debt, - )); + lockup_info + .generator_debt + .update(&reward.info, total_lockup_rewards.checked_sub(debt)?)?; } - let mut pending_reward_assets: Vec = vec![]; - lockup_info.generator_debt = lockup_info - .generator_debt - .inner_ref() - .iter() - .map(|(asset, debt)| { - let generator_rewards_per_share = pool_info - .generator_rewards_per_share - .load(asset) - .unwrap_or_default(); - let total_lockup_reward = - generator_rewards_per_share.checked_mul_uint128(astroport_lp_amount)?; - let pending_reward: Uint128 = total_lockup_reward.checked_sub(*debt)?; - - deps.api.debug(&format!( - "WASMDEBUG: rewards for {} calculated: share {}, total {}, pending {}", - user_address.to_string(), - generator_rewards_per_share, - total_lockup_reward, - pending_reward - )); - - if !pending_reward.is_zero() { - pending_reward_assets.push(Asset { - info: asset.clone(), - amount: pending_reward, - }); - } - Ok((asset.clone(), total_lockup_reward)) - }) - .collect::>>()? - .into(); - // If this is a void transaction (no state change), then return error. // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending rewards, not unlocking LP tokens in this tx if !withdraw_lp_stake && user_info.ntrn_transferred && pending_reward_assets.is_empty() { From 3b795c9d4caaf0ece1bb35ee489a7d255ec15fac Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 15 Feb 2024 14:58:04 +0400 Subject: [PATCH 10/28] fix json schema for lockdrop_pcl --- .../lockdrop-pcl/examples/lockdrop_schema.rs | 2 +- .../schema/neutron-lockdrop-pcl.json | 755 ++++++------------ .../lockdrop-pcl/schema/raw/execute.json | 493 ++++-------- .../lockdrop-pcl/schema/raw/instantiate.json | 110 ++- .../lockdrop-pcl/schema/raw/migrate.json | 11 +- .../schema/raw/response_to_config.json | 58 +- .../schema/raw/response_to_lock_up_info.json | 30 +- .../schema/raw/response_to_pool.json | 15 +- .../schema/raw/response_to_user_info.json | 38 +- 9 files changed, 533 insertions(+), 979 deletions(-) diff --git a/contracts/lockdrop-pcl/examples/lockdrop_schema.rs b/contracts/lockdrop-pcl/examples/lockdrop_schema.rs index ddfb898f..d8778255 100644 --- a/contracts/lockdrop-pcl/examples/lockdrop_schema.rs +++ b/contracts/lockdrop-pcl/examples/lockdrop_schema.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::write_api; -use astroport_periphery::lockdrop::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use astroport_periphery::lockdrop_pcl::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json index 5ec78b28..02d7e54e 100644 --- a/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json +++ b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json @@ -7,18 +7,40 @@ "title": "InstantiateMsg", "type": "object", "required": [ + "atom_incentives_share", + "atom_token", + "atom_weighted_amount", "auction_contract", "credits_contract", - "init_timestamp", - "lock_window", + "generator", + "lockdrop_incentives", "lockup_rewards_info", - "max_lock_duration", - "max_positions_per_user", - "min_lock_duration", - "token_info_manager", - "withdrawal_window" + "usdc_incentives_share", + "usdc_token", + "usdc_weighted_amount", + "xyk_lockdrop_contract" ], "properties": { + "atom_incentives_share": { + "description": "Share of total NTRN incentives allocated to the NTRN/ATOM PCL pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "atom_token": { + "description": "Address of the LP token of the NTRN/ATOM PCL pool", + "type": "string" + }, + "atom_weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/ATOM pool depositor can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + }, "auction_contract": { "description": "Auction contract address", "type": "string" @@ -27,17 +49,17 @@ "description": "Credits contract address", "type": "string" }, - "init_timestamp": { - "description": "Timestamp when Contract will start accepting LP Token deposits", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "generator": { + "description": "Generator (Staking for dual rewards) contract address", + "type": "string" }, - "lock_window": { - "description": "Number of seconds during which lockup deposits will be accepted", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "lockdrop_incentives": { + "description": "Total NTRN lockdrop incentives distributed among the users.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] }, "lockup_rewards_info": { "description": "Describes rewards coefficients for each lockup duration", @@ -46,24 +68,6 @@ "$ref": "#/definitions/LockupRewardsInfo" } }, - "max_lock_duration": { - "description": "Max. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "max_positions_per_user": { - "description": "Max lockup positions a user can have", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "min_lock_duration": { - "description": "Min. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, "owner": { "description": "Account which can update config", "type": [ @@ -71,15 +75,29 @@ "null" ] }, - "token_info_manager": { - "description": "Account which can update token addresses and generator", + "usdc_incentives_share": { + "description": "Share of total NTRN incentives allocated to the NTRN/USDC PCL pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "usdc_token": { + "description": "Address of the LP token of the NTRN/USDC PCL pool", "type": "string" }, - "withdrawal_window": { - "description": "Withdrawal Window Length :: Post the deposit window", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "usdc_weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/USDC pool depositor can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + }, + "xyk_lockdrop_contract": { + "description": "Original XYK lockdrop contract address", + "type": "string" } }, "definitions": { @@ -103,6 +121,14 @@ "minimum": 0.0 } } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint256": { + "description": "An implementation of u256 that is using strings for JSON encoding/decoding, such that the full u256 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances out of primitive uint types or `new` to provide big endian bytes:\n\n``` # use cosmwasm_std::Uint256; let a = Uint256::from(258u128); let b = Uint256::new([ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, ]); assert_eq!(a, b); ```", + "type": "string" } } }, @@ -110,64 +136,6 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "ExecuteMsg", "oneOf": [ - { - "type": "object", - "required": [ - "increase_lockup_for" - ], - "properties": { - "increase_lockup_for": { - "type": "object", - "required": [ - "amount", - "duration", - "pool_type", - "user_address" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "duration": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_type": { - "$ref": "#/definitions/PoolType" - }, - "user_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "increase_ntrn_incentives" - ], - "properties": { - "increase_ntrn_incentives": { - "type": "object" - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -188,68 +156,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "set_token_info" - ], - "properties": { - "set_token_info": { - "type": "object", - "required": [ - "atom_token", - "generator", - "usdc_token" - ], - "properties": { - "atom_token": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "usdc_token": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "withdraw_from_lockup" - ], - "properties": { - "withdraw_from_lockup": { - "type": "object", - "required": [ - "amount", - "duration", - "pool_type", - "user_address" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "duration": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_type": { - "$ref": "#/definitions/PoolType" - }, - "user_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -349,20 +255,54 @@ "additionalProperties": false }, { - "description": "Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation rewards to the address which liquidity has been migrated.", + "description": "A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable by the original lockdrop contract. Expects two **Coin**s to be attached as funds.", "type": "object", "required": [ - "migrate_liquidity_to_pcl_pools" + "migrate_xyk_liquidity" ], "properties": { - "migrate_liquidity_to_pcl_pools": { + "migrate_xyk_liquidity": { "type": "object", + "required": [ + "duration", + "lockup_info", + "pool_type", + "user_address_raw", + "user_info" + ], "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/LockupInfoV2" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType2" + } + ] + }, "user_address_raw": { - "description": "The address which liquidity is supposed to be transferred. If no user address is provided, the message sender's address is used.", - "type": [ - "string", - "null" + "description": "The address of the user which owns the lockup.", + "type": "string" + }, + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/UserInfo" + } ] } } @@ -452,14 +392,9 @@ } ] }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, "CallbackMsg": { "oneOf": [ { - "description": "Updates contract state after dual staking rewards are claimed from the generator contract.", "type": "object", "required": [ "update_pool_on_dual_rewards_claim" @@ -469,17 +404,13 @@ "type": "object", "required": [ "pool_type", - "prev_ntrn_balance", - "prev_proxy_reward_balances" + "prev_reward_balances" ], "properties": { "pool_type": { "$ref": "#/definitions/PoolType" }, - "prev_ntrn_balance": { - "$ref": "#/definitions/Uint128" - }, - "prev_proxy_reward_balances": { + "prev_reward_balances": { "type": "array", "items": { "$ref": "#/definitions/Asset" @@ -491,7 +422,6 @@ "additionalProperties": false }, { - "description": "Withdraws user rewards and LP Tokens after claims / unlocks.", "type": "object", "required": [ "withdraw_user_lockup_rewards_callback" @@ -526,18 +456,22 @@ "additionalProperties": false }, { - "description": "Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the respective callback message.", + "description": "Completes the liquidity migration process by making all necessary state updates for the lockup position.", "type": "object", "required": [ - "init_migrate_lockup_to_pcl_pools_callback" + "finish_lockup_migration_callback" ], "properties": { - "init_migrate_lockup_to_pcl_pools_callback": { + "finish_lockup_migration_callback": { "type": "object", "required": [ "duration", + "lockup_info", + "lp_token", "pool_type", - "user_address" + "staked_lp_token_amount", + "user_address", + "user_info" ], "properties": { "duration": { @@ -546,47 +480,17 @@ "format": "uint64", "minimum": 0.0 }, - "pool_type": { - "description": "The type of the pool the lockup is related to.", + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", "allOf": [ { - "$ref": "#/definitions/PoolType" + "$ref": "#/definitions/LockupInfoV2" } ] }, - "user_address": { - "description": "The address of the user which owns the lockup.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "The second step in the lockup's XYK -> PCL liquidity migration process. Claims all possible rewards that the user is eligible of and transfers them to the user.", - "type": "object", - "required": [ - "transfer_all_rewards_before_migration_callback" - ], - "properties": { - "transfer_all_rewards_before_migration_callback": { - "type": "object", - "required": [ - "duration", - "pool_type", - "user_address" - ], - "properties": { - "duration": { - "description": "The duration of the lock period.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "lp_token": { + "description": "The address of the LP token of the pool.", + "type": "string" }, "pool_type": { "description": "The type of the pool the lockup is related to.", @@ -596,75 +500,14 @@ } ] }, - "user_address": { - "description": "The address of the user which owns the lockup.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "The third step in the lockup's XYK -> PCL liquidity migration process. Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the PCL lockdrop contract.", - "type": "object", - "required": [ - "withdraw_user_lockup_callback" - ], - "properties": { - "withdraw_user_lockup_callback": { - "type": "object", - "required": [ - "astroport_lp_amount", - "astroport_lp_token", - "duration", - "generator", - "pool_type", - "user_address" - ], - "properties": { - "astroport_lp_amount": { - "description": "The amount of LP token to be unstaked and withdrawn.", + "staked_lp_token_amount": { + "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the generator. Used to calculate LP token amount received for liquidity provision.", "allOf": [ { "$ref": "#/definitions/Uint128" } ] }, - "astroport_lp_token": { - "description": "The address of the pool's liquidity token.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - }, - "duration": { - "description": "The duration of the lock period.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "generator": { - "description": "The address of the generator which possesses the staked liquidity.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - }, - "pool_type": { - "description": "The type of the pool the lockup is related to.", - "allOf": [ - { - "$ref": "#/definitions/PoolType" - } - ] - }, "user_address": { "description": "The address of the user which owns the lockup.", "allOf": [ @@ -672,69 +515,12 @@ "$ref": "#/definitions/Addr" } ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "The fourth step in the lockup's XYK -> PCL liquidity migration process. Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's lockup position.", - "type": "object", - "required": [ - "migrate_user_lockup_to_pcl_pair_callback" - ], - "properties": { - "migrate_user_lockup_to_pcl_pair_callback": { - "type": "object", - "required": [ - "duration", - "ntrn_balance", - "paired_asset_balance", - "paired_asset_denom", - "pool_type", - "user_address" - ], - "properties": { - "duration": { - "description": "The duration of the lock period.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "ntrn_balance": { - "description": "The balance in untrn of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of untrn been withdrawn from the XYK pool.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "paired_asset_balance": { - "description": "The balance in the paired denom of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of the paired asset been withdrawn from the XYK pool.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "paired_asset_denom": { - "description": "The denom of the paired asset (the asset paired with untrn in the pool).", - "type": "string" }, - "pool_type": { - "description": "The type of the pool the lockup is related to.", + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", "allOf": [ { - "$ref": "#/definitions/PoolType" - } - ] - }, - "user_address": { - "description": "The address of the user which owns the lockup.", - "allOf": [ - { - "$ref": "#/definitions/Addr" + "$ref": "#/definitions/UserInfo" } ] } @@ -745,26 +531,70 @@ } ] }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "LockupInfoV2": { "type": "object", "required": [ - "amount", - "msg", - "sender" + "generator_ntrn_debt", + "generator_proxy_debt", + "lp_units_locked", + "ntrn_rewards", + "unlock_timestamp", + "withdrawal_flag" ], "properties": { - "amount": { - "$ref": "#/definitions/Uint128" + "astroport_lp_transferred": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] }, - "msg": { - "$ref": "#/definitions/Binary" + "generator_ntrn_debt": { + "description": "Generator NTRN tokens loockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "generator_proxy_debt": { + "description": "Generator Proxy tokens lockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] }, - "sender": { - "type": "string" + "lp_units_locked": { + "description": "Terraswap LP units locked by the user", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "ntrn_rewards": { + "description": "NTRN tokens received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "unlock_timestamp": { + "description": "Timestamp beyond which this position can be unlocked", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "withdrawal_flag": { + "description": "Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff", + "type": "boolean" } - }, - "additionalProperties": false + } }, "PoolType": { "type": "string", @@ -773,6 +603,30 @@ "ATOM" ] }, + "PoolType2": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "RestrictedVector_for_AssetInfo_and_Uint128": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" @@ -780,13 +634,6 @@ "UpdateConfigMsg": { "type": "object", "properties": { - "auction_contract_address": { - "description": "Bootstrap Auction contract address", - "type": [ - "string", - "null" - ] - }, "generator_address": { "description": "Generator (Staking for dual rewards) contract address", "type": [ @@ -795,6 +642,34 @@ ] } } + }, + "UserInfo": { + "type": "object", + "required": [ + "lockup_positions_index", + "ntrn_transferred", + "total_ntrn_rewards" + ], + "properties": { + "lockup_positions_index": { + "description": "Number of lockup positions the user is having", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "ntrn_transferred": { + "description": "NTRN tokens transferred to user", + "type": "boolean" + }, + "total_ntrn_rewards": { + "description": "Total NTRN tokens user received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + } } } }, @@ -994,16 +869,7 @@ "migrate": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", - "type": "object", - "required": [ - "pcl_lockdrop_contract" - ], - "properties": { - "pcl_lockdrop_contract": { - "description": "The address of the lockdrop contract working with PCL pools. Used to transfer the lockdrop's liquidity locked in XYK pools to more efficient pools.", - "type": "string" - } - } + "type": "object" }, "sudo": null, "responses": { @@ -1014,16 +880,11 @@ "required": [ "auction_contract", "credits_contract", - "init_timestamp", - "lock_window", + "incentives", "lockdrop_incentives", "lockup_rewards_info", - "max_lock_duration", - "max_positions_per_user", - "min_lock_duration", "owner", - "token_info_manager", - "withdrawal_window" + "xyk_lockdrop_contract" ], "properties": { "auction_contract": { @@ -1042,29 +903,14 @@ } ] }, - "generator": { - "description": "Generator (Staking for dual rewards) contract address", - "anyOf": [ + "incentives": { + "description": "Incentives contract address", + "allOf": [ { "$ref": "#/definitions/Addr" - }, - { - "type": "null" } ] }, - "init_timestamp": { - "description": "Timestamp when Contract will start accepting LP Token deposits", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lock_window": { - "description": "Number of seconds during which lockup positions be accepted", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, "lockdrop_incentives": { "description": "Total NTRN lockdrop incentives to be distributed among the users", "allOf": [ @@ -1080,24 +926,6 @@ "$ref": "#/definitions/LockupRewardsInfo" } }, - "max_lock_duration": { - "description": "Max. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "max_positions_per_user": { - "description": "Max lockup positions a user can have", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "min_lock_duration": { - "description": "Min. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, "owner": { "description": "Account which can update the config", "allOf": [ @@ -1106,19 +934,13 @@ } ] }, - "token_info_manager": { - "description": "Account which can update the generator and token addresses", + "xyk_lockdrop_contract": { + "description": "Original XYK lockdrop contract address", "allOf": [ { "$ref": "#/definitions/Addr" } ] - }, - "withdrawal_window": { - "description": "Withdrawal Window Length :: Post the deposit window", - "type": "integer", - "format": "uint64", - "minimum": 0.0 } }, "definitions": { @@ -1159,11 +981,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_astro_debt", - "claimable_generator_proxy_debt", + "claimable_generator_debt", "duration", - "generator_ntrn_debt", - "generator_proxy_debt", + "generator_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -1195,16 +1015,8 @@ } ] }, - "claimable_generator_astro_debt": { - "description": "ASTRO tokens receivable as generator rewards that user can claim", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "claimable_generator_proxy_debt": { - "description": "Proxy tokens receivable as generator rewards that user can claim", + "claimable_generator_debt": { + "description": "Tokens receivable as generator rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1216,16 +1028,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_ntrn_debt": { - "description": "Generator NTRN tokens lockup received as generator rewards", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "generator_proxy_debt": { - "description": "Generator Proxy tokens lockup received as generator rewards", + "generator_debt": { + "description": "Generator tokens lockup received as generator rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1357,8 +1161,7 @@ "type": "object", "required": [ "amount_in_lockups", - "generator_ntrn_per_share", - "generator_proxy_per_share", + "generator_rewards_per_share", "incentives_share", "is_staked", "lp_token", @@ -1368,16 +1171,8 @@ "amount_in_lockups": { "$ref": "#/definitions/Uint128" }, - "generator_ntrn_per_share": { - "description": "Ratio of Generator NTRN rewards accured to astroport pool share", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] - }, - "generator_proxy_per_share": { - "description": "Ratio of Generator Proxy rewards accured to astroport pool share", + "generator_rewards_per_share": { + "description": "Ratio of Generator rewards accured to astroport pool share", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Decimal" @@ -1573,18 +1368,18 @@ "title": "UserInfoResponse", "type": "object", "required": [ - "claimable_generator_ntrn_debt", + "claimable_generator_debt", "lockup_infos", "lockup_positions_index", "ntrn_transferred", "total_ntrn_rewards" ], "properties": { - "claimable_generator_ntrn_debt": { - "description": "NTRN tokens receivable as generator rewards that user can claim", + "claimable_generator_debt": { + "description": "Tokens receivable as generator rewards that user can claim", "allOf": [ { - "$ref": "#/definitions/Uint128" + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" } ] }, @@ -1672,11 +1467,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_astro_debt", - "claimable_generator_proxy_debt", + "claimable_generator_debt", "duration", - "generator_ntrn_debt", - "generator_proxy_debt", + "generator_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -1708,16 +1501,8 @@ } ] }, - "claimable_generator_astro_debt": { - "description": "ASTRO tokens receivable as generator rewards that user can claim", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "claimable_generator_proxy_debt": { - "description": "Proxy tokens receivable as generator rewards that user can claim", + "claimable_generator_debt": { + "description": "Tokens receivable as generator rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1729,16 +1514,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_ntrn_debt": { - "description": "Generator NTRN tokens lockup received as generator rewards", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "generator_proxy_debt": { - "description": "Generator Proxy tokens lockup received as generator rewards", + "generator_debt": { + "description": "Generator tokens lockup received as generator rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" diff --git a/contracts/lockdrop-pcl/schema/raw/execute.json b/contracts/lockdrop-pcl/schema/raw/execute.json index b0e991e6..d8d0fe1d 100644 --- a/contracts/lockdrop-pcl/schema/raw/execute.json +++ b/contracts/lockdrop-pcl/schema/raw/execute.json @@ -2,64 +2,6 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "ExecuteMsg", "oneOf": [ - { - "type": "object", - "required": [ - "increase_lockup_for" - ], - "properties": { - "increase_lockup_for": { - "type": "object", - "required": [ - "amount", - "duration", - "pool_type", - "user_address" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "duration": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_type": { - "$ref": "#/definitions/PoolType" - }, - "user_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "increase_ntrn_incentives" - ], - "properties": { - "increase_ntrn_incentives": { - "type": "object" - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -80,68 +22,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "set_token_info" - ], - "properties": { - "set_token_info": { - "type": "object", - "required": [ - "atom_token", - "generator", - "usdc_token" - ], - "properties": { - "atom_token": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "usdc_token": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "withdraw_from_lockup" - ], - "properties": { - "withdraw_from_lockup": { - "type": "object", - "required": [ - "amount", - "duration", - "pool_type", - "user_address" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "duration": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_type": { - "$ref": "#/definitions/PoolType" - }, - "user_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -241,20 +121,54 @@ "additionalProperties": false }, { - "description": "Migrates user's locked liquidity from XYK pools to PCL ones, transferring lockdrop participation rewards to the address which liquidity has been migrated.", + "description": "A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable by the original lockdrop contract. Expects two **Coin**s to be attached as funds.", "type": "object", "required": [ - "migrate_liquidity_to_pcl_pools" + "migrate_xyk_liquidity" ], "properties": { - "migrate_liquidity_to_pcl_pools": { + "migrate_xyk_liquidity": { "type": "object", + "required": [ + "duration", + "lockup_info", + "pool_type", + "user_address_raw", + "user_info" + ], "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/LockupInfoV2" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType2" + } + ] + }, "user_address_raw": { - "description": "The address which liquidity is supposed to be transferred. If no user address is provided, the message sender's address is used.", - "type": [ - "string", - "null" + "description": "The address of the user which owns the lockup.", + "type": "string" + }, + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/UserInfo" + } ] } } @@ -344,14 +258,9 @@ } ] }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, "CallbackMsg": { "oneOf": [ { - "description": "Updates contract state after dual staking rewards are claimed from the generator contract.", "type": "object", "required": [ "update_pool_on_dual_rewards_claim" @@ -361,17 +270,13 @@ "type": "object", "required": [ "pool_type", - "prev_ntrn_balance", - "prev_proxy_reward_balances" + "prev_reward_balances" ], "properties": { "pool_type": { "$ref": "#/definitions/PoolType" }, - "prev_ntrn_balance": { - "$ref": "#/definitions/Uint128" - }, - "prev_proxy_reward_balances": { + "prev_reward_balances": { "type": "array", "items": { "$ref": "#/definitions/Asset" @@ -383,7 +288,6 @@ "additionalProperties": false }, { - "description": "Withdraws user rewards and LP Tokens after claims / unlocks.", "type": "object", "required": [ "withdraw_user_lockup_rewards_callback" @@ -418,18 +322,22 @@ "additionalProperties": false }, { - "description": "Entry point for a single lockup position migration to PCL lockdrop contract. Performs generator rewards claiming and initializes liquidity withdrawal+transfer process by invocation of the respective callback message.", + "description": "Completes the liquidity migration process by making all necessary state updates for the lockup position.", "type": "object", "required": [ - "init_migrate_lockup_to_pcl_pools_callback" + "finish_lockup_migration_callback" ], "properties": { - "init_migrate_lockup_to_pcl_pools_callback": { + "finish_lockup_migration_callback": { "type": "object", "required": [ "duration", + "lockup_info", + "lp_token", "pool_type", - "user_address" + "staked_lp_token_amount", + "user_address", + "user_info" ], "properties": { "duration": { @@ -438,47 +346,17 @@ "format": "uint64", "minimum": 0.0 }, - "pool_type": { - "description": "The type of the pool the lockup is related to.", + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", "allOf": [ { - "$ref": "#/definitions/PoolType" + "$ref": "#/definitions/LockupInfoV2" } ] }, - "user_address": { - "description": "The address of the user which owns the lockup.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "The second step in the lockup's XYK -> PCL liquidity migration process. Claims all possible rewards that the user is eligible of and transfers them to the user.", - "type": "object", - "required": [ - "transfer_all_rewards_before_migration_callback" - ], - "properties": { - "transfer_all_rewards_before_migration_callback": { - "type": "object", - "required": [ - "duration", - "pool_type", - "user_address" - ], - "properties": { - "duration": { - "description": "The duration of the lock period.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "lp_token": { + "description": "The address of the LP token of the pool.", + "type": "string" }, "pool_type": { "description": "The type of the pool the lockup is related to.", @@ -488,75 +366,14 @@ } ] }, - "user_address": { - "description": "The address of the user which owns the lockup.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "The third step in the lockup's XYK -> PCL liquidity migration process. Handles withdrawal of staked liquidity from the generator contract and liquidity transfer to the PCL lockdrop contract.", - "type": "object", - "required": [ - "withdraw_user_lockup_callback" - ], - "properties": { - "withdraw_user_lockup_callback": { - "type": "object", - "required": [ - "astroport_lp_amount", - "astroport_lp_token", - "duration", - "generator", - "pool_type", - "user_address" - ], - "properties": { - "astroport_lp_amount": { - "description": "The amount of LP token to be unstaked and withdrawn.", + "staked_lp_token_amount": { + "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the generator. Used to calculate LP token amount received for liquidity provision.", "allOf": [ { "$ref": "#/definitions/Uint128" } ] }, - "astroport_lp_token": { - "description": "The address of the pool's liquidity token.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - }, - "duration": { - "description": "The duration of the lock period.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "generator": { - "description": "The address of the generator which possesses the staked liquidity.", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - }, - "pool_type": { - "description": "The type of the pool the lockup is related to.", - "allOf": [ - { - "$ref": "#/definitions/PoolType" - } - ] - }, "user_address": { "description": "The address of the user which owns the lockup.", "allOf": [ @@ -564,69 +381,12 @@ "$ref": "#/definitions/Addr" } ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "The fourth step in the lockup's XYK -> PCL liquidity migration process. Invokes the PCL lockdrop contract's MigrateXYKLiquidity handler which creates an LP position in the PCL pool and a lockup in the PCL lockdrop contract in accordance with the withdrawn user's lockup position.", - "type": "object", - "required": [ - "migrate_user_lockup_to_pcl_pair_callback" - ], - "properties": { - "migrate_user_lockup_to_pcl_pair_callback": { - "type": "object", - "required": [ - "duration", - "ntrn_balance", - "paired_asset_balance", - "paired_asset_denom", - "pool_type", - "user_address" - ], - "properties": { - "duration": { - "description": "The duration of the lock period.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 }, - "ntrn_balance": { - "description": "The balance in untrn of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of untrn been withdrawn from the XYK pool.", + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", "allOf": [ { - "$ref": "#/definitions/Uint128" - } - ] - }, - "paired_asset_balance": { - "description": "The balance in the paired denom of the XYK lockdrop contract at the third migration step. Is used in the callback to calculate the amount of the paired asset been withdrawn from the XYK pool.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "paired_asset_denom": { - "description": "The denom of the paired asset (the asset paired with untrn in the pool).", - "type": "string" - }, - "pool_type": { - "description": "The type of the pool the lockup is related to.", - "allOf": [ - { - "$ref": "#/definitions/PoolType" - } - ] - }, - "user_address": { - "description": "The address of the user which owns the lockup.", - "allOf": [ - { - "$ref": "#/definitions/Addr" + "$ref": "#/definitions/UserInfo" } ] } @@ -637,26 +397,70 @@ } ] }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "LockupInfoV2": { "type": "object", "required": [ - "amount", - "msg", - "sender" + "generator_ntrn_debt", + "generator_proxy_debt", + "lp_units_locked", + "ntrn_rewards", + "unlock_timestamp", + "withdrawal_flag" ], "properties": { - "amount": { - "$ref": "#/definitions/Uint128" + "astroport_lp_transferred": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] }, - "msg": { - "$ref": "#/definitions/Binary" + "generator_ntrn_debt": { + "description": "Generator NTRN tokens loockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] }, - "sender": { - "type": "string" + "generator_proxy_debt": { + "description": "Generator Proxy tokens lockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "lp_units_locked": { + "description": "Terraswap LP units locked by the user", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "ntrn_rewards": { + "description": "NTRN tokens received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "unlock_timestamp": { + "description": "Timestamp beyond which this position can be unlocked", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "withdrawal_flag": { + "description": "Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff", + "type": "boolean" } - }, - "additionalProperties": false + } }, "PoolType": { "type": "string", @@ -665,6 +469,30 @@ "ATOM" ] }, + "PoolType2": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "RestrictedVector_for_AssetInfo_and_Uint128": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" @@ -672,13 +500,6 @@ "UpdateConfigMsg": { "type": "object", "properties": { - "auction_contract_address": { - "description": "Bootstrap Auction contract address", - "type": [ - "string", - "null" - ] - }, "generator_address": { "description": "Generator (Staking for dual rewards) contract address", "type": [ @@ -687,6 +508,34 @@ ] } } + }, + "UserInfo": { + "type": "object", + "required": [ + "lockup_positions_index", + "ntrn_transferred", + "total_ntrn_rewards" + ], + "properties": { + "lockup_positions_index": { + "description": "Number of lockup positions the user is having", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "ntrn_transferred": { + "description": "NTRN tokens transferred to user", + "type": "boolean" + }, + "total_ntrn_rewards": { + "description": "Total NTRN tokens user received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + } } } } diff --git a/contracts/lockdrop-pcl/schema/raw/instantiate.json b/contracts/lockdrop-pcl/schema/raw/instantiate.json index f91cea0f..efb88fdc 100644 --- a/contracts/lockdrop-pcl/schema/raw/instantiate.json +++ b/contracts/lockdrop-pcl/schema/raw/instantiate.json @@ -3,18 +3,40 @@ "title": "InstantiateMsg", "type": "object", "required": [ + "atom_incentives_share", + "atom_token", + "atom_weighted_amount", "auction_contract", "credits_contract", - "init_timestamp", - "lock_window", + "generator", + "lockdrop_incentives", "lockup_rewards_info", - "max_lock_duration", - "max_positions_per_user", - "min_lock_duration", - "token_info_manager", - "withdrawal_window" + "usdc_incentives_share", + "usdc_token", + "usdc_weighted_amount", + "xyk_lockdrop_contract" ], "properties": { + "atom_incentives_share": { + "description": "Share of total NTRN incentives allocated to the NTRN/ATOM PCL pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "atom_token": { + "description": "Address of the LP token of the NTRN/ATOM PCL pool", + "type": "string" + }, + "atom_weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/ATOM pool depositor can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + }, "auction_contract": { "description": "Auction contract address", "type": "string" @@ -23,17 +45,17 @@ "description": "Credits contract address", "type": "string" }, - "init_timestamp": { - "description": "Timestamp when Contract will start accepting LP Token deposits", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "generator": { + "description": "Generator (Staking for dual rewards) contract address", + "type": "string" }, - "lock_window": { - "description": "Number of seconds during which lockup deposits will be accepted", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "lockdrop_incentives": { + "description": "Total NTRN lockdrop incentives distributed among the users.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] }, "lockup_rewards_info": { "description": "Describes rewards coefficients for each lockup duration", @@ -42,24 +64,6 @@ "$ref": "#/definitions/LockupRewardsInfo" } }, - "max_lock_duration": { - "description": "Max. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "max_positions_per_user": { - "description": "Max lockup positions a user can have", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "min_lock_duration": { - "description": "Min. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, "owner": { "description": "Account which can update config", "type": [ @@ -67,15 +71,29 @@ "null" ] }, - "token_info_manager": { - "description": "Account which can update token addresses and generator", + "usdc_incentives_share": { + "description": "Share of total NTRN incentives allocated to the NTRN/USDC PCL pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "usdc_token": { + "description": "Address of the LP token of the NTRN/USDC PCL pool", "type": "string" }, - "withdrawal_window": { - "description": "Withdrawal Window Length :: Post the deposit window", - "type": "integer", - "format": "uint64", - "minimum": 0.0 + "usdc_weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/USDC pool depositor can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + }, + "xyk_lockdrop_contract": { + "description": "Original XYK lockdrop contract address", + "type": "string" } }, "definitions": { @@ -99,6 +117,14 @@ "minimum": 0.0 } } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint256": { + "description": "An implementation of u256 that is using strings for JSON encoding/decoding, such that the full u256 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances out of primitive uint types or `new` to provide big endian bytes:\n\n``` # use cosmwasm_std::Uint256; let a = Uint256::from(258u128); let b = Uint256::new([ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, ]); assert_eq!(a, b); ```", + "type": "string" } } } diff --git a/contracts/lockdrop-pcl/schema/raw/migrate.json b/contracts/lockdrop-pcl/schema/raw/migrate.json index 1efd732d..87b18ea7 100644 --- a/contracts/lockdrop-pcl/schema/raw/migrate.json +++ b/contracts/lockdrop-pcl/schema/raw/migrate.json @@ -1,14 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", - "type": "object", - "required": [ - "pcl_lockdrop_contract" - ], - "properties": { - "pcl_lockdrop_contract": { - "description": "The address of the lockdrop contract working with PCL pools. Used to transfer the lockdrop's liquidity locked in XYK pools to more efficient pools.", - "type": "string" - } - } + "type": "object" } diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_config.json b/contracts/lockdrop-pcl/schema/raw/response_to_config.json index 946da11d..7804611d 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_config.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_config.json @@ -5,16 +5,11 @@ "required": [ "auction_contract", "credits_contract", - "init_timestamp", - "lock_window", + "incentives", "lockdrop_incentives", "lockup_rewards_info", - "max_lock_duration", - "max_positions_per_user", - "min_lock_duration", "owner", - "token_info_manager", - "withdrawal_window" + "xyk_lockdrop_contract" ], "properties": { "auction_contract": { @@ -33,29 +28,14 @@ } ] }, - "generator": { - "description": "Generator (Staking for dual rewards) contract address", - "anyOf": [ + "incentives": { + "description": "Incentives contract address", + "allOf": [ { "$ref": "#/definitions/Addr" - }, - { - "type": "null" } ] }, - "init_timestamp": { - "description": "Timestamp when Contract will start accepting LP Token deposits", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lock_window": { - "description": "Number of seconds during which lockup positions be accepted", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, "lockdrop_incentives": { "description": "Total NTRN lockdrop incentives to be distributed among the users", "allOf": [ @@ -71,24 +51,6 @@ "$ref": "#/definitions/LockupRewardsInfo" } }, - "max_lock_duration": { - "description": "Max. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "max_positions_per_user": { - "description": "Max lockup positions a user can have", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "min_lock_duration": { - "description": "Min. no. of weeks allowed for lockup", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, "owner": { "description": "Account which can update the config", "allOf": [ @@ -97,19 +59,13 @@ } ] }, - "token_info_manager": { - "description": "Account which can update the generator and token addresses", + "xyk_lockdrop_contract": { + "description": "Original XYK lockdrop contract address", "allOf": [ { "$ref": "#/definitions/Addr" } ] - }, - "withdrawal_window": { - "description": "Withdrawal Window Length :: Post the deposit window", - "type": "integer", - "format": "uint64", - "minimum": 0.0 } }, "definitions": { diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json b/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json index 89a125d8..e2104126 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json @@ -4,11 +4,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_astro_debt", - "claimable_generator_proxy_debt", + "claimable_generator_debt", "duration", - "generator_ntrn_debt", - "generator_proxy_debt", + "generator_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -40,16 +38,8 @@ } ] }, - "claimable_generator_astro_debt": { - "description": "ASTRO tokens receivable as generator rewards that user can claim", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "claimable_generator_proxy_debt": { - "description": "Proxy tokens receivable as generator rewards that user can claim", + "claimable_generator_debt": { + "description": "Tokens receivable as generator rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -61,16 +51,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_ntrn_debt": { - "description": "Generator NTRN tokens lockup received as generator rewards", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "generator_proxy_debt": { - "description": "Generator Proxy tokens lockup received as generator rewards", + "generator_debt": { + "description": "Generator tokens lockup received as generator rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_pool.json b/contracts/lockdrop-pcl/schema/raw/response_to_pool.json index 865a4fe2..6c7d31a6 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_pool.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_pool.json @@ -4,8 +4,7 @@ "type": "object", "required": [ "amount_in_lockups", - "generator_ntrn_per_share", - "generator_proxy_per_share", + "generator_rewards_per_share", "incentives_share", "is_staked", "lp_token", @@ -15,16 +14,8 @@ "amount_in_lockups": { "$ref": "#/definitions/Uint128" }, - "generator_ntrn_per_share": { - "description": "Ratio of Generator NTRN rewards accured to astroport pool share", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] - }, - "generator_proxy_per_share": { - "description": "Ratio of Generator Proxy rewards accured to astroport pool share", + "generator_rewards_per_share": { + "description": "Ratio of Generator rewards accured to astroport pool share", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Decimal" diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json b/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json index a15339ce..936786b7 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json @@ -3,18 +3,18 @@ "title": "UserInfoResponse", "type": "object", "required": [ - "claimable_generator_ntrn_debt", + "claimable_generator_debt", "lockup_infos", "lockup_positions_index", "ntrn_transferred", "total_ntrn_rewards" ], "properties": { - "claimable_generator_ntrn_debt": { - "description": "NTRN tokens receivable as generator rewards that user can claim", + "claimable_generator_debt": { + "description": "Tokens receivable as generator rewards that user can claim", "allOf": [ { - "$ref": "#/definitions/Uint128" + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" } ] }, @@ -102,11 +102,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_astro_debt", - "claimable_generator_proxy_debt", + "claimable_generator_debt", "duration", - "generator_ntrn_debt", - "generator_proxy_debt", + "generator_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -138,16 +136,8 @@ } ] }, - "claimable_generator_astro_debt": { - "description": "ASTRO tokens receivable as generator rewards that user can claim", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "claimable_generator_proxy_debt": { - "description": "Proxy tokens receivable as generator rewards that user can claim", + "claimable_generator_debt": { + "description": "Tokens receivable as generator rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -159,16 +149,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_ntrn_debt": { - "description": "Generator NTRN tokens lockup received as generator rewards", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "generator_proxy_debt": { - "description": "Generator Proxy tokens lockup received as generator rewards", + "generator_debt": { + "description": "Generator tokens lockup received as generator rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" From 1ee7cba4d4bf97cffad966c79191848221f3f9e0 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Wed, 21 Feb 2024 13:18:13 +0200 Subject: [PATCH 11/28] generator -> incentives --- .../schema/neutron-lockdrop-pcl.json | 50 ++++++------ .../lockdrop-pcl/schema/raw/execute.json | 6 +- .../lockdrop-pcl/schema/raw/instantiate.json | 6 +- .../schema/raw/response_to_lock_up_info.json | 12 +-- .../schema/raw/response_to_pool.json | 8 +- .../schema/raw/response_to_user_info.json | 18 ++--- contracts/lockdrop-pcl/src/contract.rs | 70 ++++++++--------- contracts/lockdrop-pcl/src/migration.rs | 77 ------------------- contracts/lockdrop-pcl/src/raw_queries.rs | 14 ++-- .../astroport_periphery/src/lockdrop_pcl.rs | 34 ++++---- 10 files changed, 109 insertions(+), 186 deletions(-) delete mode 100644 contracts/lockdrop-pcl/src/migration.rs diff --git a/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json index 02d7e54e..4056bb08 100644 --- a/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json +++ b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json @@ -12,7 +12,7 @@ "atom_weighted_amount", "auction_contract", "credits_contract", - "generator", + "incentives", "lockdrop_incentives", "lockup_rewards_info", "usdc_incentives_share", @@ -49,8 +49,8 @@ "description": "Credits contract address", "type": "string" }, - "generator": { - "description": "Generator (Staking for dual rewards) contract address", + "incentives": { + "description": "Incentives (Staking for dual rewards) contract address", "type": "string" }, "lockdrop_incentives": { @@ -501,7 +501,7 @@ ] }, "staked_lp_token_amount": { - "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the generator. Used to calculate LP token amount received for liquidity provision.", + "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the incentives. Used to calculate LP token amount received for liquidity provision.", "allOf": [ { "$ref": "#/definitions/Uint128" @@ -634,8 +634,8 @@ "UpdateConfigMsg": { "type": "object", "properties": { - "generator_address": { - "description": "Generator (Staking for dual rewards) contract address", + "incentives_address": { + "description": "incentives (Staking for dual rewards) contract address", "type": [ "string", "null" @@ -981,9 +981,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_debt", + "claimable_incentives_debt", "duration", - "generator_debt", + "incentives_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -1015,8 +1015,8 @@ } ] }, - "claimable_generator_debt": { - "description": "Tokens receivable as generator rewards that user can claim", + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1028,8 +1028,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_debt": { - "description": "Generator tokens lockup received as generator rewards", + "incentives_debt": { + "description": "incentives tokens lockup received as incentives rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1161,7 +1161,7 @@ "type": "object", "required": [ "amount_in_lockups", - "generator_rewards_per_share", + "incentives_rewards_per_share", "incentives_share", "is_staked", "lp_token", @@ -1171,8 +1171,8 @@ "amount_in_lockups": { "$ref": "#/definitions/Uint128" }, - "generator_rewards_per_share": { - "description": "Ratio of Generator rewards accured to astroport pool share", + "incentives_rewards_per_share": { + "description": "Ratio of incentives rewards accured to astroport pool share", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Decimal" @@ -1188,7 +1188,7 @@ ] }, "is_staked": { - "description": "Boolean value indicating if the LP Tokens are staked with the Generator contract or not", + "description": "Boolean value indicating if the LP Tokens are staked with the incentives contract or not", "type": "boolean" }, "lp_token": { @@ -1368,15 +1368,15 @@ "title": "UserInfoResponse", "type": "object", "required": [ - "claimable_generator_debt", + "claimable_incentives_debt", "lockup_infos", "lockup_positions_index", "ntrn_transferred", "total_ntrn_rewards" ], "properties": { - "claimable_generator_debt": { - "description": "Tokens receivable as generator rewards that user can claim", + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1467,9 +1467,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_debt", + "claimable_incentives_debt", "duration", - "generator_debt", + "incentives_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -1501,8 +1501,8 @@ } ] }, - "claimable_generator_debt": { - "description": "Tokens receivable as generator rewards that user can claim", + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -1514,8 +1514,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_debt": { - "description": "Generator tokens lockup received as generator rewards", + "incentives_debt": { + "description": "incentives tokens lockup received as incentives rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" diff --git a/contracts/lockdrop-pcl/schema/raw/execute.json b/contracts/lockdrop-pcl/schema/raw/execute.json index d8d0fe1d..ea85cb11 100644 --- a/contracts/lockdrop-pcl/schema/raw/execute.json +++ b/contracts/lockdrop-pcl/schema/raw/execute.json @@ -367,7 +367,7 @@ ] }, "staked_lp_token_amount": { - "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the generator. Used to calculate LP token amount received for liquidity provision.", + "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the incentives. Used to calculate LP token amount received for liquidity provision.", "allOf": [ { "$ref": "#/definitions/Uint128" @@ -500,8 +500,8 @@ "UpdateConfigMsg": { "type": "object", "properties": { - "generator_address": { - "description": "Generator (Staking for dual rewards) contract address", + "incentives_address": { + "description": "incentives (Staking for dual rewards) contract address", "type": [ "string", "null" diff --git a/contracts/lockdrop-pcl/schema/raw/instantiate.json b/contracts/lockdrop-pcl/schema/raw/instantiate.json index efb88fdc..7d301b3c 100644 --- a/contracts/lockdrop-pcl/schema/raw/instantiate.json +++ b/contracts/lockdrop-pcl/schema/raw/instantiate.json @@ -8,7 +8,7 @@ "atom_weighted_amount", "auction_contract", "credits_contract", - "generator", + "incentives", "lockdrop_incentives", "lockup_rewards_info", "usdc_incentives_share", @@ -45,8 +45,8 @@ "description": "Credits contract address", "type": "string" }, - "generator": { - "description": "Generator (Staking for dual rewards) contract address", + "incentives": { + "description": "Incentives (Staking for dual rewards) contract address", "type": "string" }, "lockdrop_incentives": { diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json b/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json index e2104126..b88807de 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_lock_up_info.json @@ -4,9 +4,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_debt", + "claimable_incentives_debt", "duration", - "generator_debt", + "incentives_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -38,8 +38,8 @@ } ] }, - "claimable_generator_debt": { - "description": "Tokens receivable as generator rewards that user can claim", + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -51,8 +51,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_debt": { - "description": "Generator tokens lockup received as generator rewards", + "incentives_debt": { + "description": "incentives tokens lockup received as incentives rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_pool.json b/contracts/lockdrop-pcl/schema/raw/response_to_pool.json index 6c7d31a6..fee1dab9 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_pool.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_pool.json @@ -4,7 +4,7 @@ "type": "object", "required": [ "amount_in_lockups", - "generator_rewards_per_share", + "incentives_rewards_per_share", "incentives_share", "is_staked", "lp_token", @@ -14,8 +14,8 @@ "amount_in_lockups": { "$ref": "#/definitions/Uint128" }, - "generator_rewards_per_share": { - "description": "Ratio of Generator rewards accured to astroport pool share", + "incentives_rewards_per_share": { + "description": "Ratio of incentives rewards accured to astroport pool share", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Decimal" @@ -31,7 +31,7 @@ ] }, "is_staked": { - "description": "Boolean value indicating if the LP Tokens are staked with the Generator contract or not", + "description": "Boolean value indicating if the LP Tokens are staked with the incentives contract or not", "type": "boolean" }, "lp_token": { diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json b/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json index 936786b7..fe7527b7 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_user_info.json @@ -3,15 +3,15 @@ "title": "UserInfoResponse", "type": "object", "required": [ - "claimable_generator_debt", + "claimable_incentives_debt", "lockup_infos", "lockup_positions_index", "ntrn_transferred", "total_ntrn_rewards" ], "properties": { - "claimable_generator_debt": { - "description": "Tokens receivable as generator rewards that user can claim", + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -102,9 +102,9 @@ "type": "object", "required": [ "astroport_lp_token", - "claimable_generator_debt", + "claimable_incentives_debt", "duration", - "generator_debt", + "incentives_debt", "lp_units_locked", "ntrn_rewards", "pool_type", @@ -136,8 +136,8 @@ } ] }, - "claimable_generator_debt": { - "description": "Tokens receivable as generator rewards that user can claim", + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" @@ -149,8 +149,8 @@ "format": "uint64", "minimum": 0.0 }, - "generator_debt": { - "description": "Generator tokens lockup received as generator rewards", + "incentives_debt": { + "description": "incentives tokens lockup received as incentives rewards", "allOf": [ { "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index bf216b96..1d19658b 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -18,7 +18,7 @@ use cosmwasm_std::{ use cw2::set_contract_version; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; -use crate::raw_queries::{raw_balance, raw_generator_deposit}; +use crate::raw_queries::{raw_balance, raw_incentives_deposit}; use astroport_periphery::lockdrop::{ LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, UserInfo as LockdropXYKUserInfo, @@ -73,7 +73,7 @@ pub fn instantiate( xyk_lockdrop_contract: deps.api.addr_validate(&msg.xyk_lockdrop_contract)?, credits_contract: deps.api.addr_validate(&msg.credits_contract)?, auction_contract: deps.api.addr_validate(&msg.auction_contract)?, - incentives: deps.api.addr_validate(&msg.generator)?, + incentives: deps.api.addr_validate(&msg.incentives)?, lockdrop_incentives: msg.lockdrop_incentives, lockup_rewards_info: msg.lockup_rewards_info, }; @@ -85,7 +85,7 @@ pub fn instantiate( amount_in_lockups: Default::default(), incentives_share: msg.atom_incentives_share, weighted_amount: msg.atom_weighted_amount, - generator_rewards_per_share: RestrictedVector::default(), + incentives_rewards_per_share: RestrictedVector::default(), is_staked: true, }; ASSET_POOLS.save(deps.storage, PoolType::ATOM, &pool_info, env.block.height)?; @@ -96,7 +96,7 @@ pub fn instantiate( amount_in_lockups: Default::default(), incentives_share: msg.usdc_incentives_share, weighted_amount: msg.usdc_weighted_amount, - generator_rewards_per_share: RestrictedVector::default(), + incentives_rewards_per_share: RestrictedVector::default(), is_staked: true, }; ASSET_POOLS.save(deps.storage, PoolType::USDC, &pool_info, env.block.height)?; @@ -284,8 +284,8 @@ pub fn handle_update_config( return Err(StdError::generic_err("Unauthorized")); } - if let Some(generator) = new_config.generator_address { - // If generator is set, we check is any LP tokens are currently staked before updating generator address + if let Some(incentives) = new_config.incentives_address { + // If incentives is set, we check is any LP tokens are currently staked before updating incentives address for pool_type in ASSET_POOLS .keys(deps.storage, None, None, Order::Ascending) .collect::, StdError>>()? @@ -293,14 +293,14 @@ pub fn handle_update_config( let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; if pool_info.is_staked { return Err(StdError::generic_err(format!( - "{:?} astro LP tokens already staked. Unstake them before updating generator", + "{:?} astro LP tokens already staked. Unstake them before updating incentives", pool_type ))); } } - config.incentives = deps.api.addr_validate(&generator)?; - attributes.push(attr("new_generator", generator)) + config.incentives = deps.api.addr_validate(&incentives)?; + attributes.push(attr("new_incentives", incentives)) } CONFIG.save(deps.storage, &config)?; @@ -315,7 +315,7 @@ pub fn handle_update_config( /// /// Exactly two **Coin**s are expected to be attached to the message as funds. These **Coin**s are /// used in ProvideLiquidity message sent to the PCL pool, the minted LP tokens are staked to the -/// generator. +/// incentives. /// /// Liquidity migration process consists of several sequential messages invocation and from this /// contract's point of view it mostly mimics (and clones code of) the **IncreaseLockupFor** exec @@ -466,11 +466,11 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let astroport_lp_token = pool_info.lp_token; if pool_info.is_staked { - let generator = &config.incentives; + let incentives = &config.incentives; // QUERY :: Check if there are any pending staking rewards let pending_rewards_response: Vec = deps.querier.query_wasm_smart( - generator, + incentives, &IncentivesQueryMsg::PendingRewards { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), @@ -497,7 +497,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( .collect(); cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: generator.to_string(), + contract_addr: incentives.to_string(), funds: vec![], msg: to_json_binary(&IncentivesExecuteMsg::ClaimRewards { lp_tokens: vec![astroport_lp_token.to_string()], @@ -583,7 +583,7 @@ pub fn claim_airdrop_tokens_with_multiplier_msg( })) } -/// Updates contract state after dual staking rewards are claimed from the generator contract. Returns a default object of type [`Response`]. +/// Updates contract state after dual staking rewards are claimed from the incentives contract. Returns a default object of type [`Response`]. /// ## Params /// * **deps** is an object of type [`DepsMut`]. /// @@ -618,7 +618,7 @@ pub fn update_pool_on_dual_rewards_claim( .query_pool(&deps.querier, env.contract.address.clone())?; let received_amount = current_balance.checked_sub(prev_balance.amount)?; - pool_info.generator_rewards_per_share.update( + pool_info.incentives_rewards_per_share.update( &prev_balance.info, Decimal::from_ratio(received_amount, lp_balance), )?; @@ -628,7 +628,7 @@ pub fn update_pool_on_dual_rewards_claim( ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; Ok(Response::new().add_attributes(vec![ - attr("action", "update_generator_dual_rewards"), + attr("action", "update_incentives_dual_rewards"), attr("pool_type", format!("{:?}", pool_type)), ])) } @@ -702,7 +702,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( }; let mut pending_reward_assets: Vec = vec![]; - // If Astro LP tokens are staked with Astro generator + // If Astro LP tokens are staked with Astro incentives if pool_info.is_staked { // If this LP token is getting incentives // Calculate claimable staking rewards for this lockup @@ -714,19 +714,19 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( }, )?; for reward in pending_rewards { - let generator_rewards_per_share = pool_info - .generator_rewards_per_share + let incentives_rewards_per_share = pool_info + .incentives_rewards_per_share .load(&reward.info) .unwrap_or_default(); - if generator_rewards_per_share.is_zero() { + if incentives_rewards_per_share.is_zero() { continue; }; - let total_lockup_rewards = generator_rewards_per_share + let total_lockup_rewards = incentives_rewards_per_share .checked_mul(astroport_lp_amount.to_decimal())? .to_uint_floor(); let debt = lockup_info - .generator_debt + .incentives_debt .load(&reward.info) .unwrap_or_default(); let pending_reward = total_lockup_rewards.checked_sub(debt)?; @@ -739,7 +739,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( } lockup_info - .generator_debt + .incentives_debt .update(&reward.info, total_lockup_rewards.checked_sub(debt)?)?; } @@ -940,7 +940,7 @@ pub fn query_user_info(deps: Deps, env: Env, user: String) -> StdResult = Default::default(); + let mut claimable_incentives_debt: RestrictedVector = Default::default(); for pool_type in ASSET_POOLS .keys(deps.storage, None, None, Order::Ascending) .collect::, StdError>>()? @@ -953,8 +953,8 @@ pub fn query_user_info(deps: Deps, env: Env, user: String) -> StdResult StdResult; let astroport_lp_token_opt: Addr; - let mut claimable_generator_rewards_debt: RestrictedVector = + let mut claimable_incentives_rewards_debt: RestrictedVector = RestrictedVector::default(); if let Some(astroport_lp_transferred) = lockup_info.astroport_lp_transferred { lockup_astroport_lp_units_opt = Some(astroport_lp_transferred); @@ -1088,7 +1088,7 @@ pub fn query_lockup_info( let lockup_astroport_lp_units = { // Query Astro LP Tokens balance for the pool pool_astroport_lp_units = if pool_info.is_staked { - raw_generator_deposit( + raw_incentives_deposit( deps.querier, &config.incentives, astroport_lp_token.as_bytes(), @@ -1124,23 +1124,23 @@ pub fn query_lockup_info( // Calculate claimable staking rewards for this lockup for reward in pending_rewards { - let generator_rewards_per_share = pool_info.generator_rewards_per_share.update( + let incentives_rewards_per_share = pool_info.incentives_rewards_per_share.update( &reward.info, Decimal::from_ratio(reward.amount, pool_astroport_lp_units), )?; - let debt = generator_rewards_per_share + let debt = incentives_rewards_per_share .checked_mul_uint128(lockup_astroport_lp_units)? .checked_sub( lockup_info - .generator_debt + .incentives_debt .inner_ref() .iter() .find_map(|a| if reward.info == a.0 { Some(a.1) } else { None }) .unwrap_or_default(), )?; - claimable_generator_rewards_debt.update(&reward.info, debt)?; + claimable_incentives_rewards_debt.update(&reward.info, debt)?; } } } @@ -1162,8 +1162,8 @@ pub fn query_lockup_info( lp_units_locked: lockup_info.lp_units_locked, withdrawal_flag: lockup_info.withdrawal_flag, ntrn_rewards: lockup_info.ntrn_rewards, - generator_debt: lockup_info.generator_debt, - claimable_generator_debt: claimable_generator_rewards_debt, + incentives_debt: lockup_info.incentives_debt, + claimable_incentives_debt: claimable_incentives_rewards_debt, unlock_timestamp: lockup_info.unlock_timestamp, astroport_lp_units: lockup_astroport_lp_units_opt, astroport_lp_token: astroport_lp_token_opt, diff --git a/contracts/lockdrop-pcl/src/migration.rs b/contracts/lockdrop-pcl/src/migration.rs deleted file mode 100644 index 6c1544b1..00000000 --- a/contracts/lockdrop-pcl/src/migration.rs +++ /dev/null @@ -1,77 +0,0 @@ -use astroport::asset::AssetInfo; -use astroport::generator::{PoolInfoResponse, QueryMsg as GenQueryMsg}; -use astroport_periphery::lockdrop::MigrationInfo; -use cosmwasm_std::{Addr, Decimal, DepsMut, StdResult, Uint128, Uint256}; -use cw_storage_plus::Map; - -use crate::raw_queries::raw_proxy_asset; -use astroport::restricted_vector::RestrictedVector; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct PoolInfoV101 { - pub terraswap_pool: Addr, - pub terraswap_amount_in_lockups: Uint128, - pub migration_info: Option, - /// Share of total ASTRO incentives allocated to this pool - pub incentives_share: u64, - /// Weighted LP Token balance used to calculate ASTRO rewards a particular user can claim - pub weighted_amount: Uint256, - /// Ratio of Generator ASTRO rewards accured to astroport pool share - pub generator_astro_per_share: Decimal, - /// Ratio of Generator Proxy rewards accured to astroport pool share - pub generator_proxy_per_share: Decimal, - /// Boolean value indicating if the LP Tokens are staked with the Generator contract or not - pub is_staked: bool, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct PoolInfoV111 { - pub terraswap_pool: Addr, - pub terraswap_amount_in_lockups: Uint128, - pub migration_info: Option, - /// Share of total ASTRO incentives allocated to this pool - pub incentives_share: u64, - /// Weighted LP Token balance used to calculate ASTRO rewards a particular user can claim - pub weighted_amount: Uint256, - /// Ratio of Generator ASTRO rewards accured to astroport pool share - pub generator_astro_per_share: Decimal, - /// Ratio of Generator Proxy rewards accured to astroport pool share - pub generator_proxy_per_share: Decimal, - /// Boolean value indicating if the LP Tokens are staked with the Generator contract or not - pub is_staked: bool, - /// Flag defines whether the asset has rewards or not - pub has_asset_rewards: bool, -} - -pub const ASSET_POOLS_V101: Map<&Addr, PoolInfoV101> = Map::new("LiquidityPools"); -pub const ASSET_POOLS_V111: Map<&Addr, PoolInfoV111> = Map::new("LiquidityPools"); - -pub fn migrate_generator_proxy_per_share_to_v120( - deps: &DepsMut, - generator_proxy_per_share_old: Decimal, - generator: &Addr, - migration_info: Option, -) -> StdResult> { - let mut generator_proxy_per_share = RestrictedVector::default(); - if !generator_proxy_per_share_old.is_zero() { - let pool_info: PoolInfoResponse = deps.querier.query_wasm_smart( - generator, - &GenQueryMsg::PoolInfo { - lp_token: migration_info - .expect("Should be migrated!") - .astroport_lp_token - .to_string(), - }, - )?; - let (proxy, _) = pool_info - .accumulated_proxy_rewards_per_share - .first() - .expect("Proxy reward should be set!"); - let reward_asset = raw_proxy_asset(deps.querier, generator, proxy.as_bytes())?; - generator_proxy_per_share.update(&reward_asset, generator_proxy_per_share_old)?; - } - - Ok(generator_proxy_per_share) -} diff --git a/contracts/lockdrop-pcl/src/raw_queries.rs b/contracts/lockdrop-pcl/src/raw_queries.rs index fa8ead99..8a7cfa7a 100644 --- a/contracts/lockdrop-pcl/src/raw_queries.rs +++ b/contracts/lockdrop-pcl/src/raw_queries.rs @@ -3,10 +3,10 @@ use cosmwasm_std::{from_json, Addr, Empty, QuerierWrapper, StdError, StdResult, use cw_storage_plus::Path; use serde::Deserialize; -/// Returns generator deposit of tokens for the specified address -pub fn raw_generator_deposit( +/// Returns incentives deposit of tokens for the specified address +pub fn raw_incentives_deposit( querier: QuerierWrapper, - generator: &Addr, + incentives: &Addr, lp_token: &[u8], address: &[u8], ) -> StdResult { @@ -16,7 +16,7 @@ pub fn raw_generator_deposit( } let key: Path = Path::new(b"user_info", &[lp_token, address]); - if let Some(res) = &querier.query_wasm_raw(generator, key.to_vec())? { + if let Some(res) = &querier.query_wasm_raw(incentives, key.to_vec())? { let UserInfo { amount } = from_json(res)?; Ok(amount) } else { @@ -35,14 +35,14 @@ pub fn raw_balance(querier: QuerierWrapper, token: &Addr, address: &[u8]) -> Std } } -/// Returns AssetInfo for the specified proxy address from generator storage +/// Returns AssetInfo for the specified proxy address from incentives storage pub fn raw_proxy_asset( querier: QuerierWrapper, - generator: &Addr, + incentives: &Addr, address: &[u8], ) -> StdResult { let key: Path = Path::new(b"proxy_reward_asset", &[address]); - if let Some(res) = &querier.query_wasm_raw(generator, key.to_vec())? { + if let Some(res) = &querier.query_wasm_raw(incentives, key.to_vec())? { let res: AssetInfo = from_json(res)?; return Ok(res); } diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 42f2a13c..001d8dd7 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -88,8 +88,8 @@ pub struct InstantiateMsg { pub credits_contract: String, /// Auction contract address pub auction_contract: String, - /// Generator (Staking for dual rewards) contract address - pub generator: String, + /// Incentives (Staking for dual rewards) contract address + pub incentives: String, /// Describes rewards coefficients for each lockup duration pub lockup_rewards_info: Vec, /// Address of the LP token of the NTRN/USDC PCL pool @@ -118,8 +118,8 @@ pub struct InstantiateMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct UpdateConfigMsg { - /// Generator (Staking for dual rewards) contract address - pub generator_address: Option, + /// incentives (Staking for dual rewards) contract address + pub incentives_address: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -196,7 +196,7 @@ pub enum CallbackMsg { /// The address of the LP token of the pool. lp_token: String, /// The amount of staked LP token the PCL lockdrop contract possesses of before liquidity - /// provision and staking to the generator. Used to calculate LP token amount received for + /// provision and staking to the incentives. Used to calculate LP token amount received for /// liquidity provision. staked_lp_token_amount: Uint128, /// The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo @@ -290,9 +290,9 @@ pub struct PoolInfo { pub incentives_share: Uint128, /// Weighted LP Token balance used to calculate NTRN rewards a particular user can claim pub weighted_amount: Uint256, - /// Ratio of Generator rewards accured to astroport pool share - pub generator_rewards_per_share: RestrictedVector, - /// Boolean value indicating if the LP Tokens are staked with the Generator contract or not + /// Ratio of incentives rewards accured to astroport pool share + pub incentives_rewards_per_share: RestrictedVector, + /// Boolean value indicating if the LP Tokens are staked with the incentives contract or not pub is_staked: bool, } @@ -325,8 +325,8 @@ pub struct LockupInfo { pub withdrawal_flag: bool, /// NTRN tokens received as rewards for participation in the lockdrop pub ntrn_rewards: Uint128, - /// Generator tokens lockup received as generator rewards - pub generator_debt: RestrictedVector, + /// incentives tokens lockup received as incentives rewards + pub incentives_debt: RestrictedVector, /// Timestamp beyond which this position can be unlocked pub unlock_timestamp: u64, } @@ -343,7 +343,7 @@ impl LockupInfo { astroport_lp_transferred: None, withdrawal_flag: i.withdrawal_flag, ntrn_rewards: i.ntrn_rewards, - generator_debt: Default::default(), + incentives_debt: Default::default(), unlock_timestamp: i.unlock_timestamp, } } @@ -365,8 +365,8 @@ pub struct UserInfoResponse { pub ntrn_transferred: bool, /// Lockup positions pub lockup_infos: Vec, - /// Tokens receivable as generator rewards that user can claim - pub claimable_generator_debt: RestrictedVector, + /// Tokens receivable as incentives rewards that user can claim + pub claimable_incentives_debt: RestrictedVector, /// Number of lockup positions the user is having pub lockup_positions_index: u32, } @@ -400,10 +400,10 @@ pub struct LockUpInfoResponse { /// NTRN tokens received as rewards for participation in the lockdrop pub ntrn_rewards: Uint128, pub duration: u64, - /// Generator tokens lockup received as generator rewards - pub generator_debt: RestrictedVector, - /// Tokens receivable as generator rewards that user can claim - pub claimable_generator_debt: RestrictedVector, + /// incentives tokens lockup received as incentives rewards + pub incentives_debt: RestrictedVector, + /// Tokens receivable as incentives rewards that user can claim + pub claimable_incentives_debt: RestrictedVector, /// Timestamp beyond which this position can be unlocked pub unlock_timestamp: u64, /// User's Astroport LP units, calculated as lp_units_locked (terraswap) / total LP units locked (terraswap) * Astroport LP units minted post migration From 5b9b1a4b72fbeef18f9efa059a04fd8c194c161c Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 22 Feb 2024 21:23:20 +0200 Subject: [PATCH 12/28] remove is_staked variable from pool info state --- .../schema/neutron-lockdrop-pcl.json | 5 - .../schema/raw/response_to_pool.json | 5 - contracts/lockdrop-pcl/src/contract.rs | 268 ++++++++---------- .../astroport_periphery/src/lockdrop_pcl.rs | 2 - 4 files changed, 126 insertions(+), 154 deletions(-) diff --git a/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json index 4056bb08..874d7e53 100644 --- a/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json +++ b/contracts/lockdrop-pcl/schema/neutron-lockdrop-pcl.json @@ -1163,7 +1163,6 @@ "amount_in_lockups", "incentives_rewards_per_share", "incentives_share", - "is_staked", "lp_token", "weighted_amount" ], @@ -1187,10 +1186,6 @@ } ] }, - "is_staked": { - "description": "Boolean value indicating if the LP Tokens are staked with the incentives contract or not", - "type": "boolean" - }, "lp_token": { "$ref": "#/definitions/Addr" }, diff --git a/contracts/lockdrop-pcl/schema/raw/response_to_pool.json b/contracts/lockdrop-pcl/schema/raw/response_to_pool.json index fee1dab9..c2cb8470 100644 --- a/contracts/lockdrop-pcl/schema/raw/response_to_pool.json +++ b/contracts/lockdrop-pcl/schema/raw/response_to_pool.json @@ -6,7 +6,6 @@ "amount_in_lockups", "incentives_rewards_per_share", "incentives_share", - "is_staked", "lp_token", "weighted_amount" ], @@ -30,10 +29,6 @@ } ] }, - "is_staked": { - "description": "Boolean value indicating if the LP Tokens are staked with the incentives contract or not", - "type": "boolean" - }, "lp_token": { "$ref": "#/definitions/Addr" }, diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 1d19658b..aa8b0cb1 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -5,30 +5,30 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; +use astroport::DecimalCheckedOps; use astroport::incentives::{ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg}; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; -use astroport::DecimalCheckedOps; -use astroport_periphery::utils::Decimal256CheckedOps; use cosmwasm_std::{ - attr, coins, entry_point, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, - Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, + Addr, attr, BankMsg, Binary, coins, CosmosMsg, Decimal, Decimal256, Deps, + DepsMut, Empty, entry_point, Env, MessageInfo, Order, Response, StdError, StdResult, to_json_binary, Uint128, Uint256, WasmMsg, }; -use cw2::set_contract_version; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; +use cw2::set_contract_version; -use crate::raw_queries::{raw_balance, raw_incentives_deposit}; use astroport_periphery::lockdrop::{ LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, UserInfo as LockdropXYKUserInfo, }; use astroport_periphery::lockdrop_pcl::{ - CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, - LockupInfo, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockupInfo, LockUpInfoResponse, + LockUpInfoSummary, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfo, UserInfoResponse, UserInfoWithListResponse, }; +use astroport_periphery::utils::Decimal256CheckedOps; +use crate::raw_queries::raw_incentives_deposit; use crate::state::{ ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, STATE, TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, @@ -86,7 +86,6 @@ pub fn instantiate( incentives_share: msg.atom_incentives_share, weighted_amount: msg.atom_weighted_amount, incentives_rewards_per_share: RestrictedVector::default(), - is_staked: true, }; ASSET_POOLS.save(deps.storage, PoolType::ATOM, &pool_info, env.block.height)?; @@ -97,7 +96,6 @@ pub fn instantiate( incentives_share: msg.usdc_incentives_share, weighted_amount: msg.usdc_weighted_amount, incentives_rewards_per_share: RestrictedVector::default(), - is_staked: true, }; ASSET_POOLS.save(deps.storage, PoolType::USDC, &pool_info, env.block.height)?; @@ -147,7 +145,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S Ok(()) }) } - ExecuteMsg::UpdateConfig { new_config } => handle_update_config(deps, info, new_config), + ExecuteMsg::UpdateConfig { new_config } => handle_update_config(deps, env, info, new_config), ExecuteMsg::MigrateXYKLiquidity { pool_type, user_address_raw, @@ -273,6 +271,7 @@ pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult StdResult { @@ -291,9 +290,18 @@ pub fn handle_update_config( .collect::, StdError>>()? { let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - if pool_info.is_staked { + + let staked_lp_token_amount = deps.querier.query_wasm_smart::( + config.incentives.to_string(), + &IncentivesQueryMsg::Deposit { + lp_token: pool_info.lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; + + if !staked_lp_token_amount.is_zero() { return Err(StdError::generic_err(format!( - "{:?} astro LP tokens already staked. Unstake them before updating incentives", + "{:?} astro LP tokens already staked. Unstake them before updating generator", pool_type ))); } @@ -392,7 +400,7 @@ pub fn handle_migrate_xyk_liquidity( user_info, lockup_info, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(cosmos_msgs)) @@ -464,56 +472,51 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let mut cosmos_msgs = vec![]; let astroport_lp_token = pool_info.lp_token; + let incentives = &config.incentives; - if pool_info.is_staked { - let incentives = &config.incentives; - - // QUERY :: Check if there are any pending staking rewards - let pending_rewards_response: Vec = deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::PendingRewards { - lp_token: astroport_lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; + // QUERY :: Check if there are any pending staking rewards + let pending_rewards_response: Vec = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::PendingRewards { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; - if pending_rewards_response + if pending_rewards_response + .iter() + .any(|asset| !asset.amount.is_zero()) + { + let prev_pending_rewards_balances: Vec = pending_rewards_response .iter() - .any(|asset| !asset.amount.is_zero()) - { - let prev_pending_rewards_balances: Vec = pending_rewards_response - .iter() - .map(|asset| { - let balance = asset - .info - .query_pool(&deps.querier, env.contract.address.clone()) - .unwrap_or_default(); - - Asset { - info: asset.info.clone(), - amount: balance, - } - }) - .collect(); - - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: incentives.to_string(), - funds: vec![], - msg: to_json_binary(&IncentivesExecuteMsg::ClaimRewards { - lp_tokens: vec![astroport_lp_token.to_string()], - })?, - })); - - cosmos_msgs.push( - CallbackMsg::UpdatePoolOnDualRewardsClaim { - pool_type, - prev_reward_balances: prev_pending_rewards_balances, + .map(|asset| { + let balance = asset + .info + .query_pool(&deps.querier, env.contract.address.clone()) + .unwrap_or_default(); + + Asset { + info: asset.info.clone(), + amount: balance, } + }) + .collect(); + + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: incentives.to_string(), + funds: vec![], + msg: to_json_binary(&IncentivesExecuteMsg::ClaimRewards { + lp_tokens: vec![astroport_lp_token.to_string()], + })?, + })); + + cosmos_msgs.push( + CallbackMsg::UpdatePoolOnDualRewardsClaim { + pool_type, + prev_reward_balances: prev_pending_rewards_balances, + } .to_cosmos_msg(&env)?, - ); - } - } else if user_info.ntrn_transferred && !withdraw_lp_stake { - return Err(StdError::generic_err("No rewards available to claim!")); + ); } cosmos_msgs.push( @@ -523,7 +526,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( duration, withdraw_lp_stake, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -676,95 +679,83 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // Calculate Astro LP share for the lockup position let astroport_lp_amount: Uint128 = { - let balance: Uint128 = if pool_info.is_staked { + let balance: Uint128 = deps.querier.query_wasm_smart( incentives, &IncentivesQueryMsg::Deposit { lp_token: astroport_lp_token.to_string(), user: env.contract.address.to_string(), }, - )? - } else { - let res: BalanceResponse = deps.querier.query_wasm_smart( - astroport_lp_token.clone(), - &Cw20QueryMsg::Balance { - address: env.contract.address.to_string(), - }, )?; - res.balance - }; (lockup_info .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; let mut pending_reward_assets: Vec = vec![]; - // If Astro LP tokens are staked with Astro incentives - if pool_info.is_staked { - // If this LP token is getting incentives - // Calculate claimable staking rewards for this lockup - let pending_rewards: Vec = deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::PendingRewards { - lp_token: astroport_lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; - for reward in pending_rewards { - let incentives_rewards_per_share = pool_info - .incentives_rewards_per_share - .load(&reward.info) - .unwrap_or_default(); - if incentives_rewards_per_share.is_zero() { - continue; - }; - - let total_lockup_rewards = incentives_rewards_per_share - .checked_mul(astroport_lp_amount.to_decimal())? - .to_uint_floor(); - let debt = lockup_info - .incentives_debt - .load(&reward.info) - .unwrap_or_default(); - let pending_reward = total_lockup_rewards.checked_sub(debt)?; - - if !pending_reward.is_zero() { - pending_reward_assets.push(Asset { - info: reward.info.clone(), - amount: pending_reward, - }); - } + // If this LP token is getting incentives + // Calculate claimable staking rewards for this lockup + let pending_rewards: Vec = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::PendingRewards { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; + for reward in pending_rewards { + let incentives_rewards_per_share = pool_info + .incentives_rewards_per_share + .load(&reward.info) + .unwrap_or_default(); + if incentives_rewards_per_share.is_zero() { + continue; + }; - lockup_info - .incentives_debt - .update(&reward.info, total_lockup_rewards.checked_sub(debt)?)?; + let total_lockup_rewards = incentives_rewards_per_share + .checked_mul(astroport_lp_amount.to_decimal())? + .to_uint_floor(); + let debt = lockup_info + .incentives_debt + .load(&reward.info) + .unwrap_or_default(); + let pending_reward = total_lockup_rewards.checked_sub(debt)?; + + if !pending_reward.is_zero() { + pending_reward_assets.push(Asset { + info: reward.info.clone(), + amount: pending_reward, + }); } - // If this is a void transaction (no state change), then return error. - // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending rewards, not unlocking LP tokens in this tx - if !withdraw_lp_stake && user_info.ntrn_transferred && pending_reward_assets.is_empty() { - return Err(StdError::generic_err("No rewards available to claim!")); - } + lockup_info + .incentives_debt + .update(&reward.info, total_lockup_rewards.checked_sub(debt)?)?; + } - // If claimable staking rewards > 0, claim them - for pending_reward in pending_reward_assets { - cosmos_msgs.push(pending_reward.into_msg(user_address.clone())?); - } + // If this is a void transaction (no state change), then return error. + // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending rewards, not unlocking LP tokens in this tx + if !withdraw_lp_stake && user_info.ntrn_transferred && pending_reward_assets.is_empty() { + return Err(StdError::generic_err("No rewards available to claim!")); + } - // COSMOSMSG :: If LP Tokens are staked, we unstake the amount which needs to be returned to the user - if withdraw_lp_stake { - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: incentives.to_string(), - funds: vec![], - msg: to_json_binary(&IncentivesExecuteMsg::Withdraw { - lp_token: astroport_lp_token.to_string(), - amount: astroport_lp_amount, - })?, - })); - } + // If claimable staking rewards > 0, claim them + for pending_reward in pending_reward_assets { + cosmos_msgs.push(pending_reward.into_msg(user_address.clone())?); + } + + // COSMOSMSG :: If LP Tokens are staked, we unstake the amount which needs to be returned to the user + if withdraw_lp_stake { + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: incentives.to_string(), + funds: vec![], + msg: to_json_binary(&IncentivesExecuteMsg::Withdraw { + lp_token: astroport_lp_token.to_string(), + amount: astroport_lp_amount, + })?, + })); } if withdraw_lp_stake { @@ -1087,31 +1078,24 @@ pub fn query_lockup_info( let pool_astroport_lp_units; let lockup_astroport_lp_units = { // Query Astro LP Tokens balance for the pool - pool_astroport_lp_units = if pool_info.is_staked { + pool_astroport_lp_units = raw_incentives_deposit( deps.querier, &config.incentives, astroport_lp_token.as_bytes(), env.contract.address.as_bytes(), - )? - } else { - raw_balance( - deps.querier, - &astroport_lp_token, - env.contract.address.as_bytes(), - )? - }; + )?; // Calculate Lockup Astro LP shares (lockup_info .lp_units_locked .full_mul(pool_astroport_lp_units) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); - // If LP tokens are staked, calculate the rewards claimable by the user for this lockup position - if pool_info.is_staked && !lockup_astroport_lp_units.is_zero() { + // Calculate the rewards claimable by the user for this lockup position + if !lockup_astroport_lp_units.is_zero() { let incentives = &config.incentives; // QUERY :: Check if there are any pending staking rewards let pending_rewards: Vec = deps.querier.query_wasm_smart( @@ -1197,7 +1181,7 @@ pub fn calculate_astro_incentives_for_lockup( Uint256::from(pool_incentives_share).checked_mul(lockup_weighted_balance)?, Uint256::from(total_incentives_share).checked_mul(total_weighted_amount)?, ) - .checked_mul_uint256(total_lockdrop_incentives.into())?) + .checked_mul_uint256(total_lockdrop_incentives.into())?) } } diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 001d8dd7..72def852 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -292,8 +292,6 @@ pub struct PoolInfo { pub weighted_amount: Uint256, /// Ratio of incentives rewards accured to astroport pool share pub incentives_rewards_per_share: RestrictedVector, - /// Boolean value indicating if the LP Tokens are staked with the incentives contract or not - pub is_staked: bool, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] From da4591328bdf9765f2f11081e2805623b08f0894 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 22 Feb 2024 21:30:52 +0200 Subject: [PATCH 13/28] format --- contracts/lockdrop-pcl/src/contract.rs | 56 +++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index aa8b0cb1..4581dab1 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -5,25 +5,25 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; -use astroport::DecimalCheckedOps; use astroport::incentives::{ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg}; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; +use astroport::DecimalCheckedOps; use cosmwasm_std::{ - Addr, attr, BankMsg, Binary, coins, CosmosMsg, Decimal, Decimal256, Deps, - DepsMut, Empty, entry_point, Env, MessageInfo, Order, Response, StdError, StdResult, to_json_binary, + attr, coins, entry_point, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, + Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, Uint256, WasmMsg, }; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use cw2::set_contract_version; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use astroport_periphery::lockdrop::{ LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, UserInfo as LockdropXYKUserInfo, }; use astroport_periphery::lockdrop_pcl::{ - CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockupInfo, LockUpInfoResponse, - LockUpInfoSummary, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, + LockupInfo, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfo, UserInfoResponse, UserInfoWithListResponse, }; use astroport_periphery::utils::Decimal256CheckedOps; @@ -145,7 +145,9 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S Ok(()) }) } - ExecuteMsg::UpdateConfig { new_config } => handle_update_config(deps, env, info, new_config), + ExecuteMsg::UpdateConfig { new_config } => { + handle_update_config(deps, env, info, new_config) + } ExecuteMsg::MigrateXYKLiquidity { pool_type, user_address_raw, @@ -400,7 +402,7 @@ pub fn handle_migrate_xyk_liquidity( user_info, lockup_info, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(cosmos_msgs)) @@ -515,7 +517,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( pool_type, prev_reward_balances: prev_pending_rewards_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } @@ -526,7 +528,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( duration, withdraw_lp_stake, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -679,20 +681,19 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // Calculate Astro LP share for the lockup position let astroport_lp_amount: Uint128 = { - let balance: Uint128 = - deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::Deposit { - lp_token: astroport_lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; + let balance: Uint128 = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::Deposit { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; (lockup_info .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; let mut pending_reward_assets: Vec = vec![]; @@ -1078,19 +1079,18 @@ pub fn query_lockup_info( let pool_astroport_lp_units; let lockup_astroport_lp_units = { // Query Astro LP Tokens balance for the pool - pool_astroport_lp_units = - raw_incentives_deposit( - deps.querier, - &config.incentives, - astroport_lp_token.as_bytes(), - env.contract.address.as_bytes(), - )?; + pool_astroport_lp_units = raw_incentives_deposit( + deps.querier, + &config.incentives, + astroport_lp_token.as_bytes(), + env.contract.address.as_bytes(), + )?; // Calculate Lockup Astro LP shares (lockup_info .lp_units_locked .full_mul(pool_astroport_lp_units) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); @@ -1181,7 +1181,7 @@ pub fn calculate_astro_incentives_for_lockup( Uint256::from(pool_incentives_share).checked_mul(lockup_weighted_balance)?, Uint256::from(total_incentives_share).checked_mul(total_weighted_amount)?, ) - .checked_mul_uint256(total_lockdrop_incentives.into())?) + .checked_mul_uint256(total_lockdrop_incentives.into())?) } } From a1927dc1c83a94023f6d09031dd435aef908b1e4 Mon Sep 17 00:00:00 2001 From: quasisamurai Date: Mon, 26 Feb 2024 13:01:50 -0300 Subject: [PATCH 14/28] commit all pcl changes --- Cargo.lock | 66 +- Cargo.toml | 2 + contracts/auction/README.md | 6 +- contracts/lockdrop/README.md | 34 +- contracts/vesting-lp-pcl/.cargo/config | 6 + contracts/vesting-lp-pcl/Cargo.toml | 29 + .../examples/vesting-lp-pcl_schema.rs | 12 + .../schema/neutron-lockdrop-pcl.json | 1655 +++++++++++++++++ .../vesting-lp-pcl/schema/raw/execute.json | 658 +++++++ .../schema/raw/instantiate.json | 92 + .../vesting-lp-pcl/schema/raw/migrate.json | 7 + .../vesting-lp-pcl/schema/raw/query.json | 290 +++ .../raw/response_to_available_amount.json | 6 + .../schema/raw/response_to_config.json | 128 ++ .../raw/response_to_historical_extension.json | 59 + .../raw/response_to_managed_extension.json | 6 + .../schema/raw/response_to_timestamp.json | 7 + .../raw/response_to_vesting_account.json | 119 ++ .../raw/response_to_vesting_accounts.json | 136 ++ .../schema/raw/response_to_vesting_state.json | 35 + .../response_to_with_managers_extension.json | 21 + .../vesting-lp-pcl/schema/vesting-lp-pcl.json | 1391 ++++++++++++++ contracts/vesting-lp-pcl/src/contract.rs | 177 ++ contracts/vesting-lp-pcl/src/lib.rs | 3 + contracts/vesting-lp-pcl/src/msg.rs | 110 ++ contracts/vesting-lp-pcl/src/state.rs | 3 + contracts/vesting-lp/.cargo/config | 2 +- contracts/vesting-lp/Cargo.toml | 19 +- .../vesting-lp/examples/vesting-lp_schema.rs | 4 +- contracts/vesting-lp/schema/raw/execute.json | 588 ++++-- contracts/vesting-lp/schema/raw/migrate.json | 40 +- contracts/vesting-lp/schema/vesting-lp.json | 628 +++++-- contracts/vesting-lp/src/contract.rs | 399 +++- contracts/vesting-lp/src/lib.rs | 6 +- contracts/vesting-lp/src/msg.rs | 133 ++ contracts/vesting-lp/src/state.rs | 20 + packages/vesting-base/Cargo.toml | 4 +- packages/vesting-base/src/error.rs | 3 + packages/vesting-base/src/handlers.rs | 6 +- packages/vesting-base/src/state.rs | 8 +- packages/vesting-base/src/types.rs | 9 + 41 files changed, 6492 insertions(+), 435 deletions(-) create mode 100644 contracts/vesting-lp-pcl/.cargo/config create mode 100644 contracts/vesting-lp-pcl/Cargo.toml create mode 100644 contracts/vesting-lp-pcl/examples/vesting-lp-pcl_schema.rs create mode 100644 contracts/vesting-lp-pcl/schema/neutron-lockdrop-pcl.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/execute.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/instantiate.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/migrate.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/query.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_available_amount.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_config.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_historical_extension.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_managed_extension.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_timestamp.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_vesting_account.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_vesting_accounts.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_vesting_state.json create mode 100644 contracts/vesting-lp-pcl/schema/raw/response_to_with_managers_extension.json create mode 100644 contracts/vesting-lp-pcl/schema/vesting-lp-pcl.json create mode 100644 contracts/vesting-lp-pcl/src/contract.rs create mode 100644 contracts/vesting-lp-pcl/src/lib.rs create mode 100644 contracts/vesting-lp-pcl/src/msg.rs create mode 100644 contracts/vesting-lp-pcl/src/state.rs create mode 100644 contracts/vesting-lp/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index 4aee2278..1eb2066d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,7 +115,7 @@ dependencies = [ "astroport-token", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.16.5", "cw-storage-plus 1.2.0", "cw2 1.1.2", "cw20 1.1.2", @@ -456,6 +456,25 @@ dependencies = [ "obi", ] +[[package]] +name = "cw-multi-test" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8e81b4a7821d5eeba0d23f737c16027b39a600742ca8c32eb980895ffd270f4" +dependencies = [ + "anyhow", + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 0.15.1", + "cw-utils 0.15.1", + "derivative", + "itertools 0.10.5", + "prost", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "cw-multi-test" version = "0.16.5" @@ -682,7 +701,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "credits", - "cw-multi-test", + "cw-multi-test 0.16.5", "cw-storage-plus 1.2.0", "cw2 1.1.2", "cw20 1.1.2", @@ -1048,21 +1067,6 @@ dependencies = [ "serde", ] -[[package]] -name = "neutron-lockdrop-pcl" -version = "1.0.0" -dependencies = [ - "astroport 3.11.0", - "astroport-periphery", - "cosmwasm-schema", - "cosmwasm-std", - "credits", - "cw-storage-plus 0.15.1", - "cw2 1.1.2", - "cw20 1.1.2", - "serde", -] - [[package]] name = "neutron-price-feed" version = "0.1.0" @@ -1543,7 +1547,7 @@ dependencies = [ "cosmwasm-std", "cw-storage-plus 1.2.0", "cw-utils 0.15.1", - "cw20 1.1.2", + "cw20 0.15.1", "thiserror", ] @@ -1555,7 +1559,7 @@ dependencies = [ "astroport-token", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.16.5", "cw-utils 0.15.1", "cw2 1.1.2", "cw20 1.1.2", @@ -1570,10 +1574,28 @@ dependencies = [ "astroport-token", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.15.1", + "cw-storage-plus 0.15.1", + "cw-utils 0.15.1", + "cw2 0.15.1", + "cw20 0.15.1", + "vesting-base", + "vesting-lp-pcl", +] + +[[package]] +name = "vesting-lp-pcl" +version = "1.1.0" +dependencies = [ + "astroport 2.0.0", + "astroport-token", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test 0.16.5", + "cw-storage-plus 0.15.1", "cw-utils 0.15.1", "cw2 1.1.2", - "cw20 1.1.2", + "cw20 0.15.1", "vesting-base", ] @@ -1585,7 +1607,7 @@ dependencies = [ "astroport-token", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.16.5", "cw-utils 0.15.1", "cw2 1.1.2", "cw20 1.1.2", diff --git a/Cargo.toml b/Cargo.toml index 23499fe1..a0156b36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "contracts/lockdrop-pcl", "contracts/credits", "contracts/vesting-lp", + "contracts/vesting-lp-pcl", "contracts/vesting-lti", "contracts/vesting-investors", "contracts/cw20-merkle-airdrop", @@ -34,6 +35,7 @@ cosmwasm-schema = { version = "1.4.1", default-features = false } astroport = { path = "packages/astroport", default-features = false } astroport-periphery = { path = "packages/astroport_periphery" } vesting-base = { path = "packages/vesting-base" } +vesting-base-pcl = { path = "packages/vesting-base-pcl" } # setting cw-multi-test to 0.17.0 enables cosmwasm_1_1, we don't want that cw-multi-test = "0.16.5" itertools = "0.11.0" diff --git a/contracts/auction/README.md b/contracts/auction/README.md index c43ae90c..a4706ea5 100644 --- a/contracts/auction/README.md +++ b/contracts/auction/README.md @@ -20,7 +20,7 @@ The LP Bootstrap via auction contract facilitates cNTRN-NATIVE Neutron pool init ### Handle Messages | Message | Description | -| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `ExecuteMsg::Receive` | ReceiveCW20 Hook which facilitates cNTRN tokens delegation by lockdrop participants / airdrop recipients | | `ExecuteMsg::UpdateConfig` | Admin function to update any of the configuration parameters. | | `ExecuteMsg::DepositUst` | Facilitates UST deposits by users | @@ -32,7 +32,7 @@ The LP Bootstrap via auction contract facilitates cNTRN-NATIVE Neutron pool init ### Handle Messages :: Callback | Message | Description | -| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +|-----------------------------------------------------|------------------------------------------------------------------------------------------------------| | `CallbackMsg::UpdateStateOnLiquidityAdditionToPool` | Callback function to update state after liquidity is added to the cNTRN-UST Pool | | `CallbackMsg::UpdateStateOnRewardClaim` | Callback function to update state after cNTRN rewards are claimed from the generator | | `CallbackMsg::WithdrawUserRewardsCallback` | Callback function to facilitate cNTRN reward claiming and unlocked LP tokens withdrawal for the user | @@ -40,7 +40,7 @@ The LP Bootstrap via auction contract facilitates cNTRN-NATIVE Neutron pool init ### Query Messages | Message | Description | -| -------------------- | ----------------------------- | +|----------------------|-------------------------------| | `QueryMsg::Config` | Returns the config info | | `QueryMsg::State` | Returns state of the contract | | `QueryMsg::UserInfo` | Returns user position details | diff --git a/contracts/lockdrop/README.md b/contracts/lockdrop/README.md index 0bc572b1..ae990b11 100644 --- a/contracts/lockdrop/README.md +++ b/contracts/lockdrop/README.md @@ -10,24 +10,24 @@ Note - Users can open muliple lockup positions with different lockup duration fo ### Handle Messages -| Message | Description | -|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ExecuteMsg::UpdateConfig` | Can only be called by the admin. Facilitates updating configuration parameters | -| `ExecuteMsg::EnableClaims` | Executed by the Bootstrap auction contract when liquidity is added to the ASTRO-UST pool. Enables ASTRO withdrawals by the lockdrop recipients. | -| `ExecuteMsg::InitializePool` | Admin function. Facilitates addition of new Pool (Terraswap Pools) whose LP tokens can then be locked in the lockdrop contract | -| `ExecuteMsg::UpdatePool` | Admin function to update any configuraton parameter for a terraswap pool whose LP tokens are currently accepted for the lockdrop | -| `ExecuteMsg::IncreaseLockup` | Facilitates opening a new user position or adding to an existing position | -| `ExecuteMsg::IncreaseAstroIncentives` | Admin function to increase the ASTRO incentives that are to be distributed | +| Message | Description | +|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `ExecuteMsg::UpdateConfig` | Can only be called by the admin. Facilitates updating configuration parameters | +| `ExecuteMsg::EnableClaims` | Executed by the Bootstrap auction contract when liquidity is added to the ASTRO-UST pool. Enables ASTRO withdrawals by the lockdrop recipients. | +| `ExecuteMsg::InitializePool` | Admin function. Facilitates addition of new Pool (Terraswap Pools) whose LP tokens can then be locked in the lockdrop contract | +| `ExecuteMsg::UpdatePool` | Admin function to update any configuraton parameter for a terraswap pool whose LP tokens are currently accepted for the lockdrop | +| `ExecuteMsg::IncreaseLockup` | Facilitates opening a new user position or adding to an existing position | +| `ExecuteMsg::IncreaseAstroIncentives` | Admin function to increase the ASTRO incentives that are to be distributed | | `ExecuteMsg::WithdrawFromLockup` | Facilitates LP token withdrawals from lockup positions by users. 100% amount can be withdrawn during deposit window, which is then limited to 50% during 1st half of deposit window which then decreases linearly during 2nd half of deposit window. Only 1 withdrawal can be made by a user during the withdrawal windows | -| `ExecuteMsg::MigrateLiquidity` | Admin function. Facilitates migration of liquidity (locked terraswap LP tokens) from Terraswap to Astroport (Astroport LP tokens) | -| `ExecuteMsg::StakeLpTokens` | Admin function. Facilitates staking of Astroport LP tokens for a particular LP pool with the generator contract | -| `ExecuteMsg::DelegateAstroToAuction` | This function facilitates ASTRO tokens delegation to the Bootstrap auction contract during the bootstrap auction phase. Delegated ASTRO tokens are added to the user's position in the bootstrap auction contract | -| `ExecuteMsg::ClaimRewardsAndOptionallyUnlock` | Facilitates rewards claim by users for a particular lockup position along with unlock when possible | -| `ExecuteMsg::ClaimAssetReward` | Collects assets reward from LP and distribute reward to user if all requirements are met | -| `ExecuteMsg::TogglePoolRewards` | Admin function. Enables assets reward for specified LP | -| `ExecuteMsg::ProposeNewOwner` | Admin function. Creates an offer to change the contract ownership. The validity period of the offer is set in the `expires_in` variable. After `expires_in` seconds pass, the proposal expires and cannot be accepted anymore. | -| `ExecuteMsg::DropOwnershipProposal` | Admin function. Removes an existing offer to change the contract owner. | -| `ExecuteMsg::ClaimOwnership` | Admin function. Used to claim contract ownership. | +| `ExecuteMsg::MigrateLiquidity` | Admin function. Facilitates migration of liquidity (locked terraswap LP tokens) from Terraswap to Astroport (Astroport LP tokens) | +| `ExecuteMsg::StakeLpTokens` | Admin function. Facilitates staking of Astroport LP tokens for a particular LP pool with the generator contract | +| `ExecuteMsg::DelegateAstroToAuction` | This function facilitates ASTRO tokens delegation to the Bootstrap auction contract during the bootstrap auction phase. Delegated ASTRO tokens are added to the user's position in the bootstrap auction contract | +| `ExecuteMsg::ClaimRewardsAndOptionallyUnlock` | Facilitates rewards claim by users for a particular lockup position along with unlock when possible | +| `ExecuteMsg::ClaimAssetReward` | Collects assets reward from LP and distribute reward to user if all requirements are met | +| `ExecuteMsg::TogglePoolRewards` | Admin function. Enables assets reward for specified LP | +| `ExecuteMsg::ProposeNewOwner` | Admin function. Creates an offer to change the contract ownership. The validity period of the offer is set in the `expires_in` variable. After `expires_in` seconds pass, the proposal expires and cannot be accepted anymore. | +| `ExecuteMsg::DropOwnershipProposal` | Admin function. Removes an existing offer to change the contract owner. | +| `ExecuteMsg::ClaimOwnership` | Admin function. Used to claim contract ownership. | ### Handle Messages :: Callback diff --git a/contracts/vesting-lp-pcl/.cargo/config b/contracts/vesting-lp-pcl/.cargo/config new file mode 100644 index 00000000..f2fbc6a9 --- /dev/null +++ b/contracts/vesting-lp-pcl/.cargo/config @@ -0,0 +1,6 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +wasm-debug = "build --target wasm32-unknown-unknown" +unit-test = "test --lib" +integration-test = "test --test integration" +schema = "run --example vesting-lp_schema" diff --git a/contracts/vesting-lp-pcl/Cargo.toml b/contracts/vesting-lp-pcl/Cargo.toml new file mode 100644 index 00000000..43b07451 --- /dev/null +++ b/contracts/vesting-lp-pcl/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "vesting-lp-pcl" +version = "1.1.0" +authors = ["Neutron"] +edition = "2021" +description = "Vesting contract with a voting capabilities. Provides queries to get the amount of tokens are being held by user at certain height." + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all init/handle/query exports +library = [] + +[dependencies] +cw2 = { workspace = true } +cw20 = { version = "0.15" } +astroport = { path= "../../packages/astroport"} +vesting-base = {path = "../../packages/vesting-base"} +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +cw-storage-plus = "0.15" + +[dev-dependencies] +cw-multi-test = { workspace = true } +astroport-token = {git = "https://github.com/astroport-fi/astroport-core.git", rev = "65ce7d1879cc5d95b09fa14202f0423bba52ae0e" } +cw-utils = "0.15" diff --git a/contracts/vesting-lp-pcl/examples/vesting-lp-pcl_schema.rs b/contracts/vesting-lp-pcl/examples/vesting-lp-pcl_schema.rs new file mode 100644 index 00000000..186bbaf1 --- /dev/null +++ b/contracts/vesting-lp-pcl/examples/vesting-lp-pcl_schema.rs @@ -0,0 +1,12 @@ +use cosmwasm_schema::write_api; +use vesting_base::msg::{MigrateMsg, QueryMsg}; +use vesting_lp_pcl::msg::{ExecuteMsg, InstantiateMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg + } +} diff --git a/contracts/vesting-lp-pcl/schema/neutron-lockdrop-pcl.json b/contracts/vesting-lp-pcl/schema/neutron-lockdrop-pcl.json new file mode 100644 index 00000000..874d7e53 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/neutron-lockdrop-pcl.json @@ -0,0 +1,1655 @@ +{ + "contract_name": "neutron-lockdrop-pcl", + "contract_version": "1.0.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "atom_incentives_share", + "atom_token", + "atom_weighted_amount", + "auction_contract", + "credits_contract", + "incentives", + "lockdrop_incentives", + "lockup_rewards_info", + "usdc_incentives_share", + "usdc_token", + "usdc_weighted_amount", + "xyk_lockdrop_contract" + ], + "properties": { + "atom_incentives_share": { + "description": "Share of total NTRN incentives allocated to the NTRN/ATOM PCL pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "atom_token": { + "description": "Address of the LP token of the NTRN/ATOM PCL pool", + "type": "string" + }, + "atom_weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/ATOM pool depositor can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + }, + "auction_contract": { + "description": "Auction contract address", + "type": "string" + }, + "credits_contract": { + "description": "Credits contract address", + "type": "string" + }, + "incentives": { + "description": "Incentives (Staking for dual rewards) contract address", + "type": "string" + }, + "lockdrop_incentives": { + "description": "Total NTRN lockdrop incentives distributed among the users.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "lockup_rewards_info": { + "description": "Describes rewards coefficients for each lockup duration", + "type": "array", + "items": { + "$ref": "#/definitions/LockupRewardsInfo" + } + }, + "owner": { + "description": "Account which can update config", + "type": [ + "string", + "null" + ] + }, + "usdc_incentives_share": { + "description": "Share of total NTRN incentives allocated to the NTRN/USDC PCL pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "usdc_token": { + "description": "Address of the LP token of the NTRN/USDC PCL pool", + "type": "string" + }, + "usdc_weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular NTRN/USDC pool depositor can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + }, + "xyk_lockdrop_contract": { + "description": "Original XYK lockdrop contract address", + "type": "string" + } + }, + "definitions": { + "Decimal256": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal256(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 115792089237316195423570985008687907853269984665640564039457.584007913129639935 (which is (2^256 - 1) / 10^18)", + "type": "string" + }, + "LockupRewardsInfo": { + "type": "object", + "required": [ + "coefficient", + "duration" + ], + "properties": { + "coefficient": { + "$ref": "#/definitions/Decimal256" + }, + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint256": { + "description": "An implementation of u256 that is using strings for JSON encoding/decoding, such that the full u256 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances out of primitive uint types or `new` to provide big endian bytes:\n\n``` # use cosmwasm_std::Uint256; let a = Uint256::from(258u128); let b = Uint256::new([ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, ]); assert_eq!(a, b); ```", + "type": "string" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "update_config" + ], + "properties": { + "update_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/UpdateConfigMsg" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "claim_rewards_and_optionally_unlock" + ], + "properties": { + "claim_rewards_and_optionally_unlock": { + "type": "object", + "required": [ + "duration", + "pool_type", + "withdraw_lp_stake" + ], + "properties": { + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + }, + "withdraw_lp_stake": { + "type": "boolean" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Callbacks; only callable by the contract itself.", + "type": "object", + "required": [ + "callback" + ], + "properties": { + "callback": { + "$ref": "#/definitions/CallbackMsg" + } + }, + "additionalProperties": false + }, + { + "description": "ProposeNewOwner creates a proposal to change contract ownership. The validity period for the proposal is set in the `expires_in` variable.", + "type": "object", + "required": [ + "propose_new_owner" + ], + "properties": { + "propose_new_owner": { + "type": "object", + "required": [ + "expires_in", + "owner" + ], + "properties": { + "expires_in": { + "description": "The date after which this proposal expires", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "description": "Newly proposed contract owner", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "DropOwnershipProposal removes the existing offer to change contract ownership.", + "type": "object", + "required": [ + "drop_ownership_proposal" + ], + "properties": { + "drop_ownership_proposal": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "description": "Used to claim contract ownership.", + "type": "object", + "required": [ + "claim_ownership" + ], + "properties": { + "claim_ownership": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "description": "A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable by the original lockdrop contract. Expects two **Coin**s to be attached as funds.", + "type": "object", + "required": [ + "migrate_xyk_liquidity" + ], + "properties": { + "migrate_xyk_liquidity": { + "type": "object", + "required": [ + "duration", + "lockup_info", + "pool_type", + "user_address_raw", + "user_info" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/LockupInfoV2" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType2" + } + ] + }, + "user_address_raw": { + "description": "The address of the user which owns the lockup.", + "type": "string" + }, + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/UserInfo" + } + ] + } + } + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Asset": { + "description": "This enum describes a Terra asset (native or CW20).", + "type": "object", + "required": [ + "amount", + "info" + ], + "properties": { + "amount": { + "description": "A token amount", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "info": { + "description": "Information about an asset stored in a [`AssetInfo`] struct", + "allOf": [ + { + "$ref": "#/definitions/AssetInfo" + } + ] + } + }, + "additionalProperties": false + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "CallbackMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "update_pool_on_dual_rewards_claim" + ], + "properties": { + "update_pool_on_dual_rewards_claim": { + "type": "object", + "required": [ + "pool_type", + "prev_reward_balances" + ], + "properties": { + "pool_type": { + "$ref": "#/definitions/PoolType" + }, + "prev_reward_balances": { + "type": "array", + "items": { + "$ref": "#/definitions/Asset" + } + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_user_lockup_rewards_callback" + ], + "properties": { + "withdraw_user_lockup_rewards_callback": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address", + "withdraw_lp_stake" + ], + "properties": { + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + }, + "user_address": { + "$ref": "#/definitions/Addr" + }, + "withdraw_lp_stake": { + "type": "boolean" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Completes the liquidity migration process by making all necessary state updates for the lockup position.", + "type": "object", + "required": [ + "finish_lockup_migration_callback" + ], + "properties": { + "finish_lockup_migration_callback": { + "type": "object", + "required": [ + "duration", + "lockup_info", + "lp_token", + "pool_type", + "staked_lp_token_amount", + "user_address", + "user_info" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/LockupInfoV2" + } + ] + }, + "lp_token": { + "description": "The address of the LP token of the pool.", + "type": "string" + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "staked_lp_token_amount": { + "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the incentives. Used to calculate LP token amount received for liquidity provision.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/UserInfo" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "LockupInfoV2": { + "type": "object", + "required": [ + "generator_ntrn_debt", + "generator_proxy_debt", + "lp_units_locked", + "ntrn_rewards", + "unlock_timestamp", + "withdrawal_flag" + ], + "properties": { + "astroport_lp_transferred": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "generator_ntrn_debt": { + "description": "Generator NTRN tokens loockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "generator_proxy_debt": { + "description": "Generator Proxy tokens lockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "lp_units_locked": { + "description": "Terraswap LP units locked by the user", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "ntrn_rewards": { + "description": "NTRN tokens received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "unlock_timestamp": { + "description": "Timestamp beyond which this position can be unlocked", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "withdrawal_flag": { + "description": "Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff", + "type": "boolean" + } + } + }, + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "PoolType2": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "RestrictedVector_for_AssetInfo_and_Uint128": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "UpdateConfigMsg": { + "type": "object", + "properties": { + "incentives_address": { + "description": "incentives (Staking for dual rewards) contract address", + "type": [ + "string", + "null" + ] + } + } + }, + "UserInfo": { + "type": "object", + "required": [ + "lockup_positions_index", + "ntrn_transferred", + "total_ntrn_rewards" + ], + "properties": { + "lockup_positions_index": { + "description": "Number of lockup positions the user is having", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "ntrn_transferred": { + "description": "NTRN tokens transferred to user", + "type": "boolean" + }, + "total_ntrn_rewards": { + "description": "Total NTRN tokens user received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + } + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "state" + ], + "properties": { + "state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "pool" + ], + "properties": { + "pool": { + "type": "object", + "required": [ + "pool_type" + ], + "properties": { + "pool_type": { + "$ref": "#/definitions/PoolType" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "user_info" + ], + "properties": { + "user_info": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "user_info_with_lockups_list" + ], + "properties": { + "user_info_with_lockups_list": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "lock_up_info" + ], + "properties": { + "lock_up_info": { + "type": "object", + "required": [ + "duration", + "pool_type", + "user_address" + ], + "properties": { + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + }, + "user_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "query_user_lockup_total_at_height" + ], + "properties": { + "query_user_lockup_total_at_height": { + "type": "object", + "required": [ + "height", + "pool_type", + "user_address" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + }, + "user_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "query_lockup_total_at_height" + ], + "properties": { + "query_lockup_total_at_height": { + "type": "object", + "required": [ + "height", + "pool_type" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + } + } + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object" + }, + "sudo": null, + "responses": { + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "type": "object", + "required": [ + "auction_contract", + "credits_contract", + "incentives", + "lockdrop_incentives", + "lockup_rewards_info", + "owner", + "xyk_lockdrop_contract" + ], + "properties": { + "auction_contract": { + "description": "Bootstrap Auction contract address", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "credits_contract": { + "description": "Credits contract address", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "incentives": { + "description": "Incentives contract address", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "lockdrop_incentives": { + "description": "Total NTRN lockdrop incentives to be distributed among the users", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "lockup_rewards_info": { + "description": "Describes rewards coefficients for each lockup duration", + "type": "array", + "items": { + "$ref": "#/definitions/LockupRewardsInfo" + } + }, + "owner": { + "description": "Account which can update the config", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "xyk_lockdrop_contract": { + "description": "Original XYK lockdrop contract address", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Decimal256": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal256(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 115792089237316195423570985008687907853269984665640564039457.584007913129639935 (which is (2^256 - 1) / 10^18)", + "type": "string" + }, + "LockupRewardsInfo": { + "type": "object", + "required": [ + "coefficient", + "duration" + ], + "properties": { + "coefficient": { + "$ref": "#/definitions/Decimal256" + }, + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "lock_up_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "LockUpInfoResponse", + "type": "object", + "required": [ + "astroport_lp_token", + "claimable_incentives_debt", + "duration", + "incentives_debt", + "lp_units_locked", + "ntrn_rewards", + "pool_type", + "unlock_timestamp", + "withdrawal_flag" + ], + "properties": { + "astroport_lp_token": { + "$ref": "#/definitions/Addr" + }, + "astroport_lp_transferred": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "astroport_lp_units": { + "description": "User's Astroport LP units, calculated as lp_units_locked (terraswap) / total LP units locked (terraswap) * Astroport LP units minted post migration", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "incentives_debt": { + "description": "incentives tokens lockup received as incentives rewards", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "lp_units_locked": { + "description": "Terraswap LP units locked by the user", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "ntrn_rewards": { + "description": "NTRN tokens received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "pool_type": { + "description": "Terraswap LP token", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "unlock_timestamp": { + "description": "Timestamp beyond which this position can be unlocked", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "withdrawal_flag": { + "description": "Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff", + "type": "boolean" + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "RestrictedVector_for_AssetInfo_and_Uint128": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "pool": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PoolInfo", + "type": "object", + "required": [ + "amount_in_lockups", + "incentives_rewards_per_share", + "incentives_share", + "lp_token", + "weighted_amount" + ], + "properties": { + "amount_in_lockups": { + "$ref": "#/definitions/Uint128" + }, + "incentives_rewards_per_share": { + "description": "Ratio of incentives rewards accured to astroport pool share", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Decimal" + } + ] + }, + "incentives_share": { + "description": "Share of total NTRN incentives allocated to this pool", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "lp_token": { + "$ref": "#/definitions/Addr" + }, + "weighted_amount": { + "description": "Weighted LP Token balance used to calculate NTRN rewards a particular user can claim", + "allOf": [ + { + "$ref": "#/definitions/Uint256" + } + ] + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "RestrictedVector_for_AssetInfo_and_Decimal": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Decimal" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint256": { + "description": "An implementation of u256 that is using strings for JSON encoding/decoding, such that the full u256 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances out of primitive uint types or `new` to provide big endian bytes:\n\n``` # use cosmwasm_std::Uint256; let a = Uint256::from(258u128); let b = Uint256::new([ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, ]); assert_eq!(a, b); ```", + "type": "string" + } + } + }, + "query_lockup_total_at_height": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Uint128", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ], + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "query_user_lockup_total_at_height": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Uint128", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ], + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "state": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StateResponse", + "type": "object", + "required": [ + "supported_pairs_list", + "total_incentives_share" + ], + "properties": { + "supported_pairs_list": { + "description": "Vector containing LP addresses for all the supported LP Pools", + "type": "array", + "items": { + "$ref": "#/definitions/PoolType" + } + }, + "total_incentives_share": { + "description": "Total NTRN incentives share", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "definitions": { + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "user_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "UserInfoResponse", + "type": "object", + "required": [ + "claimable_incentives_debt", + "lockup_infos", + "lockup_positions_index", + "ntrn_transferred", + "total_ntrn_rewards" + ], + "properties": { + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "lockup_infos": { + "description": "Lockup positions", + "type": "array", + "items": { + "$ref": "#/definitions/LockUpInfoResponse" + } + }, + "lockup_positions_index": { + "description": "Number of lockup positions the user is having", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "ntrn_transferred": { + "description": "NTRN tokens transferred to user", + "type": "boolean" + }, + "total_ntrn_rewards": { + "description": "Total NTRN tokens user received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "LockUpInfoResponse": { + "type": "object", + "required": [ + "astroport_lp_token", + "claimable_incentives_debt", + "duration", + "incentives_debt", + "lp_units_locked", + "ntrn_rewards", + "pool_type", + "unlock_timestamp", + "withdrawal_flag" + ], + "properties": { + "astroport_lp_token": { + "$ref": "#/definitions/Addr" + }, + "astroport_lp_transferred": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "astroport_lp_units": { + "description": "User's Astroport LP units, calculated as lp_units_locked (terraswap) / total LP units locked (terraswap) * Astroport LP units minted post migration", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "claimable_incentives_debt": { + "description": "Tokens receivable as incentives rewards that user can claim", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "incentives_debt": { + "description": "incentives tokens lockup received as incentives rewards", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "lp_units_locked": { + "description": "Terraswap LP units locked by the user", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "ntrn_rewards": { + "description": "NTRN tokens received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "pool_type": { + "description": "Terraswap LP token", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "unlock_timestamp": { + "description": "Timestamp beyond which this position can be unlocked", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "withdrawal_flag": { + "description": "Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff", + "type": "boolean" + } + } + }, + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "RestrictedVector_for_AssetInfo_and_Uint128": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "user_info_with_lockups_list": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "UserInfoWithListResponse", + "type": "object", + "required": [ + "lockup_infos", + "lockup_positions_index", + "ntrn_transferred", + "total_ntrn_rewards" + ], + "properties": { + "lockup_infos": { + "description": "Lockup positions", + "type": "array", + "items": { + "$ref": "#/definitions/LockUpInfoSummary" + } + }, + "lockup_positions_index": { + "description": "Number of lockup positions the user is having", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "ntrn_transferred": { + "description": "NTRN tokens transferred to user", + "type": "boolean" + }, + "total_ntrn_rewards": { + "description": "Total NTRN tokens user received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "definitions": { + "LockUpInfoSummary": { + "type": "object", + "required": [ + "duration", + "pool_type" + ], + "properties": { + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + } + } + }, + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/execute.json b/contracts/vesting-lp-pcl/schema/raw/execute.json new file mode 100644 index 00000000..eef7340b --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/execute.json @@ -0,0 +1,658 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "propose_new_owner" + ], + "properties": { + "propose_new_owner": { + "type": "object", + "required": [ + "expires_in", + "owner" + ], + "properties": { + "expires_in": { + "description": "The validity period of the offer to change the owner", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "description": "The newly proposed owner", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Removes a request to change contract ownership ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "drop_ownership_proposal" + ], + "properties": { + "drop_ownership_proposal": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claims contract ownership ## Executor Only the newly proposed owner can execute this", + "type": "object", + "required": [ + "claim_ownership" + ], + "properties": { + "claim_ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Sets vesting token ## Executor Only the current owner or token info manager can execute this", + "type": "object", + "required": [ + "set_vesting_token" + ], + "properties": { + "set_vesting_token": { + "type": "object", + "required": [ + "vesting_token" + ], + "properties": { + "vesting_token": { + "$ref": "#/definitions/AssetInfo" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the managed extension for vesting contracts.", + "type": "object", + "required": [ + "managed_extension" + ], + "properties": { + "managed_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgManaged" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the with_managers extension for vesting contracts.", + "type": "object", + "required": [ + "with_managers_extension" + ], + "properties": { + "with_managers_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgWithManagers" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the historical extension for vesting contracts.", + "type": "object", + "required": [ + "historical_extension" + ], + "properties": { + "historical_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgHistorical" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "receive" + ], + "properties": { + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable by the original lockdrop contract. Expects two **Coin**s to be attached as funds.", + "type": "object", + "required": [ + "migrate_xyk_liquidity" + ], + "properties": { + "migrate_xyk_liquidity": { + "type": "object", + "required": [ + "duration", + "lockup_info", + "pool_type", + "user_address_raw", + "user_info" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/LockupInfoV2" + } + ] + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType2" + } + ] + }, + "user_address_raw": { + "description": "The address of the user which owns the lockup.", + "type": "string" + }, + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/UserInfo" + } + ] + } + } + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "type": "object", + "required": [ + "amount", + "msg", + "sender" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ExecuteMsgHistorical": { + "description": "This structure describes the execute messages available in a historical vesting contract.", + "type": "string", + "enum": [] + }, + "ExecuteMsgManaged": { + "description": "This structure describes the execute messages available in a managed vesting contract.", + "CallbackMsg": { + "oneOf": [ + { + "description": "Removes vesting targets/accounts. ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "remove_vesting_accounts" + ], + "properties": { + "remove_vesting_accounts": { + "type": "object", + "required": [ + "clawback_account", + "vesting_accounts" + ], + "properties": { + "clawback_account": { + "description": "Specifies the account that will receive the funds taken from the vesting accounts.", + "type": "string" + }, + "vesting_accounts": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "ExecuteMsgWithManagers": { + "description": "This structure describes the execute messages available in a with_managers vesting contract.", + "oneOf": [ + { + "description": "Adds vesting managers ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "add_vesting_managers" + ], + "properties": { + "add_vesting_managers": { + "type": "object", + "required": [ + "managers" + ], + "properties": { + "duration": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "pool_type": { + "$ref": "#/definitions/PoolType" + }, + "user_address": { + "$ref": "#/definitions/Addr" + }, + "withdraw_lp_stake": { + "type": "boolean" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Completes the liquidity migration process by making all necessary state updates for the lockup position.", + "type": "object", + "required": [ + "finish_lockup_migration_callback" + ], + "properties": { + "finish_lockup_migration_callback": { + "type": "object", + "required": [ + "duration", + "lockup_info", + "lp_token", + "pool_type", + "staked_lp_token_amount", + "user_address", + "user_info" + ], + "properties": { + "duration": { + "description": "The duration of the lock period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "lockup_info": { + "description": "The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/LockupInfoV2" + } + ] + }, + "lp_token": { + "description": "The address of the LP token of the pool.", + "type": "string" + }, + "pool_type": { + "description": "The type of the pool the lockup is related to.", + "allOf": [ + { + "$ref": "#/definitions/PoolType" + } + ] + }, + "staked_lp_token_amount": { + "description": "The amount of staked LP token the PCL lockdrop contract possesses of before liquidity provision and staking to the incentives. Used to calculate LP token amount received for liquidity provision.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "user_address": { + "description": "The address of the user which owns the lockup.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "user_info": { + "description": "The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo entry on the PCL lockdrop contract's side.", + "allOf": [ + { + "$ref": "#/definitions/UserInfo" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "LockupInfoV2": { + "type": "object", + "required": [ + "generator_ntrn_debt", + "generator_proxy_debt", + "lp_units_locked", + "ntrn_rewards", + "unlock_timestamp", + "withdrawal_flag" + ], + "properties": { + "astroport_lp_transferred": { + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "generator_ntrn_debt": { + "description": "Generator NTRN tokens loockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "generator_proxy_debt": { + "description": "Generator Proxy tokens lockup received as generator rewards", + "allOf": [ + { + "$ref": "#/definitions/RestrictedVector_for_AssetInfo_and_Uint128" + } + ] + }, + "lp_units_locked": { + "description": "Terraswap LP units locked by the user", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "ntrn_rewards": { + "description": "NTRN tokens received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "unlock_timestamp": { + "description": "Timestamp beyond which this position can be unlocked", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "withdrawal_flag": { + "description": "Boolean value indicating if the user's has withdrawn funds post the only 1 withdrawal limit cutoff", + "type": "boolean" + } + } + }, + "PoolType": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "PoolType2": { + "type": "string", + "enum": [ + "USDC", + "ATOM" + ] + }, + "RestrictedVector_for_AssetInfo_and_Uint128": { + "description": "Vec wrapper for internal use. Some business logic relies on an order of this vector, thus it is forbidden to sort it or remove elements. New values can be added using .update() ONLY.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "$ref": "#/definitions/Uint128" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingAccount": { + "description": "This structure stores vesting information for a specific address that is getting tokens.", + "type": "object", + "required": [ + "address", + "schedules" + ], + "properties": { + "address": { + "description": "The address that is getting tokens", + "type": "string" + }, + "schedules": { + "description": "The vesting schedules targeted at the `address`", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, + "VestingSchedule": { + "description": "This structure stores parameters for a specific vesting schedule", + "type": "object", + "required": [ + "start_point" + ], + "properties": { + "end_point": { + "description": "The end point for the vesting schedule", + "anyOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + }, + { + "type": "null" + } + "incentives_address": { + "description": "incentives (Staking for dual rewards) contract address", + "type": [ + "string", + "null" + ] + } + } + }, + "UserInfo": { + "type": "object", + "required": [ + "lockup_positions_index", + "ntrn_transferred", + "total_ntrn_rewards" + ], + "properties": { + "lockup_positions_index": { + "description": "Number of lockup positions the user is having", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_point": { + "description": "The start date for the vesting schedule", + "allOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + } + "ntrn_transferred": { + "description": "NTRN tokens transferred to user", + "type": "boolean" + }, + "total_ntrn_rewards": { + "description": "Total NTRN tokens user received as rewards for participation in the lockdrop", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false + }, + "VestingSchedulePoint": { + "description": "This structure stores the parameters used to create a vesting schedule.", + "type": "object", + "required": [ + "amount", + "time" + ], + "properties": { + "amount": { + "description": "The amount of tokens being vested", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "time": { + "description": "The start time for the vesting schedule", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/instantiate.json b/contracts/vesting-lp-pcl/schema/raw/instantiate.json new file mode 100644 index 00000000..cf950c42 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/instantiate.json @@ -0,0 +1,92 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "This structure describes the parameters used for creating a contract.", + "type": "object", + "required": [ + "owner", + "token_info_manager", + "vesting_managers", + "vesting_token", + "xyk_vesting_lp_contract" + ], + "properties": { + "owner": { + "description": "Address allowed to change contract parameters", + "type": "string" + }, + "token_info_manager": { + "description": "Token info manager address", + "type": "string" + }, + "vesting_managers": { + "description": "Initial list of whitelisted vesting managers", + "type": "array", + "items": { + "type": "string" + } + }, + "vesting_token": { + "$ref": "#/definitions/AssetInfo" + }, + "xyk_vesting_lp_contract": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/migrate.json b/contracts/vesting-lp-pcl/schema/raw/migrate.json new file mode 100644 index 00000000..1b9dcecf --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/migrate.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "description": "This structure describes a migration message. We currently take no arguments for migrations.", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/vesting-lp-pcl/schema/raw/query.json b/contracts/vesting-lp-pcl/schema/raw/query.json new file mode 100644 index 00000000..64a0b398 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/query.json @@ -0,0 +1,290 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "description": "This structure describes the query messages available in a vesting contract.", + "oneOf": [ + { + "description": "Returns the configuration for the contract using a [`ConfigResponse`] object.", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns information about an address vesting tokens using a [`VestingAccountResponse`] object.", + "type": "object", + "required": [ + "vesting_account" + ], + "properties": { + "vesting_account": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns a list of addresses that are vesting tokens using a [`VestingAccountsResponse`] object.", + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "order_by": { + "anyOf": [ + { + "$ref": "#/definitions/OrderBy" + }, + { + "type": "null" + } + ] + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total unvested amount of tokens for a specific address.", + "type": "object", + "required": [ + "available_amount" + ], + "properties": { + "available_amount": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Timestamp returns the current timestamp", + "type": "object", + "required": [ + "timestamp" + ], + "properties": { + "timestamp": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "VestingState returns the current vesting state.", + "type": "object", + "required": [ + "vesting_state" + ], + "properties": { + "vesting_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the managed extension for vesting contracts.", + "type": "object", + "required": [ + "managed_extension" + ], + "properties": { + "managed_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/QueryMsgManaged" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the with_managers extension for vesting contracts.", + "type": "object", + "required": [ + "with_managers_extension" + ], + "properties": { + "with_managers_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/QueryMsgWithManagers" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the historical extension for vesting contracts.", + "type": "object", + "required": [ + "historical_extension" + ], + "properties": { + "historical_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/QueryMsgHistorical" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "OrderBy": { + "description": "This enum describes the types of sorting that can be applied to some piece of data", + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "QueryMsgHistorical": { + "description": "This structure describes the query messages available in a historical vesting contract.", + "oneOf": [ + { + "description": "Returns the total unclaimed amount of tokens for a specific address at certain height.", + "type": "object", + "required": [ + "unclaimed_amount_at_height" + ], + "properties": { + "unclaimed_amount_at_height": { + "type": "object", + "required": [ + "address", + "height" + ], + "properties": { + "address": { + "type": "string" + }, + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total unclaimed amount of tokens for all the users at certain height.", + "type": "object", + "required": [ + "unclaimed_total_amount_at_height" + ], + "properties": { + "unclaimed_total_amount_at_height": { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "QueryMsgManaged": { + "description": "This structure describes the query messages available in a managed vesting contract.", + "type": "string", + "enum": [] + }, + "QueryMsgWithManagers": { + "description": "This structure describes the query messages available in a with_managers vesting contract.", + "oneOf": [ + { + "description": "Returns list of vesting managers (the persons who are able to add/remove vesting schedules)", + "type": "object", + "required": [ + "vesting_managers" + ], + "properties": { + "vesting_managers": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_available_amount.json b/contracts/vesting-lp-pcl/schema/raw/response_to_available_amount.json new file mode 100644 index 00000000..25b73e8f --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_available_amount.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Uint128", + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_config.json b/contracts/vesting-lp-pcl/schema/raw/response_to_config.json new file mode 100644 index 00000000..de35d970 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_config.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "description": "This structure stores the main parameters for the generator vesting contract.", + "type": "object", + "required": [ + "extensions", + "owner", + "token_info_manager" + ], + "properties": { + "extensions": { + "description": "Contains extensions information of the contract", + "allOf": [ + { + "$ref": "#/definitions/Extensions" + } + ] + }, + "owner": { + "description": "Address that's allowed to change contract parameters", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "token_info_manager": { + "description": "Address that's allowed to change vesting token", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "vesting_token": { + "description": "[`AssetInfo`] of the vested token", + "anyOf": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Extensions": { + "description": "Contains extensions information for the contract.", + "type": "object", + "required": [ + "historical", + "managed", + "with_managers" + ], + "properties": { + "historical": { + "description": "Whether the historical extension is enabled for the contract.", + "type": "boolean" + }, + "managed": { + "description": "Whether the managed extension is enabled for the contract.", + "type": "boolean" + }, + "with_managers": { + "description": "Whether the with_managers extension is enabled for the contract.", + "type": "boolean" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_historical_extension.json b/contracts/vesting-lp-pcl/schema/raw/response_to_historical_extension.json new file mode 100644 index 00000000..83edad79 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_historical_extension.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsgHistorical", + "description": "This structure describes the query messages available in a historical vesting contract.", + "oneOf": [ + { + "description": "Returns the total unclaimed amount of tokens for a specific address at certain height.", + "type": "object", + "required": [ + "unclaimed_amount_at_height" + ], + "properties": { + "unclaimed_amount_at_height": { + "type": "object", + "required": [ + "address", + "height" + ], + "properties": { + "address": { + "type": "string" + }, + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total unclaimed amount of tokens for all the users at certain height.", + "type": "object", + "required": [ + "unclaimed_total_amount_at_height" + ], + "properties": { + "unclaimed_total_amount_at_height": { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_managed_extension.json b/contracts/vesting-lp-pcl/schema/raw/response_to_managed_extension.json new file mode 100644 index 00000000..a46573aa --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_managed_extension.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Binary", + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_timestamp.json b/contracts/vesting-lp-pcl/schema/raw/response_to_timestamp.json new file mode 100644 index 00000000..7b729a7b --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_timestamp.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint64", + "type": "integer", + "format": "uint64", + "minimum": 0.0 +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_account.json b/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_account.json new file mode 100644 index 00000000..b85fc3d3 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_account.json @@ -0,0 +1,119 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingAccountResponse", + "description": "This structure describes a custom struct used to return vesting data about a specific vesting target.", + "type": "object", + "required": [ + "address", + "info" + ], + "properties": { + "address": { + "description": "The address that's vesting tokens", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "info": { + "description": "Vesting information", + "allOf": [ + { + "$ref": "#/definitions/VestingInfo" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingInfo": { + "description": "This structure stores parameters for a batch of vesting schedules.", + "type": "object", + "required": [ + "released_amount", + "schedules" + ], + "properties": { + "released_amount": { + "description": "The total amount of vested tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "schedules": { + "description": "The vesting schedules", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, + "VestingSchedule": { + "description": "This structure stores parameters for a specific vesting schedule", + "type": "object", + "required": [ + "start_point" + ], + "properties": { + "end_point": { + "description": "The end point for the vesting schedule", + "anyOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + }, + { + "type": "null" + } + ] + }, + "start_point": { + "description": "The start date for the vesting schedule", + "allOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + } + ] + } + }, + "additionalProperties": false + }, + "VestingSchedulePoint": { + "description": "This structure stores the parameters used to create a vesting schedule.", + "type": "object", + "required": [ + "amount", + "time" + ], + "properties": { + "amount": { + "description": "The amount of tokens being vested", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "time": { + "description": "The start time for the vesting schedule", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_accounts.json b/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_accounts.json new file mode 100644 index 00000000..6d2af531 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_accounts.json @@ -0,0 +1,136 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingAccountsResponse", + "description": "This structure describes a custom struct used to return vesting data for multiple vesting targets.", + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "description": "A list of accounts that are vesting tokens", + "type": "array", + "items": { + "$ref": "#/definitions/VestingAccountResponse" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingAccountResponse": { + "description": "This structure describes a custom struct used to return vesting data about a specific vesting target.", + "type": "object", + "required": [ + "address", + "info" + ], + "properties": { + "address": { + "description": "The address that's vesting tokens", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "info": { + "description": "Vesting information", + "allOf": [ + { + "$ref": "#/definitions/VestingInfo" + } + ] + } + }, + "additionalProperties": false + }, + "VestingInfo": { + "description": "This structure stores parameters for a batch of vesting schedules.", + "type": "object", + "required": [ + "released_amount", + "schedules" + ], + "properties": { + "released_amount": { + "description": "The total amount of vested tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "schedules": { + "description": "The vesting schedules", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, + "VestingSchedule": { + "description": "This structure stores parameters for a specific vesting schedule", + "type": "object", + "required": [ + "start_point" + ], + "properties": { + "end_point": { + "description": "The end point for the vesting schedule", + "anyOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + }, + { + "type": "null" + } + ] + }, + "start_point": { + "description": "The start date for the vesting schedule", + "allOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + } + ] + } + }, + "additionalProperties": false + }, + "VestingSchedulePoint": { + "description": "This structure stores the parameters used to create a vesting schedule.", + "type": "object", + "required": [ + "amount", + "time" + ], + "properties": { + "amount": { + "description": "The amount of tokens being vested", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "time": { + "description": "The start time for the vesting schedule", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_state.json b/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_state.json new file mode 100644 index 00000000..b38701e4 --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_vesting_state.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingState", + "description": "This structure stores the accumulated vesting information for all addresses.", + "type": "object", + "required": [ + "total_granted", + "total_released" + ], + "properties": { + "total_granted": { + "description": "The total amount of tokens granted to the users", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "total_released": { + "description": "The total amount of tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting-lp-pcl/schema/raw/response_to_with_managers_extension.json b/contracts/vesting-lp-pcl/schema/raw/response_to_with_managers_extension.json new file mode 100644 index 00000000..bcacc2ac --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/raw/response_to_with_managers_extension.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsgWithManagers", + "description": "This structure describes the query messages available in a with_managers vesting contract.", + "oneOf": [ + { + "description": "Returns list of vesting managers (the persons who are able to add/remove vesting schedules)", + "type": "object", + "required": [ + "vesting_managers" + ], + "properties": { + "vesting_managers": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/vesting-lp-pcl/schema/vesting-lp-pcl.json b/contracts/vesting-lp-pcl/schema/vesting-lp-pcl.json new file mode 100644 index 00000000..d05a001f --- /dev/null +++ b/contracts/vesting-lp-pcl/schema/vesting-lp-pcl.json @@ -0,0 +1,1391 @@ +{ + "contract_name": "vesting-lp-pcl", + "contract_version": "1.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "This structure describes the parameters used for creating a contract.", + "type": "object", + "required": [ + "owner", + "token_info_manager", + "vesting_managers", + "vesting_token", + "xyk_vesting_lp_contract" + ], + "properties": { + "owner": { + "description": "Address allowed to change contract parameters", + "type": "string" + }, + "token_info_manager": { + "description": "Token info manager address", + "type": "string" + }, + "vesting_managers": { + "description": "Initial list of whitelisted vesting managers", + "type": "array", + "items": { + "type": "string" + } + }, + "vesting_token": { + "$ref": "#/definitions/AssetInfo" + }, + "xyk_vesting_lp_contract": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "claim" + ], + "properties": { + "claim": { + "type": "object", + "properties": { + "amount": { + "description": "The amount of tokens to claim", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "recipient": { + "description": "The address that receives the vested tokens", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "RegisterVestingAccounts registers vesting targets/accounts", + "type": "object", + "required": [ + "register_vesting_accounts" + ], + "properties": { + "register_vesting_accounts": { + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "type": "array", + "items": { + "$ref": "#/definitions/VestingAccount" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Creates a request to change contract ownership ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "propose_new_owner" + ], + "properties": { + "propose_new_owner": { + "type": "object", + "required": [ + "expires_in", + "owner" + ], + "properties": { + "expires_in": { + "description": "The validity period of the offer to change the owner", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "description": "The newly proposed owner", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Removes a request to change contract ownership ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "drop_ownership_proposal" + ], + "properties": { + "drop_ownership_proposal": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claims contract ownership ## Executor Only the newly proposed owner can execute this", + "type": "object", + "required": [ + "claim_ownership" + ], + "properties": { + "claim_ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Sets vesting token ## Executor Only the current owner or token info manager can execute this", + "type": "object", + "required": [ + "set_vesting_token" + ], + "properties": { + "set_vesting_token": { + "type": "object", + "required": [ + "vesting_token" + ], + "properties": { + "vesting_token": { + "$ref": "#/definitions/AssetInfo" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the managed extension for vesting contracts.", + "type": "object", + "required": [ + "managed_extension" + ], + "properties": { + "managed_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgManaged" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the with_managers extension for vesting contracts.", + "type": "object", + "required": [ + "with_managers_extension" + ], + "properties": { + "with_managers_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgWithManagers" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the historical extension for vesting contracts.", + "type": "object", + "required": [ + "historical_extension" + ], + "properties": { + "historical_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgHistorical" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "receive" + ], + "properties": { + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "type": "object", + "required": [ + "amount", + "msg", + "sender" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ExecuteMsgHistorical": { + "description": "This structure describes the execute messages available in a historical vesting contract.", + "type": "string", + "enum": [] + }, + "ExecuteMsgManaged": { + "description": "This structure describes the execute messages available in a managed vesting contract.", + "oneOf": [ + { + "description": "Removes vesting targets/accounts. ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "remove_vesting_accounts" + ], + "properties": { + "remove_vesting_accounts": { + "type": "object", + "required": [ + "clawback_account", + "vesting_accounts" + ], + "properties": { + "clawback_account": { + "description": "Specifies the account that will receive the funds taken from the vesting accounts.", + "type": "string" + }, + "vesting_accounts": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "ExecuteMsgWithManagers": { + "description": "This structure describes the execute messages available in a with_managers vesting contract.", + "oneOf": [ + { + "description": "Adds vesting managers ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "add_vesting_managers" + ], + "properties": { + "add_vesting_managers": { + "type": "object", + "required": [ + "managers" + ], + "properties": { + "managers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Removes vesting managers ## Executor Only the current owner can execute this", + "type": "object", + "required": [ + "remove_vesting_managers" + ], + "properties": { + "remove_vesting_managers": { + "type": "object", + "required": [ + "managers" + ], + "properties": { + "managers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingAccount": { + "description": "This structure stores vesting information for a specific address that is getting tokens.", + "type": "object", + "required": [ + "address", + "schedules" + ], + "properties": { + "address": { + "description": "The address that is getting tokens", + "type": "string" + }, + "schedules": { + "description": "The vesting schedules targeted at the `address`", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, + "VestingSchedule": { + "description": "This structure stores parameters for a specific vesting schedule", + "type": "object", + "required": [ + "start_point" + ], + "properties": { + "end_point": { + "description": "The end point for the vesting schedule", + "anyOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + }, + { + "type": "null" + } + ] + }, + "start_point": { + "description": "The start date for the vesting schedule", + "allOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + } + ] + } + }, + "additionalProperties": false + }, + "VestingSchedulePoint": { + "description": "This structure stores the parameters used to create a vesting schedule.", + "type": "object", + "required": [ + "amount", + "time" + ], + "properties": { + "amount": { + "description": "The amount of tokens being vested", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "time": { + "description": "The start time for the vesting schedule", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "description": "This structure describes the query messages available in a vesting contract.", + "oneOf": [ + { + "description": "Returns the configuration for the contract using a [`ConfigResponse`] object.", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns information about an address vesting tokens using a [`VestingAccountResponse`] object.", + "type": "object", + "required": [ + "vesting_account" + ], + "properties": { + "vesting_account": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns a list of addresses that are vesting tokens using a [`VestingAccountsResponse`] object.", + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "order_by": { + "anyOf": [ + { + "$ref": "#/definitions/OrderBy" + }, + { + "type": "null" + } + ] + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total unvested amount of tokens for a specific address.", + "type": "object", + "required": [ + "available_amount" + ], + "properties": { + "available_amount": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Timestamp returns the current timestamp", + "type": "object", + "required": [ + "timestamp" + ], + "properties": { + "timestamp": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "VestingState returns the current vesting state.", + "type": "object", + "required": [ + "vesting_state" + ], + "properties": { + "vesting_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the managed extension for vesting contracts.", + "type": "object", + "required": [ + "managed_extension" + ], + "properties": { + "managed_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/QueryMsgManaged" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the with_managers extension for vesting contracts.", + "type": "object", + "required": [ + "with_managers_extension" + ], + "properties": { + "with_managers_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/QueryMsgWithManagers" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Contains messages associated with the historical extension for vesting contracts.", + "type": "object", + "required": [ + "historical_extension" + ], + "properties": { + "historical_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/QueryMsgHistorical" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "OrderBy": { + "description": "This enum describes the types of sorting that can be applied to some piece of data", + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "QueryMsgHistorical": { + "description": "This structure describes the query messages available in a historical vesting contract.", + "oneOf": [ + { + "description": "Returns the total unclaimed amount of tokens for a specific address at certain height.", + "type": "object", + "required": [ + "unclaimed_amount_at_height" + ], + "properties": { + "unclaimed_amount_at_height": { + "type": "object", + "required": [ + "address", + "height" + ], + "properties": { + "address": { + "type": "string" + }, + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total unclaimed amount of tokens for all the users at certain height.", + "type": "object", + "required": [ + "unclaimed_total_amount_at_height" + ], + "properties": { + "unclaimed_total_amount_at_height": { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "QueryMsgManaged": { + "description": "This structure describes the query messages available in a managed vesting contract.", + "type": "string", + "enum": [] + }, + "QueryMsgWithManagers": { + "description": "This structure describes the query messages available in a with_managers vesting contract.", + "oneOf": [ + { + "description": "Returns list of vesting managers (the persons who are able to add/remove vesting schedules)", + "type": "object", + "required": [ + "vesting_managers" + ], + "properties": { + "vesting_managers": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "description": "This structure describes a migration message. We currently take no arguments for migrations.", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "available_amount": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Uint128", + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "description": "This structure stores the main parameters for the generator vesting contract.", + "type": "object", + "required": [ + "extensions", + "owner", + "token_info_manager" + ], + "properties": { + "extensions": { + "description": "Contains extensions information of the contract", + "allOf": [ + { + "$ref": "#/definitions/Extensions" + } + ] + }, + "owner": { + "description": "Address that's allowed to change contract parameters", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "token_info_manager": { + "description": "Address that's allowed to change vesting token", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "vesting_token": { + "description": "[`AssetInfo`] of the vested token", + "anyOf": [ + { + "$ref": "#/definitions/AssetInfo" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Native token", + "type": "object", + "required": [ + "native_token" + ], + "properties": { + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Extensions": { + "description": "Contains extensions information for the contract.", + "type": "object", + "required": [ + "historical", + "managed", + "with_managers" + ], + "properties": { + "historical": { + "description": "Whether the historical extension is enabled for the contract.", + "type": "boolean" + }, + "managed": { + "description": "Whether the managed extension is enabled for the contract.", + "type": "boolean" + }, + "with_managers": { + "description": "Whether the with_managers extension is enabled for the contract.", + "type": "boolean" + } + }, + "additionalProperties": false + } + } + }, + "historical_extension": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsgHistorical", + "description": "This structure describes the query messages available in a historical vesting contract.", + "oneOf": [ + { + "description": "Returns the total unclaimed amount of tokens for a specific address at certain height.", + "type": "object", + "required": [ + "unclaimed_amount_at_height" + ], + "properties": { + "unclaimed_amount_at_height": { + "type": "object", + "required": [ + "address", + "height" + ], + "properties": { + "address": { + "type": "string" + }, + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total unclaimed amount of tokens for all the users at certain height.", + "type": "object", + "required": [ + "unclaimed_total_amount_at_height" + ], + "properties": { + "unclaimed_total_amount_at_height": { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "managed_extension": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Binary", + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "timestamp": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint64", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vesting_account": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingAccountResponse", + "description": "This structure describes a custom struct used to return vesting data about a specific vesting target.", + "type": "object", + "required": [ + "address", + "info" + ], + "properties": { + "address": { + "description": "The address that's vesting tokens", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "info": { + "description": "Vesting information", + "allOf": [ + { + "$ref": "#/definitions/VestingInfo" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingInfo": { + "description": "This structure stores parameters for a batch of vesting schedules.", + "type": "object", + "required": [ + "released_amount", + "schedules" + ], + "properties": { + "released_amount": { + "description": "The total amount of vested tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "schedules": { + "description": "The vesting schedules", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, + "VestingSchedule": { + "description": "This structure stores parameters for a specific vesting schedule", + "type": "object", + "required": [ + "start_point" + ], + "properties": { + "end_point": { + "description": "The end point for the vesting schedule", + "anyOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + }, + { + "type": "null" + } + ] + }, + "start_point": { + "description": "The start date for the vesting schedule", + "allOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + } + ] + } + }, + "additionalProperties": false + }, + "VestingSchedulePoint": { + "description": "This structure stores the parameters used to create a vesting schedule.", + "type": "object", + "required": [ + "amount", + "time" + ], + "properties": { + "amount": { + "description": "The amount of tokens being vested", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "time": { + "description": "The start time for the vesting schedule", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "vesting_accounts": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingAccountsResponse", + "description": "This structure describes a custom struct used to return vesting data for multiple vesting targets.", + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "description": "A list of accounts that are vesting tokens", + "type": "array", + "items": { + "$ref": "#/definitions/VestingAccountResponse" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingAccountResponse": { + "description": "This structure describes a custom struct used to return vesting data about a specific vesting target.", + "type": "object", + "required": [ + "address", + "info" + ], + "properties": { + "address": { + "description": "The address that's vesting tokens", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "info": { + "description": "Vesting information", + "allOf": [ + { + "$ref": "#/definitions/VestingInfo" + } + ] + } + }, + "additionalProperties": false + }, + "VestingInfo": { + "description": "This structure stores parameters for a batch of vesting schedules.", + "type": "object", + "required": [ + "released_amount", + "schedules" + ], + "properties": { + "released_amount": { + "description": "The total amount of vested tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "schedules": { + "description": "The vesting schedules", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, + "VestingSchedule": { + "description": "This structure stores parameters for a specific vesting schedule", + "type": "object", + "required": [ + "start_point" + ], + "properties": { + "end_point": { + "description": "The end point for the vesting schedule", + "anyOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + }, + { + "type": "null" + } + ] + }, + "start_point": { + "description": "The start date for the vesting schedule", + "allOf": [ + { + "$ref": "#/definitions/VestingSchedulePoint" + } + ] + } + }, + "additionalProperties": false + }, + "VestingSchedulePoint": { + "description": "This structure stores the parameters used to create a vesting schedule.", + "type": "object", + "required": [ + "amount", + "time" + ], + "properties": { + "amount": { + "description": "The amount of tokens being vested", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "time": { + "description": "The start time for the vesting schedule", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "vesting_state": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingState", + "description": "This structure stores the accumulated vesting information for all addresses.", + "type": "object", + "required": [ + "total_granted", + "total_released" + ], + "properties": { + "total_granted": { + "description": "The total amount of tokens granted to the users", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "total_released": { + "description": "The total amount of tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "with_managers_extension": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsgWithManagers", + "description": "This structure describes the query messages available in a with_managers vesting contract.", + "oneOf": [ + { + "description": "Returns list of vesting managers (the persons who are able to add/remove vesting schedules)", + "type": "object", + "required": [ + "vesting_managers" + ], + "properties": { + "vesting_managers": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/vesting-lp-pcl/src/contract.rs b/contracts/vesting-lp-pcl/src/contract.rs new file mode 100644 index 00000000..54f11a5d --- /dev/null +++ b/contracts/vesting-lp-pcl/src/contract.rs @@ -0,0 +1,177 @@ +use crate::msg::{Cw20HookMsg, ExecuteMsg, InstantiateMsg}; +use crate::state::XYK_VESTING_LP_CONTRACT; +use astroport::asset::token_asset_info; +use cosmwasm_std::{ + entry_point, from_json, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, + Storage, Uint128, +}; +use cw2::set_contract_version; +use cw20::Cw20ReceiveMsg; +use vesting_base::error::ContractError; +use vesting_base::handlers::{execute as base_execute, query as base_query}; +use vesting_base::handlers::{get_vesting_token, register_vesting_accounts}; +use vesting_base::msg::{ExecuteMsg as BaseExecute, QueryMsg}; +use vesting_base::state::{vesting_info, vesting_state, CONFIG, VESTING_MANAGERS}; +use vesting_base::types::{Config, Extensions, VestingInfo}; + +/// Contract name that is used for migration. +const CONTRACT_NAME: &str = "neutron-vesting-lp-pcl"; +/// Contract version that is used for migration. +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +/// Creates a new contract with the specified parameters packed in the `msg` variable. +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, +) -> StdResult { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + let owner = deps.api.addr_validate(&msg.owner)?; + CONFIG.save( + deps.storage, + &Config { + owner, + vesting_token: Option::from(msg.vesting_token), + token_info_manager: deps.api.addr_validate(&msg.token_info_manager)?, + + extensions: Extensions { + historical: true, + managed: false, + with_managers: true, + }, + }, + )?; + for m in msg.vesting_managers.iter() { + let ma = deps.api.addr_validate(m)?; + VESTING_MANAGERS.save(deps.storage, ma, &())?; + } + XYK_VESTING_LP_CONTRACT.save( + deps.storage, + &deps + .api + .addr_validate(&msg.xyk_vesting_lp_contract.clone())?, + )?; + Ok(Response::default()) +} + +/// Exposes execute functions available in the contract. +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::Receive(msg) => receive_cw20(deps, env, info, msg), + _ => { + let base_msg: BaseExecute = msg.into(); + base_execute(deps, env, info, base_msg) + } + } +} + +/// Receives a message of type [`Cw20HookMsg`] and processes it depending on the received template. +/// +/// * **cw20_msg** CW20 message to process. +fn receive_cw20( + deps: DepsMut, + env: Env, + info: MessageInfo, + cw20_msg: Cw20ReceiveMsg, +) -> Result { + let config = CONFIG.load(deps.storage)?; + let vesting_token = get_vesting_token(&config)?; + let sender = info.sender; + + match from_json(&cw20_msg.msg)? { + Cw20HookMsg::RegisterVestingAccounts { vesting_accounts } => { + if !is_sender_whitelisted( + deps.storage, + &config, + &deps.api.addr_validate(sender.as_str())?, + ) || token_asset_info(sender.clone()) != vesting_token + { + return Err(ContractError::Unauthorized {}); + } + register_vesting_accounts(deps, vesting_accounts, cw20_msg.amount, env.block.height) + } + Cw20HookMsg::MigrateXYKLiquidity { + user_address_raw, + user_vesting_info, + } => { + if !is_sender_xyk_vesting_lp(deps.storage, &sender) { + return Err(ContractError::Unauthorized {}); + } + handle_migrate_xyk_liquidity(deps, env, user_address_raw, user_vesting_info) + } + } +} + +fn is_sender_whitelisted(store: &mut dyn Storage, config: &Config, sender: &Addr) -> bool { + if *sender == config.owner { + return true; + } + let xyk_vesting_lp_contract = XYK_VESTING_LP_CONTRACT.load(store).unwrap(); + if *sender == xyk_vesting_lp_contract { + return true; + } + if VESTING_MANAGERS.has(store, sender.clone()) { + return true; + } + + false +} + +fn is_sender_xyk_vesting_lp(store: &mut dyn Storage, sender: &Addr) -> bool { + let xyk_vesting_lp_contract = XYK_VESTING_LP_CONTRACT.load(store).unwrap(); + if *sender == xyk_vesting_lp_contract { + return true; + } + + false +} + +fn handle_migrate_xyk_liquidity( + deps: DepsMut, + env: Env, + user_addr: Addr, + user_vesting_info: VestingInfo, +) -> Result { + let height = env.block.height; + let config = CONFIG.load(deps.storage)?; + + let mut to_deposit = Uint128::zero(); + for sch in &user_vesting_info.schedules { + let amount = if let Some(end_point) = &sch.end_point { + end_point.amount + } else { + sch.start_point.amount + }; + to_deposit = to_deposit.checked_add(amount)?; + } + + let vesting_info = vesting_info(config.extensions.historical); + + vesting_info.save(deps.storage, user_addr, &user_vesting_info, height)?; + + vesting_state(config.extensions.historical).update::<_, ContractError>( + deps.storage, + height, + |s| { + let mut state = s.unwrap_or_default(); + state.total_granted = state.total_granted.checked_add(to_deposit)?; + Ok(state) + }, + )?; + + Ok(Response::default()) +} + +/// Exposes all the queries available in the contract. +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { + base_query(deps, env, msg) +} diff --git a/contracts/vesting-lp-pcl/src/lib.rs b/contracts/vesting-lp-pcl/src/lib.rs new file mode 100644 index 00000000..4934c19d --- /dev/null +++ b/contracts/vesting-lp-pcl/src/lib.rs @@ -0,0 +1,3 @@ +pub mod contract; +pub mod msg; +pub mod state; diff --git a/contracts/vesting-lp-pcl/src/msg.rs b/contracts/vesting-lp-pcl/src/msg.rs new file mode 100644 index 00000000..2af63d0d --- /dev/null +++ b/contracts/vesting-lp-pcl/src/msg.rs @@ -0,0 +1,110 @@ +use astroport::asset::AssetInfo; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Uint128}; +use cw20::Cw20ReceiveMsg; +use vesting_base::msg::{ + ExecuteMsg as BaseExecute, ExecuteMsgHistorical, ExecuteMsgManaged, ExecuteMsgWithManagers, +}; +use vesting_base::types::{VestingAccount, VestingInfo}; + +/// This structure describes the parameters used for creating a contract. +#[cw_serde] +pub struct InstantiateMsg { + /// Address allowed to change contract parameters + pub owner: String, + /// Initial list of whitelisted vesting managers + pub vesting_managers: Vec, + /// Token info manager address + pub token_info_manager: String, + pub xyk_vesting_lp_contract: String, + pub vesting_token: AssetInfo, +} + +#[cw_serde] +pub enum ExecuteMsg { + // Claim claims vested tokens and sends them to a recipient + Claim { + /// The address that receives the vested tokens + recipient: Option, + /// The amount of tokens to claim + amount: Option, + }, + /// RegisterVestingAccounts registers vesting targets/accounts + RegisterVestingAccounts { + vesting_accounts: Vec, + }, + /// Creates a request to change contract ownership + /// ## Executor + /// Only the current owner can execute this + ProposeNewOwner { + /// The newly proposed owner + owner: String, + /// The validity period of the offer to change the owner + expires_in: u64, + }, + /// Removes a request to change contract ownership + /// ## Executor + /// Only the current owner can execute this + DropOwnershipProposal {}, + /// Claims contract ownership + /// ## Executor + /// Only the newly proposed owner can execute this + ClaimOwnership {}, + /// Sets vesting token + /// ## Executor + /// Only the current owner or token info manager can execute this + SetVestingToken { + vesting_token: AssetInfo, + }, + /// Contains messages associated with the managed extension for vesting contracts. + ManagedExtension { + msg: ExecuteMsgManaged, + }, + /// Contains messages associated with the with_managers extension for vesting contracts. + WithManagersExtension { + msg: ExecuteMsgWithManagers, + }, + /// Contains messages associated with the historical extension for vesting contracts. + HistoricalExtension { + msg: ExecuteMsgHistorical, + }, + Receive(Cw20ReceiveMsg), +} + +/// This structure describes a CW20 hook message. +#[cw_serde] +pub enum Cw20HookMsg { + /// RegisterVestingAccounts registers vesting targets/accounts + RegisterVestingAccounts { + vesting_accounts: Vec, + }, + #[serde(rename = "migrate_xyk_liquidity")] + MigrateXYKLiquidity { + /// The address of the user which owns the vested tokens. + user_address_raw: Addr, + user_vesting_info: VestingInfo, + }, +} + +impl From for BaseExecute { + fn from(item: ExecuteMsg) -> Self { + match item { + ExecuteMsg::Claim { recipient, amount } => BaseExecute::Claim { recipient, amount }, + ExecuteMsg::RegisterVestingAccounts { vesting_accounts } => { + BaseExecute::RegisterVestingAccounts { vesting_accounts } + } + ExecuteMsg::ProposeNewOwner { owner, expires_in } => { + BaseExecute::ProposeNewOwner { owner, expires_in } + } + ExecuteMsg::DropOwnershipProposal {} => BaseExecute::DropOwnershipProposal {}, + ExecuteMsg::ClaimOwnership {} => BaseExecute::ClaimOwnership {}, + ExecuteMsg::SetVestingToken { vesting_token } => { + BaseExecute::SetVestingToken { vesting_token } + } + ExecuteMsg::ManagedExtension { msg } => BaseExecute::ManagedExtension { msg }, + ExecuteMsg::WithManagersExtension { msg } => BaseExecute::WithManagersExtension { msg }, + ExecuteMsg::HistoricalExtension { msg } => BaseExecute::HistoricalExtension { msg }, + _ => panic!("Unhandled ExecuteMsg variant"), + } + } +} diff --git a/contracts/vesting-lp-pcl/src/state.rs b/contracts/vesting-lp-pcl/src/state.rs new file mode 100644 index 00000000..e3fb2078 --- /dev/null +++ b/contracts/vesting-lp-pcl/src/state.rs @@ -0,0 +1,3 @@ +use cosmwasm_std::Addr; +use cw_storage_plus::Item; +pub(crate) const XYK_VESTING_LP_CONTRACT: Item = Item::new("xyk_vesting_lp_contract"); diff --git a/contracts/vesting-lp/.cargo/config b/contracts/vesting-lp/.cargo/config index f2fbc6a9..a79b8fdb 100644 --- a/contracts/vesting-lp/.cargo/config +++ b/contracts/vesting-lp/.cargo/config @@ -3,4 +3,4 @@ wasm = "build --release --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example vesting-lp_schema" +schema = "run --example vesting_schema" diff --git a/contracts/vesting-lp/Cargo.toml b/contracts/vesting-lp/Cargo.toml index 31f70c7c..0dadfa86 100644 --- a/contracts/vesting-lp/Cargo.toml +++ b/contracts/vesting-lp/Cargo.toml @@ -9,20 +9,21 @@ description = "Vesting contract with a voting capabilities. Provides queries to crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all init/handle/query exports library = [] [dependencies] -cw2 = { workspace = true } -cw20 = { workspace = true } -astroport = { workspace = true } -vesting-base = { workspace = true } -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } +cw2 = { version = "0.15" } +vesting-base = {path = "../../packages/vesting-base"} +vesting-lp-pcl = {path = "../vesting-lp-pcl"} +astroport = { path = "../../packages/astroport" } +cosmwasm-schema = { version = "1.1", default-features = false } +cosmwasm-std = { version = "1.1" } +cw-storage-plus = "0.15" +cw20 = { version = "0.15" } [dev-dependencies] -cw-multi-test = { workspace = true } +cw-multi-test = "0.15" astroport-token = {git = "https://github.com/astroport-fi/astroport-core.git", rev = "65ce7d1879cc5d95b09fa14202f0423bba52ae0e" } +cw20 = { version = "0.15" } cw-utils = "0.15" diff --git a/contracts/vesting-lp/examples/vesting-lp_schema.rs b/contracts/vesting-lp/examples/vesting-lp_schema.rs index 90284134..821d12fc 100644 --- a/contracts/vesting-lp/examples/vesting-lp_schema.rs +++ b/contracts/vesting-lp/examples/vesting-lp_schema.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::write_api; -use vesting_base::msg::{ExecuteMsg, MigrateMsg, QueryMsg}; -use vesting_lp::msg::InstantiateMsg; +use vesting_base::msg::QueryMsg; +use vesting_lp::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}; fn main() { write_api! { diff --git a/contracts/vesting-lp/schema/raw/execute.json b/contracts/vesting-lp/schema/raw/execute.json index e5aa732d..c981b115 100644 --- a/contracts/vesting-lp/schema/raw/execute.json +++ b/contracts/vesting-lp/schema/raw/execute.json @@ -1,31 +1,29 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "ExecuteMsg", - "description": "This structure describes the execute messages available in a vesting contract.", "oneOf": [ { - "description": "Claim claims vested tokens and sends them to a recipient", "type": "object", "required": [ - "claim" + "base" ], "properties": { - "claim": { + "base": { + "$ref": "#/definitions/ExecuteMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "migrate_liquidity_to_pcl_pool" + ], + "properties": { + "migrate_liquidity_to_pcl_pool": { "type": "object", "properties": { - "amount": { - "description": "The amount of tokens to claim", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "description": "The address that receives the vested tokens", + "user": { "type": [ "string", "null" @@ -38,213 +36,369 @@ "additionalProperties": false }, { - "description": "Receives a message of type [`Cw20ReceiveMsg`] and processes it depending on the received template", + "description": "Callbacks; only callable by the contract itself.", "type": "object", "required": [ - "receive" + "callback" ], "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" + "callback": { + "$ref": "#/definitions/CallbackMsg" } }, "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" }, - { - "description": "RegisterVestingAccounts registers vesting targets/accounts", - "type": "object", - "required": [ - "register_vesting_accounts" - ], - "properties": { - "register_vesting_accounts": { + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", "type": "object", "required": [ - "vesting_accounts" + "token" ], "properties": { - "vesting_accounts": { - "type": "array", - "items": { - "$ref": "#/definitions/VestingAccount" - } + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates a request to change contract ownership ## Executor Only the current owner can execute this", - "type": "object", - "required": [ - "propose_new_owner" - ], - "properties": { - "propose_new_owner": { + }, + { + "description": "Native token", "type": "object", "required": [ - "expires_in", - "owner" + "native_token" ], "properties": { - "expires_in": { - "description": "The validity period of the offer to change the owner", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "description": "The newly proposed owner", - "type": "string" + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false } - }, - "additionalProperties": false + ] }, - { - "description": "Removes a request to change contract ownership ## Executor Only the current owner can execute this", - "type": "object", - "required": [ - "drop_ownership_proposal" - ], - "properties": { - "drop_ownership_proposal": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "CallbackMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "migrate_liquidity_to_cl_pair" + ], + "properties": { + "migrate_liquidity_to_cl_pair": { + "type": "object", + "required": [ + "amount", + "cl_pair", + "ntrn_denom", + "paired_asset_denom", + "slippage_tolerance", + "user", + "xyk_lp_token", + "xyk_pair" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "cl_pair": { + "$ref": "#/definitions/Addr" + }, + "ntrn_denom": { + "type": "string" + }, + "paired_asset_denom": { + "type": "string" + }, + "slippage_tolerance": { + "$ref": "#/definitions/Decimal" + }, + "user": { + "$ref": "#/definitions/VestingAccountResponse" + }, + "xyk_lp_token": { + "$ref": "#/definitions/Addr" + }, + "xyk_pair": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { "type": "object", + "required": [ + "provide_liquidity_to_cl_pair_after_withdrawal" + ], + "properties": { + "provide_liquidity_to_cl_pair_after_withdrawal": { + "type": "object", + "required": [ + "cl_pair", + "ntrn_denom", + "ntrn_init_balance", + "paired_asset_denom", + "paired_asset_init_balance", + "slippage_tolerance", + "user" + ], + "properties": { + "cl_pair": { + "$ref": "#/definitions/Addr" + }, + "ntrn_denom": { + "type": "string" + }, + "ntrn_init_balance": { + "$ref": "#/definitions/Uint128" + }, + "paired_asset_denom": { + "type": "string" + }, + "paired_asset_init_balance": { + "$ref": "#/definitions/Uint128" + }, + "slippage_tolerance": { + "$ref": "#/definitions/Decimal" + }, + "user": { + "$ref": "#/definitions/VestingAccountResponse" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "post_migration_vesting_reschedule" + ], + "properties": { + "post_migration_vesting_reschedule": { + "type": "object", + "required": [ + "user" + ], + "properties": { + "user": { + "$ref": "#/definitions/VestingAccountResponse" + } + }, + "additionalProperties": false + } + }, "additionalProperties": false } - }, - "additionalProperties": false + ] }, - { - "description": "Claims contract ownership ## Executor Only the newly proposed owner can execute this", + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", "type": "object", "required": [ - "claim_ownership" + "amount", + "msg", + "sender" ], "properties": { - "claim_ownership": { - "type": "object", - "additionalProperties": false + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" } }, "additionalProperties": false }, - { - "description": "Sets vesting token ## Executor Only the current owner or token info manager can execute this", - "type": "object", - "required": [ - "set_vesting_token" - ], - "properties": { - "set_vesting_token": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "ExecuteMsg": { + "description": "This structure describes the execute messages available in a vesting contract.", + "oneOf": [ + { + "description": "Claim claims vested tokens and sends them to a recipient", "type": "object", "required": [ - "vesting_token" + "claim" ], "properties": { - "vesting_token": { - "$ref": "#/definitions/AssetInfo" + "claim": { + "type": "object", + "properties": { + "amount": { + "description": "The amount of tokens to claim", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "recipient": { + "description": "The address that receives the vested tokens", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Contains messages associated with the managed extension for vesting contracts.", - "type": "object", - "required": [ - "managed_extension" - ], - "properties": { - "managed_extension": { + }, + { + "description": "Receives a message of type [`Cw20ReceiveMsg`] and processes it depending on the received template", "type": "object", "required": [ - "msg" + "receive" ], "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsgManaged" + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Contains messages associated with the with_managers extension for vesting contracts.", - "type": "object", - "required": [ - "with_managers_extension" - ], - "properties": { - "with_managers_extension": { + }, + { + "description": "RegisterVestingAccounts registers vesting targets/accounts", "type": "object", "required": [ - "msg" + "register_vesting_accounts" ], "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsgWithManagers" + "register_vesting_accounts": { + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "type": "array", + "items": { + "$ref": "#/definitions/VestingAccount" + } + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Contains messages associated with the historical extension for vesting contracts.", - "type": "object", - "required": [ - "historical_extension" - ], - "properties": { - "historical_extension": { + }, + { + "description": "Creates a request to change contract ownership ## Executor Only the current owner can execute this", "type": "object", "required": [ - "msg" + "propose_new_owner" ], "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsgHistorical" + "propose_new_owner": { + "type": "object", + "required": [ + "expires_in", + "owner" + ], + "properties": { + "expires_in": { + "description": "The validity period of the offer to change the owner", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "description": "The newly proposed owner", + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfo": { - "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", - "oneOf": [ + }, { - "description": "Non-native Token", + "description": "Removes a request to change contract ownership ## Executor Only the current owner can execute this", "type": "object", "required": [ - "token" + "drop_ownership_proposal" ], "properties": { - "token": { + "drop_ownership_proposal": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claims contract ownership ## Executor Only the newly proposed owner can execute this", + "type": "object", + "required": [ + "claim_ownership" + ], + "properties": { + "claim_ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Sets vesting token ## Executor Only the current owner or token info manager can execute this", + "type": "object", + "required": [ + "set_vesting_token" + ], + "properties": { + "set_vesting_token": { "type": "object", "required": [ - "contract_addr" + "vesting_token" ], "properties": { - "contract_addr": { - "$ref": "#/definitions/Addr" + "vesting_token": { + "$ref": "#/definitions/AssetInfo" } }, "additionalProperties": false @@ -253,53 +407,72 @@ "additionalProperties": false }, { - "description": "Native token", + "description": "Contains messages associated with the managed extension for vesting contracts.", "type": "object", "required": [ - "native_token" + "managed_extension" ], "properties": { - "native_token": { + "managed_extension": { "type": "object", "required": [ - "denom" + "msg" ], "properties": { - "denom": { - "type": "string" + "msg": { + "$ref": "#/definitions/ExecuteMsgManaged" } }, "additionalProperties": false } }, "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" }, - "msg": { - "$ref": "#/definitions/Binary" + { + "description": "Contains messages associated with the with_managers extension for vesting contracts.", + "type": "object", + "required": [ + "with_managers_extension" + ], + "properties": { + "with_managers_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgWithManagers" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false }, - "sender": { - "type": "string" + { + "description": "Contains messages associated with the historical extension for vesting contracts.", + "type": "object", + "required": [ + "historical_extension" + ], + "properties": { + "historical_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgHistorical" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } - }, - "additionalProperties": false + ] }, "ExecuteMsgHistorical": { "description": "This structure describes the execute messages available in a historical vesting contract.", @@ -422,6 +595,59 @@ }, "additionalProperties": false }, + "VestingAccountResponse": { + "description": "This structure describes a custom struct used to return vesting data about a specific vesting target.", + "type": "object", + "required": [ + "address", + "info" + ], + "properties": { + "address": { + "description": "The address that's vesting tokens", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "info": { + "description": "Vesting information", + "allOf": [ + { + "$ref": "#/definitions/VestingInfo" + } + ] + } + }, + "additionalProperties": false + }, + "VestingInfo": { + "description": "This structure stores parameters for a batch of vesting schedules.", + "type": "object", + "required": [ + "released_amount", + "schedules" + ], + "properties": { + "released_amount": { + "description": "The total amount of vested tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "schedules": { + "description": "The vesting schedules", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, "VestingSchedule": { "description": "This structure stores parameters for a specific vesting schedule", "type": "object", diff --git a/contracts/vesting-lp/schema/raw/migrate.json b/contracts/vesting-lp/schema/raw/migrate.json index 1b9dcecf..c8134b6c 100644 --- a/contracts/vesting-lp/schema/raw/migrate.json +++ b/contracts/vesting-lp/schema/raw/migrate.json @@ -3,5 +3,43 @@ "title": "MigrateMsg", "description": "This structure describes a migration message. We currently take no arguments for migrations.", "type": "object", - "additionalProperties": false + "required": [ + "cl_pair", + "max_slippage", + "new_lp_token", + "ntrn_denom", + "paired_denom", + "pcl_vesting", + "xyk_pair" + ], + "properties": { + "cl_pair": { + "type": "string" + }, + "max_slippage": { + "$ref": "#/definitions/Decimal" + }, + "new_lp_token": { + "type": "string" + }, + "ntrn_denom": { + "type": "string" + }, + "paired_denom": { + "type": "string" + }, + "pcl_vesting": { + "type": "string" + }, + "xyk_pair": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + } + } } diff --git a/contracts/vesting-lp/schema/vesting-lp.json b/contracts/vesting-lp/schema/vesting-lp.json index 395775f8..8a8f1873 100644 --- a/contracts/vesting-lp/schema/vesting-lp.json +++ b/contracts/vesting-lp/schema/vesting-lp.json @@ -34,31 +34,29 @@ "execute": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "ExecuteMsg", - "description": "This structure describes the execute messages available in a vesting contract.", "oneOf": [ { - "description": "Claim claims vested tokens and sends them to a recipient", "type": "object", "required": [ - "claim" + "base" ], "properties": { - "claim": { + "base": { + "$ref": "#/definitions/ExecuteMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "migrate_liquidity_to_pcl_pool" + ], + "properties": { + "migrate_liquidity_to_pcl_pool": { "type": "object", "properties": { - "amount": { - "description": "The amount of tokens to claim", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "description": "The address that receives the vested tokens", + "user": { "type": [ "string", "null" @@ -71,213 +69,369 @@ "additionalProperties": false }, { - "description": "Receives a message of type [`Cw20ReceiveMsg`] and processes it depending on the received template", + "description": "Callbacks; only callable by the contract itself.", "type": "object", "required": [ - "receive" + "callback" ], "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" + "callback": { + "$ref": "#/definitions/CallbackMsg" } }, "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" }, - { - "description": "RegisterVestingAccounts registers vesting targets/accounts", - "type": "object", - "required": [ - "register_vesting_accounts" - ], - "properties": { - "register_vesting_accounts": { + "AssetInfo": { + "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", + "oneOf": [ + { + "description": "Non-native Token", "type": "object", "required": [ - "vesting_accounts" + "token" ], "properties": { - "vesting_accounts": { - "type": "array", - "items": { - "$ref": "#/definitions/VestingAccount" - } + "token": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates a request to change contract ownership ## Executor Only the current owner can execute this", - "type": "object", - "required": [ - "propose_new_owner" - ], - "properties": { - "propose_new_owner": { + }, + { + "description": "Native token", "type": "object", "required": [ - "expires_in", - "owner" + "native_token" ], "properties": { - "expires_in": { - "description": "The validity period of the offer to change the owner", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "description": "The newly proposed owner", - "type": "string" + "native_token": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false } - }, - "additionalProperties": false + ] }, - { - "description": "Removes a request to change contract ownership ## Executor Only the current owner can execute this", - "type": "object", - "required": [ - "drop_ownership_proposal" - ], - "properties": { - "drop_ownership_proposal": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "CallbackMsg": { + "oneOf": [ + { "type": "object", + "required": [ + "migrate_liquidity_to_cl_pair" + ], + "properties": { + "migrate_liquidity_to_cl_pair": { + "type": "object", + "required": [ + "amount", + "cl_pair", + "ntrn_denom", + "paired_asset_denom", + "slippage_tolerance", + "user", + "xyk_lp_token", + "xyk_pair" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "cl_pair": { + "$ref": "#/definitions/Addr" + }, + "ntrn_denom": { + "type": "string" + }, + "paired_asset_denom": { + "type": "string" + }, + "slippage_tolerance": { + "$ref": "#/definitions/Decimal" + }, + "user": { + "$ref": "#/definitions/VestingAccountResponse" + }, + "xyk_lp_token": { + "$ref": "#/definitions/Addr" + }, + "xyk_pair": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "provide_liquidity_to_cl_pair_after_withdrawal" + ], + "properties": { + "provide_liquidity_to_cl_pair_after_withdrawal": { + "type": "object", + "required": [ + "cl_pair", + "ntrn_denom", + "ntrn_init_balance", + "paired_asset_denom", + "paired_asset_init_balance", + "slippage_tolerance", + "user" + ], + "properties": { + "cl_pair": { + "$ref": "#/definitions/Addr" + }, + "ntrn_denom": { + "type": "string" + }, + "ntrn_init_balance": { + "$ref": "#/definitions/Uint128" + }, + "paired_asset_denom": { + "type": "string" + }, + "paired_asset_init_balance": { + "$ref": "#/definitions/Uint128" + }, + "slippage_tolerance": { + "$ref": "#/definitions/Decimal" + }, + "user": { + "$ref": "#/definitions/VestingAccountResponse" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "post_migration_vesting_reschedule" + ], + "properties": { + "post_migration_vesting_reschedule": { + "type": "object", + "required": [ + "user" + ], + "properties": { + "user": { + "$ref": "#/definitions/VestingAccountResponse" + } + }, + "additionalProperties": false + } + }, "additionalProperties": false } - }, - "additionalProperties": false + ] }, - { - "description": "Claims contract ownership ## Executor Only the newly proposed owner can execute this", + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", "type": "object", "required": [ - "claim_ownership" + "amount", + "msg", + "sender" ], "properties": { - "claim_ownership": { - "type": "object", - "additionalProperties": false + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" } }, "additionalProperties": false }, - { - "description": "Sets vesting token ## Executor Only the current owner or token info manager can execute this", - "type": "object", - "required": [ - "set_vesting_token" - ], - "properties": { - "set_vesting_token": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "ExecuteMsg": { + "description": "This structure describes the execute messages available in a vesting contract.", + "oneOf": [ + { + "description": "Claim claims vested tokens and sends them to a recipient", "type": "object", "required": [ - "vesting_token" + "claim" ], "properties": { - "vesting_token": { - "$ref": "#/definitions/AssetInfo" + "claim": { + "type": "object", + "properties": { + "amount": { + "description": "The amount of tokens to claim", + "anyOf": [ + { + "$ref": "#/definitions/Uint128" + }, + { + "type": "null" + } + ] + }, + "recipient": { + "description": "The address that receives the vested tokens", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Contains messages associated with the managed extension for vesting contracts.", - "type": "object", - "required": [ - "managed_extension" - ], - "properties": { - "managed_extension": { + }, + { + "description": "Receives a message of type [`Cw20ReceiveMsg`] and processes it depending on the received template", "type": "object", "required": [ - "msg" + "receive" ], "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsgManaged" + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Contains messages associated with the with_managers extension for vesting contracts.", - "type": "object", - "required": [ - "with_managers_extension" - ], - "properties": { - "with_managers_extension": { + }, + { + "description": "RegisterVestingAccounts registers vesting targets/accounts", "type": "object", "required": [ - "msg" + "register_vesting_accounts" ], "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsgWithManagers" + "register_vesting_accounts": { + "type": "object", + "required": [ + "vesting_accounts" + ], + "properties": { + "vesting_accounts": { + "type": "array", + "items": { + "$ref": "#/definitions/VestingAccount" + } + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Contains messages associated with the historical extension for vesting contracts.", - "type": "object", - "required": [ - "historical_extension" - ], - "properties": { - "historical_extension": { + }, + { + "description": "Creates a request to change contract ownership ## Executor Only the current owner can execute this", "type": "object", "required": [ - "msg" + "propose_new_owner" ], "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsgHistorical" + "propose_new_owner": { + "type": "object", + "required": [ + "expires_in", + "owner" + ], + "properties": { + "expires_in": { + "description": "The validity period of the offer to change the owner", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "description": "The newly proposed owner", + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfo": { - "description": "This enum describes available Token types. ## Examples ``` # use cosmwasm_std::Addr; # use astroport::asset::AssetInfo::{NativeToken, Token}; Token { contract_addr: Addr::unchecked(\"stake...\") }; NativeToken { denom: String::from(\"uluna\") }; ```", - "oneOf": [ + }, { - "description": "Non-native Token", + "description": "Removes a request to change contract ownership ## Executor Only the current owner can execute this", "type": "object", "required": [ - "token" + "drop_ownership_proposal" ], "properties": { - "token": { + "drop_ownership_proposal": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claims contract ownership ## Executor Only the newly proposed owner can execute this", + "type": "object", + "required": [ + "claim_ownership" + ], + "properties": { + "claim_ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Sets vesting token ## Executor Only the current owner or token info manager can execute this", + "type": "object", + "required": [ + "set_vesting_token" + ], + "properties": { + "set_vesting_token": { "type": "object", "required": [ - "contract_addr" + "vesting_token" ], "properties": { - "contract_addr": { - "$ref": "#/definitions/Addr" + "vesting_token": { + "$ref": "#/definitions/AssetInfo" } }, "additionalProperties": false @@ -286,53 +440,72 @@ "additionalProperties": false }, { - "description": "Native token", + "description": "Contains messages associated with the managed extension for vesting contracts.", "type": "object", "required": [ - "native_token" + "managed_extension" ], "properties": { - "native_token": { + "managed_extension": { "type": "object", "required": [ - "denom" + "msg" ], "properties": { - "denom": { - "type": "string" + "msg": { + "$ref": "#/definitions/ExecuteMsgManaged" } }, "additionalProperties": false } }, "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" }, - "msg": { - "$ref": "#/definitions/Binary" + { + "description": "Contains messages associated with the with_managers extension for vesting contracts.", + "type": "object", + "required": [ + "with_managers_extension" + ], + "properties": { + "with_managers_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgWithManagers" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false }, - "sender": { - "type": "string" + { + "description": "Contains messages associated with the historical extension for vesting contracts.", + "type": "object", + "required": [ + "historical_extension" + ], + "properties": { + "historical_extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/ExecuteMsgHistorical" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } - }, - "additionalProperties": false + ] }, "ExecuteMsgHistorical": { "description": "This structure describes the execute messages available in a historical vesting contract.", @@ -455,6 +628,59 @@ }, "additionalProperties": false }, + "VestingAccountResponse": { + "description": "This structure describes a custom struct used to return vesting data about a specific vesting target.", + "type": "object", + "required": [ + "address", + "info" + ], + "properties": { + "address": { + "description": "The address that's vesting tokens", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "info": { + "description": "Vesting information", + "allOf": [ + { + "$ref": "#/definitions/VestingInfo" + } + ] + } + }, + "additionalProperties": false + }, + "VestingInfo": { + "description": "This structure stores parameters for a batch of vesting schedules.", + "type": "object", + "required": [ + "released_amount", + "schedules" + ], + "properties": { + "released_amount": { + "description": "The total amount of vested tokens already claimed", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "schedules": { + "description": "The vesting schedules", + "type": "array", + "items": { + "$ref": "#/definitions/VestingSchedule" + } + } + }, + "additionalProperties": false + }, "VestingSchedule": { "description": "This structure stores parameters for a specific vesting schedule", "type": "object", @@ -806,7 +1032,45 @@ "title": "MigrateMsg", "description": "This structure describes a migration message. We currently take no arguments for migrations.", "type": "object", - "additionalProperties": false + "required": [ + "cl_pair", + "max_slippage", + "new_lp_token", + "ntrn_denom", + "paired_denom", + "pcl_vesting", + "xyk_pair" + ], + "properties": { + "cl_pair": { + "type": "string" + }, + "max_slippage": { + "$ref": "#/definitions/Decimal" + }, + "new_lp_token": { + "type": "string" + }, + "ntrn_denom": { + "type": "string" + }, + "paired_denom": { + "type": "string" + }, + "pcl_vesting": { + "type": "string" + }, + "xyk_pair": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + } + } }, "sudo": null, "responses": { diff --git a/contracts/vesting-lp/src/contract.rs b/contracts/vesting-lp/src/contract.rs index 4b3a4659..18f0135b 100644 --- a/contracts/vesting-lp/src/contract.rs +++ b/contracts/vesting-lp/src/contract.rs @@ -1,10 +1,24 @@ -use crate::msg::InstantiateMsg; -use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use crate::msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg}; +use crate::state::{XykToClMigrationConfig, XYK_TO_CL_MIGRATION_CONFIG}; +use astroport::asset::{native_asset, PairInfo}; +use astroport::pair::{ + Cw20HookMsg as PairCw20HookMsg, ExecuteMsg as PairExecuteMsg, QueryMsg as PairQueryMsg, +}; +use cosmwasm_std::{ + entry_point, to_json_binary, Addr, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, + MessageInfo, Response, StdResult, Uint128, WasmMsg, +}; use cw2::set_contract_version; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use vesting_base::builder::VestingBaseBuilder; use vesting_base::error::ContractError; -use vesting_base::handlers::{execute as base_execute, query as base_query}; -use vesting_base::msg::{ExecuteMsg, QueryMsg}; +use vesting_base::handlers::execute as base_execute; +use vesting_base::handlers::query as base_query; +use vesting_base::msg::{ExecuteMsg as BaseExecute, QueryMsg}; +use vesting_base::state::{vesting_info, vesting_state, CONFIG}; +use vesting_base::types::{ + VestingAccountFullInfo, VestingInfo, VestingSchedule, VestingSchedulePoint, +}; /// Contract name that is used for migration. const CONTRACT_NAME: &str = "neutron-vesting-lp"; @@ -36,7 +50,16 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - base_execute(deps, env, info, msg) + match msg { + ExecuteMsg::MigrateLiquidityToPCLPool { user } => { + execute_migrate_liquidity(deps, info, env, None, user) + } + ExecuteMsg::Callback(msg) => _handle_callback(deps, env, info, msg), + _ => { + let base_msg: BaseExecute = msg.into(); + base_execute(deps, env, info, base_msg) + } + } } /// Exposes all the queries available in the contract. @@ -44,3 +67,369 @@ pub fn execute( pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { base_query(deps, env, msg) } + +/// Manages contract migration. +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + XYK_TO_CL_MIGRATION_CONFIG.save( + deps.storage, + &XykToClMigrationConfig { + max_slippage: msg.max_slippage, + ntrn_denom: msg.ntrn_denom, + xyk_pair: deps.api.addr_validate(msg.xyk_pair.as_str())?, + paired_denom: msg.paired_denom, + cl_pair: deps.api.addr_validate(msg.cl_pair.as_str())?, + new_lp_token: deps.api.addr_validate(msg.new_lp_token.as_str())?, + pcl_vesting: deps.api.addr_validate(msg.pcl_vesting.as_str())?, + dust_threshold: msg.dust_threshold, + }, + )?; + + Ok(Response::default()) +} + +fn execute_migrate_liquidity( + deps: DepsMut, + info: MessageInfo, + env: Env, + slippage_tolerance: Option, + user: Option, +) -> Result { + let config = CONFIG.load(deps.storage)?; + let migration_config: XykToClMigrationConfig = XYK_TO_CL_MIGRATION_CONFIG.load(deps.storage)?; + let address = match user { + Some(val) => deps.api.addr_validate(&val)?, + None => info.sender, + }; + let vesting_info = vesting_info(config.extensions.historical); + let info = vesting_info.load(deps.storage, address.clone())?; + let mut resp = Response::default(); + let user = VestingAccountFullInfo { address, info }; + + // get pairs LP token addresses + let pair_info: PairInfo = deps + .querier + .query_wasm_smart(migration_config.xyk_pair.clone(), &PairQueryMsg::Pair {})?; + + let user_share = compute_share(&user.info)?; + + // if there is nothing to migrate just update vi and quit. + // if there is only dust, than send it back to user, update vi and quit + if user_share < migration_config.dust_threshold { + if !user_share.is_zero() { + resp = resp.add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: pair_info.liquidity_token.to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: user.address.to_string(), + amount: user_share, + })?, + funds: vec![], + })); + } + + vesting_info.save( + deps.storage, + user.address.clone(), + &VestingInfo { + schedules: vec![], + released_amount: Uint128::zero(), + }, + env.block.height, + )?; + return Ok(resp); + }; + + if let Some(slippage_tolerance) = slippage_tolerance { + if slippage_tolerance.gt(&migration_config.max_slippage) { + return Err(ContractError::MigrationError {}); + } + } + + let slippage_tolerance = slippage_tolerance.unwrap_or(migration_config.max_slippage); + + resp = resp.add_message( + CallbackMsg::MigrateLiquidityToClPair { + xyk_pair: migration_config.xyk_pair.clone(), + xyk_lp_token: pair_info.liquidity_token.clone(), + amount: user_share, + slippage_tolerance, + cl_pair: migration_config.cl_pair.clone(), + ntrn_denom: migration_config.ntrn_denom.clone(), + paired_asset_denom: migration_config.paired_denom.clone(), + user, + } + .to_cosmos_msg(&env)?, + ); + + Ok(resp) +} + +fn _handle_callback( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: CallbackMsg, +) -> Result { + // Only the contract itself can call callbacks + if info.sender != env.contract.address { + return Err(ContractError::Unauthorized {}); + } + match msg { + CallbackMsg::MigrateLiquidityToClPair { + xyk_pair, + xyk_lp_token, + amount, + slippage_tolerance, + cl_pair, + ntrn_denom, + paired_asset_denom, + user, + } => migrate_liquidity_to_cl_pair_callback( + deps, + env, + xyk_pair, + xyk_lp_token, + amount, + slippage_tolerance, + cl_pair, + ntrn_denom, + paired_asset_denom, + user, + ), + CallbackMsg::ProvideLiquidityToClPairAfterWithdrawal { + ntrn_denom, + ntrn_init_balance, + paired_asset_denom, + paired_asset_init_balance, + cl_pair, + slippage_tolerance, + user, + } => provide_liquidity_to_cl_pair_after_withdrawal_callback( + deps, + env, + ntrn_denom, + ntrn_init_balance, + paired_asset_denom, + paired_asset_init_balance, + cl_pair, + slippage_tolerance, + user, + ), + CallbackMsg::PostMigrationVestingReschedule { + user, + init_balance_pcl_lp, + } => post_migration_vesting_reschedule_callback(deps, env, &user, init_balance_pcl_lp), + } +} + +#[allow(clippy::too_many_arguments)] +fn migrate_liquidity_to_cl_pair_callback( + deps: DepsMut, + env: Env, + xyk_pair: Addr, + xyk_lp_token: Addr, + amount: Uint128, + slippage_tolerance: Decimal, + cl_pair: Addr, + ntrn_denom: String, + paired_asset_denom: String, + user: VestingAccountFullInfo, +) -> Result { + let ntrn_init_balance = deps + .querier + .query_balance(env.contract.address.to_string(), ntrn_denom.clone())? + .amount; + let paired_asset_init_balance = deps + .querier + .query_balance(env.contract.address.to_string(), paired_asset_denom.clone())? + .amount; + + let mut msgs: Vec = vec![]; + + // push message to withdraw liquidity from the xyk pair + msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: xyk_lp_token.to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: xyk_pair.to_string(), + amount, + msg: to_json_binary(&PairCw20HookMsg::WithdrawLiquidity { assets: vec![] })?, + })?, + funds: vec![], + })); + let config = CONFIG.load(deps.storage)?; + vesting_state(config.extensions.historical).update::<_, ContractError>( + deps.storage, + env.block.height, + |s| { + let mut state = s.unwrap_or_default(); + state.total_granted = state.total_granted.checked_sub(amount)?; + Ok(state) + }, + )?; + // push the next migration step as a callback message + msgs.push( + CallbackMsg::ProvideLiquidityToClPairAfterWithdrawal { + ntrn_denom, + ntrn_init_balance, + paired_asset_denom, + paired_asset_init_balance, + cl_pair, + slippage_tolerance, + user, + } + .to_cosmos_msg(&env)?, + ); + + Ok(Response::default().add_messages(msgs)) +} + +#[allow(clippy::too_many_arguments)] +fn provide_liquidity_to_cl_pair_after_withdrawal_callback( + deps: DepsMut, + env: Env, + ntrn_denom: String, + ntrn_init_balance: Uint128, + paired_asset_denom: String, + paired_asset_init_balance: Uint128, + cl_pair_address: Addr, + slippage_tolerance: Decimal, + user: VestingAccountFullInfo, +) -> Result { + let ntrn_balance_after_withdrawal = deps + .querier + .query_balance(env.contract.address.to_string(), ntrn_denom.clone())? + .amount; + let paired_asset_balance_after_withdrawal = deps + .querier + .query_balance(env.contract.address.to_string(), paired_asset_denom.clone())? + .amount; + + // calc amount of assets that's been withdrawn + let withdrawn_ntrn_amount = ntrn_balance_after_withdrawal.checked_sub(ntrn_init_balance)?; + let withdrawn_paired_asset_amount = + paired_asset_balance_after_withdrawal.checked_sub(paired_asset_init_balance)?; + + let mut msgs: Vec = vec![]; + + let migration_config: XykToClMigrationConfig = XYK_TO_CL_MIGRATION_CONFIG.load(deps.storage)?; + + let balance_response: BalanceResponse = deps.querier.query_wasm_smart( + migration_config.new_lp_token, + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )?; + let current_balance = balance_response.balance; + + msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: cl_pair_address.to_string(), + msg: to_json_binary(&PairExecuteMsg::ProvideLiquidity { + assets: vec![ + native_asset(ntrn_denom.clone(), withdrawn_ntrn_amount), + native_asset(paired_asset_denom.clone(), withdrawn_paired_asset_amount), + ], + slippage_tolerance: Some(slippage_tolerance), + auto_stake: None, + receiver: None, + })?, + funds: vec![ + Coin::new(withdrawn_ntrn_amount.into(), ntrn_denom), + Coin::new(withdrawn_paired_asset_amount.into(), paired_asset_denom), + ], + })); + + msgs.push( + CallbackMsg::PostMigrationVestingReschedule { + user, + init_balance_pcl_lp: current_balance, + } + .to_cosmos_msg(&env)?, + ); + + Ok(Response::default().add_messages(msgs)) +} + +fn post_migration_vesting_reschedule_callback( + deps: DepsMut, + env: Env, + user: &VestingAccountFullInfo, + init_balance_pcl_lp: Uint128, +) -> Result { + let config = CONFIG.load(deps.storage)?; + let migration_config: XykToClMigrationConfig = XYK_TO_CL_MIGRATION_CONFIG.load(deps.storage)?; + let balance_response: BalanceResponse = deps.querier.query_wasm_smart( + &migration_config.new_lp_token, + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )?; + let balance_diff = balance_response.balance.checked_sub(init_balance_pcl_lp)?; + + let schedule = user + .info + .schedules + .last() + .ok_or(ContractError::VestingScheduleExtractError( + user.address.to_string(), + ))?; + + let new_end_point = match &schedule.end_point { + Some(end_point) => Option::from(VestingSchedulePoint { + time: end_point.time, + amount: balance_diff, + }), + None => None, + }; + + let new_schedule = VestingSchedule { + start_point: VestingSchedulePoint { + time: schedule.start_point.time, + amount: Uint128::zero(), + }, + end_point: new_end_point, + }; + + let vesting_info = vesting_info(config.extensions.historical); + + vesting_info.save( + deps.storage, + user.address.clone(), + &VestingInfo { + schedules: vec![], + released_amount: Uint128::zero(), + }, + env.block.height, + )?; + if !balance_diff.is_zero() { + let msgs = vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: migration_config.new_lp_token.to_string(), + funds: vec![], + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: migration_config.pcl_vesting.to_string(), + amount: balance_diff, + msg: to_json_binary(&vesting_lp_pcl::msg::Cw20HookMsg::MigrateXYKLiquidity { + user_address_raw: user.address.clone(), + user_vesting_info: VestingInfo { + schedules: vec![new_schedule], + released_amount: Uint128::zero(), + }, + })?, + })?, + })]; + + Ok(Response::new().add_messages(msgs)) + } else { + Ok(Response::new()) + } +} + +fn compute_share(vesting_info: &VestingInfo) -> StdResult { + let mut available_amount: Uint128 = Uint128::zero(); + for sch in &vesting_info.schedules { + if let Some(end_point) = &sch.end_point { + available_amount = available_amount.checked_add(end_point.amount)? + } + } + + Ok(available_amount.checked_sub(vesting_info.released_amount)?) +} diff --git a/contracts/vesting-lp/src/lib.rs b/contracts/vesting-lp/src/lib.rs index 08d6d688..172c45a6 100644 --- a/contracts/vesting-lp/src/lib.rs +++ b/contracts/vesting-lp/src/lib.rs @@ -1,5 +1,5 @@ +extern crate core; + pub mod contract; pub mod msg; - -#[cfg(test)] -mod tests; +pub mod state; diff --git a/contracts/vesting-lp/src/msg.rs b/contracts/vesting-lp/src/msg.rs index b35ee7ff..21018e6e 100644 --- a/contracts/vesting-lp/src/msg.rs +++ b/contracts/vesting-lp/src/msg.rs @@ -1,4 +1,11 @@ +use astroport::asset::AssetInfo; use cosmwasm_schema::cw_serde; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, Decimal, Env, StdResult, Uint128, WasmMsg}; +use cw20::Cw20ReceiveMsg; +use vesting_base::msg::{ + ExecuteMsg as BaseExecute, ExecuteMsgHistorical, ExecuteMsgManaged, ExecuteMsgWithManagers, +}; +use vesting_base::types::{VestingAccount, VestingAccountFullInfo}; /// This structure describes the parameters used for creating a contract. #[cw_serde] @@ -10,3 +17,129 @@ pub struct InstantiateMsg { /// Token info manager address pub token_info_manager: String, } + +#[cw_serde] +pub enum ExecuteMsg { + /// Claim claims vested tokens and sends them to a recipient + Claim { + /// The address that receives the vested tokens + recipient: Option, + /// The amount of tokens to claim + amount: Option, + }, + /// Receives a message of type [`Cw20ReceiveMsg`] and processes it depending on the received template + Receive(Cw20ReceiveMsg), + /// RegisterVestingAccounts registers vesting targets/accounts + RegisterVestingAccounts { + vesting_accounts: Vec, + }, + /// Creates a request to change contract ownership + /// ## Executor + /// Only the current owner can execute this + ProposeNewOwner { + /// The newly proposed owner + owner: String, + /// The validity period of the offer to change the owner + expires_in: u64, + }, + /// Removes a request to change contract ownership + /// ## Executor + /// Only the current owner can execute this + DropOwnershipProposal {}, + /// Claims contract ownership + /// ## Executor + /// Only the newly proposed owner can execute this + ClaimOwnership {}, + /// Sets vesting token + /// ## Executor + /// Only the current owner or token info manager can execute this + SetVestingToken { vesting_token: AssetInfo }, + /// Contains messages associated with the managed extension for vesting contracts. + ManagedExtension { msg: ExecuteMsgManaged }, + /// Contains messages associated with the with_managers extension for vesting contracts. + WithManagersExtension { msg: ExecuteMsgWithManagers }, + /// Contains messages associated with the historical extension for vesting contracts. + HistoricalExtension { msg: ExecuteMsgHistorical }, + #[serde(rename = "migrate_liquidity_to_pcl_pool")] + MigrateLiquidityToPCLPool { user: Option }, + /// Callbacks; only callable by the contract itself. + Callback(CallbackMsg), +} + +#[cw_serde] +pub enum CallbackMsg { + MigrateLiquidityToClPair { + xyk_pair: Addr, + xyk_lp_token: Addr, + amount: Uint128, + slippage_tolerance: Decimal, + cl_pair: Addr, + ntrn_denom: String, + paired_asset_denom: String, + user: VestingAccountFullInfo, + }, + ProvideLiquidityToClPairAfterWithdrawal { + ntrn_denom: String, + ntrn_init_balance: Uint128, + paired_asset_denom: String, + paired_asset_init_balance: Uint128, + cl_pair: Addr, + slippage_tolerance: Decimal, + user: VestingAccountFullInfo, + }, + PostMigrationVestingReschedule { + user: VestingAccountFullInfo, + init_balance_pcl_lp: Uint128, + }, +} + +// Modified from +// https://github.com/CosmWasm/cosmwasm-plus/blob/v0.2.3/packages/cw20/src/receiver.rs#L15 +impl CallbackMsg { + pub fn to_cosmos_msg(self, env: &Env) -> StdResult { + Ok(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.to_string(), + msg: to_json_binary(&ExecuteMsg::Callback(self))?, + funds: vec![], + })) + } +} + +/// This structure describes a migration message. +/// We currently take no arguments for migrations. +#[cw_serde] +#[serde(rename_all = "snake_case")] +pub struct MigrateMsg { + pub max_slippage: Decimal, + pub ntrn_denom: String, + pub paired_denom: String, + pub xyk_pair: String, + pub cl_pair: String, + pub new_lp_token: String, + pub pcl_vesting: String, + pub dust_threshold: Uint128, +} + +impl From for BaseExecute { + fn from(item: ExecuteMsg) -> Self { + match item { + ExecuteMsg::Claim { recipient, amount } => BaseExecute::Claim { recipient, amount }, + ExecuteMsg::Receive(msg) => BaseExecute::Receive(msg), + ExecuteMsg::RegisterVestingAccounts { vesting_accounts } => { + BaseExecute::RegisterVestingAccounts { vesting_accounts } + } + ExecuteMsg::ProposeNewOwner { owner, expires_in } => { + BaseExecute::ProposeNewOwner { owner, expires_in } + } + ExecuteMsg::DropOwnershipProposal {} => BaseExecute::DropOwnershipProposal {}, + ExecuteMsg::ClaimOwnership {} => BaseExecute::ClaimOwnership {}, + ExecuteMsg::SetVestingToken { vesting_token } => { + BaseExecute::SetVestingToken { vesting_token } + } + ExecuteMsg::ManagedExtension { msg } => BaseExecute::ManagedExtension { msg }, + ExecuteMsg::WithManagersExtension { msg } => BaseExecute::WithManagersExtension { msg }, + ExecuteMsg::HistoricalExtension { msg } => BaseExecute::HistoricalExtension { msg }, + _ => panic!("Unhandled ExecuteMsg variant"), + } + } +} diff --git a/contracts/vesting-lp/src/state.rs b/contracts/vesting-lp/src/state.rs new file mode 100644 index 00000000..4036cd9c --- /dev/null +++ b/contracts/vesting-lp/src/state.rs @@ -0,0 +1,20 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Decimal, Uint128}; +use cw_storage_plus::Item; + +/// Config for xyk->CL liquidity migration. +#[cw_serde] +pub struct XykToClMigrationConfig { + /// The maximum allowed slippage tolerance for xyk to CL liquidity migration calls. + pub max_slippage: Decimal, + pub ntrn_denom: String, + pub xyk_pair: Addr, + pub paired_denom: String, + pub cl_pair: Addr, + pub new_lp_token: Addr, + pub pcl_vesting: Addr, + pub dust_threshold: Uint128, +} + +pub const XYK_TO_CL_MIGRATION_CONFIG: Item = + Item::new("xyk_to_cl_migration_config"); diff --git a/packages/vesting-base/Cargo.toml b/packages/vesting-base/Cargo.toml index ffe8e644..f533e362 100644 --- a/packages/vesting-base/Cargo.toml +++ b/packages/vesting-base/Cargo.toml @@ -13,10 +13,10 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cw20 = { workspace = true } +cw20 = { version = "0.15" } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } -astroport = { workspace = true } +astroport = { path = "../../packages/astroport" } thiserror = { workspace = true } # we keep it at 0.15 instead of latest version just for vesting investors contract cw-utils = "0.15" diff --git a/packages/vesting-base/src/error.rs b/packages/vesting-base/src/error.rs index a1859ac0..efee45d3 100644 --- a/packages/vesting-base/src/error.rs +++ b/packages/vesting-base/src/error.rs @@ -20,6 +20,9 @@ pub enum ContractError { #[error("Vesting schedule error on addr: {0}. Should satisfy: (start < end and at_start < total) or (start = end and at_start = total)")] VestingScheduleError(String), + #[error("Vesting schedule error on addr: {0}. No schedule found")] + VestingScheduleExtractError(String), + #[error("Vesting schedule amount error. The total amount should be equal to the CW20 receive amount.")] VestingScheduleAmountError {}, diff --git a/packages/vesting-base/src/handlers.rs b/packages/vesting-base/src/handlers.rs index b85929ad..b05062e1 100644 --- a/packages/vesting-base/src/handlers.rs +++ b/packages/vesting-base/src/handlers.rs @@ -120,7 +120,7 @@ fn receive_cw20( /// * **vesting_accounts** list of accounts and associated vesting schedules to create. /// /// * **cw20_amount** sets the amount that confirms the total amount of all accounts to register. -fn register_vesting_accounts( +pub fn register_vesting_accounts( deps: DepsMut, vesting_accounts: Vec, amount: Uint128, @@ -275,7 +275,7 @@ pub(crate) fn set_vesting_token( ])) } -pub(crate) fn get_vesting_token(config: &Config) -> Result { +pub fn get_vesting_token(config: &Config) -> Result { config .vesting_token .clone() @@ -398,7 +398,7 @@ fn is_sender_whitelisted(store: &mut dyn Storage, config: &Config, sender: &Addr /// * **addr** receiver of the vested tokens. /// /// * **vesting_schedules** vesting schedules to validate. -fn assert_vesting_schedules( +pub fn assert_vesting_schedules( addr: &Addr, vesting_schedules: &[VestingSchedule], ) -> Result<(), ContractError> { diff --git a/packages/vesting-base/src/state.rs b/packages/vesting-base/src/state.rs index 978fd8c6..9178f7ca 100644 --- a/packages/vesting-base/src/state.rs +++ b/packages/vesting-base/src/state.rs @@ -3,9 +3,9 @@ use astroport::common::OwnershipProposal; use cosmwasm_std::{Addr, Deps, StdResult}; use cw_storage_plus::{Bound, Item, Map, SnapshotItem, SnapshotMap, Strategy}; -pub(crate) const CONFIG: Item = Item::new("config"); +pub const CONFIG: Item = Item::new("config"); pub(crate) const OWNERSHIP_PROPOSAL: Item = Item::new("ownership_proposal"); -pub(crate) const VESTING_MANAGERS: Map = Map::new("vesting_managers"); +pub const VESTING_MANAGERS: Map = Map::new("vesting_managers"); pub(crate) const VESTING_STATE: SnapshotItem = SnapshotItem::new( "vesting_state", "vesting_state__checkpoints", @@ -31,14 +31,14 @@ pub(crate) const VESTING_INFO_HISTORICAL: SnapshotMap = Snaps Strategy::EveryBlock, ); -pub(crate) fn vesting_state(historical: bool) -> SnapshotItem<'static, VestingState> { +pub fn vesting_state(historical: bool) -> SnapshotItem<'static, VestingState> { if historical { return VESTING_STATE_HISTORICAL; } VESTING_STATE } -pub(crate) fn vesting_info(historical: bool) -> SnapshotMap<'static, Addr, VestingInfo> { +pub fn vesting_info(historical: bool) -> SnapshotMap<'static, Addr, VestingInfo> { if historical { return VESTING_INFO_HISTORICAL; } diff --git a/packages/vesting-base/src/types.rs b/packages/vesting-base/src/types.rs index f6081025..6a1378b4 100644 --- a/packages/vesting-base/src/types.rs +++ b/packages/vesting-base/src/types.rs @@ -81,6 +81,15 @@ pub struct VestingAccountResponse { pub info: VestingInfo, } +/// This structure describes a custom struct used to pass the vesting data about a specific vesting target during migration. +#[cw_serde] +pub struct VestingAccountFullInfo { + /// The address that's vesting tokens + pub address: Addr, + /// Vesting information + pub info: VestingInfo, +} + /// This structure describes a custom struct used to return vesting data for multiple vesting targets. #[cw_serde] pub struct VestingAccountsResponse { From 0207d5deb9f7782804d415e066c445180e6fc5a8 Mon Sep 17 00:00:00 2001 From: quasisamurai Date: Mon, 26 Feb 2024 13:04:27 -0300 Subject: [PATCH 15/28] recommit new lockfile --- Cargo.lock | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 1eb2066d..46208ad0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1067,6 +1067,21 @@ dependencies = [ "serde", ] +[[package]] +name = "neutron-lockdrop-pcl" +version = "1.0.0" +dependencies = [ + "astroport 3.11.0", + "astroport-periphery", + "cosmwasm-schema", + "cosmwasm-std", + "credits", + "cw-storage-plus 0.15.1", + "cw2 1.1.2", + "cw20 1.1.2", + "serde", +] + [[package]] name = "neutron-price-feed" version = "0.1.0" From e86b087f99f20c72416cdb3439a003eb5269f562 Mon Sep 17 00:00:00 2001 From: quasisamurai Date: Tue, 27 Feb 2024 07:49:12 -0300 Subject: [PATCH 16/28] fix sender issue & rm whitelist check for lp contract --- contracts/vesting-lp-pcl/src/contract.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/contracts/vesting-lp-pcl/src/contract.rs b/contracts/vesting-lp-pcl/src/contract.rs index 54f11a5d..89f3d6dd 100644 --- a/contracts/vesting-lp-pcl/src/contract.rs +++ b/contracts/vesting-lp-pcl/src/contract.rs @@ -91,7 +91,7 @@ fn receive_cw20( if !is_sender_whitelisted( deps.storage, &config, - &deps.api.addr_validate(sender.as_str())?, + &deps.api.addr_validate(cw20_msg.sender.as_str())?, ) || token_asset_info(sender.clone()) != vesting_token { return Err(ContractError::Unauthorized {}); @@ -102,7 +102,10 @@ fn receive_cw20( user_address_raw, user_vesting_info, } => { - if !is_sender_xyk_vesting_lp(deps.storage, &sender) { + if !is_sender_xyk_vesting_lp( + deps.storage, + &deps.api.addr_validate(cw20_msg.sender.as_str())?, + ) { return Err(ContractError::Unauthorized {}); } handle_migrate_xyk_liquidity(deps, env, user_address_raw, user_vesting_info) @@ -114,10 +117,6 @@ fn is_sender_whitelisted(store: &mut dyn Storage, config: &Config, sender: &Addr if *sender == config.owner { return true; } - let xyk_vesting_lp_contract = XYK_VESTING_LP_CONTRACT.load(store).unwrap(); - if *sender == xyk_vesting_lp_contract { - return true; - } if VESTING_MANAGERS.has(store, sender.clone()) { return true; } From 54f05d9ed60cc222622fe68f31d7cd4436c186e8 Mon Sep 17 00:00:00 2001 From: Dmitry Kolupaev Date: Wed, 13 Mar 2024 13:44:07 +0400 Subject: [PATCH 17/28] remove dust_threshold in migration; make query instead to rule out empty pool --- contracts/vesting-lp/src/contract.rs | 12 ++++++++---- contracts/vesting-lp/src/msg.rs | 1 - contracts/vesting-lp/src/state.rs | 3 +-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/contracts/vesting-lp/src/contract.rs b/contracts/vesting-lp/src/contract.rs index 18f0135b..9bc22797 100644 --- a/contracts/vesting-lp/src/contract.rs +++ b/contracts/vesting-lp/src/contract.rs @@ -1,6 +1,7 @@ use crate::msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg}; use crate::state::{XykToClMigrationConfig, XYK_TO_CL_MIGRATION_CONFIG}; -use astroport::asset::{native_asset, PairInfo}; +use astroport::asset::{native_asset, Asset, PairInfo}; +use astroport::pair::QueryMsg::Share; use astroport::pair::{ Cw20HookMsg as PairCw20HookMsg, ExecuteMsg as PairExecuteMsg, QueryMsg as PairQueryMsg, }; @@ -81,7 +82,6 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result = deps.querier.query_wasm_smart( + migration_config.xyk_pair.clone(), + &Share { amount: user_share }, + )?; // if there is nothing to migrate just update vi and quit. - // if there is only dust, than send it back to user, update vi and quit - if user_share < migration_config.dust_threshold { + // if there is only dust, then send it back to user, update vi and quit + if xyk_amount_to_withdraw.iter().any(|a| a.amount.is_zero()) { if !user_share.is_zero() { resp = resp.add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: pair_info.liquidity_token.to_string(), diff --git a/contracts/vesting-lp/src/msg.rs b/contracts/vesting-lp/src/msg.rs index 21018e6e..0936bc33 100644 --- a/contracts/vesting-lp/src/msg.rs +++ b/contracts/vesting-lp/src/msg.rs @@ -117,7 +117,6 @@ pub struct MigrateMsg { pub cl_pair: String, pub new_lp_token: String, pub pcl_vesting: String, - pub dust_threshold: Uint128, } impl From for BaseExecute { diff --git a/contracts/vesting-lp/src/state.rs b/contracts/vesting-lp/src/state.rs index 4036cd9c..9cf45b80 100644 --- a/contracts/vesting-lp/src/state.rs +++ b/contracts/vesting-lp/src/state.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Decimal, Uint128}; +use cosmwasm_std::{Addr, Decimal}; use cw_storage_plus::Item; /// Config for xyk->CL liquidity migration. @@ -13,7 +13,6 @@ pub struct XykToClMigrationConfig { pub cl_pair: Addr, pub new_lp_token: Addr, pub pcl_vesting: Addr, - pub dust_threshold: Uint128, } pub const XYK_TO_CL_MIGRATION_CONFIG: Item = From 8e8840922beac82548f058bad59f0f215224813c Mon Sep 17 00:00:00 2001 From: Dmitry Kolupaev Date: Wed, 13 Mar 2024 17:04:36 +0400 Subject: [PATCH 18/28] rename --- contracts/vesting-lp/src/contract.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/vesting-lp/src/contract.rs b/contracts/vesting-lp/src/contract.rs index 9bc22797..ba5e0dcd 100644 --- a/contracts/vesting-lp/src/contract.rs +++ b/contracts/vesting-lp/src/contract.rs @@ -112,14 +112,14 @@ fn execute_migrate_liquidity( .query_wasm_smart(migration_config.xyk_pair.clone(), &PairQueryMsg::Pair {})?; let user_share = compute_share(&user.info)?; - let xyk_amount_to_withdraw: Vec = deps.querier.query_wasm_smart( + let user_share_assets: Vec = deps.querier.query_wasm_smart( migration_config.xyk_pair.clone(), &Share { amount: user_share }, )?; // if there is nothing to migrate just update vi and quit. // if there is only dust, then send it back to user, update vi and quit - if xyk_amount_to_withdraw.iter().any(|a| a.amount.is_zero()) { + if user_share_assets.iter().any(|a| a.amount.is_zero()) { if !user_share.is_zero() { resp = resp.add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: pair_info.liquidity_token.to_string(), From 3e10ee224628003a86f816a78145560bccc21a2c Mon Sep 17 00:00:00 2001 From: Dmitry Kolupaev Date: Wed, 20 Mar 2024 12:04:57 +0400 Subject: [PATCH 19/28] fix: load user info safely #ntrn-240 --- contracts/lockdrop-pcl/src/contract.rs | 4 +--- contracts/lockdrop/src/contract.rs | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 4581dab1..0eaf15fb 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -437,9 +437,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( // CHECK ::: Is LP Token Pool supported or not ? let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - let mut user_info = USER_INFO - .may_load(deps.storage, &user_address)? - .unwrap_or_default(); + let mut user_info = USER_INFO.load(deps.storage, &user_address)?; // If user's total NTRN rewards == 0 :: We update all of the user's lockup positions to calculate NTRN rewards and for each alongwith their equivalent Astroport LP Shares if user_info.total_ntrn_rewards == Uint128::zero() { diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index a275602f..23271bf0 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -530,9 +530,7 @@ pub fn handle_migrate_liquidity_to_pcl_pools( let config = CONFIG.load(deps.storage)?; let state = STATE.load(deps.storage)?; - let mut user_info = USER_INFO - .may_load(deps.storage, &user_address)? - .unwrap_or_default(); + let mut user_info = USER_INFO.load(deps.storage, &user_address)?; // If user's total NTRN rewards == 0 :: We update all of the user's lockup positions to // calculate NTRN rewards and for each alongwith their equivalent Astroport LP Shares if user_info.total_ntrn_rewards == Uint128::zero() { @@ -1190,9 +1188,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( // CHECK ::: Is LP Token Pool supported or not ? let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - let mut user_info = USER_INFO - .may_load(deps.storage, &user_address)? - .unwrap_or_default(); + let mut user_info = USER_INFO.load(deps.storage, &user_address)?; // If user's total NTRN rewards == 0 :: We update all of the user's lockup positions to calculate NTRN rewards and for each alongwith their equivalent Astroport LP Shares if user_info.total_ntrn_rewards == Uint128::zero() { From 374eea0f1314b5f43ab9394401fab05cb47e46f5 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 21 Mar 2024 16:49:01 +0200 Subject: [PATCH 20/28] update pool info on LP deposit to reflect implicit rewards claim --- contracts/lockdrop-pcl/src/contract.rs | 68 ++++++++++++++++++++------ 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 4581dab1..16a6c21f 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -5,25 +5,25 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; +use astroport::DecimalCheckedOps; use astroport::incentives::{ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg}; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; -use astroport::DecimalCheckedOps; use cosmwasm_std::{ - attr, coins, entry_point, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, - Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, + Addr, attr, BankMsg, Binary, coins, CosmosMsg, Decimal, Decimal256, Deps, + DepsMut, Empty, entry_point, Env, MessageInfo, Order, Response, StdError, StdResult, to_json_binary, Uint128, Uint256, WasmMsg, }; -use cw2::set_contract_version; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; +use cw2::set_contract_version; use astroport_periphery::lockdrop::{ LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, UserInfo as LockdropXYKUserInfo, }; use astroport_periphery::lockdrop_pcl::{ - CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, - LockupInfo, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockupInfo, LockUpInfoResponse, + LockUpInfoSummary, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfo, UserInfoResponse, UserInfoWithListResponse, }; use astroport_periphery::utils::Decimal256CheckedOps; @@ -371,8 +371,9 @@ pub fn handle_migrate_xyk_liquidity( }, )?; + let mut cosmos_msgs: Vec> = vec![]; // provide the transferred liquidity to the PCL pool - let mut cosmos_msgs: Vec> = vec![CosmosMsg::Wasm(WasmMsg::Execute { + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: astroport_pool.to_string(), funds: info.funds.clone(), msg: to_json_binary(&ProvideLiquidity { @@ -390,7 +391,46 @@ pub fn handle_migrate_xyk_liquidity( auto_stake: Some(true), receiver: None, })?, - })]; + })); + + let incentives = &config.incentives; + + // QUERY :: Check if there are any pending staking rewards + let pending_rewards_response: StdResult> = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::PendingRewards { + lp_token: pool_info.lp_token.to_string(), + user: env.contract.address.to_string(), + }, + ); + + // the incentives contract claims rewards on LP Deposit: https://github.com/astroport-fi/astroport-core/blob/514d83331da3232111c5c590fd8086ef62025ca9/contracts/tokenomics/incentives/src/execute.rs#L190 + // thus we need update pool info after the deposit otherwise there will be unaccounted rewards on PCL lockdrop during users migration + if let Ok(pending_rewards) = pending_rewards_response { + let prev_pending_rewards_balances: Vec = pending_rewards + .iter() + .map(|asset| { + let balance = asset + .info + .query_pool(&deps.querier, env.contract.address.clone()) + .unwrap_or_default(); + + Asset { + info: asset.info.clone(), + amount: balance, + } + }) + .collect(); + + cosmos_msgs.push( + CallbackMsg::UpdatePoolOnDualRewardsClaim { + pool_type: pool_type.into(), + prev_reward_balances: prev_pending_rewards_balances, + } + .to_cosmos_msg(&env)?, + ); + } + // invoke callback that creates a lockup entry for the provided liquidity cosmos_msgs.push( CallbackMsg::FinishLockupMigrationCallback { @@ -402,7 +442,7 @@ pub fn handle_migrate_xyk_liquidity( user_info, lockup_info, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(cosmos_msgs)) @@ -517,7 +557,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( pool_type, prev_reward_balances: prev_pending_rewards_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } @@ -528,7 +568,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( duration, withdraw_lp_stake, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -693,7 +733,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; let mut pending_reward_assets: Vec = vec![]; @@ -1090,7 +1130,7 @@ pub fn query_lockup_info( .lp_units_locked .full_mul(pool_astroport_lp_units) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); @@ -1181,7 +1221,7 @@ pub fn calculate_astro_incentives_for_lockup( Uint256::from(pool_incentives_share).checked_mul(lockup_weighted_balance)?, Uint256::from(total_incentives_share).checked_mul(total_weighted_amount)?, ) - .checked_mul_uint256(total_lockdrop_incentives.into())?) + .checked_mul_uint256(total_lockdrop_incentives.into())?) } } From d44ee2f39e61ac3bd6a4f82b77c01f31d42ce072 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Thu, 21 Mar 2024 16:50:34 +0200 Subject: [PATCH 21/28] formatting --- contracts/lockdrop-pcl/src/contract.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 16a6c21f..8663bcf8 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -5,25 +5,25 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; -use astroport::DecimalCheckedOps; use astroport::incentives::{ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg}; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; +use astroport::DecimalCheckedOps; use cosmwasm_std::{ - Addr, attr, BankMsg, Binary, coins, CosmosMsg, Decimal, Decimal256, Deps, - DepsMut, Empty, entry_point, Env, MessageInfo, Order, Response, StdError, StdResult, to_json_binary, + attr, coins, entry_point, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, + Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, Uint256, WasmMsg, }; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use cw2::set_contract_version; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; use astroport_periphery::lockdrop::{ LockupInfoV2 as LockdropXYKLockupInfoV2, PoolType as LockdropXYKPoolType, UserInfo as LockdropXYKUserInfo, }; use astroport_periphery::lockdrop_pcl::{ - CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockupInfo, LockUpInfoResponse, - LockUpInfoSummary, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, + CallbackMsg, Config, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, + LockupInfo, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfo, UserInfoResponse, UserInfoWithListResponse, }; use astroport_periphery::utils::Decimal256CheckedOps; @@ -427,7 +427,7 @@ pub fn handle_migrate_xyk_liquidity( pool_type: pool_type.into(), prev_reward_balances: prev_pending_rewards_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } @@ -442,7 +442,7 @@ pub fn handle_migrate_xyk_liquidity( user_info, lockup_info, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(cosmos_msgs)) @@ -557,7 +557,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( pool_type, prev_reward_balances: prev_pending_rewards_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } @@ -568,7 +568,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( duration, withdraw_lp_stake, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -733,7 +733,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; let mut pending_reward_assets: Vec = vec![]; @@ -1130,7 +1130,7 @@ pub fn query_lockup_info( .lp_units_locked .full_mul(pool_astroport_lp_units) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); @@ -1221,7 +1221,7 @@ pub fn calculate_astro_incentives_for_lockup( Uint256::from(pool_incentives_share).checked_mul(lockup_weighted_balance)?, Uint256::from(total_incentives_share).checked_mul(total_weighted_amount)?, ) - .checked_mul_uint256(total_lockdrop_incentives.into())?) + .checked_mul_uint256(total_lockdrop_incentives.into())?) } } From caf5e1e576be1b977bdf6334772f5a99907131cc Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Tue, 26 Mar 2024 14:42:46 +0200 Subject: [PATCH 22/28] proper handling of unnecessary vesting lp migration --- contracts/lockdrop/src/contract.rs | 38 +++++++++++---------- contracts/vesting-lp/src/contract.rs | 50 ++++++++++++++++------------ 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index a275602f..f59ffa6e 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -6,30 +6,30 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; +use astroport::DecimalCheckedOps; use astroport::generator::{ ExecuteMsg as GenExecuteMsg, PendingTokenResponse, QueryMsg as GenQueryMsg, RewardInfoResponse, }; use astroport::restricted_vector::RestrictedVector; -use astroport::DecimalCheckedOps; -use astroport_periphery::utils::Decimal256CheckedOps; use cosmwasm_std::{ - attr, coins, entry_point, from_json, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, - Decimal, Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, + Addr, attr, BankMsg, Binary, Coin, coins, CosmosMsg, Decimal, Decimal256, Deps, + DepsMut, entry_point, Env, from_json, MessageInfo, Order, Response, StdError, StdResult, to_json_binary, Uint128, Uint256, WasmMsg, }; -use cw2::set_contract_version; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg, MinterResponse}; +use cw2::set_contract_version; -use crate::raw_queries::{raw_balance, raw_generator_deposit}; use astroport_periphery::lockdrop::{ CallbackMsg, Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, LockUpInfoSummary, LockupInfoV2, MigrateMsg, PoolInfo, PoolType, QueryMsg, State, StateResponse, UpdateConfigMsg, UserInfoResponse, UserInfoWithListResponse, }; use astroport_periphery::lockdrop_pcl::ExecuteMsg as LockdropPCLExecuteMsg; +use astroport_periphery::utils::Decimal256CheckedOps; +use crate::raw_queries::{raw_balance, raw_generator_deposit}; use crate::state::{ - CompatibleLoader, ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, PCL_LOCKDROP_CONTRACT, + ASSET_POOLS, CompatibleLoader, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, PCL_LOCKDROP_CONTRACT, STATE, TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, }; @@ -450,6 +450,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { /// * **_msg** is an object of type [`MigrateMsg`]. #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + PCL_LOCKDROP_CONTRACT.save( deps.storage, &deps.api.addr_validate(&msg.pcl_lockdrop_contract)?, @@ -569,7 +571,7 @@ pub fn handle_migrate_liquidity_to_pcl_pools( user_address: user_address.clone(), duration, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } Ok(Response::default().add_messages(cosmos_msgs)) @@ -665,7 +667,7 @@ fn callback_init_migrate_lockup_to_pcl_pools( prev_ntrn_balance: reward_token_balance, prev_proxy_reward_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } @@ -675,7 +677,7 @@ fn callback_init_migrate_lockup_to_pcl_pools( user_address, duration, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(cosmos_msgs)) @@ -1292,7 +1294,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( prev_ntrn_balance: reward_token_balance, prev_proxy_reward_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } } else if user_info.ntrn_transferred && !withdraw_lp_stake { @@ -1306,7 +1308,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( duration, withdraw_lp_stake, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -1518,7 +1520,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; // If Astro LP tokens are staked with Astro generator @@ -1733,7 +1735,7 @@ pub fn callback_transfer_all_rewards_before_migration( .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( @@ -1835,7 +1837,7 @@ pub fn callback_transfer_all_rewards_before_migration( astroport_lp_token, astroport_lp_amount, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -1943,7 +1945,7 @@ pub fn callback_withdraw_user_lockup( paired_asset_denom, paired_asset_balance, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -2216,7 +2218,7 @@ pub fn query_lockup_info( .lp_units_locked .full_mul(pool_astroport_lp_units) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); @@ -2331,7 +2333,7 @@ pub fn calculate_astro_incentives_for_lockup( Uint256::from(pool_incentives_share).checked_mul(lockup_weighted_balance)?, Uint256::from(total_incentives_share).checked_mul(total_weighted_amount)?, ) - .checked_mul_uint256(total_lockdrop_incentives.into())?) + .checked_mul_uint256(total_lockdrop_incentives.into())?) } } diff --git a/contracts/vesting-lp/src/contract.rs b/contracts/vesting-lp/src/contract.rs index 18f0135b..250a1b0a 100644 --- a/contracts/vesting-lp/src/contract.rs +++ b/contracts/vesting-lp/src/contract.rs @@ -1,25 +1,27 @@ -use crate::msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg}; -use crate::state::{XykToClMigrationConfig, XYK_TO_CL_MIGRATION_CONFIG}; +use cosmwasm_std::{ + Addr, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, entry_point, Env, MessageInfo, + Response, StdResult, to_json_binary, Uint128, WasmMsg, +}; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; +use cw2::set_contract_version; + use astroport::asset::{native_asset, PairInfo}; use astroport::pair::{ Cw20HookMsg as PairCw20HookMsg, ExecuteMsg as PairExecuteMsg, QueryMsg as PairQueryMsg, }; -use cosmwasm_std::{ - entry_point, to_json_binary, Addr, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, - MessageInfo, Response, StdResult, Uint128, WasmMsg, -}; -use cw2::set_contract_version; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use vesting_base::builder::VestingBaseBuilder; use vesting_base::error::ContractError; use vesting_base::handlers::execute as base_execute; use vesting_base::handlers::query as base_query; use vesting_base::msg::{ExecuteMsg as BaseExecute, QueryMsg}; -use vesting_base::state::{vesting_info, vesting_state, CONFIG}; +use vesting_base::state::{CONFIG, vesting_info, vesting_state}; use vesting_base::types::{ VestingAccountFullInfo, VestingInfo, VestingSchedule, VestingSchedulePoint, }; +use crate::msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg}; +use crate::state::{XYK_TO_CL_MIGRATION_CONFIG, XykToClMigrationConfig}; + /// Contract name that is used for migration. const CONTRACT_NAME: &str = "neutron-vesting-lp"; /// Contract version that is used for migration. @@ -71,6 +73,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { /// Manages contract migration. #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + XYK_TO_CL_MIGRATION_CONFIG.save( deps.storage, &XykToClMigrationConfig { @@ -104,7 +108,7 @@ fn execute_migrate_liquidity( let vesting_info = vesting_info(config.extensions.historical); let info = vesting_info.load(deps.storage, address.clone())?; let mut resp = Response::default(); - let user = VestingAccountFullInfo { address, info }; + let user = VestingAccountFullInfo { address, info: info.clone() }; // get pairs LP token addresses let pair_info: PairInfo = deps @@ -127,15 +131,17 @@ fn execute_migrate_liquidity( })); } - vesting_info.save( - deps.storage, - user.address.clone(), - &VestingInfo { - schedules: vec![], - released_amount: Uint128::zero(), - }, - env.block.height, - )?; + if !info.schedules.is_empty() { + vesting_info.save( + deps.storage, + user.address.clone(), + &VestingInfo { + schedules: vec![], + released_amount: Uint128::zero(), + }, + env.block.height, + )?; + } return Ok(resp); }; @@ -158,7 +164,7 @@ fn execute_migrate_liquidity( paired_asset_denom: migration_config.paired_denom.clone(), user, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(resp) @@ -277,7 +283,7 @@ fn migrate_liquidity_to_cl_pair_callback( slippage_tolerance, user, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(msgs)) @@ -343,7 +349,7 @@ fn provide_liquidity_to_cl_pair_after_withdrawal_callback( user, init_balance_pcl_lp: current_balance, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(msgs)) From 3ecc8c8574b32f59728213a4d0febcd745f4831f Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Tue, 26 Mar 2024 14:44:00 +0200 Subject: [PATCH 23/28] format --- contracts/lockdrop/src/contract.rs | 32 ++++++++++++++-------------- contracts/vesting-lp/src/contract.rs | 21 ++++++++++-------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index f59ffa6e..20b7d83b 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -6,18 +6,18 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; -use astroport::DecimalCheckedOps; use astroport::generator::{ ExecuteMsg as GenExecuteMsg, PendingTokenResponse, QueryMsg as GenQueryMsg, RewardInfoResponse, }; use astroport::restricted_vector::RestrictedVector; +use astroport::DecimalCheckedOps; use cosmwasm_std::{ - Addr, attr, BankMsg, Binary, Coin, coins, CosmosMsg, Decimal, Decimal256, Deps, - DepsMut, entry_point, Env, from_json, MessageInfo, Order, Response, StdError, StdResult, to_json_binary, + attr, coins, entry_point, from_json, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, + Decimal, Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, Uint256, WasmMsg, }; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg, MinterResponse}; use cw2::set_contract_version; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, Cw20ReceiveMsg, MinterResponse}; use astroport_periphery::lockdrop::{ CallbackMsg, Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, LockUpInfoResponse, @@ -29,7 +29,7 @@ use astroport_periphery::utils::Decimal256CheckedOps; use crate::raw_queries::{raw_balance, raw_generator_deposit}; use crate::state::{ - ASSET_POOLS, CompatibleLoader, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, PCL_LOCKDROP_CONTRACT, + CompatibleLoader, ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, PCL_LOCKDROP_CONTRACT, STATE, TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, }; @@ -571,7 +571,7 @@ pub fn handle_migrate_liquidity_to_pcl_pools( user_address: user_address.clone(), duration, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } Ok(Response::default().add_messages(cosmos_msgs)) @@ -667,7 +667,7 @@ fn callback_init_migrate_lockup_to_pcl_pools( prev_ntrn_balance: reward_token_balance, prev_proxy_reward_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } @@ -677,7 +677,7 @@ fn callback_init_migrate_lockup_to_pcl_pools( user_address, duration, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(cosmos_msgs)) @@ -1294,7 +1294,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( prev_ntrn_balance: reward_token_balance, prev_proxy_reward_balances, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); } } else if user_info.ntrn_transferred && !withdraw_lp_stake { @@ -1308,7 +1308,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( duration, withdraw_lp_stake, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -1520,7 +1520,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; // If Astro LP tokens are staked with Astro generator @@ -1735,7 +1735,7 @@ pub fn callback_transfer_all_rewards_before_migration( .lp_units_locked .full_mul(balance) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; let rwi: RewardInfoResponse = deps.querier.query_wasm_smart( @@ -1837,7 +1837,7 @@ pub fn callback_transfer_all_rewards_before_migration( astroport_lp_token, astroport_lp_amount, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -1945,7 +1945,7 @@ pub fn callback_withdraw_user_lockup( paired_asset_denom, paired_asset_balance, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::new().add_messages(cosmos_msgs)) @@ -2218,7 +2218,7 @@ pub fn query_lockup_info( .lp_units_locked .full_mul(pool_astroport_lp_units) .checked_div(Uint256::from(pool_info.amount_in_lockups))?) - .try_into()? + .try_into()? }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); @@ -2333,7 +2333,7 @@ pub fn calculate_astro_incentives_for_lockup( Uint256::from(pool_incentives_share).checked_mul(lockup_weighted_balance)?, Uint256::from(total_incentives_share).checked_mul(total_weighted_amount)?, ) - .checked_mul_uint256(total_lockdrop_incentives.into())?) + .checked_mul_uint256(total_lockdrop_incentives.into())?) } } diff --git a/contracts/vesting-lp/src/contract.rs b/contracts/vesting-lp/src/contract.rs index 250a1b0a..260c5a22 100644 --- a/contracts/vesting-lp/src/contract.rs +++ b/contracts/vesting-lp/src/contract.rs @@ -1,9 +1,9 @@ use cosmwasm_std::{ - Addr, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, entry_point, Env, MessageInfo, - Response, StdResult, to_json_binary, Uint128, WasmMsg, + entry_point, to_json_binary, Addr, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, + MessageInfo, Response, StdResult, Uint128, WasmMsg, }; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use cw2::set_contract_version; +use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use astroport::asset::{native_asset, PairInfo}; use astroport::pair::{ @@ -14,13 +14,13 @@ use vesting_base::error::ContractError; use vesting_base::handlers::execute as base_execute; use vesting_base::handlers::query as base_query; use vesting_base::msg::{ExecuteMsg as BaseExecute, QueryMsg}; -use vesting_base::state::{CONFIG, vesting_info, vesting_state}; +use vesting_base::state::{vesting_info, vesting_state, CONFIG}; use vesting_base::types::{ VestingAccountFullInfo, VestingInfo, VestingSchedule, VestingSchedulePoint, }; use crate::msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg}; -use crate::state::{XYK_TO_CL_MIGRATION_CONFIG, XykToClMigrationConfig}; +use crate::state::{XykToClMigrationConfig, XYK_TO_CL_MIGRATION_CONFIG}; /// Contract name that is used for migration. const CONTRACT_NAME: &str = "neutron-vesting-lp"; @@ -108,7 +108,10 @@ fn execute_migrate_liquidity( let vesting_info = vesting_info(config.extensions.historical); let info = vesting_info.load(deps.storage, address.clone())?; let mut resp = Response::default(); - let user = VestingAccountFullInfo { address, info: info.clone() }; + let user = VestingAccountFullInfo { + address, + info: info.clone(), + }; // get pairs LP token addresses let pair_info: PairInfo = deps @@ -164,7 +167,7 @@ fn execute_migrate_liquidity( paired_asset_denom: migration_config.paired_denom.clone(), user, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(resp) @@ -283,7 +286,7 @@ fn migrate_liquidity_to_cl_pair_callback( slippage_tolerance, user, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(msgs)) @@ -349,7 +352,7 @@ fn provide_liquidity_to_cl_pair_after_withdrawal_callback( user, init_balance_pcl_lp: current_balance, } - .to_cosmos_msg(&env)?, + .to_cosmos_msg(&env)?, ); Ok(Response::default().add_messages(msgs)) From 705de7c228bd99a12dc02d848989c7a8a5036a69 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Tue, 26 Mar 2024 16:32:26 +0300 Subject: [PATCH 24/28] pass reward tokens info instead of querying for pcl lockdrop --- contracts/lockdrop-pcl/src/contract.rs | 24 +++++++++---------- .../astroport_periphery/src/lockdrop_pcl.rs | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 4581dab1..c40ad036 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -190,6 +190,7 @@ fn _handle_callback( user_address, duration, withdraw_lp_stake, + reward_tokens, } => callback_withdraw_user_rewards_for_lockup_optional_withdraw( deps, env, @@ -197,6 +198,7 @@ fn _handle_callback( user_address, duration, withdraw_lp_stake, + reward_tokens, ), CallbackMsg::FinishLockupMigrationCallback { pool_type, @@ -485,6 +487,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( }, )?; + let mut reward_tokens: Vec = vec![]; if pending_rewards_response .iter() .any(|asset| !asset.amount.is_zero()) @@ -492,6 +495,8 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let prev_pending_rewards_balances: Vec = pending_rewards_response .iter() .map(|asset| { + reward_tokens.push(asset.info.clone()); + let balance = asset .info .query_pool(&deps.querier, env.contract.address.clone()) @@ -527,6 +532,7 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( user_address, duration, withdraw_lp_stake, + reward_tokens, } .to_cosmos_msg(&env)?, ); @@ -658,6 +664,7 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( user_address: Addr, duration: u64, withdraw_lp_stake: bool, + reward_tokens: Vec, ) -> StdResult { let config = CONFIG.load(deps.storage)?; let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; @@ -699,17 +706,10 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( let mut pending_reward_assets: Vec = vec![]; // If this LP token is getting incentives // Calculate claimable staking rewards for this lockup - let pending_rewards: Vec = deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::PendingRewards { - lp_token: astroport_lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; - for reward in pending_rewards { + for reward_token in reward_tokens { let incentives_rewards_per_share = pool_info .incentives_rewards_per_share - .load(&reward.info) + .load(&reward_token) .unwrap_or_default(); if incentives_rewards_per_share.is_zero() { continue; @@ -720,20 +720,20 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .to_uint_floor(); let debt = lockup_info .incentives_debt - .load(&reward.info) + .load(&reward_token) .unwrap_or_default(); let pending_reward = total_lockup_rewards.checked_sub(debt)?; if !pending_reward.is_zero() { pending_reward_assets.push(Asset { - info: reward.info.clone(), + info: reward_token.clone(), amount: pending_reward, }); } lockup_info .incentives_debt - .update(&reward.info, total_lockup_rewards.checked_sub(debt)?)?; + .update(&reward_token, total_lockup_rewards.checked_sub(debt)?)?; } // If this is a void transaction (no state change), then return error. diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 72def852..6b9fd83f 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -183,6 +183,7 @@ pub enum CallbackMsg { user_address: Addr, duration: u64, withdraw_lp_stake: bool, + reward_tokens: Vec, }, /// Completes the liquidity migration process by making all necessary state updates for the lockup /// position. From f6cb16883b8019b083041feb3fe70cfcc959fa31 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Wed, 27 Mar 2024 13:51:53 +0300 Subject: [PATCH 25/28] bump lockdrop and vesting-lp contracts versions --- Cargo.lock | 4 ++-- contracts/lockdrop/Cargo.toml | 2 +- contracts/vesting-lp/Cargo.toml | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46208ad0..322d89cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1054,7 +1054,7 @@ dependencies = [ [[package]] name = "neutron-lockdrop" -version = "1.2.1" +version = "1.3.0" dependencies = [ "astroport 3.11.0", "astroport-periphery", @@ -1583,7 +1583,7 @@ dependencies = [ [[package]] name = "vesting-lp" -version = "1.1.0" +version = "1.2.0" dependencies = [ "astroport 2.0.0", "astroport-token", diff --git a/contracts/lockdrop/Cargo.toml b/contracts/lockdrop/Cargo.toml index e98eceb1..ff26a052 100644 --- a/contracts/lockdrop/Cargo.toml +++ b/contracts/lockdrop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "neutron-lockdrop" -version = "1.2.1" +version = "1.3.0" authors = ["_astromartian"] edition = "2021" diff --git a/contracts/vesting-lp/Cargo.toml b/contracts/vesting-lp/Cargo.toml index 0dadfa86..1ff8cfd2 100644 --- a/contracts/vesting-lp/Cargo.toml +++ b/contracts/vesting-lp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vesting-lp" -version = "1.1.0" +version = "1.2.0" authors = ["Neutron"] edition = "2021" description = "Vesting contract with a voting capabilities. Provides queries to get the amount of tokens are being held by user at certain height." @@ -14,16 +14,16 @@ library = [] [dependencies] cw2 = { version = "0.15" } -vesting-base = {path = "../../packages/vesting-base"} -vesting-lp-pcl = {path = "../vesting-lp-pcl"} +vesting-base = { path = "../../packages/vesting-base" } +vesting-lp-pcl = { path = "../vesting-lp-pcl" } astroport = { path = "../../packages/astroport" } -cosmwasm-schema = { version = "1.1", default-features = false } +cosmwasm-schema = { version = "1.1", default-features = false } cosmwasm-std = { version = "1.1" } cw-storage-plus = "0.15" cw20 = { version = "0.15" } [dev-dependencies] cw-multi-test = "0.15" -astroport-token = {git = "https://github.com/astroport-fi/astroport-core.git", rev = "65ce7d1879cc5d95b09fa14202f0423bba52ae0e" } +astroport-token = { git = "https://github.com/astroport-fi/astroport-core.git", rev = "65ce7d1879cc5d95b09fa14202f0423bba52ae0e" } cw20 = { version = "0.15" } cw-utils = "0.15" From 2aadccf455caad4ac4df2835d14683929f74c34b Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Fri, 29 Mar 2024 17:52:01 +0300 Subject: [PATCH 26/28] add missing reward_tokens param description --- contracts/lockdrop-pcl/src/contract.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index c40ad036..72510f80 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -657,6 +657,8 @@ pub fn update_pool_on_dual_rewards_claim( /// * **duration** is a vector of type [`u64`]. Duration of the lockup for which rewards have been claimed / position unlocked. /// /// * **withdraw_lp_stake** is an object of type [`bool`]. Boolean value indicating if the ASTRO LP Tokens are to be sent to the user or not. +/// +/// * **reward_tokens** is vector of [`AssetInfo`]. A list of assets to calculate claimable staking rewards for. pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( deps: DepsMut, env: Env, From a7077937b4f85bc91bb0fa5bf84caec6d75bb32a Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 4 Apr 2024 15:08:35 +0300 Subject: [PATCH 27/28] delay migrated liquidity staking until pool fully migrated --- contracts/lockdrop-pcl/src/contract.rs | 419 +++++++++--------- contracts/lockdrop/src/contract.rs | 17 + .../astroport_periphery/src/lockdrop_pcl.rs | 25 +- 3 files changed, 247 insertions(+), 214 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 767b9a29..7de038ce 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -11,8 +11,8 @@ use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; use cosmwasm_std::{ attr, coins, entry_point, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, - Decimal256, Deps, DepsMut, Empty, Env, MessageInfo, Order, Response, StdError, StdResult, - Uint128, Uint256, WasmMsg, + Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Uint128, + Uint256, WasmMsg, }; use cw2::set_contract_version; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse}; @@ -28,7 +28,7 @@ use astroport_periphery::lockdrop_pcl::{ }; use astroport_periphery::utils::Decimal256CheckedOps; -use crate::raw_queries::raw_incentives_deposit; +use crate::raw_queries::{raw_balance, raw_incentives_deposit}; use crate::state::{ ASSET_POOLS, CONFIG, LOCKUP_INFO, OWNERSHIP_PROPOSAL, STATE, TOTAL_USER_LOCKUP_AMOUNT, USER_INFO, @@ -86,6 +86,7 @@ pub fn instantiate( incentives_share: msg.atom_incentives_share, weighted_amount: msg.atom_weighted_amount, incentives_rewards_per_share: RestrictedVector::default(), + is_staked: false, }; ASSET_POOLS.save(deps.storage, PoolType::ATOM, &pool_info, env.block.height)?; @@ -96,6 +97,7 @@ pub fn instantiate( incentives_share: msg.usdc_incentives_share, weighted_amount: msg.usdc_weighted_amount, incentives_rewards_per_share: RestrictedVector::default(), + is_staked: false, }; ASSET_POOLS.save(deps.storage, PoolType::USDC, &pool_info, env.block.height)?; @@ -154,6 +156,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S duration, user_info, lockup_info, + stake, } => handle_migrate_xyk_liquidity( deps, env, @@ -163,6 +166,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S duration, user_info, lockup_info, + stake, ), } } @@ -205,9 +209,10 @@ fn _handle_callback( user_address, duration, lp_token, - staked_lp_token_amount, + prev_lp_token_amount, user_info, lockup_info, + stake, } => callback_finish_lockup_migration( deps, env, @@ -215,9 +220,10 @@ fn _handle_callback( user_address, duration, lp_token, - staked_lp_token_amount, + prev_lp_token_amount, user_info, lockup_info, + stake, ), } } @@ -295,7 +301,7 @@ pub fn handle_update_config( { let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; - let staked_lp_token_amount = deps.querier.query_wasm_smart::( + let staked_lp_token_amount: Uint128 = deps.querier.query_wasm_smart( config.incentives.to_string(), &IncentivesQueryMsg::Deposit { lp_token: pool_info.lp_token.to_string(), @@ -305,7 +311,7 @@ pub fn handle_update_config( if !staked_lp_token_amount.is_zero() { return Err(StdError::generic_err(format!( - "{:?} astro LP tokens already staked. Unstake them before updating generator", + "{:?} astro LP tokens already staked. Unstake them before updating incentives contract", pool_type ))); } @@ -343,6 +349,7 @@ pub fn handle_migrate_xyk_liquidity( duration: u64, user_info: LockdropXYKUserInfo, lockup_info: LockdropXYKLockupInfoV2, + stake: bool, ) -> StdResult { let config = CONFIG.load(deps.storage)?; if info.sender != config.xyk_lockdrop_contract { @@ -356,7 +363,7 @@ pub fn handle_migrate_xyk_liquidity( )); } - // determine the PCL pool info and the current staked lp token amount + // determine the PCL pool info and the current amount of lp tokens on contract's account let pool_info = ASSET_POOLS.load(deps.storage, pool_type.into())?; let astroport_pool: String = deps .querier @@ -365,89 +372,50 @@ pub fn handle_migrate_xyk_liquidity( &cw20::Cw20QueryMsg::Minter {}, )? .minter; - let staked_lp_token_amount = deps.querier.query_wasm_smart::( - config.incentives.to_string(), - &IncentivesQueryMsg::Deposit { - lp_token: pool_info.lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; - - let mut cosmos_msgs: Vec> = vec![]; - // provide the transferred liquidity to the PCL pool - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: astroport_pool.to_string(), - funds: info.funds.clone(), - msg: to_json_binary(&ProvideLiquidity { - assets: info - .funds - .iter() - .map(|f| Asset { - info: AssetInfo::NativeToken { - denom: f.denom.clone(), - }, - amount: f.amount, - }) - .collect(), - slippage_tolerance: None, - auto_stake: Some(true), - receiver: None, - })?, - })); - - let incentives = &config.incentives; - - // QUERY :: Check if there are any pending staking rewards - let pending_rewards_response: StdResult> = deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::PendingRewards { - lp_token: pool_info.lp_token.to_string(), - user: env.contract.address.to_string(), - }, - ); - - // the incentives contract claims rewards on LP Deposit: https://github.com/astroport-fi/astroport-core/blob/514d83331da3232111c5c590fd8086ef62025ca9/contracts/tokenomics/incentives/src/execute.rs#L190 - // thus we need update pool info after the deposit otherwise there will be unaccounted rewards on PCL lockdrop during users migration - if let Ok(pending_rewards) = pending_rewards_response { - let prev_pending_rewards_balances: Vec = pending_rewards - .iter() - .map(|asset| { - let balance = asset - .info - .query_pool(&deps.querier, env.contract.address.clone()) - .unwrap_or_default(); - - Asset { - info: asset.info.clone(), - amount: balance, - } - }) - .collect(); - - cosmos_msgs.push( - CallbackMsg::UpdatePoolOnDualRewardsClaim { - pool_type: pool_type.into(), - prev_reward_balances: prev_pending_rewards_balances, - } - .to_cosmos_msg(&env)?, - ); - } - - // invoke callback that creates a lockup entry for the provided liquidity - cosmos_msgs.push( + let lp_token_amount: Uint128 = deps + .querier + .query_wasm_smart::( + pool_info.lp_token.to_string(), + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )? + .balance; + + Ok(Response::default().add_messages(vec![ + // provide the transferred liquidity to the PCL pool + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: astroport_pool.to_string(), + funds: info.funds.clone(), + msg: to_json_binary(&ProvideLiquidity { + assets: info + .funds + .iter() + .map(|f| Asset { + info: AssetInfo::NativeToken { + denom: f.denom.clone(), + }, + amount: f.amount, + }) + .collect(), + slippage_tolerance: None, + auto_stake: Some(false), // for each pool staking is done at the last user migration + receiver: None, + })?, + }), + // invoke callback that creates a lockup entry for the provided liquidity CallbackMsg::FinishLockupMigrationCallback { pool_type: pool_type.into(), user_address: deps.api.addr_validate(&user_address_raw)?, duration, lp_token: pool_info.lp_token.to_string(), - staked_lp_token_amount, + prev_lp_token_amount: lp_token_amount, user_info, lockup_info, + stake, } .to_cosmos_msg(&env)?, - ); - - Ok(Response::default().add_messages(cosmos_msgs)) + ])) } /// Claims user Rewards for a particular Lockup position. Returns a default object of type [`Response`]. @@ -511,57 +479,58 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( )); } - let mut cosmos_msgs = vec![]; - let astroport_lp_token = pool_info.lp_token; - let incentives = &config.incentives; - - // QUERY :: Check if there are any pending staking rewards - let pending_rewards_response: Vec = deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::PendingRewards { - lp_token: astroport_lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; + let mut cosmos_msgs = vec![]; let mut reward_tokens: Vec = vec![]; - if pending_rewards_response - .iter() - .any(|asset| !asset.amount.is_zero()) - { - let prev_pending_rewards_balances: Vec = pending_rewards_response - .iter() - .map(|asset| { - reward_tokens.push(asset.info.clone()); - - let balance = asset - .info - .query_pool(&deps.querier, env.contract.address.clone()) - .unwrap_or_default(); + if pool_info.is_staked { + let incentives = &config.incentives; + // QUERY :: Check if there are any pending staking rewards + let pending_rewards_response: Vec = deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::PendingRewards { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; - Asset { - info: asset.info.clone(), - amount: balance, + if pending_rewards_response + .iter() + .any(|asset| !asset.amount.is_zero()) + { + let prev_pending_rewards_balances: Vec = pending_rewards_response + .iter() + .map(|asset| { + reward_tokens.push(asset.info.clone()); + + let balance = asset + .info + .query_pool(&deps.querier, env.contract.address.clone()) + .unwrap_or_default(); + + Asset { + info: asset.info.clone(), + amount: balance, + } + }) + .collect(); + + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: incentives.to_string(), + funds: vec![], + msg: to_json_binary(&IncentivesExecuteMsg::ClaimRewards { + lp_tokens: vec![astroport_lp_token.to_string()], + })?, + })); + + cosmos_msgs.push( + CallbackMsg::UpdatePoolOnDualRewardsClaim { + pool_type, + prev_reward_balances: prev_pending_rewards_balances, } - }) - .collect(); - - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: incentives.to_string(), - funds: vec![], - msg: to_json_binary(&IncentivesExecuteMsg::ClaimRewards { - lp_tokens: vec![astroport_lp_token.to_string()], - })?, - })); - - cosmos_msgs.push( - CallbackMsg::UpdatePoolOnDualRewardsClaim { - pool_type, - prev_reward_balances: prev_pending_rewards_balances, - } - .to_cosmos_msg(&env)?, - ); + .to_cosmos_msg(&env)?, + ); + } } cosmos_msgs.push( @@ -728,13 +697,23 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( // Calculate Astro LP share for the lockup position let astroport_lp_amount: Uint128 = { - let balance: Uint128 = deps.querier.query_wasm_smart( - incentives, - &IncentivesQueryMsg::Deposit { - lp_token: astroport_lp_token.to_string(), - user: env.contract.address.to_string(), - }, - )?; + let balance: Uint128 = if pool_info.is_staked { + deps.querier.query_wasm_smart( + incentives, + &IncentivesQueryMsg::Deposit { + lp_token: astroport_lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )? + } else { + let res: BalanceResponse = deps.querier.query_wasm_smart( + astroport_lp_token.clone(), + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), + }, + )?; + res.balance + }; (lockup_info .lp_units_locked @@ -743,60 +722,62 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( .try_into()? }; - let mut pending_reward_assets: Vec = vec![]; - // If this LP token is getting incentives - // Calculate claimable staking rewards for this lockup - for reward_token in reward_tokens { - let incentives_rewards_per_share = pool_info - .incentives_rewards_per_share - .load(&reward_token) - .unwrap_or_default(); - if incentives_rewards_per_share.is_zero() { - continue; - }; + if pool_info.is_staked { + let mut pending_reward_assets: Vec = vec![]; + // If this LP token is getting incentives + // Calculate claimable staking rewards for this lockup + for reward_token in reward_tokens { + let incentives_rewards_per_share = pool_info + .incentives_rewards_per_share + .load(&reward_token) + .unwrap_or_default(); + if incentives_rewards_per_share.is_zero() { + continue; + }; + + let total_lockup_rewards = incentives_rewards_per_share + .checked_mul(astroport_lp_amount.to_decimal())? + .to_uint_floor(); + let debt = lockup_info + .incentives_debt + .load(&reward_token) + .unwrap_or_default(); + let pending_reward = total_lockup_rewards.checked_sub(debt)?; + + if !pending_reward.is_zero() { + pending_reward_assets.push(Asset { + info: reward_token.clone(), + amount: pending_reward, + }); + } - let total_lockup_rewards = incentives_rewards_per_share - .checked_mul(astroport_lp_amount.to_decimal())? - .to_uint_floor(); - let debt = lockup_info - .incentives_debt - .load(&reward_token) - .unwrap_or_default(); - let pending_reward = total_lockup_rewards.checked_sub(debt)?; - - if !pending_reward.is_zero() { - pending_reward_assets.push(Asset { - info: reward_token.clone(), - amount: pending_reward, - }); + lockup_info + .incentives_debt + .update(&reward_token, pending_reward)?; } - lockup_info - .incentives_debt - .update(&reward_token, total_lockup_rewards.checked_sub(debt)?)?; - } - - // If this is a void transaction (no state change), then return error. - // Void tx scenario = ASTRO already claimed, 0 pending ASTRO staking reward, 0 pending rewards, not unlocking LP tokens in this tx - if !withdraw_lp_stake && user_info.ntrn_transferred && pending_reward_assets.is_empty() { - return Err(StdError::generic_err("No rewards available to claim!")); - } + // If this is a void transaction (no state change), then return error. + // Void tx scenario = not unlocking LP tokens in this tx, NTRN already claimed, 0 pending staking reward + if !withdraw_lp_stake && user_info.ntrn_transferred && pending_reward_assets.is_empty() { + return Err(StdError::generic_err("No rewards available to claim!")); + } - // If claimable staking rewards > 0, claim them - for pending_reward in pending_reward_assets { - cosmos_msgs.push(pending_reward.into_msg(user_address.clone())?); - } + // If there are claimable staking rewards, send them to the user + for pending_reward in pending_reward_assets { + cosmos_msgs.push(pending_reward.into_msg(user_address.clone())?); + } - // COSMOSMSG :: If LP Tokens are staked, we unstake the amount which needs to be returned to the user - if withdraw_lp_stake { - cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: incentives.to_string(), - funds: vec![], - msg: to_json_binary(&IncentivesExecuteMsg::Withdraw { - lp_token: astroport_lp_token.to_string(), - amount: astroport_lp_amount, - })?, - })); + // COSMOSMSG :: If LP Tokens are staked, we unstake the amount which needs to be returned to the user + if withdraw_lp_stake { + cosmos_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: incentives.to_string(), + funds: vec![], + msg: to_json_binary(&IncentivesExecuteMsg::Withdraw { + lp_token: astroport_lp_token.to_string(), + amount: astroport_lp_amount, + })?, + })); + } } if withdraw_lp_stake { @@ -881,36 +862,36 @@ pub fn callback_finish_lockup_migration( user_address: Addr, duration: u64, lp_token: String, - staked_lp_token_amount: Uint128, + prev_lp_token_amount: Uint128, user_info: LockdropXYKUserInfo, lockup_info: LockdropXYKLockupInfoV2, + stake: bool, ) -> StdResult { - let config = CONFIG.load(deps.storage)?; - let staked_lp_token_amount_diff = deps + let lp_token_amount = deps .querier - .query_wasm_smart::( - config.incentives.to_string(), - &IncentivesQueryMsg::Deposit { - lp_token, - user: env.contract.address.to_string(), + .query_wasm_smart::( + lp_token.to_string(), + &Cw20QueryMsg::Balance { + address: env.contract.address.to_string(), }, )? - .sub(staked_lp_token_amount); + .balance; + let lp_token_amount_diff = lp_token_amount.sub(prev_lp_token_amount); let user_info: UserInfo = user_info.into(); let lockup_info: LockupInfo = - LockupInfo::from_xyk_lockup_info(lockup_info, staked_lp_token_amount_diff); + LockupInfo::from_xyk_lockup_info(lockup_info, lp_token_amount_diff); let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; let config = CONFIG.load(deps.storage)?; pool_info.weighted_amount = pool_info.weighted_amount.checked_add(calculate_weight( - staked_lp_token_amount_diff, + lp_token_amount_diff, duration, &config, )?)?; pool_info.amount_in_lockups = pool_info .amount_in_lockups - .checked_add(staked_lp_token_amount_diff)?; + .checked_add(lp_token_amount_diff)?; let lockup_key = (pool_type, &user_address, duration); LOCKUP_INFO.save(deps.storage, lockup_key, &lockup_info)?; @@ -921,9 +902,9 @@ pub fn callback_finish_lockup_migration( env.block.height, |lockup_amount| -> StdResult { if let Some(la) = lockup_amount { - Ok(la.checked_add(staked_lp_token_amount_diff)?) + Ok(la.checked_add(lp_token_amount_diff)?) } else { - Ok(staked_lp_token_amount_diff) + Ok(lp_token_amount_diff) } }, )?; @@ -931,7 +912,23 @@ pub fn callback_finish_lockup_migration( ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; USER_INFO.save(deps.storage, &user_address, &user_info)?; - Ok(Response::default()) + let mut resp = Response::default(); + if stake { + resp = resp.add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: lp_token.to_string(), + funds: vec![], + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: config.incentives.to_string(), + msg: to_json_binary(&IncentivesExecuteMsg::Deposit { recipient: None })?, + amount: lp_token_amount, + })?, + })); + + pool_info.is_staked = true; + ASSET_POOLS.save(deps.storage, pool_type, &pool_info, env.block.height)?; + } + + Ok(resp) } /// Returns the contract's State. @@ -1119,12 +1116,20 @@ pub fn query_lockup_info( let pool_astroport_lp_units; let lockup_astroport_lp_units = { // Query Astro LP Tokens balance for the pool - pool_astroport_lp_units = raw_incentives_deposit( - deps.querier, - &config.incentives, - astroport_lp_token.as_bytes(), - env.contract.address.as_bytes(), - )?; + pool_astroport_lp_units = if pool_info.is_staked { + raw_incentives_deposit( + deps.querier, + &config.incentives, + astroport_lp_token.as_bytes(), + env.contract.address.as_bytes(), + )? + } else { + raw_balance( + deps.querier, + &astroport_lp_token, + env.contract.address.as_bytes(), + )? + }; // Calculate Lockup Astro LP shares (lockup_info .lp_units_locked @@ -1134,8 +1139,8 @@ pub fn query_lockup_info( }; lockup_astroport_lp_units_opt = Some(lockup_astroport_lp_units); astroport_lp_token_opt = astroport_lp_token.clone(); - // Calculate the rewards claimable by the user for this lockup position - if !lockup_astroport_lp_units.is_zero() { + // If LP tokens are staked, calculate the rewards claimable by the user for this lockup position + if pool_info.is_staked && !lockup_astroport_lp_units.is_zero() { let incentives = &config.incentives; // QUERY :: Check if there are any pending staking rewards let pending_rewards: Vec = deps.querier.query_wasm_smart( diff --git a/contracts/lockdrop/src/contract.rs b/contracts/lockdrop/src/contract.rs index 6bd024d2..207b96cb 100644 --- a/contracts/lockdrop/src/contract.rs +++ b/contracts/lockdrop/src/contract.rs @@ -1983,6 +1983,20 @@ pub fn callback_migrate_user_lockup_to_pcl_pair( .sub(paired_asset_balance); let pcl_lockdrop = PCL_LOCKDROP_CONTRACT.load(deps.storage)?; + + let pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; + let generator = config + .generator + .as_ref() + .ok_or_else(|| StdError::generic_err("Generator should be set"))?; + let staked_lp_tokens: Uint128 = deps.querier.query_wasm_smart( + generator, + &GenQueryMsg::Deposit { + lp_token: pool_info.lp_token.to_string(), + user: env.contract.address.to_string(), + }, + )?; + Ok( Response::default().add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: pcl_lockdrop.to_string(), @@ -2002,6 +2016,9 @@ pub fn callback_migrate_user_lockup_to_pcl_pair( duration, user_info, lockup_info, + // zero LP tokens left for the XYK lockdrop contract means this is the last + // lockdrop participant being migrated, => time to stake pool's LP tokens + stake: staked_lp_tokens.is_zero(), })?, })), ) diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 6b9fd83f..14d1a694 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -152,7 +152,7 @@ pub enum ExecuteMsg { DropOwnershipProposal {}, /// Used to claim contract ownership. ClaimOwnership {}, - /// A handler to receive lockdrop liquidity migrated from xyl pools to PCL ones. Only callable + /// A handler to receive lockdrop liquidity migrated from XYK pools to PCL ones. Only callable /// by the original lockdrop contract. Expects two **Coin**s to be attached as funds. #[serde(rename = "migrate_xyk_liquidity")] MigrateXYKLiquidity { @@ -168,6 +168,11 @@ pub enum ExecuteMsg { /// The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry /// on the PCL lockdrop contract's side. lockup_info: LockdropXYKLockupInfoV2, + /// Whether to stake all LP tokens in PCL Lockdrop possession to the incentives contract. + /// Should be false unless the last lockdrop participant is being migrated for a given + /// pool type. Before staked, all LP tokens are just collected on the PCL Lockdrop + /// contract's account and therefore no incentive rewards are accrued. + stake: bool, }, } @@ -185,8 +190,8 @@ pub enum CallbackMsg { withdraw_lp_stake: bool, reward_tokens: Vec, }, - /// Completes the liquidity migration process by making all necessary state updates for the lockup - /// position. + /// Completes the liquidity migration process by making all necessary state updates for the + /// lockup position. FinishLockupMigrationCallback { /// The type of the pool the lockup is related to. pool_type: PoolType, @@ -196,16 +201,20 @@ pub enum CallbackMsg { duration: u64, /// The address of the LP token of the pool. lp_token: String, - /// The amount of staked LP token the PCL lockdrop contract possesses of before liquidity - /// provision and staking to the incentives. Used to calculate LP token amount received for - /// liquidity provision. - staked_lp_token_amount: Uint128, + /// The amount of LP token the PCL lockdrop contract possesses of before liquidity provision. + /// Used to calculate LP token amount received for liquidity provision. + prev_lp_token_amount: Uint128, /// The lockup owner's info from the XYK lockdrop contract. Is used to create a UserInfo /// entry on the PCL lockdrop contract's side. user_info: LockdropXYKUserInfo, /// The lockup info from the XYK lockdrop contract. Is used to create a LockupInfoV2 entry /// on the PCL lockdrop contract's side. lockup_info: LockdropXYKLockupInfoV2, + /// Whether to stake all LP tokens in PCL Lockdrop possession to the incentives contract. + /// Should be false unless the last lockdrop participant is being migrated for a given + /// pool type. Before staked, all LP tokens are just collected on the PCL Lockdrop + /// contract's account and therefore no incentive rewards are accrued. + stake: bool, }, } @@ -293,6 +302,8 @@ pub struct PoolInfo { pub weighted_amount: Uint256, /// Ratio of incentives rewards accured to astroport pool share pub incentives_rewards_per_share: RestrictedVector, + /// Boolean value indicating if the LP Tokens are staked with the Incentives contract + pub is_staked: bool, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] From 44ca3a1b3e7cc93ce88dbd4f34e35a7fe4c507e1 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 11 Apr 2024 16:20:25 +0300 Subject: [PATCH 28/28] replace reward assets list from PendingRewards with RewardInfo query in WithdrawUserLockupRewardsCallback --- contracts/lockdrop-pcl/src/contract.rs | 28 +++++++++++++------ .../astroport_periphery/src/lockdrop_pcl.rs | 1 - 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/contracts/lockdrop-pcl/src/contract.rs b/contracts/lockdrop-pcl/src/contract.rs index 7de038ce..92bf7ab2 100644 --- a/contracts/lockdrop-pcl/src/contract.rs +++ b/contracts/lockdrop-pcl/src/contract.rs @@ -5,7 +5,9 @@ use std::str::FromStr; use astroport::asset::{Asset, AssetInfo}; use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_owner}; use astroport::cosmwasm_ext::IntegerToDecimal; -use astroport::incentives::{ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg}; +use astroport::incentives::{ + ExecuteMsg as IncentivesExecuteMsg, QueryMsg as IncentivesQueryMsg, RewardInfo, RewardType, +}; use astroport::pair::ExecuteMsg::ProvideLiquidity; use astroport::restricted_vector::RestrictedVector; use astroport::DecimalCheckedOps; @@ -194,7 +196,6 @@ fn _handle_callback( user_address, duration, withdraw_lp_stake, - reward_tokens, } => callback_withdraw_user_rewards_for_lockup_optional_withdraw( deps, env, @@ -202,7 +203,6 @@ fn _handle_callback( user_address, duration, withdraw_lp_stake, - reward_tokens, ), CallbackMsg::FinishLockupMigrationCallback { pool_type, @@ -482,7 +482,6 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let astroport_lp_token = pool_info.lp_token; let mut cosmos_msgs = vec![]; - let mut reward_tokens: Vec = vec![]; if pool_info.is_staked { let incentives = &config.incentives; // QUERY :: Check if there are any pending staking rewards @@ -501,8 +500,6 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( let prev_pending_rewards_balances: Vec = pending_rewards_response .iter() .map(|asset| { - reward_tokens.push(asset.info.clone()); - let balance = asset .info .query_pool(&deps.querier, env.contract.address.clone()) @@ -539,7 +536,6 @@ pub fn handle_claim_rewards_and_unlock_for_lockup( user_address, duration, withdraw_lp_stake, - reward_tokens, } .to_cosmos_msg(&env)?, ); @@ -673,7 +669,6 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( user_address: Addr, duration: u64, withdraw_lp_stake: bool, - reward_tokens: Vec, ) -> StdResult { let config = CONFIG.load(deps.storage)?; let mut pool_info = ASSET_POOLS.load(deps.storage, pool_type)?; @@ -723,10 +718,25 @@ pub fn callback_withdraw_user_rewards_for_lockup_optional_withdraw( }; if pool_info.is_staked { + // QUERY :: Get list of all reward assets for the lp token + let reward_infos: Vec = deps.querier.query_wasm_smart( + &config.incentives, + &IncentivesQueryMsg::RewardInfo { + lp_token: astroport_lp_token.to_string(), + }, + )?; + let mut pending_reward_assets: Vec = vec![]; // If this LP token is getting incentives // Calculate claimable staking rewards for this lockup - for reward_token in reward_tokens { + for reward_info in reward_infos { + let reward_token: AssetInfo = match reward_info.reward { + RewardType::Int(asset) => asset, + RewardType::Ext { + info, + next_update_ts: _, + } => info, + }; let incentives_rewards_per_share = pool_info .incentives_rewards_per_share .load(&reward_token) diff --git a/packages/astroport_periphery/src/lockdrop_pcl.rs b/packages/astroport_periphery/src/lockdrop_pcl.rs index 14d1a694..15a8bea8 100644 --- a/packages/astroport_periphery/src/lockdrop_pcl.rs +++ b/packages/astroport_periphery/src/lockdrop_pcl.rs @@ -188,7 +188,6 @@ pub enum CallbackMsg { user_address: Addr, duration: u64, withdraw_lp_stake: bool, - reward_tokens: Vec, }, /// Completes the liquidity migration process by making all necessary state updates for the /// lockup position.