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

dex: restore support for eth-like assets #2805

Merged
merged 4 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions crates/core/asset/src/asset/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,31 +241,29 @@ pub static REGISTRY: Lazy<Registry> = Lazy::new(|| {
"wtest_usd".to_string(),
vec![
denom_metadata::BareDenomUnit {
// TODO(erwan): temporarily reduced to 1e6 (see #2560)
exponent: 6,
exponent: 18,
denom: "test_usd".to_string(),
},
],
)
}) as for<'r> fn(&'r str) -> _,
)
// TODO(erwan): temporarily disabling `test_eth` (see #2560)
//.add_asset(
// "^wtest_eth$",
// &["^test_eth$"],
// (|data: &str| {
// assert!(data.is_empty());
// denom::Inner::new(
// "wtest_eth".to_string(),
// vec![
// denom::UnitData {
// exponent: 18,
// denom: "test_eth".to_string(),
// },
// ],
// )
// }) as for<'r> fn(&'r str) -> _,
//)
.add_asset(
"^wtest_eth$",
&["^test_eth$"],
(|data: &str| {
assert!(data.is_empty());
denom_metadata::Inner::new(
"wtest_eth".to_string(),
vec![
denom_metadata::BareDenomUnit {
exponent: 18,
denom: "test_eth".to_string(),
},
],
)
}) as for<'r> fn(&'r str) -> _,
)
.add_asset(
"^test_sat$",
&["^test_btc$"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ impl ActionHandler for PositionOpen {
async fn check_stateless(&self, _context: ()) -> Result<()> {
// TODO(chris, erwan, henry): brainstorm safety on `TradingFunction`.
// Check:
// + reserves are at most 112 bits wide,
// + reserves are at most 80 bits wide,
// + the trading function coefficients are at most 80 bits wide.
// + at least some assets are provisioned.
// + the trading function coefficients are at most 112 bits wide.
// + the trading function coefficients are non-zero,
// + the trading function doesn't specify a cyclic pair,
// + the fee is <=50%.
// + if the position is a limit-order, it only quotes one asset.
self.position.check_stateless()?;
// This is a temporary check that limits DEX values to 60 bits.
// To lift this check, delete this line and the method it invokes.
self.position.temporary_check()?;
Ok(())
}

Expand Down
17 changes: 7 additions & 10 deletions crates/core/component/dex/src/component/router/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1662,26 +1662,23 @@ async fn path_search_testnet_53_1_reproduction() -> anyhow::Result<()> {
let Some(path_entry) = cache_guard.0.remove(&penumbra.id()) else {
panic!("Path entry not found");
};

let path_price = path_entry.path.price;
let spill_price = path_entry.spill.unwrap().price;
// `U128x128` can be approximated to `f64` for comparison purposes.
let path_price: f64 = path_entry.path.price.into();
let spill_price: f64 = path_entry.spill.unwrap().price.into();
tracing::debug!("path start: {}", path_entry.path.start);
tracing::debug!("hops: {:?}", path_entry.path.nodes);

let correct_path_price = U128x128::ratio(1u64, 10u64).unwrap();
let correct_spill_price = U128x128::ratio(2u64, 10u64).unwrap();
let correct_path_price = 0.1f64;
let correct_spill_price = 0.2f64;

assert_eq!(
path_price, correct_path_price,
"check that the path price is correct (correct={}, actual={})",
path_price, correct_path_price
);
assert_eq!(
spill_price,
U128x128::ratio(2u64, 10u64).unwrap(),
spill_price, correct_spill_price,
"check that the spill price is correct (correct={}, actual={})",
spill_price,
correct_spill_price
spill_price, correct_spill_price
);

Ok(())
Expand Down
23 changes: 4 additions & 19 deletions crates/core/component/dex/src/lp/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::{DirectedTradingPair, TradingPair};

use super::{trading_function::TradingFunction, Reserves};

/// Reserve amounts for positions must be at most 112 bits wide.
pub const MAX_RESERVE_AMOUNT: u128 = (1 << 112) - 1;
/// Reserve amounts for positions must be at most 80 bits wide.
pub const MAX_RESERVE_AMOUNT: u128 = (1 << 80) - 1;

/// A trading function's fee (spread) must be at most 50% (5000 bps)
pub const MAX_FEE_BPS: u32 = 5000;
Expand Down Expand Up @@ -131,8 +131,8 @@ impl Position {
Err(anyhow::anyhow!(
"trading function coefficients must be nonzero"
))
} else if self.phi.component.p.value() as u128 > MAX_RESERVE_AMOUNT
|| self.phi.component.q.value() as u128 > MAX_RESERVE_AMOUNT
} else if self.phi.component.p.value() > MAX_RESERVE_AMOUNT
|| self.phi.component.q.value() > MAX_RESERVE_AMOUNT
{
Err(anyhow!("trading function coefficients are too large"))
} else if self.phi.pair.asset_1() == self.phi.pair.asset_2() {
Expand All @@ -144,21 +144,6 @@ impl Position {
}
}

/// Implements temporary limiting reserve/valuations values to 60 bits, for more
/// details, please check issue #2560.
pub fn temporary_check(&self) -> anyhow::Result<()> {
let max_60_bits: u128 = (1 << 60) - 1;
if self.reserves.r1.value() > max_60_bits || self.reserves.r2.value() > max_60_bits {
anyhow::bail!("we are temporarily limiting reserves to be at most 60 bits wide")
} else if self.phi.component.p.value() > max_60_bits
|| self.phi.component.q.value() > max_60_bits
{
anyhow::bail!("we are temporarily limiting trading function coefficient to be at most 60 bits wide")
} else {
Ok(())
}
}

/// Returns the amount of the given asset that is currently in the position's reserves.
pub fn reserves_for(&self, asset: asset::Id) -> Option<Amount> {
if asset == self.phi.pair.asset_1() {
Expand Down