diff --git a/Cargo.lock b/Cargo.lock index add039ec..177b3e32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1719,13 +1719,12 @@ dependencies = [ [[package]] name = "neutron-reserve" -version = "0.1.1" +version = "0.1.0" dependencies = [ - "astroport 2.5.0", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.1.0", - "cw20 0.13.4", + "cw2 1.1.1", "cwd-macros", "exec-control", "neutron-sdk", diff --git a/contracts/tokenomics/reserve/Cargo.toml b/contracts/tokenomics/reserve/Cargo.toml index ae3db207..0ef24594 100644 --- a/contracts/tokenomics/reserve/Cargo.toml +++ b/contracts/tokenomics/reserve/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "Apache-2.0" name = "neutron-reserve" repository = "https://github.com/neutron/neutron-dao" -version = "0.1.1" +version = "0.1.0" [lib] crate-type = ["cdylib", "rlib"] @@ -13,16 +13,15 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] [dependencies] -cosmwasm-schema = { version = "1.3.0", default-features = false } -cosmwasm-std = { version = "1.3.0" } +cosmwasm-schema = {version = "1.3.0", default-features = false} +cosmwasm-std = {version = "1.3.0"} cw-storage-plus = "1.1.0" -cwd-macros = { path = "../../../packages/cwd-macros" } -exec-control = { path = "../../../packages/exec-control" } -neutron-sdk = { package = "neutron-sdk", version = "0.7.0" } +cwd-macros = {path = "../../../packages/cwd-macros"} +exec-control = {path = "../../../packages/exec-control"} +neutron-sdk = {package = "neutron-sdk", version = "0.7.0" } schemars = "0.8.8" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = { version = "1.0" } -astroport = { git = "https://github.com/astroport-fi/astroport-core.git", tag = "v2.5.0" } -cw20 = "0.13" +serde = {version = "1.0.103", default-features = false, features = ["derive"]} +thiserror = {version = "1.0"} +cw2 = "1.1.0" [dev-dependencies] diff --git a/contracts/tokenomics/reserve/schema/neutron-reserve.json b/contracts/tokenomics/reserve/schema/neutron-reserve.json index 1bd1df40..273f6aab 100644 --- a/contracts/tokenomics/reserve/schema/neutron-reserve.json +++ b/contracts/tokenomics/reserve/schema/neutron-reserve.json @@ -1,6 +1,6 @@ { "contract_name": "neutron-reserve", - "contract_version": "0.1.1", + "contract_version": "0.1.0", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", @@ -154,64 +154,6 @@ }, "additionalProperties": false }, - { - "description": "Processes either partial or full xyk->CL migration of contract's liquidity.", - "type": "object", - "required": [ - "migrate_from_xyk_to_cl" - ], - "properties": { - "migrate_from_xyk_to_cl": { - "type": "object", - "properties": { - "ntrn_atom_amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "ntrn_usdc_amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "slippage_tolerance": { - "anyOf": [ - { - "$ref": "#/definitions/Decimal" - }, - { - "type": "null" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Callbacks; only callable by the contract itself.", - "type": "object", - "required": [ - "callback" - ], - "properties": { - "callback": { - "$ref": "#/definitions/CallbackMsg" - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -248,137 +190,9 @@ } ], "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" - }, - "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", - "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" - }, - "xyk_lp_token": { - "$ref": "#/definitions/Addr" - }, - "xyk_pair": { - "$ref": "#/definitions/Addr" - } - } - } - }, - "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" - ], - "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" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "post_migration_balances_check" - ], - "properties": { - "post_migration_balances_check": { - "type": "object", - "required": [ - "ntrn_denom", - "ntrn_init_balance", - "paired_asset_denom", - "paired_asset_init_balance" - ], - "properties": { - "ntrn_denom": { - "type": "string" - }, - "ntrn_init_balance": { - "$ref": "#/definitions/Uint128" - }, - "paired_asset_denom": { - "type": "string" - }, - "paired_asset_init_balance": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "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" - }, - "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/tokenomics/reserve/schema/raw/execute.json b/contracts/tokenomics/reserve/schema/raw/execute.json index abc72a7b..2d179055 100644 --- a/contracts/tokenomics/reserve/schema/raw/execute.json +++ b/contracts/tokenomics/reserve/schema/raw/execute.json @@ -87,64 +87,6 @@ }, "additionalProperties": false }, - { - "description": "Processes either partial or full xyk->CL migration of contract's liquidity.", - "type": "object", - "required": [ - "migrate_from_xyk_to_cl" - ], - "properties": { - "migrate_from_xyk_to_cl": { - "type": "object", - "properties": { - "ntrn_atom_amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "ntrn_usdc_amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "slippage_tolerance": { - "anyOf": [ - { - "$ref": "#/definitions/Decimal" - }, - { - "type": "null" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Callbacks; only callable by the contract itself.", - "type": "object", - "required": [ - "callback" - ], - "properties": { - "callback": { - "$ref": "#/definitions/CallbackMsg" - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -181,137 +123,9 @@ } ], "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" - }, - "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", - "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" - }, - "xyk_lp_token": { - "$ref": "#/definitions/Addr" - }, - "xyk_pair": { - "$ref": "#/definitions/Addr" - } - } - } - }, - "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" - ], - "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" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "post_migration_balances_check" - ], - "properties": { - "post_migration_balances_check": { - "type": "object", - "required": [ - "ntrn_denom", - "ntrn_init_balance", - "paired_asset_denom", - "paired_asset_init_balance" - ], - "properties": { - "ntrn_denom": { - "type": "string" - }, - "ntrn_init_balance": { - "$ref": "#/definitions/Uint128" - }, - "paired_asset_denom": { - "type": "string" - }, - "paired_asset_init_balance": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "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" - }, - "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/tokenomics/reserve/src/contract.rs b/contracts/tokenomics/reserve/src/contract.rs index 7cb89fbe..75199b85 100644 --- a/contracts/tokenomics/reserve/src/contract.rs +++ b/contracts/tokenomics/reserve/src/contract.rs @@ -1,31 +1,29 @@ use crate::distribution_params::DistributionParams; use crate::error::ContractError; -use crate::msg::{ - CallbackMsg, DistributeMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, StatsResponse, -}; -use crate::state::{ - Config, XykToClMigrationConfig, CONFIG, LAST_BURNED_COINS_AMOUNT, LAST_DISTRIBUTION_TIME, - PAUSED_UNTIL, TOTAL_DISTRIBUTED, TOTAL_RESERVED, XYK_TO_CL_MIGRATION_CONFIG, -}; -use crate::vesting::{ - get_burned_coins, safe_burned_coins_for_period, update_distribution_stats, vesting_function, -}; -use astroport::asset::{native_asset, PairInfo}; -use astroport::pair::{ - Cw20HookMsg as PairCw20HookMsg, ExecuteMsg as PairExecuteMsg, QueryMsg as PairQueryMsg, -}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - coins, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, - MessageInfo, Response, StdResult, Uint128, WasmMsg, + coins, to_binary, Addr, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, + StdResult, Uint128, WasmMsg, }; -use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use exec_control::pause::{ can_pause, can_unpause, validate_duration, PauseError, PauseInfoResponse, }; use neutron_sdk::bindings::query::NeutronQuery; +use crate::msg::{DistributeMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, StatsResponse}; +use crate::state::{ + Config, CONFIG, LAST_BURNED_COINS_AMOUNT, LAST_DISTRIBUTION_TIME, PAUSED_UNTIL, + TOTAL_DISTRIBUTED, TOTAL_RESERVED, +}; +use crate::vesting::{ + get_burned_coins, safe_burned_coins_for_period, update_distribution_stats, vesting_function, +}; +use cw2::set_contract_version; + +pub(crate) const CONTRACT_NAME: &str = "crates.io:neutron-reserve"; +pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + //-------------------------------------------------------------------------------------------------- // Instantiation //-------------------------------------------------------------------------------------------------- @@ -174,18 +172,6 @@ pub fn execute( ), ExecuteMsg::Pause { duration } => execute_pause(deps, env, info.sender, duration), ExecuteMsg::Unpause {} => execute_unpause(deps, info.sender), - ExecuteMsg::MigrateFromXykToCl { - slippage_tolerance, - ntrn_atom_amount, - ntrn_usdc_amount, - } => execute_migrate_from_xyk_to_cl( - deps, - env, - slippage_tolerance, - ntrn_atom_amount, - ntrn_usdc_amount, - ), - ExecuteMsg::Callback(msg) => _handle_callback(deps, env, info, msg), } } @@ -313,315 +299,6 @@ pub fn execute_distribute( .add_attribute("distributed", to_distribute)) } -fn execute_migrate_from_xyk_to_cl( - deps: DepsMut, - env: Env, - slippage_tolerance: Option, - ntrn_atom_amount: Option, - ntrn_usdc_amount: Option, -) -> Result { - let migration_config: XykToClMigrationConfig = XYK_TO_CL_MIGRATION_CONFIG.load(deps.storage)?; - - // get pairs LP token addresses - let ntrn_atom_pair_info: PairInfo = deps.querier.query_wasm_smart( - migration_config.ntrn_atom_xyk_pair.clone(), - &PairQueryMsg::Pair {}, - )?; - let ntrn_usdc_pair_info: PairInfo = deps.querier.query_wasm_smart( - migration_config.ntrn_usdc_xyk_pair.clone(), - &PairQueryMsg::Pair {}, - )?; - - // query max available amounts to be withdrawn from both pairs - let max_available_ntrn_atom_amount = { - let resp: BalanceResponse = deps.querier.query_wasm_smart( - ntrn_atom_pair_info.liquidity_token.clone(), - &Cw20QueryMsg::Balance { - address: env.contract.address.to_string(), - }, - )?; - resp.balance - }; - let max_available_ntrn_usdc_amount = { - let resp: BalanceResponse = deps.querier.query_wasm_smart( - ntrn_usdc_pair_info.liquidity_token.clone(), - &Cw20QueryMsg::Balance { - address: env.contract.address.to_string(), - }, - )?; - resp.balance - }; - if max_available_ntrn_atom_amount.is_zero() && max_available_ntrn_usdc_amount.is_zero() { - return Err(ContractError::MigrationComplete {}); - } - - // validate parameters to the max available values - if let Some(ntrn_atom_amount) = ntrn_atom_amount { - if ntrn_atom_amount.gt(&max_available_ntrn_atom_amount) { - return Err(ContractError::MigrationAmountUnavailable { - amount: ntrn_atom_amount, - max_amount: max_available_ntrn_atom_amount, - }); - } - } - if let Some(ntrn_usdc_amount) = ntrn_usdc_amount { - if ntrn_usdc_amount.gt(&max_available_ntrn_usdc_amount) { - return Err(ContractError::MigrationAmountUnavailable { - amount: ntrn_usdc_amount, - max_amount: max_available_ntrn_usdc_amount, - }); - } - } - if let Some(slippage_tolerance) = slippage_tolerance { - if slippage_tolerance.gt(&migration_config.max_slippage) { - return Err(ContractError::MigrationSlippageToBig { - slippage_tolerance, - max_slippage_tolerance: migration_config.max_slippage, - }); - } - } - - let ntrn_atom_amount = ntrn_atom_amount.unwrap_or(max_available_ntrn_atom_amount); - let ntrn_usdc_amount = ntrn_usdc_amount.unwrap_or(max_available_ntrn_usdc_amount); - let slippage_tolerance = slippage_tolerance.unwrap_or(migration_config.max_slippage); - - let mut resp = Response::default(); - if !ntrn_atom_amount.is_zero() { - resp = resp.add_message( - CallbackMsg::MigrateLiquidityToClPair { - ntrn_denom: migration_config.ntrn_denom.clone(), - amount: ntrn_atom_amount, - slippage_tolerance, - xyk_pair: migration_config.ntrn_atom_xyk_pair, - xyk_lp_token: ntrn_atom_pair_info.liquidity_token, - cl_pair: migration_config.ntrn_atom_cl_pair, - paired_asset_denom: migration_config.atom_denom, - } - .to_cosmos_msg(&env)?, - ); - } - if !ntrn_usdc_amount.is_zero() { - resp = resp.add_message( - CallbackMsg::MigrateLiquidityToClPair { - ntrn_denom: migration_config.ntrn_denom, - amount: ntrn_usdc_amount, - slippage_tolerance, - xyk_pair: migration_config.ntrn_usdc_xyk_pair, - xyk_lp_token: ntrn_usdc_pair_info.liquidity_token, - cl_pair: migration_config.ntrn_usdc_cl_pair, - paired_asset_denom: migration_config.usdc_denom, - } - .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, - } => migrate_liquidity_to_cl_pair_callback( - deps, - env, - xyk_pair, - xyk_lp_token, - amount, - slippage_tolerance, - cl_pair, - ntrn_denom, - paired_asset_denom, - ), - CallbackMsg::ProvideLiquidityToClPairAfterWithdrawal { - ntrn_denom, - ntrn_init_balance, - paired_asset_denom, - paired_asset_init_balance, - cl_pair: cl_pair_address, - slippage_tolerance, - } => provide_liquidity_to_cl_pair_after_withdrawal_callback( - deps, - env, - ntrn_denom, - ntrn_init_balance, - paired_asset_denom, - paired_asset_init_balance, - cl_pair_address, - slippage_tolerance, - ), - CallbackMsg::PostMigrationBalancesCheck { - ntrn_denom, - ntrn_init_balance, - paired_asset_denom, - paired_asset_init_balance, - } => post_migration_balances_check_callback( - deps, - env, - ntrn_denom, - ntrn_init_balance, - paired_asset_denom, - paired_asset_init_balance, - ), - } -} - -#[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, -) -> 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 msgs: Vec = vec![ - // push message to withdraw liquidity from the xyk pair - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: xyk_lp_token.to_string(), - msg: to_binary(&Cw20ExecuteMsg::Send { - contract: xyk_pair.to_string(), - amount, - msg: to_binary(&PairCw20HookMsg::WithdrawLiquidity { assets: vec![] })?, - })?, - funds: vec![], - }), - // push the next migration step as a callback message - CallbackMsg::ProvideLiquidityToClPairAfterWithdrawal { - ntrn_denom, - ntrn_init_balance, - paired_asset_denom, - paired_asset_init_balance, - cl_pair, - slippage_tolerance, - } - .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, -) -> 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 msgs: Vec = vec![ - // push message to provide liquidity to the CL pair - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: cl_pair_address.to_string(), - msg: to_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.clone()), - Coin::new( - withdrawn_paired_asset_amount.into(), - paired_asset_denom.clone(), - ), - ], - }), - // push the next migration step as a callback message - CallbackMsg::PostMigrationBalancesCheck { - ntrn_denom, - ntrn_init_balance, - paired_asset_denom, - paired_asset_init_balance, - } - .to_cosmos_msg(&env)?, - ]; - - Ok(Response::default().add_messages(msgs)) -} - -fn post_migration_balances_check_callback( - deps: DepsMut, - env: Env, - ntrn_denom: String, - ntrn_init_balance: Uint128, - paired_asset_denom: String, - paired_asset_init_balance: Uint128, -) -> Result { - let ntrn_balance = deps - .querier - .query_balance(env.contract.address.to_string(), ntrn_denom.clone())? - .amount; - let paired_asset_balance = deps - .querier - .query_balance(env.contract.address.to_string(), paired_asset_denom.clone())? - .amount; - - if !ntrn_balance.eq(&ntrn_init_balance) { - return Err(ContractError::MigrationBalancesMismatch { - denom: ntrn_denom, - initial_balance: ntrn_init_balance, - final_balance: ntrn_balance, - }); - } - if !paired_asset_balance.eq(&paired_asset_init_balance) { - return Err(ContractError::MigrationBalancesMismatch { - denom: paired_asset_denom, - initial_balance: paired_asset_init_balance, - final_balance: paired_asset_balance, - }); - } - - Ok(Response::default()) -} - //-------------------------------------------------------------------------------------------------- // Queries //-------------------------------------------------------------------------------------------------- @@ -687,25 +364,9 @@ pub fn create_distribution_response( Ok(resp) } -//-------------------------------------------------------------------------------------------------- -// Migration -//-------------------------------------------------------------------------------------------------- - -/// Withdraws liquidity from Astroport xyk pairs and provides it to the concentrated liquidity ones. #[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, - atom_denom: msg.atom_denom, - ntrn_atom_xyk_pair: deps.api.addr_validate(msg.ntrn_atom_xyk_pair.as_str())?, - ntrn_atom_cl_pair: deps.api.addr_validate(msg.ntrn_atom_cl_pair.as_str())?, - usdc_denom: msg.usdc_denom, - ntrn_usdc_xyk_pair: deps.api.addr_validate(msg.ntrn_usdc_xyk_pair.as_str())?, - ntrn_usdc_cl_pair: deps.api.addr_validate(msg.ntrn_usdc_cl_pair.as_str())?, - }, - )?; +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Set contract to version to latest + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(Response::default()) } diff --git a/contracts/tokenomics/reserve/src/error.rs b/contracts/tokenomics/reserve/src/error.rs index 366fedad..2bb2f131 100644 --- a/contracts/tokenomics/reserve/src/error.rs +++ b/contracts/tokenomics/reserve/src/error.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Decimal, OverflowError, StdError, Uint128}; +use cosmwasm_std::{OverflowError, StdError}; use exec_control::pause::PauseError; use thiserror::Error; @@ -31,35 +31,6 @@ pub enum ContractError { #[error("no coins were burned, nothing to distribute")] NoBurnedCoins {}, - #[error("Unknown reply ID {reply_id}")] - UnkownReplyID { reply_id: u64 }, - - #[error("{denom} balance {final_balance} after liquidity withdrawal and providing doesn't match the initial one {initial_balance}")] - MigrationBalancesMismatch { - denom: String, - initial_balance: Uint128, - final_balance: Uint128, - }, - - #[error( - "Amount to be migrated is greater that the max available amount: {amount} > {max_amount}" - )] - MigrationAmountUnavailable { - amount: Uint128, - max_amount: Uint128, - }, - - #[error( - "Provided slippage tolerance {slippage_tolerance} is more than the max allowed {max_slippage_tolerance}" - )] - MigrationSlippageToBig { - slippage_tolerance: Decimal, - max_slippage_tolerance: Decimal, - }, - - #[error("Migration from xyk pairs to CL ones is complete: nothing to migrate")] - MigrationComplete {}, - #[error("Overflow")] OverflowError(#[from] OverflowError), } diff --git a/contracts/tokenomics/reserve/src/msg.rs b/contracts/tokenomics/reserve/src/msg.rs index 10d24b8c..b0e8d173 100644 --- a/contracts/tokenomics/reserve/src/msg.rs +++ b/contracts/tokenomics/reserve/src/msg.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, Decimal, Env, StdResult, Uint128, WasmMsg}; +use cosmwasm_std::{Decimal, Uint128}; use cwd_macros::{pausable, pausable_query}; use exec_control::pause::PauseInfoResponse; use schemars::JsonSchema; @@ -44,56 +44,6 @@ pub enum ExecuteMsg { security_dao_address: Option, vesting_denominator: Option, }, - - /// Processes either partial or full xyk->CL migration of contract's liquidity. - MigrateFromXykToCl { - slippage_tolerance: Option, - ntrn_atom_amount: Option, - ntrn_usdc_amount: Option, - }, - - /// Callbacks; only callable by the contract itself. - Callback(CallbackMsg), -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -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, - }, - ProvideLiquidityToClPairAfterWithdrawal { - ntrn_denom: String, - ntrn_init_balance: Uint128, - paired_asset_denom: String, - paired_asset_init_balance: Uint128, - cl_pair: Addr, - slippage_tolerance: Decimal, - }, - PostMigrationBalancesCheck { - ntrn_denom: String, - ntrn_init_balance: Uint128, - paired_asset_denom: String, - paired_asset_init_balance: 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_binary(&ExecuteMsg::Callback(self))?, - funds: vec![], - })) - } } #[pausable_query] @@ -127,13 +77,4 @@ pub enum DistributeMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub struct MigrateMsg { - pub max_slippage: Decimal, - pub ntrn_denom: String, - pub atom_denom: String, - pub ntrn_atom_xyk_pair: String, - pub ntrn_atom_cl_pair: String, - pub usdc_denom: String, - pub ntrn_usdc_xyk_pair: String, - pub ntrn_usdc_cl_pair: String, -} +pub enum MigrateMsg {} diff --git a/contracts/tokenomics/reserve/src/state.rs b/contracts/tokenomics/reserve/src/state.rs index b1394e15..689ff150 100644 --- a/contracts/tokenomics/reserve/src/state.rs +++ b/contracts/tokenomics/reserve/src/state.rs @@ -44,20 +44,6 @@ impl Config { } } -/// Config for xyk->CL liquidity migration. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct XykToClMigrationConfig { - /// The maximum allowed slippage tolerance for xyk to CL liquidity migration calls. - pub max_slippage: Decimal, - pub ntrn_denom: String, - pub atom_denom: String, - pub ntrn_atom_xyk_pair: Addr, - pub ntrn_atom_cl_pair: Addr, - pub usdc_denom: String, - pub ntrn_usdc_xyk_pair: Addr, - pub ntrn_usdc_cl_pair: Addr, -} - pub const TOTAL_DISTRIBUTED: Item = Item::new("total_distributed"); pub const TOTAL_RESERVED: Item = Item::new("total_reserved"); @@ -69,9 +55,6 @@ pub const CONFIG: Item = Item::new("config"); /// The height the contract is paused until. If it's None, the contract is not paused. pub const PAUSED_UNTIL: Item> = Item::new("paused_until"); -pub const XYK_TO_CL_MIGRATION_CONFIG: Item = - Item::new("xyk_to_cl_migration_config"); - #[cfg(test)] mod tests { use super::Config;