diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/assert.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/assert.rs deleted file mode 100644 index 94757a368..000000000 --- a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/assert.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::ContractError; -use cosmwasm_std::{coin, Coin}; - -pub(crate) fn must_pay_one_or_two( - funds: &[Coin], - denoms: (String, String), -) -> Result<(Coin, Coin), ContractError> { - let token0 = funds - .iter() - .find(|coin| coin.denom == denoms.0) - .cloned() - .unwrap_or(coin(0, denoms.0)); - - let token1 = funds - .iter() - .find(|coin| coin.denom == denoms.1) - .cloned() - .unwrap_or(coin(0, denoms.1)); - - Ok((token0, token1)) -} - -#[cfg(test)] -mod tests { - - use cosmwasm_std::coin; - - use super::*; - - #[test] - fn must_pay_one_or_two_works_ordered() { - let expected0 = coin(100, "uatom"); - let expected1 = coin(200, "uosmo"); - let funds = vec![expected0.clone(), expected1.clone()]; - let (token0, token1) = - must_pay_one_or_two(&funds, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!(expected0, token0); - assert_eq!(expected1, token1); - } - - #[test] - fn must_pay_one_or_two_works_unordered() { - let expected0 = coin(100, "uatom"); - let expected1 = coin(200, "uosmo"); - let funds = vec![expected0.clone(), expected1.clone()]; - let (token0, token1) = - must_pay_one_or_two(&funds, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!(expected0, token0); - assert_eq!(expected1, token1); - } - - #[test] - fn must_pay_one_or_two_accepts_second_token() { - let funds = vec![coin(200, "uosmo")]; - let res = must_pay_one_or_two(&funds, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!((coin(0, "uatom"), coin(200, "uosmo")), res) - } - - #[test] - fn must_pay_one_or_two_accepts_first_token() { - let funds = vec![coin(200, "uatom")]; - let res = must_pay_one_or_two(&funds, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!((coin(200, "uatom"), coin(0, "uosmo")), res) - } -} diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs index 7627970ac..3e7f32a89 100644 --- a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs @@ -8,7 +8,6 @@ use quasar_types::pool_pair::PoolPair; use crate::vault::concentrated_liquidity::get_position; use crate::{ - helpers::assert::must_pay_one_or_two, math::tick::tick_to_price, state::{PoolConfig, POOL_CONFIG, RANGE_ADMIN}, ContractError, @@ -77,29 +76,31 @@ pub struct DepositInfo { pub fn get_depositable_tokens( deps: &DepsMut, - funds: &[Coin], + funds: Vec, pool_config: &PoolConfig, ) -> Result { - let (token0, token1) = must_pay_one_or_two( - funds, - (pool_config.token0.clone(), pool_config.token1.clone()), - )?; + let funds_in_pool = get_vault_funds_or_zero(&CoinList::from_coins(funds), pool_config); let position = get_position(deps.storage, &deps.querier)?; let assets = PoolPair::new( position.asset0.unwrap_or_default().try_into()?, position.asset1.unwrap_or_default().try_into()?, ); - get_deposit_info(&assets, token0, token1) + get_deposit_info(&assets, &funds_in_pool) +} + +fn get_vault_funds_or_zero(funds: &CoinList, config: &PoolConfig) -> PoolPair { + let base = funds.find(&config.token0); + let quote = funds.find(&config.token1); + PoolPair::new(base, quote) } fn get_deposit_info( assets: &PoolPair, - provided_base: Coin, - provided_quote: Coin, + provided: &PoolPair, ) -> Result { - let provided_base_amount: Uint256 = provided_base.amount.into(); - let provided_quote_amount: Uint256 = provided_quote.amount.into(); + let provided_base_amount: Uint256 = provided.base.amount.into(); + let provided_quote_amount: Uint256 = provided.quote.amount.into(); let base_deposit = if assets.quote.amount.is_zero() { provided_base_amount @@ -213,11 +214,9 @@ pub fn get_unused_pair_balances( pool_config: &PoolConfig, ) -> Result, ContractError> { let unused_balances = get_unused_balances(&deps.querier, env)?; + let vault_funds = get_vault_funds_or_zero(&unused_balances, pool_config); - let base = unused_balances.find(&pool_config.token0); - let quote = unused_balances.find(&pool_config.token1); - - Ok(vec![base, quote]) + Ok(vec![vault_funds.base, vault_funds.quote]) } #[cfg(test)] @@ -355,7 +354,8 @@ mod tests { let token1 = coin(100_000_000_000_000_000_000_000_000_000, TOKEN1); let assets = PoolPair::new(token0.clone(), token1.clone()); - let result = get_deposit_info(&assets, token0.clone(), token1.clone()).unwrap(); + let provided = PoolPair::new(token0.clone(), token1.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); assert_eq!( result, DepositInfo { @@ -373,7 +373,8 @@ mod tests { let token1 = coin(100, TOKEN1); let assets = PoolPair::new(coin(0, TOKEN0), token1.clone()); - let result = get_deposit_info(&assets, token0.clone(), token1.clone()).unwrap(); + let provided = PoolPair::new(token0.clone(), token1.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); assert_eq!( result, DepositInfo { @@ -391,7 +392,8 @@ mod tests { let token1 = coin(100, TOKEN1); let assets = PoolPair::new(token0.clone(), coin(0, TOKEN1)); - let result = get_deposit_info(&assets, token0.clone(), token1.clone()).unwrap(); + let provided = PoolPair::new(token0.clone(), token1.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); assert_eq!( result, DepositInfo { @@ -410,7 +412,8 @@ mod tests { let assets = PoolPair::new(token0.clone(), token1.clone()); let base_deposit = coin(2000, TOKEN0); - let result = get_deposit_info(&assets, base_deposit.clone(), coin(5000, TOKEN1)).unwrap(); + let provided = PoolPair::new(base_deposit.clone(), coin(5000, TOKEN1)); + let result = get_deposit_info(&assets, &provided).unwrap(); assert_eq!( result, DepositInfo { @@ -429,7 +432,8 @@ mod tests { let assets = PoolPair::new(token0.clone(), token1.clone()); let quote_deposit = coin(3000, TOKEN1); - let result = get_deposit_info(&assets, coin(2000, TOKEN0), quote_deposit.clone()).unwrap(); + let provided = PoolPair::new(coin(2000, TOKEN0), quote_deposit.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); assert_eq!( result, DepositInfo { diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs index c517f5cf2..0cefdac7b 100644 --- a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs @@ -1,4 +1,3 @@ -pub mod assert; pub mod coinlist; pub mod generic; pub mod getters; diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs b/smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs index 4910dd2a6..8da71b281 100644 --- a/smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs @@ -11,8 +11,8 @@ use osmosis_std::types::osmosis::tokenfactory::v1beta1::{ MsgCreateDenom, MsgCreateDenomResponse, MsgMint, }; -use crate::helpers::assert::must_pay_one_or_two; -use crate::helpers::getters::get_value_wrt_asset0; +use crate::error::assert_deposits; +use crate::helpers::getters::{get_unused_pair_balances, get_value_wrt_asset0}; use crate::math::tick::{build_tick_exp_cache, verify_tick_exp_cache}; use crate::msg::InstantiateMsg; use crate::reply::Replies; @@ -50,15 +50,13 @@ pub fn handle_instantiate( pool_id: msg.pool_id, })? .try_into()?; - - POOL_CONFIG.save( - deps.storage, - &PoolConfig { - pool_id: pool.id, - token0: pool.token0.clone(), - token1: pool.token1.clone(), - }, - )?; + let pool_config = PoolConfig { + pool_id: pool.id, + token0: pool.token0.clone(), + token1: pool.token1.clone(), + }; + assert_deposits(&info.funds, &pool_config)?; + POOL_CONFIG.save(deps.storage, &pool_config)?; METADATA.save( deps.storage, @@ -79,15 +77,14 @@ pub fn handle_instantiate( } .into(); - // in order to create the initial position, we need some funds to throw in there, these funds should be seen as burned - let (initial0, initial1) = must_pay_one_or_two(&info.funds, (pool.token0, pool.token1))?; + let vault_funds = get_unused_pair_balances(&deps, &env, &pool_config)?; let create_position_msg = create_position( deps, &env, msg.initial_lower_tick, msg.initial_upper_tick, - vec![initial0, initial1], + vault_funds, Uint128::zero(), Uint128::zero(), )?; diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs index ac6c3e978..bcb27f9dc 100644 --- a/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs @@ -34,7 +34,7 @@ pub(crate) fn execute_exact_deposit( let pool_config = POOL_CONFIG.load(deps.storage)?; assert_deposits(&info.funds, &pool_config)?; let recipient = recipient.map_or(Ok(info.sender.clone()), |x| deps.api.addr_validate(&x))?; - let deposit_info = get_depositable_tokens(&deps, &info.funds, &pool_config)?; + let deposit_info = get_depositable_tokens(&deps, info.funds, &pool_config)?; execute_deposit(&mut deps, env, recipient, deposit_info) } @@ -55,7 +55,7 @@ pub(crate) fn execute_any_deposit( .position .ok_or(ContractError::MissingPosition {})?; - let deposit_info = get_depositable_tokens(&deps.branch(), &info.funds, &pool_config)?; + let deposit_info = get_depositable_tokens(&deps.branch(), info.funds, &pool_config)?; if deposit_info.base_refund.amount.is_zero() && deposit_info.quote_refund.amount.is_zero() { return execute_deposit(&mut deps, env, recipient, deposit_info); }