Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring new Astroport features and adjustments #391

Merged
merged 12 commits into from
Dec 8, 2023
Merged
420 changes: 137 additions & 283 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ members = [
"contracts/pair",
"contracts/pair_stable",
"contracts/pair_concentrated",
"contracts/pair_concentrated_inj",
# "contracts/pair_concentrated_inj", TODO: rewrite OB liquidity deployment
"contracts/pair_astro_xastro",
"contracts/router",
"contracts/token",
"contracts/whitelist",
"contracts/cw20_ics20",
"templates/*",
"contracts/tokenomics/generator",
"contracts/tokenomics/maker",
"contracts/tokenomics/staking",
"contracts/tokenomics/vesting",
"contracts/tokenomics/xastro_token",
"contracts/tokenomics/xastro_outpost_token",
"contracts/tokenomics/*",
"contracts/periphery/*",
]

Expand Down
2 changes: 1 addition & 1 deletion contracts/pair/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ fn provide_liquidity() {
assert_eq!(
res,
ContractError::Std(StdError::generic_err(
"Native token balance mismatch between the argument and the transferred",
"Native token balance mismatch between the argument (50000000000000000000uusd) and the transferred (100000000000000000000uusd)",
))
);

Expand Down
90 changes: 90 additions & 0 deletions contracts/pair/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2179,3 +2179,93 @@ fn test_fee_share(
+ acceptable_spread_amount
);
}

