From 86fc7c0745dc0f78c3cbefc981055d727483c949 Mon Sep 17 00:00:00 2001 From: trung2891 Date: Thu, 8 Aug 2024 10:39:16 +0700 Subject: [PATCH 1/3] feat: incentives fund manager --- Cargo.lock | 27 +++ Cargo.toml | 2 + contracts/incentives-fund-manager/Cargo.toml | 29 +++ .../incentives-fund-manager/src/bin/schema.rs | 13 ++ .../incentives-fund-manager/src/contract.rs | 123 +++++++++++++ contracts/incentives-fund-manager/src/lib.rs | 2 + .../incentives-fund-manager/src/state.rs | 11 ++ contracts/oraiswap-v3/Cargo.toml | 3 + contracts/oraiswap-v3/src/contract.rs | 4 +- .../oraiswap-v3/src/entrypoints/common.rs | 8 +- .../oraiswap-v3/src/entrypoints/execute.rs | 21 ++- .../oraiswap-v3/src/entrypoints/query.rs | 13 +- contracts/oraiswap-v3/src/interface.rs | 140 +-------------- contracts/oraiswap-v3/src/lib.rs | 3 - contracts/oraiswap-v3/src/logic/math.rs | 2 +- contracts/oraiswap-v3/src/math/clamm.rs | 3 +- contracts/oraiswap-v3/src/math/log.rs | 2 +- .../oraiswap-v3/src/math/types/fee_growth.rs | 6 +- .../src/math/types/seconds_per_liquidity.rs | 3 +- .../oraiswap-v3/src/math/types/sqrt_price.rs | 2 +- .../src/math/types/token_amount.rs | 2 +- contracts/oraiswap-v3/src/msg.rs | 9 +- contracts/oraiswap-v3/src/state.rs | 3 +- contracts/oraiswap-v3/src/storage/config.rs | 1 + contracts/oraiswap-v3/src/storage/fee_tier.rs | 3 +- .../oraiswap-v3/src/storage/incentive.rs | 6 +- contracts/oraiswap-v3/src/storage/mod.rs | 2 - contracts/oraiswap-v3/src/storage/pool.rs | 16 +- contracts/oraiswap-v3/src/storage/pool_key.rs | 3 +- contracts/oraiswap-v3/src/storage/position.rs | 4 +- contracts/oraiswap-v3/src/storage/tick.rs | 2 +- .../oraiswap-v3/src/tests/add_fee_tier.rs | 2 +- contracts/oraiswap-v3/src/tests/admin.rs | 2 +- .../src/tests/change_fee_receiver.rs | 2 +- .../src/tests/change_protocol_fee.rs | 2 +- contracts/oraiswap-v3/src/tests/claim.rs | 43 ++++- .../src/tests/get_position_ticks.rs | 12 +- contracts/oraiswap-v3/src/tests/helper.rs | 58 +++++- contracts/oraiswap-v3/src/tests/incentive.rs | 66 ++++--- .../oraiswap-v3/src/tests/liquidity_gap.rs | 3 +- contracts/oraiswap-v3/src/tests/nft.rs | 3 +- contracts/oraiswap-v3/src/tests/position.rs | 3 +- .../src/tests/position_slippage.rs | 3 +- .../oraiswap-v3/src/tests/protocol_fee.rs | 3 +- .../oraiswap-v3/src/tests/remove_fee_tier.rs | 3 +- contracts/oraiswap-v3/src/tests/slippage.rs | 3 +- contracts/oraiswap-v3/src/tests/swap.rs | 3 +- packages/oraiswap-v3-common/Cargo.toml | 18 ++ packages/oraiswap-v3-common/src/asset.rs | 136 ++++++++++++++ packages/oraiswap-v3-common/src/error.rs | 168 ++++++++++++++++++ .../src/incentives_fund_manager.rs | 38 ++++ packages/oraiswap-v3-common/src/lib.rs | 3 + 52 files changed, 803 insertions(+), 239 deletions(-) create mode 100644 contracts/incentives-fund-manager/Cargo.toml create mode 100644 contracts/incentives-fund-manager/src/bin/schema.rs create mode 100644 contracts/incentives-fund-manager/src/contract.rs create mode 100644 contracts/incentives-fund-manager/src/lib.rs create mode 100644 contracts/incentives-fund-manager/src/state.rs create mode 100644 packages/oraiswap-v3-common/Cargo.toml create mode 100644 packages/oraiswap-v3-common/src/asset.rs create mode 100644 packages/oraiswap-v3-common/src/error.rs create mode 100644 packages/oraiswap-v3-common/src/incentives_fund_manager.rs create mode 100644 packages/oraiswap-v3-common/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ade137e..ca14726 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1023,6 +1023,20 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "incentives-fund-manager" +version = "0.2.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus", + "cw2", + "cw20", + "oraiswap-v3-common", + "thiserror", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1233,6 +1247,19 @@ dependencies = [ "cw20-base", "decimal", "derive_more", + "incentives-fund-manager", + "oraiswap-v3-common", + "thiserror", +] + +[[package]] +name = "oraiswap-v3-common" +version = "0.2.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw20", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index a4c6eed..30508de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,8 @@ cw-storage-plus = { version = "1.0.1" } derive_more = "0.99.17" decimal-core = { path = "./packages/decimal-core" } decimal = { path = "./packages/decimal" } +oraiswap-v3-common = { path = "./packages/oraiswap-v3-common" } +incentives-fund-manager = { path = "./contracts/incentives-fund-manager" } [profile.release] opt-level = 3 diff --git a/contracts/incentives-fund-manager/Cargo.toml b/contracts/incentives-fund-manager/Cargo.toml new file mode 100644 index 0000000..81a41e2 --- /dev/null +++ b/contracts/incentives-fund-manager/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "incentives-fund-manager" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +documentation = { workspace = true } + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-storage = { workspace = true } +oraiswap-v3-common = { workspace = true } + +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +cw20 = { workspace = true } +thiserror = { workspace = true } diff --git a/contracts/incentives-fund-manager/src/bin/schema.rs b/contracts/incentives-fund-manager/src/bin/schema.rs new file mode 100644 index 0000000..e92bc25 --- /dev/null +++ b/contracts/incentives-fund-manager/src/bin/schema.rs @@ -0,0 +1,13 @@ +use cosmwasm_schema::write_api; +use oraiswap_v3_common::incentives_fund_manager::{ + ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, +}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + migrate: MigrateMsg + } +} diff --git a/contracts/incentives-fund-manager/src/contract.rs b/contracts/incentives-fund-manager/src/contract.rs new file mode 100644 index 0000000..fffa81e --- /dev/null +++ b/contracts/incentives-fund-manager/src/contract.rs @@ -0,0 +1,123 @@ +use crate::state::{Config, CONFIG}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdResult, +}; +use cw2::set_contract_version; +use oraiswap_v3_common::{ + asset::Asset, + error::ContractError, + incentives_fund_manager::{ExecuteMsg, InstantiateMsg, QueryMsg}, +}; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:incentives-fund-manager"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + CONFIG.save( + deps.storage, + &Config { + owner: msg.owner.unwrap_or(info.sender), + oraiswap_v3: msg.oraiswap_v3, + }, + )?; + + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::UpdateConfig { owner, oraiswap_v3 } => { + execute_update_config(deps, info, owner, oraiswap_v3) + } + ExecuteMsg::SendFund { asset, receiver } => execute_send_fund(deps, info, asset, receiver), + } +} + +/// Allows owner can adjust config +/// +/// # Parameters +/// - `owner`: new owner +/// - `oraiswap_v3`: new oraiswapV3 contract +/// +/// # Errors +/// - Reverts the call when the caller is an unauthorized user +/// +fn execute_update_config( + deps: DepsMut, + info: MessageInfo, + owner: Option, + oraiswap_v3: Option, +) -> Result { + let mut config = CONFIG.load(deps.storage)?; + if info.sender != config.owner { + return Err(ContractError::Unauthorized {}); + } + + if let Some(owner) = owner { + config.owner = owner; + } + if let Some(oraiswap_v3) = oraiswap_v3 { + config.oraiswap_v3 = oraiswap_v3; + } + CONFIG.save(deps.storage, &config)?; + + Ok(Response::new().add_attribute("action", "update_config")) +} + +/// Allows oraiswap_v3_contract can send fund +/// +/// # Parameters +/// - `asset`: asset to send. +/// - `receiver`: receiver address +/// +/// # Errors +/// - Reverts the call when the caller is an unauthorized user or contract not enough fund +/// +fn execute_send_fund( + deps: DepsMut, + info: MessageInfo, + asset: Asset, + receiver: Addr, +) -> Result { + let config = CONFIG.load(deps.storage)?; + if info.sender != config.oraiswap_v3 { + return Err(ContractError::Unauthorized {}); + } + + let mut msgs: Vec = vec![]; + asset.transfer( + &mut msgs, + &MessageInfo { + sender: receiver, + funds: vec![], + }, + )?; + + Ok(Response::new() + .add_messages(msgs) + .add_attribute("action", "send_fund")) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Config {} => to_json_binary(&CONFIG.load(deps.storage)?), + } +} diff --git a/contracts/incentives-fund-manager/src/lib.rs b/contracts/incentives-fund-manager/src/lib.rs new file mode 100644 index 0000000..3407c19 --- /dev/null +++ b/contracts/incentives-fund-manager/src/lib.rs @@ -0,0 +1,2 @@ +pub mod contract; +pub mod state; diff --git a/contracts/incentives-fund-manager/src/state.rs b/contracts/incentives-fund-manager/src/state.rs new file mode 100644 index 0000000..64a9c61 --- /dev/null +++ b/contracts/incentives-fund-manager/src/state.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Addr; +use cw_storage_plus::Item; + +pub const CONFIG: Item = Item::new("config"); + +#[cw_serde] +pub struct Config { + pub owner: Addr, + pub oraiswap_v3: Addr, +} diff --git a/contracts/oraiswap-v3/Cargo.toml b/contracts/oraiswap-v3/Cargo.toml index 58632ed..4f4ace1 100644 --- a/contracts/oraiswap-v3/Cargo.toml +++ b/contracts/oraiswap-v3/Cargo.toml @@ -29,6 +29,9 @@ thiserror = { workspace = true } decimal = { workspace = true } derive_more = { workspace = true } +oraiswap-v3-common = { workspace = true } + [dev-dependencies] cw20-base = { workspace = true, features = ["library"] } cosmwasm-testing-util = { git = "https://github.com/oraichain/cosmwasm-testing-util.git", rev = "1b9c412" } +incentives-fund-manager = { workspace = true } diff --git a/contracts/oraiswap-v3/src/contract.rs b/contracts/oraiswap-v3/src/contract.rs index 59765a1..10b36f1 100644 --- a/contracts/oraiswap-v3/src/contract.rs +++ b/contracts/oraiswap-v3/src/contract.rs @@ -1,10 +1,10 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::CONFIG; use crate::{entrypoints::*, Config}; +use oraiswap_v3_common::error::ContractError; use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; @@ -25,6 +25,7 @@ pub fn instantiate( fee_tiers: vec![], admin: info.sender, protocol_fee: msg.protocol_fee, + incentives_fund_manager: msg.incentives_fund_manager, }; CONFIG.save(deps.storage, &config)?; @@ -193,6 +194,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Admin {} => to_json_binary(&query_admin(deps)?), QueryMsg::ProtocolFee {} => to_json_binary(&get_protocol_fee(deps)?), + QueryMsg::IncentivesFundManager {} => to_json_binary(&get_incentives_fund_manager(deps)?), QueryMsg::Position { owner_id, index } => { to_json_binary(&get_position(deps, owner_id, index)?) } diff --git a/contracts/oraiswap-v3/src/entrypoints/common.rs b/contracts/oraiswap-v3/src/entrypoints/common.rs index ac47f1e..6f88d7d 100644 --- a/contracts/oraiswap-v3/src/entrypoints/common.rs +++ b/contracts/oraiswap-v3/src/entrypoints/common.rs @@ -5,13 +5,17 @@ use decimal::{CheckedOps, Decimal}; use crate::{ check_tick, compute_swap_step, - interface::{Approval, Asset, AssetInfo, CalculateSwapResult, SwapHop}, + interface::{Approval, CalculateSwapResult, SwapHop}, sqrt_price::{get_max_tick, get_min_tick, SqrtPrice}, state::{self}, token_amount::TokenAmount, - ContractError, PoolKey, Position, Tick, UpdatePoolTick, MAX_SQRT_PRICE, MAX_TICKMAP_QUERY_SIZE, + PoolKey, Position, Tick, UpdatePoolTick, MAX_SQRT_PRICE, MAX_TICKMAP_QUERY_SIZE, MIN_SQRT_PRICE, }; +use oraiswap_v3_common::{ + asset::{Asset, AssetInfo}, + error::ContractError, +}; pub trait TimeStampExt { fn millis(&self) -> u64; diff --git a/contracts/oraiswap-v3/src/entrypoints/execute.rs b/contracts/oraiswap-v3/src/entrypoints/execute.rs index eac2d63..e293446 100644 --- a/contracts/oraiswap-v3/src/entrypoints/execute.rs +++ b/contracts/oraiswap-v3/src/entrypoints/execute.rs @@ -1,19 +1,23 @@ -use crate::error::ContractError; use crate::fee_growth::FeeGrowth; use crate::incentive::IncentiveRecord; -use crate::interface::{Asset, AssetInfo, CalculateSwapResult, Cw721ReceiveMsg, SwapHop}; +use crate::interface::{CalculateSwapResult, Cw721ReceiveMsg, SwapHop}; use crate::liquidity::Liquidity; use crate::percentage::Percentage; use crate::sqrt_price::SqrtPrice; use crate::state::{self, CONFIG, POOLS}; use crate::token_amount::TokenAmount; use crate::{calculate_min_amount_out, check_tick, FeeTier, Pool, PoolKey, Position}; +use oraiswap_v3_common::asset::{Asset, AssetInfo}; +use oraiswap_v3_common::error::ContractError; +use oraiswap_v3_common::incentives_fund_manager; use super::{ check_can_send, create_tick, remove_tick_and_flip_bitmap, swap_internal, swap_route_internal, transfer_nft, update_approvals, TimeStampExt, }; -use cosmwasm_std::{attr, Addr, Attribute, Binary, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{ + attr, wasm_execute, Addr, Attribute, Binary, DepsMut, Env, MessageInfo, Response, +}; use cw20::Expiration; use decimal::Decimal; @@ -540,6 +544,7 @@ pub fn claim_incentives( index: u32, ) -> Result { let mut position = state::get_position(deps.storage, &info.sender, index)?; + let config = CONFIG.load(deps.storage)?; let lower_tick = state::get_tick(deps.storage, &position.pool_key, position.lower_tick_index)?; let upper_tick = state::get_tick(deps.storage, &position.pool_key, position.upper_tick_index)?; @@ -558,7 +563,15 @@ pub fn claim_incentives( let mut msgs = vec![]; for asset in incentives.clone() { - asset.transfer(&mut msgs, &info)?; + msgs.push(wasm_execute( + config.incentives_fund_manager.clone(), + &incentives_fund_manager::ExecuteMsg::SendFund { + asset, + receiver: info.sender.clone(), + }, + vec![], + )?); + // asset.transfer(&mut msgs, &info)?; } let mut event_attributes: Vec = vec![]; diff --git a/contracts/oraiswap-v3/src/entrypoints/query.rs b/contracts/oraiswap-v3/src/entrypoints/query.rs index beb7efa..e494103 100644 --- a/contracts/oraiswap-v3/src/entrypoints/query.rs +++ b/contracts/oraiswap-v3/src/entrypoints/query.rs @@ -4,17 +4,18 @@ use cw_storage_plus::Bound; use crate::{ get_max_chunk, get_min_chunk, interface::{ - AllNftInfoResponse, Approval, ApprovedForAllResponse, Asset, NftInfoResponse, - NumTokensResponse, OwnerOfResponse, PoolWithPoolKey, QuoteResult, SwapHop, TokensResponse, + AllNftInfoResponse, Approval, ApprovedForAllResponse, NftInfoResponse, NumTokensResponse, + OwnerOfResponse, PoolWithPoolKey, QuoteResult, SwapHop, TokensResponse, }, percentage::Percentage, sqrt_price::{get_max_tick, get_min_tick, SqrtPrice}, state::{self, CONFIG, MAX_LIMIT, POSITIONS}, tick_to_position, token_amount::TokenAmount, - ContractError, FeeTier, LiquidityTick, Pool, PoolKey, Position, PositionTick, Tick, CHUNK_SIZE, + FeeTier, LiquidityTick, Pool, PoolKey, Position, PositionTick, Tick, CHUNK_SIZE, LIQUIDITY_TICK_LIMIT, POSITION_TICK_LIMIT, }; +use oraiswap_v3_common::{asset::Asset, error::ContractError}; use super::{calculate_swap, route, tickmap_slice, TimeStampExt}; @@ -30,6 +31,12 @@ pub fn get_protocol_fee(deps: Deps) -> Result { Ok(config.protocol_fee) } +/// Retrieves the incentives_fund_manager contract address. +pub fn get_incentives_fund_manager(deps: Deps) -> Result { + let config = CONFIG.load(deps.storage)?; + Ok(config.incentives_fund_manager) +} + /// Retrieves information about a single position. /// /// # Parameters diff --git a/contracts/oraiswap-v3/src/interface.rs b/contracts/oraiswap-v3/src/interface.rs index 7bc6d59..8a15479 100644 --- a/contracts/oraiswap-v3/src/interface.rs +++ b/contracts/oraiswap-v3/src/interface.rs @@ -1,13 +1,10 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - to_json_binary, Addr, Api, BankMsg, Binary, Coin, CosmosMsg, MessageInfo, StdResult, Uint128, - WasmMsg, -}; -use cw20::{Cw20ExecuteMsg, Expiration}; +use cosmwasm_std::{to_json_binary, Addr, Binary, CosmosMsg, StdResult, WasmMsg}; +use cw20::Expiration; use crate::{ - fee_growth::FeeGrowth, sqrt_price::SqrtPrice, token_amount::TokenAmount, ContractError, Pool, - PoolKey, Position, Tick, + fee_growth::FeeGrowth, sqrt_price::SqrtPrice, token_amount::TokenAmount, Pool, PoolKey, + Position, Tick, }; #[cw_serde] @@ -27,135 +24,6 @@ pub struct SwapHop { pub x_to_y: bool, } -/// AssetInfo contract_addr is usually passed from the cw20 hook -/// so we can trust the contract_addr is properly validated. -#[cw_serde] -pub enum AssetInfo { - Token { contract_addr: Addr }, - NativeToken { denom: String }, -} - -impl AssetInfo { - pub fn from_denom(api: &dyn Api, denom: &str) -> Self { - if let Ok(contract_addr) = api.addr_validate(denom) { - Self::Token { contract_addr } - } else { - Self::NativeToken { - denom: denom.to_string(), - } - } - } - - pub fn denom(&self) -> String { - match self { - AssetInfo::Token { contract_addr } => contract_addr.to_string(), - AssetInfo::NativeToken { denom } => denom.to_string(), - } - } -} - -#[cw_serde] -pub struct Asset { - pub info: AssetInfo, - pub amount: Uint128, -} - -impl Asset { - pub fn transfer( - &self, - msgs: &mut Vec, - info: &MessageInfo, - ) -> Result<(), ContractError> { - if !self.amount.is_zero() { - match &self.info { - AssetInfo::Token { contract_addr } => { - msgs.push( - WasmMsg::Execute { - contract_addr: contract_addr.to_string(), - msg: to_json_binary(&Cw20ExecuteMsg::Transfer { - recipient: info.sender.to_string(), - amount: self.amount, - })?, - funds: vec![], - } - .into(), - ); - } - AssetInfo::NativeToken { denom } => msgs.push( - BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![Coin { - amount: self.amount, - denom: denom.to_string(), - }], - } - .into(), - ), - } - } - Ok(()) - } - - pub fn transfer_from( - &self, - msgs: &mut Vec, - info: &MessageInfo, - recipient: String, - ) -> Result<(), ContractError> { - if !self.amount.is_zero() { - match &self.info { - AssetInfo::Token { contract_addr } => { - msgs.push( - WasmMsg::Execute { - contract_addr: contract_addr.to_string(), - msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { - owner: info.sender.to_string(), - recipient, - amount: self.amount, - })?, - funds: vec![], - } - .into(), - ); - } - AssetInfo::NativeToken { denom } => { - match info.funds.iter().find(|x| x.denom.eq(denom)) { - Some(coin) => { - if coin.amount >= self.amount { - let refund_amount = coin.amount - self.amount; - // refund for user - if !refund_amount.is_zero() { - msgs.push( - BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![Coin { - amount: refund_amount, - denom: denom.to_string(), - }], - } - .into(), - ) - } - } else { - return Err(ContractError::InvalidFunds { - transfer_amount: self.amount, - }); - } - } - None => { - return Err(ContractError::InvalidFunds { - transfer_amount: self.amount, - }); - } - } - } - } - } - - Ok(()) - } -} - #[cw_serde] pub struct Approval { /// Account that can transfer/send the token diff --git a/contracts/oraiswap-v3/src/lib.rs b/contracts/oraiswap-v3/src/lib.rs index f2bda32..0a8e45c 100644 --- a/contracts/oraiswap-v3/src/lib.rs +++ b/contracts/oraiswap-v3/src/lib.rs @@ -1,5 +1,3 @@ -mod error; - pub mod contract; pub mod entrypoints; pub mod interface; @@ -10,7 +8,6 @@ pub mod logic; pub mod math; pub mod storage; -pub use crate::error::ContractError; pub use math::*; pub use storage::*; diff --git a/contracts/oraiswap-v3/src/logic/math.rs b/contracts/oraiswap-v3/src/logic/math.rs index 4eb2e0a..48daf5f 100644 --- a/contracts/oraiswap-v3/src/logic/math.rs +++ b/contracts/oraiswap-v3/src/logic/math.rs @@ -4,7 +4,7 @@ use crate::math::liquidity::Liquidity; use crate::math::sqrt_price::{calculate_sqrt_price, SqrtPrice}; use crate::math::token_amount::TokenAmount; use crate::math::MAX_TICK; -use crate::ContractError; +use oraiswap_v3_common::error::ContractError; #[derive(Debug)] pub struct LiquidityResult { diff --git a/contracts/oraiswap-v3/src/math/clamm.rs b/contracts/oraiswap-v3/src/math/clamm.rs index 67216c1..5d15a6e 100644 --- a/contracts/oraiswap-v3/src/math/clamm.rs +++ b/contracts/oraiswap-v3/src/math/clamm.rs @@ -3,8 +3,7 @@ use decimal::*; use crate::math::consts::*; use crate::math::types::{liquidity::*, percentage::*, sqrt_price::*, token_amount::*}; -use crate::ContractError; - +use oraiswap_v3_common::error::ContractError; pub const CASTING_INTEGER_TO_U128_ERROR: &str = "integer overflow when casting to u128"; #[cw_serde] diff --git a/contracts/oraiswap-v3/src/math/log.rs b/contracts/oraiswap-v3/src/math/log.rs index 8f4253b..7f16eb1 100644 --- a/contracts/oraiswap-v3/src/math/log.rs +++ b/contracts/oraiswap-v3/src/math/log.rs @@ -2,7 +2,7 @@ use decimal::*; use crate::math::consts::*; use crate::math::types::sqrt_price::SqrtPrice; -use crate::ContractError; +use oraiswap_v3_common::error::ContractError; const LOG2_SCALE: u8 = 32; const LOG2_DOUBLE_SCALE: u8 = 64; diff --git a/contracts/oraiswap-v3/src/math/types/fee_growth.rs b/contracts/oraiswap-v3/src/math/types/fee_growth.rs index fa2ed94..b22093d 100644 --- a/contracts/oraiswap-v3/src/math/types/fee_growth.rs +++ b/contracts/oraiswap-v3/src/math/types/fee_growth.rs @@ -1,9 +1,7 @@ -use crate::{ - math::types::{liquidity::*, token_amount::*}, - ContractError, -}; +use crate::math::types::{liquidity::*, token_amount::*}; use cosmwasm_schema::cw_serde; use decimal::*; +use oraiswap_v3_common::error::ContractError; #[decimal(28)] #[cw_serde] diff --git a/contracts/oraiswap-v3/src/math/types/seconds_per_liquidity.rs b/contracts/oraiswap-v3/src/math/types/seconds_per_liquidity.rs index a784c2e..5ca3a7f 100644 --- a/contracts/oraiswap-v3/src/math/types/seconds_per_liquidity.rs +++ b/contracts/oraiswap-v3/src/math/types/seconds_per_liquidity.rs @@ -1,7 +1,8 @@ use cosmwasm_schema::cw_serde; use decimal::*; -use crate::{math::types::liquidity::Liquidity, ContractError}; +use crate::math::types::liquidity::Liquidity; +use oraiswap_v3_common::error::ContractError; #[decimal(24)] #[cw_serde] diff --git a/contracts/oraiswap-v3/src/math/types/sqrt_price.rs b/contracts/oraiswap-v3/src/math/types/sqrt_price.rs index 6f2c853..e4c6601 100644 --- a/contracts/oraiswap-v3/src/math/types/sqrt_price.rs +++ b/contracts/oraiswap-v3/src/math/types/sqrt_price.rs @@ -3,7 +3,7 @@ use decimal::*; use crate::math::consts::*; use crate::math::types::{fixed_point::FixedPoint, token_amount::TokenAmount}; -use crate::ContractError; +use oraiswap_v3_common::error::ContractError; #[decimal(24)] #[cw_serde] diff --git a/contracts/oraiswap-v3/src/math/types/token_amount.rs b/contracts/oraiswap-v3/src/math/types/token_amount.rs index 5616310..1d5c187 100644 --- a/contracts/oraiswap-v3/src/math/types/token_amount.rs +++ b/contracts/oraiswap-v3/src/math/types/token_amount.rs @@ -2,7 +2,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Uint128; use decimal::*; -use crate::ContractError; +use oraiswap_v3_common::error::ContractError; use super::sqrt_price::SqrtPrice; diff --git a/contracts/oraiswap-v3/src/msg.rs b/contracts/oraiswap-v3/src/msg.rs index ae80bac..08067dc 100644 --- a/contracts/oraiswap-v3/src/msg.rs +++ b/contracts/oraiswap-v3/src/msg.rs @@ -2,10 +2,11 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, Binary}; use cw20::Expiration; +use oraiswap_v3_common::asset::{Asset, AssetInfo}; use crate::interface::{ - AllNftInfoResponse, ApprovedForAllResponse, Asset, AssetInfo, NftInfoResponse, - NumTokensResponse, OwnerOfResponse, PoolWithPoolKey, PositionTick, QuoteResult, TokensResponse, + AllNftInfoResponse, ApprovedForAllResponse, NftInfoResponse, NumTokensResponse, + OwnerOfResponse, PoolWithPoolKey, PositionTick, QuoteResult, TokensResponse, }; #[allow(unused_imports)] use crate::{ @@ -17,6 +18,7 @@ use crate::{ #[cw_serde] pub struct InstantiateMsg { pub protocol_fee: Percentage, + pub incentives_fund_manager: Addr, } #[cw_serde] @@ -164,6 +166,9 @@ pub enum QueryMsg { #[returns(Percentage)] ProtocolFee {}, + #[returns(Addr)] + IncentivesFundManager {}, + #[returns(Position)] Position { owner_id: Addr, index: u32 }, diff --git a/contracts/oraiswap-v3/src/state.rs b/contracts/oraiswap-v3/src/state.rs index ce9fd9d..bca8606 100644 --- a/contracts/oraiswap-v3/src/state.rs +++ b/contracts/oraiswap-v3/src/state.rs @@ -7,8 +7,9 @@ use crate::{ incentive::IncentiveRecord, interface::PoolWithPoolKey, sqrt_price::{calculate_sqrt_price, SqrtPrice}, - tick_to_position, Config, ContractError, Pool, PoolKey, Position, Tick, CHUNK_SIZE, MAX_TICK, + tick_to_position, Config, Pool, PoolKey, Position, Tick, CHUNK_SIZE, MAX_TICK, }; +use oraiswap_v3_common::error::ContractError; pub const CONFIG: Item = Item::new("config"); diff --git a/contracts/oraiswap-v3/src/storage/config.rs b/contracts/oraiswap-v3/src/storage/config.rs index fae3255..a7aeaa8 100644 --- a/contracts/oraiswap-v3/src/storage/config.rs +++ b/contracts/oraiswap-v3/src/storage/config.rs @@ -8,4 +8,5 @@ pub struct Config { pub admin: Addr, pub fee_tiers: Vec, pub protocol_fee: Percentage, + pub incentives_fund_manager: Addr, } diff --git a/contracts/oraiswap-v3/src/storage/fee_tier.rs b/contracts/oraiswap-v3/src/storage/fee_tier.rs index 57ac5be..019fbb6 100644 --- a/contracts/oraiswap-v3/src/storage/fee_tier.rs +++ b/contracts/oraiswap-v3/src/storage/fee_tier.rs @@ -1,6 +1,7 @@ -use crate::{math::types::percentage::Percentage, ContractError}; +use crate::math::types::percentage::Percentage; use cosmwasm_schema::cw_serde; use decimal::*; +use oraiswap_v3_common::error::ContractError; #[cw_serde] #[derive(Eq, Copy, Default)] diff --git a/contracts/oraiswap-v3/src/storage/incentive.rs b/contracts/oraiswap-v3/src/storage/incentive.rs index 6046336..a46bf9d 100644 --- a/contracts/oraiswap-v3/src/storage/incentive.rs +++ b/contracts/oraiswap-v3/src/storage/incentive.rs @@ -1,9 +1,7 @@ use cosmwasm_schema::cw_serde; -use crate::{ - fee_growth::FeeGrowth, interface::AssetInfo, liquidity::Liquidity, token_amount::TokenAmount, - ContractError, -}; +use crate::{fee_growth::FeeGrowth, liquidity::Liquidity, token_amount::TokenAmount}; +use oraiswap_v3_common::{asset::AssetInfo, error::ContractError}; #[cw_serde] pub struct IncentiveRecord { diff --git a/contracts/oraiswap-v3/src/storage/mod.rs b/contracts/oraiswap-v3/src/storage/mod.rs index f9b89bb..7d24e42 100644 --- a/contracts/oraiswap-v3/src/storage/mod.rs +++ b/contracts/oraiswap-v3/src/storage/mod.rs @@ -14,5 +14,3 @@ pub use pool_key::*; pub use position::*; pub use tick::*; pub use tickmap::*; - -pub use crate::error::ContractError; diff --git a/contracts/oraiswap-v3/src/storage/pool.rs b/contracts/oraiswap-v3/src/storage/pool.rs index ff32080..3233a71 100644 --- a/contracts/oraiswap-v3/src/storage/pool.rs +++ b/contracts/oraiswap-v3/src/storage/pool.rs @@ -1,17 +1,15 @@ use super::{FeeTier, Tick}; use crate::incentive::IncentiveRecord; use crate::math::types::sqrt_price::check_tick_to_sqrt_price_relationship; -use crate::{ - math::{ - clamm::*, - log::get_tick_at_sqrt_price, - types::{ - fee_growth::FeeGrowth, liquidity::Liquidity, percentage::Percentage, - sqrt_price::SqrtPrice, token_amount::TokenAmount, - }, +use crate::math::{ + clamm::*, + log::get_tick_at_sqrt_price, + types::{ + fee_growth::FeeGrowth, liquidity::Liquidity, percentage::Percentage, sqrt_price::SqrtPrice, + token_amount::TokenAmount, }, - ContractError, }; +use oraiswap_v3_common::error::ContractError; use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; diff --git a/contracts/oraiswap-v3/src/storage/pool_key.rs b/contracts/oraiswap-v3/src/storage/pool_key.rs index ff835ce..c847a3b 100644 --- a/contracts/oraiswap-v3/src/storage/pool_key.rs +++ b/contracts/oraiswap-v3/src/storage/pool_key.rs @@ -1,9 +1,10 @@ use core::fmt; -use crate::{ContractError, FeeTier}; +use crate::FeeTier; use cosmwasm_schema::cw_serde; use cosmwasm_storage::to_length_prefixed_nested; use cw_storage_plus::KeyDeserialize; +use oraiswap_v3_common::error::ContractError; #[cw_serde] #[derive(Default, Eq)] diff --git a/contracts/oraiswap-v3/src/storage/position.rs b/contracts/oraiswap-v3/src/storage/position.rs index 19cd4e6..c959598 100644 --- a/contracts/oraiswap-v3/src/storage/position.rs +++ b/contracts/oraiswap-v3/src/storage/position.rs @@ -1,7 +1,7 @@ use super::{Pool, PoolKey, Tick}; use crate::{ incentive::{calculate_incentive_growth_inside, PositionIncentives}, - interface::{Approval, Asset}, + interface::Approval, math::{ clamm::*, types::{ @@ -11,10 +11,10 @@ use crate::{ token_amount::TokenAmount, }, }, - ContractError, }; use cosmwasm_schema::cw_serde; use decimal::*; +use oraiswap_v3_common::{asset::Asset, error::ContractError}; #[cw_serde] #[derive(Default)] diff --git a/contracts/oraiswap-v3/src/storage/tick.rs b/contracts/oraiswap-v3/src/storage/tick.rs index 3fc2f38..d7d464c 100644 --- a/contracts/oraiswap-v3/src/storage/tick.rs +++ b/contracts/oraiswap-v3/src/storage/tick.rs @@ -6,10 +6,10 @@ use crate::{ liquidity::Liquidity, sqrt_price::{calculate_sqrt_price, SqrtPrice}, }, - ContractError, }; use cosmwasm_schema::cw_serde; use decimal::*; +use oraiswap_v3_common::error::ContractError; #[cw_serde] #[derive(Eq, Default)] diff --git a/contracts/oraiswap-v3/src/tests/add_fee_tier.rs b/contracts/oraiswap-v3/src/tests/add_fee_tier.rs index 86b17c2..e1acd00 100644 --- a/contracts/oraiswap-v3/src/tests/add_fee_tier.rs +++ b/contracts/oraiswap-v3/src/tests/add_fee_tier.rs @@ -1,9 +1,9 @@ use crate::math::types::percentage::Percentage; use crate::msg::QueryMsg; use crate::tests::helper::{macros::*, MockApp}; -use crate::ContractError; use crate::FeeTier; use decimal::Decimal; +use oraiswap_v3_common::error::ContractError; #[test] fn test_add_multiple_fee_tiers() { diff --git a/contracts/oraiswap-v3/src/tests/admin.rs b/contracts/oraiswap-v3/src/tests/admin.rs index 90d7fbc..1ba997e 100644 --- a/contracts/oraiswap-v3/src/tests/admin.rs +++ b/contracts/oraiswap-v3/src/tests/admin.rs @@ -2,7 +2,7 @@ use crate::msg::{ExecuteMsg, QueryMsg}; use crate::percentage::Percentage; use crate::tests::helper::macros::*; use crate::tests::helper::MockApp; -use crate::ContractError; +use oraiswap_v3_common::error::ContractError; use cosmwasm_std::Addr; use decimal::Decimal; diff --git a/contracts/oraiswap-v3/src/tests/change_fee_receiver.rs b/contracts/oraiswap-v3/src/tests/change_fee_receiver.rs index 49cf2a1..9861eb7 100644 --- a/contracts/oraiswap-v3/src/tests/change_fee_receiver.rs +++ b/contracts/oraiswap-v3/src/tests/change_fee_receiver.rs @@ -2,10 +2,10 @@ use crate::math::types::percentage::Percentage; use crate::math::types::sqrt_price::calculate_sqrt_price; use crate::tests::helper::macros::*; use crate::tests::helper::MockApp; -use crate::ContractError; use crate::{FeeTier, PoolKey}; use cosmwasm_std::Addr; use decimal::Decimal; +use oraiswap_v3_common::error::ContractError; #[test] fn test_change_fee_reciever() { diff --git a/contracts/oraiswap-v3/src/tests/change_protocol_fee.rs b/contracts/oraiswap-v3/src/tests/change_protocol_fee.rs index d87e319..9df23e9 100644 --- a/contracts/oraiswap-v3/src/tests/change_protocol_fee.rs +++ b/contracts/oraiswap-v3/src/tests/change_protocol_fee.rs @@ -2,7 +2,7 @@ use crate::msg::{ExecuteMsg, QueryMsg}; use crate::percentage::Percentage; use crate::tests::helper::macros::*; use crate::tests::helper::MockApp; -use crate::ContractError; +use oraiswap_v3_common::error::ContractError; use cosmwasm_std::Addr; use decimal::Decimal; diff --git a/contracts/oraiswap-v3/src/tests/claim.rs b/contracts/oraiswap-v3/src/tests/claim.rs index e01f20b..e6b2bea 100644 --- a/contracts/oraiswap-v3/src/tests/claim.rs +++ b/contracts/oraiswap-v3/src/tests/claim.rs @@ -1,8 +1,8 @@ use cosmwasm_std::Timestamp; use decimal::{Decimal, Factories}; +use oraiswap_v3_common::asset::AssetInfo; use crate::{ - interface::AssetInfo, liquidity::Liquidity, percentage::Percentage, sqrt_price::{self, calculate_sqrt_price, SqrtPrice}, @@ -71,6 +71,35 @@ fn claim_both_fee_and_incentives() { mint!(app, token_a, dex_raw, initial_amount, "alice").unwrap(); mint!(app, token_b, dex_raw, initial_amount, "alice").unwrap(); + let incentives_fund_manager = app.get_incentives_fund_manager(dex_raw).unwrap(); + let incentives_fund_manager_raw = &incentives_fund_manager.to_string(); + + // mint token for incentive contract + mint!( + app, + token_a, + incentives_fund_manager_raw, + initial_amount, + "alice" + ) + .unwrap(); + mint!( + app, + token_b, + incentives_fund_manager_raw, + initial_amount, + "alice" + ) + .unwrap(); + mint!( + app, + token_z, + incentives_fund_manager_raw, + initial_amount, + "alice" + ) + .unwrap(); + let fee_tier = FeeTier::new(protocol_fee, 1).unwrap(); add_fee_tier!(app, dex, fee_tier, "alice").unwrap(); @@ -157,7 +186,7 @@ fn claim_both_fee_and_incentives() { .unwrap(); let before_dex_balance_token_x = balance_of!(app, token_x, dex); - let before_dex_balance_token_z = balance_of!(app, token_z, dex); + let before_incentive_balance_token_z = balance_of!(app, token_z, incentives_fund_manager); let before_user_balance_token_x = balance_of!(app, token_x, "alice"); let before_user_balance_token_z = balance_of!(app, token_z, "alice"); @@ -189,15 +218,17 @@ fn claim_both_fee_and_incentives() { let total_emit = (timestamp_after - timestamp_init) as u128 * reward_per_sec.0; let after_dex_balance_token_x = balance_of!(app, token_x, dex); - let after_dex_balance_token_z = balance_of!(app, token_z, dex); + let after_incentive_balance_token_z = balance_of!(app, token_z, incentives_fund_manager); let after_user_balance_token_x = balance_of!(app, token_x, "alice"); let after_user_balance_token_z = balance_of!(app, token_z, "alice"); // incentive assert - assert!(before_dex_balance_token_z.gt(&after_dex_balance_token_z)); + assert!(before_incentive_balance_token_z.gt(&after_incentive_balance_token_z)); assert!(before_user_balance_token_z.lt(&after_user_balance_token_z)); - assert!((before_user_balance_token_z + before_dex_balance_token_z) - .eq(&(after_user_balance_token_z + after_dex_balance_token_z))); + assert!( + (before_user_balance_token_z + before_incentive_balance_token_z) + .eq(&(after_user_balance_token_z + after_incentive_balance_token_z)) + ); assert!((after_user_balance_token_z - before_user_balance_token_z).le(&total_emit)); // fee claimed assert diff --git a/contracts/oraiswap-v3/src/tests/get_position_ticks.rs b/contracts/oraiswap-v3/src/tests/get_position_ticks.rs index a5ef4c8..733363a 100644 --- a/contracts/oraiswap-v3/src/tests/get_position_ticks.rs +++ b/contracts/oraiswap-v3/src/tests/get_position_ticks.rs @@ -289,8 +289,8 @@ fn test_query_all_positions() { [ Position { pool_key: PoolKey { - token_x: String::from("contract1"), - token_y: String::from("contract2"), + token_x: String::from("contract2"), + token_y: String::from("contract3"), fee_tier: FeeTier { fee: Percentage(10000000000), tick_spacing: 1 @@ -301,7 +301,7 @@ fn test_query_all_positions() { upper_tick_index: 10, fee_growth_inside_x: FeeGrowth(0), fee_growth_inside_y: FeeGrowth(0), - last_block_number: 12353, + last_block_number: 12356, tokens_owed_x: TokenAmount(0), tokens_owed_y: TokenAmount(0), approvals: vec![], @@ -310,8 +310,8 @@ fn test_query_all_positions() { }, Position { pool_key: PoolKey { - token_x: String::from("contract1"), - token_y: String::from("contract2"), + token_x: String::from("contract2"), + token_y: String::from("contract3"), fee_tier: FeeTier { fee: Percentage(10000000000), tick_spacing: 1 @@ -322,7 +322,7 @@ fn test_query_all_positions() { upper_tick_index: 100, fee_growth_inside_x: FeeGrowth(0), fee_growth_inside_y: FeeGrowth(0), - last_block_number: 12354, + last_block_number: 12357, tokens_owed_x: TokenAmount(0), tokens_owed_y: TokenAmount(0), token_id: 2, diff --git a/contracts/oraiswap-v3/src/tests/helper.rs b/contracts/oraiswap-v3/src/tests/helper.rs index 1545774..6895c70 100644 --- a/contracts/oraiswap-v3/src/tests/helper.rs +++ b/contracts/oraiswap-v3/src/tests/helper.rs @@ -1,8 +1,9 @@ use cosmwasm_std::{Addr, Binary, Coin, Event, StdResult, Timestamp}; use cosmwasm_testing_util::{AppResponse, ContractWrapper, MockResult}; +use oraiswap_v3_common::asset::{Asset, AssetInfo}; use crate::{ - interface::{Asset, AssetInfo, PoolWithPoolKey, QuoteResult, SwapHop}, + interface::{PoolWithPoolKey, QuoteResult, SwapHop}, liquidity::Liquidity, msg::{self}, percentage::Percentage, @@ -19,6 +20,7 @@ pub struct MockApp { #[deref_mut] app: cosmwasm_testing_util::MockApp, dex_id: u64, + incentives_id: u64, } #[allow(dead_code)] @@ -32,17 +34,64 @@ impl MockApp { crate::contract::query, ))); - Self { app, dex_id } + let incentives_id = app.upload(Box::new(ContractWrapper::new_with_empty( + incentives_fund_manager::contract::execute, + incentives_fund_manager::contract::instantiate, + incentives_fund_manager::contract::query, + ))); + + Self { + app, + dex_id, + incentives_id, + } } pub fn create_dex(&mut self, owner: &str, protocol_fee: Percentage) -> MockResult { + // create incentive_contract + let incentive_id = self.incentives_id; + + let incentive_addr = self.instantiate( + incentive_id, + Addr::unchecked(owner), + &oraiswap_v3_common::incentives_fund_manager::InstantiateMsg { + owner: None, + oraiswap_v3: Addr::unchecked("oraiswap_v3"), + }, + &[], + "incentives_fund_mamnager", + )?; + let code_id = self.dex_id; - self.instantiate( + let dex_addr = self.instantiate( code_id, Addr::unchecked(owner), - &msg::InstantiateMsg { protocol_fee }, + &msg::InstantiateMsg { + protocol_fee, + incentives_fund_manager: incentive_addr.clone(), + }, &[], "oraiswap_v3", + )?; + + // update config for incentive_contract + self.execute( + Addr::unchecked(owner), + incentive_addr.clone(), + &oraiswap_v3_common::incentives_fund_manager::ExecuteMsg::UpdateConfig { + owner: None, + oraiswap_v3: Some(dex_addr.clone()), + }, + &[], + )?; + + Ok(dex_addr) + } + + pub fn get_incentives_fund_manager(&mut self, dex: &str) -> StdResult { + self.query( + Addr::unchecked(dex), + &msg::QueryMsg::IncentivesFundManager {}, ) } @@ -460,6 +509,7 @@ pub fn extract_amount(events: &[Event], key: &str) -> Option { } pub mod macros { + macro_rules! create_dex { ($app:ident, $protocol_fee:expr) => {{ $app.create_dex("alice", $protocol_fee).unwrap() diff --git a/contracts/oraiswap-v3/src/tests/incentive.rs b/contracts/oraiswap-v3/src/tests/incentive.rs index e88b3e9..bb460a9 100644 --- a/contracts/oraiswap-v3/src/tests/incentive.rs +++ b/contracts/oraiswap-v3/src/tests/incentive.rs @@ -1,16 +1,18 @@ -use cosmwasm_std::{Addr, Timestamp, Uint128}; -use decimal::*; - use crate::{ fee_growth::FeeGrowth, incentive::{IncentiveRecord, PositionIncentives}, - interface::{Asset, AssetInfo}, liquidity::Liquidity, percentage::Percentage, sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::{macros::*, MockApp}, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, MAX_SQRT_PRICE, MIN_SQRT_PRICE, + FeeTier, PoolKey, MAX_SQRT_PRICE, MIN_SQRT_PRICE, +}; +use cosmwasm_std::{Addr, Timestamp, Uint128}; +use decimal::*; +use oraiswap_v3_common::{ + asset::{Asset, AssetInfo}, + error::ContractError, }; #[test] @@ -624,7 +626,9 @@ pub fn test_incentive_with_position_cross_out_of_range() { let initial_amount = 10u128.pow(10); let (token_x, token_y, token_z) = create_3_tokens!(app, initial_amount, initial_amount, initial_amount); - mint!(app, token_z, dex_raw, initial_amount, "alice").unwrap(); + let incentives_addr = app.get_incentives_fund_manager(dex_raw).unwrap(); + let incentives_addr_raw = &incentives_addr.to_string(); + mint!(app, token_z, incentives_addr_raw, initial_amount, "alice").unwrap(); let fee_tier = FeeTier::new(protocol_fee, 1).unwrap(); @@ -821,19 +825,18 @@ pub fn test_incentive_with_position_cross_out_of_range() { ); // try claim incentives - let before_dex_balance = balance_of!(app, token_z, dex); + let before_incentive_balance = balance_of!(app, token_z, incentives_addr); let before_user_balance = balance_of!(app, token_z, "alice"); claim_incentives!(app, dex, 0, "alice").unwrap(); claim_incentives!(app, dex, 1, "alice").unwrap(); - let after_dex_balance = balance_of!(app, token_z, dex); + let after_incentive_balance = balance_of!(app, token_z, incentives_addr); let after_user_balance = balance_of!(app, token_z, "alice"); - assert!(before_dex_balance.gt(&after_dex_balance)); + assert!(before_incentive_balance.gt(&after_incentive_balance)); assert!(before_user_balance.lt(&after_user_balance)); - assert!( - (before_user_balance + before_dex_balance).eq(&(after_user_balance + after_dex_balance)) - ); + assert!((before_user_balance + before_incentive_balance) + .eq(&(after_user_balance + after_incentive_balance))); } #[test] @@ -1073,7 +1076,10 @@ pub fn test_claim_incentive_with_single_position() { let initial_amount = 10u128.pow(10); let (token_x, token_y, token_z) = create_3_tokens!(app, initial_amount, initial_amount, initial_amount); - mint!(app, token_z, dex_raw, initial_amount, "alice").unwrap(); + + let incentives_addr = app.get_incentives_fund_manager(dex_raw).unwrap(); + let incentives_addr_raw = &incentives_addr.to_string(); + mint!(app, token_z, incentives_addr_raw, initial_amount, "alice").unwrap(); let fee_tier = FeeTier::new(protocol_fee, 1).unwrap(); @@ -1132,7 +1138,7 @@ pub fn test_claim_incentive_with_single_position() { ) .unwrap(); - let before_dex_balance = balance_of!(app, token_z, dex); + let before_incentive_balance = balance_of!(app, token_z, incentives_addr); let before_user_balance = balance_of!(app, token_z, "alice"); // increase block time @@ -1150,14 +1156,13 @@ pub fn test_claim_incentive_with_single_position() { let timestamp_after = app.app.block_info().time.seconds(); let total_emit = (timestamp_after - timestamp_init) as u128 * reward_per_sec.0; - let after_dex_balance = balance_of!(app, token_z, dex); + let after_incentive_balance = balance_of!(app, token_z, incentives_addr); let after_user_balance = balance_of!(app, token_z, "alice"); - assert!(before_dex_balance.gt(&after_dex_balance)); + assert!(before_incentive_balance.gt(&after_incentive_balance)); assert!(before_user_balance.lt(&after_user_balance)); - assert!( - (before_user_balance + before_dex_balance).eq(&(after_user_balance + after_dex_balance)) - ); + assert!((before_user_balance + before_incentive_balance) + .eq(&(after_user_balance + after_incentive_balance))); // total claimed of user must be less than or equal total emit assert!((after_user_balance - before_user_balance).le(&total_emit)); } @@ -1172,7 +1177,9 @@ pub fn test_claim_incentive_with_multi_position() { let initial_amount = 10u128.pow(10); let (token_x, token_y, token_z) = create_3_tokens!(app, initial_amount, initial_amount, initial_amount); - mint!(app, token_z, dex_raw, initial_amount, "alice").unwrap(); + let incentives_addr = app.get_incentives_fund_manager(dex_raw).unwrap(); + let incentives_addr_raw = &incentives_addr.to_string(); + mint!(app, token_z, incentives_addr_raw, initial_amount, "alice").unwrap(); let fee_tier = FeeTier::new(protocol_fee, 1).unwrap(); @@ -1241,7 +1248,7 @@ pub fn test_claim_incentive_with_multi_position() { .unwrap(); } - let before_dex_balance = balance_of!(app, token_z, dex); + let before_incentive_balance = balance_of!(app, token_z, incentives_addr); let before_user_balance = balance_of!(app, token_z, "alice"); // increase block time @@ -1261,14 +1268,13 @@ pub fn test_claim_incentive_with_multi_position() { let timestamp_after = app.app.block_info().time.seconds(); let total_emit = (timestamp_after - timestamp_init) as u128 * reward_per_sec.0; - let after_dex_balance = balance_of!(app, token_z, dex); + let after_incentive_balance = balance_of!(app, token_z, incentives_addr); let after_user_balance = balance_of!(app, token_z, "alice"); - assert!(before_dex_balance.gt(&after_dex_balance)); + assert!(before_incentive_balance.gt(&after_incentive_balance)); assert!(before_user_balance.lt(&after_user_balance)); - assert!( - (before_user_balance + before_dex_balance).eq(&(after_user_balance + after_dex_balance)) - ); + assert!((before_user_balance + before_incentive_balance) + .eq(&(after_user_balance + after_incentive_balance))); // total claimed of user must be less than or equal total emit assert!((after_user_balance - before_user_balance).le(&total_emit)); } @@ -1283,7 +1289,9 @@ pub fn test_update_incentive_with_tick_move_left_to_right() { let initial_amount = 10u128.pow(10); let (token_x, token_y, token_z) = create_3_tokens!(app, initial_amount, initial_amount, initial_amount); - mint!(app, token_z, dex_raw, initial_amount, "alice").unwrap(); + let incentives_addr = app.get_incentives_fund_manager(dex_raw).unwrap(); + let incentives_addr_raw = &incentives_addr.to_string(); + mint!(app, token_z, incentives_addr_raw, initial_amount, "alice").unwrap(); let fee_tier = FeeTier::new(protocol_fee, 1).unwrap(); @@ -1436,7 +1444,9 @@ pub fn test_update_incentive_with_tick_move_right_to_left() { let initial_amount = 10u128.pow(10); let (token_x, token_y, token_z) = create_3_tokens!(app, initial_amount, initial_amount, initial_amount); - mint!(app, token_z, dex_raw, initial_amount, "alice").unwrap(); + let incentives_addr = app.get_incentives_fund_manager(dex_raw).unwrap(); + let incentives_addr_raw = &incentives_addr.to_string(); + mint!(app, token_z, incentives_addr_raw, initial_amount, "alice").unwrap(); let fee_tier = FeeTier::new(protocol_fee, 1).unwrap(); diff --git a/contracts/oraiswap-v3/src/tests/liquidity_gap.rs b/contracts/oraiswap-v3/src/tests/liquidity_gap.rs index 9ca8a08..a4b0f72 100644 --- a/contracts/oraiswap-v3/src/tests/liquidity_gap.rs +++ b/contracts/oraiswap-v3/src/tests/liquidity_gap.rs @@ -7,8 +7,9 @@ use crate::{ sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::{macros::*, MockApp}, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, MIN_SQRT_PRICE, + FeeTier, PoolKey, MIN_SQRT_PRICE, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_liquidity_gap() { diff --git a/contracts/oraiswap-v3/src/tests/nft.rs b/contracts/oraiswap-v3/src/tests/nft.rs index 9d15c91..b4d5b0b 100644 --- a/contracts/oraiswap-v3/src/tests/nft.rs +++ b/contracts/oraiswap-v3/src/tests/nft.rs @@ -10,8 +10,9 @@ use crate::{ sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::{macros::*, MockApp}, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, Position, MIN_SQRT_PRICE, + FeeTier, PoolKey, Position, MIN_SQRT_PRICE, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_mint_nft() { diff --git a/contracts/oraiswap-v3/src/tests/position.rs b/contracts/oraiswap-v3/src/tests/position.rs index b1536a6..ea15faf 100644 --- a/contracts/oraiswap-v3/src/tests/position.rs +++ b/contracts/oraiswap-v3/src/tests/position.rs @@ -7,8 +7,9 @@ use crate::{ sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::{macros::*, MockApp}, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, MIN_SQRT_PRICE, + FeeTier, PoolKey, MIN_SQRT_PRICE, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_create_position() { diff --git a/contracts/oraiswap-v3/src/tests/position_slippage.rs b/contracts/oraiswap-v3/src/tests/position_slippage.rs index c7053ea..c7b879d 100644 --- a/contracts/oraiswap-v3/src/tests/position_slippage.rs +++ b/contracts/oraiswap-v3/src/tests/position_slippage.rs @@ -5,8 +5,9 @@ use crate::{ percentage::Percentage, sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::{macros::*, MockApp}, - ContractError, FeeTier, PoolKey, + FeeTier, PoolKey, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_position_slippage_zero_slippage_and_inside_range() { diff --git a/contracts/oraiswap-v3/src/tests/protocol_fee.rs b/contracts/oraiswap-v3/src/tests/protocol_fee.rs index ea443db..6608970 100644 --- a/contracts/oraiswap-v3/src/tests/protocol_fee.rs +++ b/contracts/oraiswap-v3/src/tests/protocol_fee.rs @@ -4,8 +4,9 @@ use crate::{ percentage::Percentage, tests::helper::{macros::*, MockApp}, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, + FeeTier, PoolKey, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_protocol_fee() { diff --git a/contracts/oraiswap-v3/src/tests/remove_fee_tier.rs b/contracts/oraiswap-v3/src/tests/remove_fee_tier.rs index a7c622c..70bc82b 100644 --- a/contracts/oraiswap-v3/src/tests/remove_fee_tier.rs +++ b/contracts/oraiswap-v3/src/tests/remove_fee_tier.rs @@ -3,8 +3,9 @@ use decimal::*; use crate::{ percentage::Percentage, tests::helper::{macros::*, MockApp}, - ContractError, FeeTier, + FeeTier, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_remove_fee_tier() { diff --git a/contracts/oraiswap-v3/src/tests/slippage.rs b/contracts/oraiswap-v3/src/tests/slippage.rs index 22eb60b..3397db8 100644 --- a/contracts/oraiswap-v3/src/tests/slippage.rs +++ b/contracts/oraiswap-v3/src/tests/slippage.rs @@ -6,8 +6,9 @@ use crate::{ sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::{macros::*, MockApp}, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, MAX_SQRT_PRICE, + FeeTier, PoolKey, MAX_SQRT_PRICE, }; +use oraiswap_v3_common::error::ContractError; #[test] fn test_basic_slippage() { diff --git a/contracts/oraiswap-v3/src/tests/swap.rs b/contracts/oraiswap-v3/src/tests/swap.rs index 3edfe52..fce4e67 100644 --- a/contracts/oraiswap-v3/src/tests/swap.rs +++ b/contracts/oraiswap-v3/src/tests/swap.rs @@ -7,8 +7,9 @@ use crate::{ sqrt_price::{calculate_sqrt_price, SqrtPrice}, tests::helper::macros::*, token_amount::TokenAmount, - ContractError, FeeTier, PoolKey, MAX_SQRT_PRICE, MIN_SQRT_PRICE, + FeeTier, PoolKey, MAX_SQRT_PRICE, MIN_SQRT_PRICE, }; +use oraiswap_v3_common::error::ContractError; use super::helper::MockApp; diff --git a/packages/oraiswap-v3-common/Cargo.toml b/packages/oraiswap-v3-common/Cargo.toml new file mode 100644 index 0000000..9a5e533 --- /dev/null +++ b/packages/oraiswap-v3-common/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "oraiswap-v3-common" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-storage = { workspace = true } + +cw20 = { workspace = true } +thiserror = { workspace = true } diff --git a/packages/oraiswap-v3-common/src/asset.rs b/packages/oraiswap-v3-common/src/asset.rs new file mode 100644 index 0000000..9a9fcaa --- /dev/null +++ b/packages/oraiswap-v3-common/src/asset.rs @@ -0,0 +1,136 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ + to_json_binary, Addr, Api, BankMsg, Coin, CosmosMsg, MessageInfo, Uint128, WasmMsg, +}; +use cw20::Cw20ExecuteMsg; + +use crate::error::ContractError; + +/// AssetInfo contract_addr is usually passed from the cw20 hook +/// so we can trust the contract_addr is properly validated. +#[cw_serde] +pub enum AssetInfo { + Token { contract_addr: Addr }, + NativeToken { denom: String }, +} + +impl AssetInfo { + pub fn from_denom(api: &dyn Api, denom: &str) -> Self { + if let Ok(contract_addr) = api.addr_validate(denom) { + Self::Token { contract_addr } + } else { + Self::NativeToken { + denom: denom.to_string(), + } + } + } + + pub fn denom(&self) -> String { + match self { + AssetInfo::Token { contract_addr } => contract_addr.to_string(), + AssetInfo::NativeToken { denom } => denom.to_string(), + } + } +} + +#[cw_serde] +pub struct Asset { + pub info: AssetInfo, + pub amount: Uint128, +} + +impl Asset { + pub fn transfer( + &self, + msgs: &mut Vec, + info: &MessageInfo, + ) -> Result<(), ContractError> { + if !self.amount.is_zero() { + match &self.info { + AssetInfo::Token { contract_addr } => { + msgs.push( + WasmMsg::Execute { + contract_addr: contract_addr.to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: info.sender.to_string(), + amount: self.amount, + })?, + funds: vec![], + } + .into(), + ); + } + AssetInfo::NativeToken { denom } => msgs.push( + BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![Coin { + amount: self.amount, + denom: denom.to_string(), + }], + } + .into(), + ), + } + } + Ok(()) + } + + pub fn transfer_from( + &self, + msgs: &mut Vec, + info: &MessageInfo, + recipient: String, + ) -> Result<(), ContractError> { + if !self.amount.is_zero() { + match &self.info { + AssetInfo::Token { contract_addr } => { + msgs.push( + WasmMsg::Execute { + contract_addr: contract_addr.to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::TransferFrom { + owner: info.sender.to_string(), + recipient, + amount: self.amount, + })?, + funds: vec![], + } + .into(), + ); + } + AssetInfo::NativeToken { denom } => { + match info.funds.iter().find(|x| x.denom.eq(denom)) { + Some(coin) => { + if coin.amount >= self.amount { + let refund_amount = coin.amount - self.amount; + // refund for user + if !refund_amount.is_zero() { + msgs.push( + BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![Coin { + amount: refund_amount, + denom: denom.to_string(), + }], + } + .into(), + ) + } + } else { + return Err(ContractError::InvalidFunds { + transfer_amount: self.amount, + }); + } + } + None => { + return Err(ContractError::InvalidFunds { + transfer_amount: self.amount, + }); + } + } + } + } + } + + Ok(()) + } +} diff --git a/packages/oraiswap-v3-common/src/error.rs b/packages/oraiswap-v3-common/src/error.rs new file mode 100644 index 0000000..d903b89 --- /dev/null +++ b/packages/oraiswap-v3-common/src/error.rs @@ -0,0 +1,168 @@ +use std::string::FromUtf8Error; + +use cosmwasm_std::{StdError, Uint128}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("{0}")] + FromUtf8(#[from] FromUtf8Error), + + #[error("{0}")] + CheckMathOverUnderFlowError(String), + + #[error("invalid tick spacing")] + InvalidTickSpacing, + + #[error("invalid fee")] + InvalidFee, + + #[error("invalid tick index")] + InvalidTickIndex, + + #[error("invalid tick")] + InvalidTick, + + #[error("tokens are the same")] + TokensAreSame, + + #[error("invalid tick")] + InvalidInitTick, + + #[error("invalid sqrt price")] + InvalidInitSqrtPrice, + + #[error("invalid offset")] + InvalidOffset, + + #[error("Assertion failed; require minimum amount: {transfer_amount}")] + InvalidFunds { transfer_amount: Uint128 }, + + #[error("multiplication overflow")] + Mul, + + #[error("division overflow or division by zero")] + Div, + + #[error("type failed")] + Cast, + + #[error("addition overflow")] + Add, + + #[error("subtraction underflow")] + Sub, + + #[error("empty position pokes")] + EmptyPositionPokes, + + #[error("price limit reached")] + PriceLimitReached, + + #[error("insufficient liquidity")] + InsufficientLiquidity, + + #[error("current_timestamp - pool.start_timestamp underflow")] + TimestampSubOverflow, + + #[error("tick limit reached")] + TickLimitReached, + + #[error("tick not found")] + TickNotFound, + + #[error("tick already exist")] + TickAlreadyExist, + + #[error("invalid tick liquidity")] + InvalidTickLiquidity, + + #[error("invalid size")] + InvalidSize, + + #[error("sqrt_price out of range")] + SqrtPriceOutOfRange, + + #[error("current_timestamp > last_timestamp failed")] + TimestampCheckFailed, + + #[error("can not parse from u320 to u256")] + U320ToU256, + + #[error("tick over bounds")] + TickOverBounds, + + #[error("calculate_sqrt_price: parsing from scale failed")] + ParseFromScale, + + #[error("calcaule_sqrt_price::checked_div division failed")] + CheckedDiv, + + #[error("big_liquidity -/+ sqrt_price * x")] + BigLiquidityOverflow, + + #[error("upper_tick is not greater than lower_tick")] + UpperTickNotGreater, + + #[error("tick_lower > tick_upper")] + TickLowerGreater, + + #[error("tick initialize tick again")] + TickReInitialize, + + #[error("Upper Sqrt Price < Current Sqrt Price")] + UpperSqrtPriceLess, + + #[error("Current Sqrt Price < Lower Sqrt Price")] + CurrentSqrtPriceLess, + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("Cannot set approval that is already expired")] + Expired {}, + + #[error("amount is zero")] + AmountIsZero, + + #[error("wrong limit")] + WrongLimit, + + #[error("no gain swap")] + NoGainSwap, + + #[error("amount under minimum amount out")] + AmountUnderMinimumAmountOut, + + #[error("pool already exist")] + PoolAlreadyExist, + + #[error("FeeTierNotFound")] + FeeTierNotFound, + + #[error("NotEmptyTickDeinitialization")] + NotEmptyTickDeinitialization, +} + +impl From for StdError { + fn from(source: ContractError) -> Self { + Self::generic_err(source.to_string()) + } +} + +// Implementing From for ContractError +impl From for ContractError { + fn from(error: String) -> Self { + ContractError::CheckMathOverUnderFlowError(error) + } +} + +// Implementing From<&str> for ContractError +impl From<&str> for ContractError { + fn from(error: &str) -> Self { + ContractError::CheckMathOverUnderFlowError(error.to_string()) + } +} diff --git a/packages/oraiswap-v3-common/src/incentives_fund_manager.rs b/packages/oraiswap-v3-common/src/incentives_fund_manager.rs new file mode 100644 index 0000000..6b97bd1 --- /dev/null +++ b/packages/oraiswap-v3-common/src/incentives_fund_manager.rs @@ -0,0 +1,38 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Addr; + +use crate::asset::Asset; + +#[cw_serde] +pub struct InstantiateMsg { + pub owner: Option, + pub oraiswap_v3: Addr, +} + +#[cw_serde] +pub enum ExecuteMsg { + UpdateConfig { + owner: Option, + oraiswap_v3: Option, + }, + SendFund { + asset: Asset, + receiver: Addr, + }, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(ConfigResponse)] + Config {}, +} + +#[cw_serde] +pub struct MigrateMsg {} + +#[cw_serde] +pub struct ConfigResponse { + pub owner: Addr, + pub oraiswap_v3: Addr, +} diff --git a/packages/oraiswap-v3-common/src/lib.rs b/packages/oraiswap-v3-common/src/lib.rs new file mode 100644 index 0000000..5ffabcb --- /dev/null +++ b/packages/oraiswap-v3-common/src/lib.rs @@ -0,0 +1,3 @@ +pub mod asset; +pub mod error; +pub mod incentives_fund_manager; From d48208a8624fccb02812befc45f8b24e637dd441 Mon Sep 17 00:00:00 2001 From: Pham Tu Date: Tue, 13 Aug 2024 17:47:15 +0700 Subject: [PATCH 2/3] remove error in oraiswap-v3 --- contracts/oraiswap-v3/src/error.rs | 168 ----------------------------- 1 file changed, 168 deletions(-) delete mode 100644 contracts/oraiswap-v3/src/error.rs diff --git a/contracts/oraiswap-v3/src/error.rs b/contracts/oraiswap-v3/src/error.rs deleted file mode 100644 index d903b89..0000000 --- a/contracts/oraiswap-v3/src/error.rs +++ /dev/null @@ -1,168 +0,0 @@ -use std::string::FromUtf8Error; - -use cosmwasm_std::{StdError, Uint128}; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - FromUtf8(#[from] FromUtf8Error), - - #[error("{0}")] - CheckMathOverUnderFlowError(String), - - #[error("invalid tick spacing")] - InvalidTickSpacing, - - #[error("invalid fee")] - InvalidFee, - - #[error("invalid tick index")] - InvalidTickIndex, - - #[error("invalid tick")] - InvalidTick, - - #[error("tokens are the same")] - TokensAreSame, - - #[error("invalid tick")] - InvalidInitTick, - - #[error("invalid sqrt price")] - InvalidInitSqrtPrice, - - #[error("invalid offset")] - InvalidOffset, - - #[error("Assertion failed; require minimum amount: {transfer_amount}")] - InvalidFunds { transfer_amount: Uint128 }, - - #[error("multiplication overflow")] - Mul, - - #[error("division overflow or division by zero")] - Div, - - #[error("type failed")] - Cast, - - #[error("addition overflow")] - Add, - - #[error("subtraction underflow")] - Sub, - - #[error("empty position pokes")] - EmptyPositionPokes, - - #[error("price limit reached")] - PriceLimitReached, - - #[error("insufficient liquidity")] - InsufficientLiquidity, - - #[error("current_timestamp - pool.start_timestamp underflow")] - TimestampSubOverflow, - - #[error("tick limit reached")] - TickLimitReached, - - #[error("tick not found")] - TickNotFound, - - #[error("tick already exist")] - TickAlreadyExist, - - #[error("invalid tick liquidity")] - InvalidTickLiquidity, - - #[error("invalid size")] - InvalidSize, - - #[error("sqrt_price out of range")] - SqrtPriceOutOfRange, - - #[error("current_timestamp > last_timestamp failed")] - TimestampCheckFailed, - - #[error("can not parse from u320 to u256")] - U320ToU256, - - #[error("tick over bounds")] - TickOverBounds, - - #[error("calculate_sqrt_price: parsing from scale failed")] - ParseFromScale, - - #[error("calcaule_sqrt_price::checked_div division failed")] - CheckedDiv, - - #[error("big_liquidity -/+ sqrt_price * x")] - BigLiquidityOverflow, - - #[error("upper_tick is not greater than lower_tick")] - UpperTickNotGreater, - - #[error("tick_lower > tick_upper")] - TickLowerGreater, - - #[error("tick initialize tick again")] - TickReInitialize, - - #[error("Upper Sqrt Price < Current Sqrt Price")] - UpperSqrtPriceLess, - - #[error("Current Sqrt Price < Lower Sqrt Price")] - CurrentSqrtPriceLess, - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Cannot set approval that is already expired")] - Expired {}, - - #[error("amount is zero")] - AmountIsZero, - - #[error("wrong limit")] - WrongLimit, - - #[error("no gain swap")] - NoGainSwap, - - #[error("amount under minimum amount out")] - AmountUnderMinimumAmountOut, - - #[error("pool already exist")] - PoolAlreadyExist, - - #[error("FeeTierNotFound")] - FeeTierNotFound, - - #[error("NotEmptyTickDeinitialization")] - NotEmptyTickDeinitialization, -} - -impl From for StdError { - fn from(source: ContractError) -> Self { - Self::generic_err(source.to_string()) - } -} - -// Implementing From for ContractError -impl From for ContractError { - fn from(error: String) -> Self { - ContractError::CheckMathOverUnderFlowError(error) - } -} - -// Implementing From<&str> for ContractError -impl From<&str> for ContractError { - fn from(error: &str) -> Self { - ContractError::CheckMathOverUnderFlowError(error.to_string()) - } -} From eb700aa5c0e064e7dbd62a9628843cd4562b090c Mon Sep 17 00:00:00 2001 From: vuonghuuhung Date: Wed, 4 Sep 2024 17:29:04 +0700 Subject: [PATCH 3/3] load config once --- contracts/oraiswap-v3/src/entrypoints/execute.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/oraiswap-v3/src/entrypoints/execute.rs b/contracts/oraiswap-v3/src/entrypoints/execute.rs index 149c4fc..8e7b44d 100644 --- a/contracts/oraiswap-v3/src/entrypoints/execute.rs +++ b/contracts/oraiswap-v3/src/entrypoints/execute.rs @@ -724,8 +724,8 @@ pub fn remove_position( asset_0.transfer(&mut msgs, &info)?; asset_1.transfer(&mut msgs, &info)?; // claim incentives + let config = CONFIG.load(deps.storage)?; for asset in incentives.clone() { - let config = CONFIG.load(deps.storage)?; msgs.push( wasm_execute( config.incentives_fund_manager.clone(),