Skip to content

Commit

Permalink
Merge pull request #14 from WHELP-project/13-pair-implement-lp-share-…
Browse files Browse the repository at this point in the history
…token-as-smart-token

Pair: Implement LP Share token as a Smart Token
  • Loading branch information
ueco-jb committed Oct 19, 2023
2 parents 9d95439 + 0755664 commit 6745759
Show file tree
Hide file tree
Showing 14 changed files with 2,022 additions and 2,217 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ repository = "https://github.com/WHELP-project/whelp-contracts"
[workspace.dependencies]
anyhow = "1"
cw20-base = { version = "1.1", package = "cw20-base", features = ["library"] }
coreum-wasm-sdk = "0.1.1"
cosmwasm-schema = "1.4"
cosmwasm-std = "1.4"
cw2 = "1.1"
Expand Down
1 change: 1 addition & 0 deletions contracts/pair/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ backtraces = ["cosmwasm-std/backtraces"]
library = []

[dependencies]
coreum-wasm-sdk = { workspace = true }
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw2 = { workspace = true }
Expand Down
80 changes: 41 additions & 39 deletions contracts/pair/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::state::{Config, CIRCUIT_BREAKER, CONFIG, FROZEN};
use std::str::FromStr;
use std::vec;

use coreum_wasm_sdk::core::{CoreumMsg, CoreumQueries};
use cosmwasm_std::{
attr, ensure, entry_point, from_binary, to_binary, Addr, Binary, CosmosMsg, Decimal,
Decimal256, Deps, DepsMut, Env, Isqrt, MessageInfo, QuerierWrapper, Reply, Response, StdError,
Expand All @@ -8,6 +10,7 @@ use cosmwasm_std::{

use cw2::set_contract_version;
use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg};

use dex::asset::{
addr_opt_validate, check_swap_parameters, Asset, AssetInfoValidated, AssetValidated,
MINIMUM_LIQUIDITY_AMOUNT,
Expand All @@ -17,17 +20,17 @@ use dex::factory::{ConfigResponse as FactoryConfig, PairType};
use dex::fee_config::FeeConfig;
use dex::pair::{
add_referral, assert_max_spread, check_asset_infos, check_assets, check_cw20_in_pool,
create_lp_token, get_share_in_assets, handle_referral, handle_reply, migration_check,
mint_token_message, save_tmp_staking_config, take_referral, ConfigResponse, ContractError,
Cw20HookMsg, MigrateMsg, DEFAULT_SLIPPAGE, MAX_ALLOWED_SLIPPAGE,
create_lp_token, get_share_in_assets, handle_referral, handle_reply, mint_token_message,
save_tmp_staking_config, take_referral, ConfigResponse, ContractError, Cw20HookMsg, MigrateMsg,
DEFAULT_SLIPPAGE, MAX_ALLOWED_SLIPPAGE,
};
use dex::pair::{
CumulativePricesResponse, ExecuteMsg, InstantiateMsg, PairInfo, PoolResponse, QueryMsg,
ReverseSimulationResponse, SimulationResponse, TWAP_PRECISION,
};
use dex::querier::{query_factory_config, query_supply};
use std::str::FromStr;
use std::vec;

use crate::state::{Config, CIRCUIT_BREAKER, CONFIG, FROZEN};

/// Contract name that is used for migration.
const CONTRACT_NAME: &str = "dex-pair";
Expand All @@ -37,11 +40,11 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
/// Creates a new contract with the specified parameters in the [`InstantiateMsg`].
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
env: Env,
_info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
) -> Result<Response<CoreumMsg>, ContractError> {
let asset_infos = check_asset_infos(deps.api, &msg.asset_infos)?;

if asset_infos.len() != 2 {
Expand All @@ -54,13 +57,7 @@ pub fn instantiate(

let factory_addr = deps.api.addr_validate(msg.factory_addr.as_str())?;

let create_lp_token_msg = create_lp_token(
&deps.querier,
&env,
msg.token_code_id,
&asset_infos,
&factory_addr,
)?;
let create_lp_token_msg = create_lp_token(&deps.querier, &asset_infos)?;

let config = Config {
pair_info: PairInfo {
Expand All @@ -87,7 +84,11 @@ pub fn instantiate(

/// The entry point to the contract for processing replies from submessages.
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
pub fn reply(
deps: DepsMut<CoreumQueries>,
_env: Env,
msg: Reply,
) -> Result<Response, ContractError> {
let mut config = CONFIG.load(deps.storage)?;
let res = handle_reply(&deps, msg, &config.factory_addr, &mut config.pair_info)?;
CONFIG.save(deps.storage, &config)?;
Expand All @@ -97,7 +98,11 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractE

/// Manages the contract migration.
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
pub fn migrate(
deps: DepsMut<CoreumQueries>,
_env: Env,
msg: MigrateMsg,
) -> Result<Response, ContractError> {
match msg {
MigrateMsg::UpdateFreeze {
frozen,
Expand Down Expand Up @@ -135,17 +140,11 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, Co
/// }** Performs a swap operation with the specified parameters.
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
let cfg = CONFIG.load(deps.storage)?;

if migration_check(deps.querier, &cfg.factory_addr, &env.contract.address)? {
return Err(ContractError::PairIsNotMigrated {});
}

match msg {
ExecuteMsg::Receive(msg) => receive_cw20(deps, env, info, msg),
ExecuteMsg::ProvideLiquidity {
Expand Down Expand Up @@ -203,7 +202,7 @@ pub fn execute(
///
/// * **cw20_msg** is the CW20 receive message to process.
pub fn receive_cw20(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
env: Env,
info: MessageInfo,
cw20_msg: Cw20ReceiveMsg,
Expand Down Expand Up @@ -251,7 +250,7 @@ pub fn receive_cw20(
}

pub fn update_fees(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
info: MessageInfo,
fee_config: FeeConfig,
) -> Result<Response, ContractError> {
Expand Down Expand Up @@ -283,7 +282,7 @@ pub fn update_fees(
///
/// NOTE - the address that wants to provide liquidity should approve the pair contract to pull its relevant tokens.
pub fn provide_liquidity(
mut deps: DepsMut,
mut deps: DepsMut<CoreumQueries>,
env: Env,
info: MessageInfo,
assets: Vec<Asset>,
Expand Down Expand Up @@ -494,7 +493,7 @@ pub fn provide_liquidity(
///
/// * **amount** is the amount of LP tokens to burn.
pub fn withdraw_liquidity(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
env: Env,
info: MessageInfo,
sender: Addr,
Expand Down Expand Up @@ -569,7 +568,7 @@ pub fn withdraw_liquidity(
/// NOTE - the address that wants to swap should approve the pair contract to pull the offer token.
#[allow(clippy::too_many_arguments)]
pub fn swap(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
env: Env,
info: MessageInfo,
sender: Addr,
Expand Down Expand Up @@ -657,7 +656,7 @@ pub fn swap(
]))
}

fn check_if_frozen(deps: &DepsMut) -> Result<(), ContractError> {
fn check_if_frozen(deps: &DepsMut<CoreumQueries>) -> Result<(), ContractError> {
let is_frozen: bool = FROZEN.load(deps.storage)?;
ensure!(!is_frozen, ContractError::ContractFrozen {});
Ok(())
Expand All @@ -678,7 +677,7 @@ struct SwapResult {
/// Important: When providing the pool balances for this method, make sure that those do *not* include the offer asset.
#[allow(clippy::too_many_arguments)]
fn do_swap(
deps: DepsMut,
deps: DepsMut<CoreumQueries>,
env: &Env,
config: &mut Config,
factory_config: &FactoryConfig,
Expand Down Expand Up @@ -868,7 +867,7 @@ pub fn calculate_protocol_fee(
///
/// * **QueryMsg::Config {}** Returns the configuration for the pair contract using a [`ConfigResponse`] object.
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
pub fn query(deps: Deps<CoreumQueries>, env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::Pair {} => to_binary(&CONFIG.load(deps.storage)?.pair_info),
QueryMsg::Pool {} => to_binary(&query_pool(deps)?),
Expand Down Expand Up @@ -915,7 +914,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {

/// Returns the amounts of assets in the pair contract as well as the amount of LP
/// tokens currently minted in an object of type [`PoolResponse`].
pub fn query_pool(deps: Deps) -> StdResult<PoolResponse> {
pub fn query_pool(deps: Deps<CoreumQueries>) -> StdResult<PoolResponse> {
let config = CONFIG.load(deps.storage)?;
let (assets, total_share) = pool_info(deps.querier, &config)?;

Expand All @@ -931,7 +930,7 @@ pub fn query_pool(deps: Deps) -> StdResult<PoolResponse> {
/// The result is returned in a vector that contains objects of type [`Asset`].
///
/// * **amount** is the amount of LP tokens for which we calculate associated amounts of assets.
pub fn query_share(deps: Deps, amount: Uint128) -> StdResult<Vec<AssetValidated>> {
pub fn query_share(deps: Deps<CoreumQueries>, amount: Uint128) -> StdResult<Vec<AssetValidated>> {
let config = CONFIG.load(deps.storage)?;
let (pools, total_share) = pool_info(deps.querier, &config)?;
let refund_assets = get_share_in_assets(&pools, amount, total_share);
Expand All @@ -943,7 +942,7 @@ pub fn query_share(deps: Deps, amount: Uint128) -> StdResult<Vec<AssetValidated>
///
/// * **offer_asset** is the asset to swap as well as an amount of the said asset.
pub fn query_simulation(
deps: Deps,
deps: Deps<CoreumQueries>,
offer_asset: Asset,
referral: bool,
referral_commission: Option<Decimal>,
Expand Down Expand Up @@ -996,7 +995,7 @@ pub fn query_simulation(
/// * **ask_asset** is the asset to swap to as well as the desired amount of ask
/// assets to receive from the swap.
pub fn query_reverse_simulation(
deps: Deps,
deps: Deps<CoreumQueries>,
ask_asset: Asset,
referral: bool,
referral_commission: Option<Decimal>,
Expand Down Expand Up @@ -1051,7 +1050,10 @@ pub fn query_reverse_simulation(
}

/// Returns information about cumulative prices for the assets in the pool using a [`CumulativePricesResponse`] object.
pub fn query_cumulative_prices(deps: Deps, env: Env) -> StdResult<CumulativePricesResponse> {
pub fn query_cumulative_prices(
deps: Deps<CoreumQueries>,
env: Env,
) -> StdResult<CumulativePricesResponse> {
let config = CONFIG.load(deps.storage)?;
let (assets, total_share) = pool_info(deps.querier, &config)?;

Expand Down Expand Up @@ -1088,7 +1090,7 @@ pub fn query_cumulative_prices(deps: Deps, env: Env) -> StdResult<CumulativePric
}

/// Returns the pair contract configuration in a [`ConfigResponse`] object.
pub fn query_config(deps: Deps) -> StdResult<ConfigResponse> {
pub fn query_config(deps: Deps<CoreumQueries>) -> StdResult<ConfigResponse> {
let config: Config = CONFIG.load(deps.storage)?;
Ok(ConfigResponse {
block_time_last: config.block_time_last,
Expand Down Expand Up @@ -1221,7 +1223,7 @@ fn assert_slippage_tolerance(

/// Returns the total amount of assets in the pool as well as the total amount of LP tokens currently minted.
pub fn pool_info(
querier: QuerierWrapper,
querier: QuerierWrapper<CoreumQueries>,
config: &Config,
) -> StdResult<(Vec<AssetValidated>, Uint128)> {
let pools = config
Expand Down
17 changes: 10 additions & 7 deletions contracts/pair/src/mock_querier.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::collections::HashMap;
use std::marker::PhantomData;

use coreum_wasm_sdk::core::{CoreumMsg, CoreumQueries};

Check warning on line 4 in contracts/pair/src/mock_querier.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `CoreumMsg`

Check failure on line 4 in contracts/pair/src/mock_querier.rs

View workflow job for this annotation

GitHub Actions / Lints

unused import: `CoreumMsg`
use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR};
use cosmwasm_std::{
from_binary, from_slice, to_binary, Addr, Coin, Decimal, Empty, OwnedDeps, Querier,

Check warning on line 7 in contracts/pair/src/mock_querier.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `Empty`

Check failure on line 7 in contracts/pair/src/mock_querier.rs

View workflow job for this annotation

GitHub Actions / Lints

unused import: `Empty`
QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery,
};
use std::collections::HashMap;

use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse};
use dex::factory::{
Expand All @@ -15,20 +18,20 @@ use dex::factory::{
/// This uses the Dex CustomQuerier.
pub fn mock_dependencies(
contract_balance: &[Coin],
) -> OwnedDeps<MockStorage, MockApi, WasmMockQuerier> {
) -> OwnedDeps<MockStorage, MockApi, WasmMockQuerier, CoreumQueries> {
let custom_querier: WasmMockQuerier =
WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)]));

OwnedDeps {
storage: MockStorage::default(),
api: MockApi::default(),
querier: custom_querier,
custom_query_type: Default::default(),
custom_query_type: PhantomData,
}
}

pub struct WasmMockQuerier {
base: MockQuerier<Empty>,
base: MockQuerier<CoreumQueries>,
token_querier: TokenQuerier,
}

Expand Down Expand Up @@ -64,7 +67,7 @@ pub(crate) fn balances_to_map(
impl Querier for WasmMockQuerier {
fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
// MockQuerier doesn't support Custom, so we ignore it completely
let request: QueryRequest<Empty> = match from_slice(bin_request) {
let request: QueryRequest<CoreumQueries> = match from_slice(bin_request) {
Ok(v) => v,
Err(e) => {
return SystemResult::Err(SystemError::InvalidRequest {
Expand All @@ -78,7 +81,7 @@ impl Querier for WasmMockQuerier {
}

impl WasmMockQuerier {
pub fn handle_query(&self, request: &QueryRequest<Empty>) -> QuerierResult {
pub fn handle_query(&self, request: &QueryRequest<CoreumQueries>) -> QuerierResult {
match &request {
QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => {
if contract_addr == "factory" {
Expand Down Expand Up @@ -169,7 +172,7 @@ impl WasmMockQuerier {
}

impl WasmMockQuerier {
pub fn new(base: MockQuerier<Empty>) -> Self {
pub fn new(base: MockQuerier<CoreumQueries>) -> Self {
WasmMockQuerier {
base,
token_querier: TokenQuerier::default(),
Expand Down
Loading

0 comments on commit 6745759

Please sign in to comment.