Skip to content

Commit

Permalink
chore: make swap before providing liqudity with a single asset
Browse files Browse the repository at this point in the history
  • Loading branch information
kerber0x committed May 1, 2024
1 parent 5d6ba8d commit c87ebaa
Show file tree
Hide file tree
Showing 13 changed files with 402 additions and 168 deletions.
46 changes: 44 additions & 2 deletions contracts/liquidity_hub/pool-manager/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use crate::error::ContractError;
use crate::helpers::simulate_swap_operations;
use crate::helpers::{simulate_swap_operations, validate_asset_balance};
use crate::queries::{get_swap_route, get_swap_route_creator, get_swap_routes};
use crate::router::commands::{add_swap_routes, remove_swap_routes};
use crate::state::{Config, MANAGER_CONFIG, PAIRS, PAIR_COUNTER};
use crate::state::{
Config, SingleSideLiquidityProvisionBuffer, MANAGER_CONFIG, PAIRS, PAIR_COUNTER,
TMP_SINGLE_SIDE_LIQUIDITY_PROVISION,
};
use crate::{liquidity, manager, queries, router, swap};
#[cfg(not(feature = "library"))]
use cosmwasm_std::{
entry_point, to_json_binary, Addr, Api, Binary, Deps, DepsMut, Env, MessageInfo, Response,
};
use cosmwasm_std::{wasm_execute, Reply, StdError};
use cw2::set_contract_version;
use semver::Version;
use white_whale_std::pool_manager::{
Expand All @@ -17,6 +21,7 @@ use white_whale_std::pool_manager::{
// version info for migration info
const CONTRACT_NAME: &str = "crates.io:ww-pool-manager";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const SINGLE_SIDE_LIQUIDITY_PROVISION_REPLY_ID: u64 = 1;

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
Expand Down Expand Up @@ -45,6 +50,41 @@ pub fn instantiate(
Ok(Response::default())
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result<Response, ContractError> {
match msg.id {
SINGLE_SIDE_LIQUIDITY_PROVISION_REPLY_ID => {
let SingleSideLiquidityProvisionBuffer {
receiver,
expected_offer_asset_balance_in_contract,
expected_ask_asset_balance_in_contract,
offer_asset_half,
expected_ask_asset,
liquidity_provision_data,
} = TMP_SINGLE_SIDE_LIQUIDITY_PROVISION.load(deps.storage)?;

validate_asset_balance(&deps, &env, &expected_offer_asset_balance_in_contract)?;
validate_asset_balance(&deps, &env, &expected_ask_asset_balance_in_contract)?;

TMP_SINGLE_SIDE_LIQUIDITY_PROVISION.remove(deps.storage);

Ok(Response::default().add_message(wasm_execute(
env.contract.address.into_string(),
&ExecuteMsg::ProvideLiquidity {
slippage_tolerance: liquidity_provision_data.slippage_tolerance,
max_spread: liquidity_provision_data.max_spread,
receiver: Some(receiver),
pair_identifier: liquidity_provision_data.pair_identifier,
unlocking_duration: liquidity_provision_data.unlocking_duration,
lock_position_identifier: liquidity_provision_data.lock_position_identifier,
},
vec![offer_asset_half, expected_ask_asset],
)?))
}
_ => Err(StdError::generic_err("reply id not found").into()),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
Expand All @@ -70,6 +110,7 @@ pub fn execute(
pair_identifier,
),
ExecuteMsg::ProvideLiquidity {
max_spread,
slippage_tolerance,
receiver,
pair_identifier,
Expand All @@ -80,6 +121,7 @@ pub fn execute(
env,
info,
slippage_tolerance,
max_spread,
receiver,
pair_identifier,
unlocking_duration,
Expand Down
6 changes: 6 additions & 0 deletions contracts/liquidity_hub/pool-manager/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ pub enum ContractError {
#[error("Trying to provide liquidity without any assets")]
EmptyAssets,

#[error("Invalid single side liquidity provision swap, expected {expected} got {actual}")]
InvalidSingleSideLiquidityProvisionSwap { expected: Uint128, actual: Uint128 },

#[error("Cannot provide single-side liquidity when the pool is empty")]
EmptyPoolForSingleSideLiquidityProvision,

#[error("Pair does not exist")]
UnExistingPair {},

Expand Down
57 changes: 54 additions & 3 deletions contracts/liquidity_hub/pool-manager/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use std::ops::Mul;

use cosmwasm_schema::cw_serde;
use cosmwasm_std::{
coin, Addr, Coin, Decimal, Decimal256, Deps, Env, StdError, StdResult, Storage, Uint128,
Uint256,
coin, ensure, Addr, Coin, Decimal, Decimal256, Deps, DepsMut, Env, StdError, StdResult,
Storage, Uint128, Uint256,
};

use white_whale_std::fee::PoolFee;
use white_whale_std::pool_manager::{SimulateSwapOperationsResponse, SwapOperation};
use white_whale_std::pool_manager::{
SimulateSwapOperationsResponse, SimulationResponse, SwapOperation,
};
use white_whale_std::pool_network::asset::{Asset, AssetInfo, PairType};

use crate::error::ContractError;
Expand Down Expand Up @@ -172,6 +174,9 @@ pub fn compute_swap(
let protocol_fee_amount: Uint256 = pool_fees.protocol_fee.compute(return_amount);
let burn_fee_amount: Uint256 = pool_fees.burn_fee.compute(return_amount);

//todo compute the extra fees
//let extra_fees_amount: Uint256 = pool_fees.extra_fees.compute(return_amount);

// swap and protocol fee will be absorbed by the pool. Burn fee amount will be burned on a subsequent msg.
#[cfg(not(feature = "osmosis"))]
{
Expand Down Expand Up @@ -632,3 +637,49 @@ pub fn simulate_swap_operations(

Ok(SimulateSwapOperationsResponse { amount })
}

/// Validates the amounts after a single side liquidity provision swap are correct.
pub fn validate_asset_balance(
deps: &DepsMut,
env: &Env,
expected_balance: &Coin,
) -> Result<(), ContractError> {
let new_asset_balance = deps
.querier
.query_balance(&env.contract.address, expected_balance.denom.to_owned())?;

ensure!(
expected_balance == &new_asset_balance,
ContractError::InvalidSingleSideLiquidityProvisionSwap {
expected: expected_balance.amount,
actual: new_asset_balance.amount
}
);

Ok(())
}

/// Aggregates the fees from a simulation response that go out of the contract, i.e. protocol fee, burn fee
/// and osmosis fee, if applicable. Doesn't know about the denom, just the amount.
pub fn aggregate_outgoing_fees(
simulation_response: &SimulationResponse,
) -> Result<Uint128, ContractError> {
let fees = {
#[cfg(not(feature = "osmosis"))]
{
simulation_response
.protocol_fee_amount
.checked_add(simulation_response.burn_fee_amount)?
}

#[cfg(feature = "osmosis")]
{
simulation_response
.protocol_fee_amount
.checked_add(simulation_response.burn_fee_amount)?
.checked_add(simulation_response.osmosis_fee_amount)?
}
};

Ok(fees)
}
Loading

0 comments on commit c87ebaa

Please sign in to comment.