#[test]
fn test_provide_liquidity_without_funds() {
let owner = Addr::unchecked("owner");
let alice_address = Addr::unchecked("alice");
let mut router = mock_app(
owner.clone(),
vec![
Coin {
denom: "uusd".to_string(),
amount: Uint128::new(100_000_000_000u128),
},
Coin {
denom: "uluna".to_string(),
amount: Uint128::new(100_000_000_000u128),
},
Coin {
denom: "cny".to_string(),
amount: Uint128::new(100_000_000_000u128),
},
],
);

// Set Alice's balances
router
.send_tokens(
owner.clone(),
alice_address.clone(),
&[
Coin {
denom: "uusd".to_string(),
amount: Uint128::new(233_000_000u128),
},
Coin {
denom: "uluna".to_string(),
amount: Uint128::new(2_00_000_000u128),
},
Coin {
denom: "cny".to_string(),
amount: Uint128::from(100_000_000u128),
},
],
)
.unwrap();

// Init pair
let pair_instance = instantiate_pair(&mut router, &owner);

let res: PairInfo = router
.wrap()
.query_wasm_smart(pair_instance.to_string(), &QueryMsg::Pair {})
.unwrap();

assert_eq!(
res.asset_infos,
[
AssetInfo::NativeToken {
denom: "uusd".to_string(),
},
AssetInfo::NativeToken {
denom: "uluna".to_string(),
},
],
);

// provide some liquidity to assume contract have funds (to prevent underflow err)
let (msg, coins) = provide_liquidity_msg(
Uint128::new(100_000_000),
Uint128::new(100_000_000),
None,
None,
);

router
.execute_contract(alice_address.clone(), pair_instance.clone(), &msg, &coins)
.unwrap();

router
.execute_contract(alice_address.clone(), pair_instance.clone(), &msg, &coins)
.unwrap();

// provide liquidity without funds
let err = router
.execute_contract(alice_address.clone(), pair_instance.clone(), &msg, &[])
.unwrap_err();
assert_eq!(
err.root_cause().to_string(),
"Generic error: Native token balance mismatch between the argument (100000000uusd) and the transferred (0uusd)"
);
}
2 changes: 1 addition & 1 deletion contracts/pair_concentrated/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "astroport-pair-concentrated"
version = "2.2.0"
version = "2.3.0"
authors = ["Astroport"]
edition = "2021"
description = "The Astroport concentrated liquidity pair"
Expand Down
24 changes: 9 additions & 15 deletions contracts/pair_concentrated/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,9 @@ mod testing {
let array = (1..=30)
.into_iter()
.map(|i| Observation {
timestamp: env.block.time.seconds() + i * 1000,
base_sma: Default::default(),
base_amount: i.into(),
quote_sma: Default::default(),
quote_amount: (i * i).into(),
ts: env.block.time.seconds() + i * 1000,
price_sma: Decimal::from_ratio(i, i * i),
price: Default::default(),
})
.collect_vec();
buffer.push_many(&array);
Expand Down Expand Up @@ -389,11 +387,9 @@ mod testing {
let array = (1..=30)
.into_iter()
.map(|i| Observation {
timestamp: env.block.time.seconds() + i * 1000,
base_sma: Default::default(),
base_amount: i.into(),
quote_sma: Default::default(),
quote_amount: (i * i).into(),
ts: env.block.time.seconds() + i * 1000,
price: Default::default(),
price_sma: Decimal::from_ratio(i, i * i),
})
.collect_vec();
buffer.push_many(&array);
Expand Down Expand Up @@ -433,11 +429,9 @@ mod testing {
let array = (1..=CAPACITY * 3)
.into_iter()
.map(|i| Observation {
timestamp: ts + i as u64 * 1000,
base_sma: Default::default(),
base_amount: (i * i).into(),
quote_sma: Default::default(),
quote_amount: i.into(),
ts: ts + i as u64 * 1000,
price: Default::default(),
price_sma: Decimal::from_ratio(i * i, i),
})
.collect_vec();

Expand Down
65 changes: 30 additions & 35 deletions contracts/pair_concentrated/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use cosmwasm_std::{Addr, Env, QuerierWrapper, StdResult, Storage, Uint128};
use cosmwasm_std::{Addr, Decimal, Env, QuerierWrapper, StdResult, Storage, Uint128};

use astroport::asset::{Asset, DecimalAsset};
use astroport::observation::{safe_sma_buffer_not_full, safe_sma_calculation};
use astroport::observation::{Observation, PrecommitObservation};
use astroport::querier::query_supply;
use astroport_circular_buffer::error::BufferResult;
use astroport_circular_buffer::BufferManager;
use astroport_pcl_common::state::{Config, Precisions};
use astroport_pcl_common::utils::{safe_sma_buffer_not_full, safe_sma_calculation};

use crate::error::ContractError;
use crate::state::OBSERVATIONS;
Expand Down Expand Up @@ -43,7 +43,7 @@ pub(crate) fn query_pools(
.collect()
}

/// Calculate and save moving averages of swap sizes.
/// Calculate and save price moving average
pub fn accumulate_swap_sizes(storage: &mut dyn Storage, env: &Env) -> BufferResult<()> {
if let Some(PrecommitObservation {
base_amount,
Expand All @@ -52,45 +52,35 @@ pub fn accumulate_swap_sizes(storage: &mut dyn Storage, env: &Env) -> BufferResu
}) = PrecommitObservation::may_load(storage)?
{
let mut buffer = BufferManager::new(storage, OBSERVATIONS)?;
let observed_price = Decimal::from_ratio(base_amount, quote_amount);

let new_observation;
if let Some(last_obs) = buffer.read_last(storage)? {
// Skip saving observation if it has been already saved
if last_obs.timestamp < precommit_ts {
if last_obs.ts < precommit_ts {
// Since this is circular buffer the next index contains the oldest value
let count = buffer.capacity();
if let Some(oldest_obs) = buffer.read_single(storage, buffer.head() + 1)? {
let new_base_sma = safe_sma_calculation(
last_obs.base_sma,
oldest_obs.base_amount,
let price_sma = safe_sma_calculation(
last_obs.price_sma,
oldest_obs.price,
count,
base_amount,
)?;
let new_quote_sma = safe_sma_calculation(
last_obs.quote_sma,
oldest_obs.quote_amount,
count,
quote_amount,
observed_price,
)?;
new_observation = Observation {
base_amount,
quote_amount,
base_sma: new_base_sma,
quote_sma: new_quote_sma,
timestamp: precommit_ts,
ts: precommit_ts,
price: observed_price,
price_sma,
};
} else {
// Buffer is not full yet
let count = buffer.head();
let base_sma = safe_sma_buffer_not_full(last_obs.base_sma, count, base_amount)?;
let quote_sma =
safe_sma_buffer_not_full(last_obs.quote_sma, count, quote_amount)?;
let price_sma =
safe_sma_buffer_not_full(last_obs.price_sma, count, observed_price)?;
new_observation = Observation {
base_amount,
quote_amount,
base_sma,
quote_sma,
timestamp: precommit_ts,
ts: precommit_ts,
price: observed_price,
price_sma,
};
}

Expand All @@ -100,11 +90,9 @@ pub fn accumulate_swap_sizes(storage: &mut dyn Storage, env: &Env) -> BufferResu
// Buffer is empty
if env.block.time.seconds() > precommit_ts {
new_observation = Observation {
timestamp: precommit_ts,
base_sma: base_amount,
base_amount,
quote_sma: quote_amount,
quote_amount,
ts: precommit_ts,
price: observed_price,
price_sma: observed_price,
};

buffer.instant_push(storage, &new_observation)?
Expand All @@ -117,11 +105,18 @@ pub fn accumulate_swap_sizes(storage: &mut dyn Storage, env: &Env) -> BufferResu

#[cfg(test)]
mod tests {
use std::fmt::Display;
use std::str::FromStr;

use cosmwasm_std::testing::{mock_env, MockStorage};
use cosmwasm_std::{BlockInfo, Timestamp};

use super::*;

pub fn dec_to_f64(val: impl Display) -> f64 {
f64::from_str(&val.to_string()).unwrap()
}

#[test]
fn test_swap_observations() {
let mut store = MockStorage::new();
Expand All @@ -144,9 +139,9 @@ mod tests {
let buffer = BufferManager::new(&store, OBSERVATIONS).unwrap();

let obs = buffer.read_last(&store).unwrap().unwrap();
assert_eq!(obs.timestamp, 50);
assert_eq!(obs.ts, 50);
assert_eq!(buffer.head(), 0);
assert_eq!(obs.base_sma.u128(), 1000u128);
assert_eq!(obs.quote_sma.u128(), 500u128);
assert_eq!(dec_to_f64(obs.price_sma), 2.0);
assert_eq!(dec_to_f64(obs.price), 2.0);
}
}
15 changes: 9 additions & 6 deletions contracts/pair_concentrated/tests/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ use astroport_pair_concentrated::contract::{execute, instantiate, reply};
use astroport_pair_concentrated::queries::query;
use astroport_pcl_common::state::Config;

const NATIVE_TOKEN_PRECISION: u8 = 6;

const INIT_BALANCE: u128 = 1_000_000_000000;
const INIT_BALANCE: u128 = u128::MAX;

pub fn common_pcl_params() -> ConcentratedPoolParams {
ConcentratedPoolParams {
Expand Down Expand Up @@ -99,7 +97,7 @@ pub fn init_native_coins(test_coins: &[TestCoin]) -> Vec<Coin> {
.iter()
.filter_map(|test_coin| match test_coin {
TestCoin::Native(name) => {
let init_balance = INIT_BALANCE * 10u128.pow(NATIVE_TOKEN_PRECISION as u32);
let init_balance = INIT_BALANCE;
Some(coin(init_balance, name))
}
_ => None,
Expand Down Expand Up @@ -214,7 +212,12 @@ impl Helper {
owner.clone(),
coin_registry_address.clone(),
&astroport::native_coin_registry::ExecuteMsg::Add {
native_coins: vec![("uluna".to_owned(), 6), ("uusd".to_owned(), 6)],
native_coins: vec![
("uluna".to_owned(), 6),
("uusd".to_owned(), 6),
("wsteth".to_owned(), 18),
("eth".to_owned(), 18),
],
},
&[],
)
Expand Down Expand Up @@ -414,7 +417,7 @@ impl Helper {
decimals: u8,
owner: &Addr,
) -> Addr {
let init_balance = INIT_BALANCE * 10u128.pow(decimals as u32);
let init_balance = INIT_BALANCE;
app.instantiate_contract(
token_code,
owner.clone(),
Expand Down
Loading
Loading