Skip to content

Commit

Permalink
dex(state_key): add lookup/sorted indices for volume
Browse files Browse the repository at this point in the history
  • Loading branch information
erwanor committed Jan 28, 2025
1 parent 0d8fa13 commit a5aadf1
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions crates/core/component/dex/src/state_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,82 @@ pub fn aggregate_value() -> &'static str {
"dex/aggregate_value"
}

pub mod lqt {
pub mod v1 {
pub mod lp {
pub mod lookup {
use penumbra_sdk_asset::asset;

pub(crate) fn _prefix(epoch_index: u64) -> String {
format!("dex/lqt/v1/lp/lookup/{epoch_index:020}/")
}

// A lookup index used to update cumulative volumes.
/// It maps an trading pair (staking token, asset) to the cumulative volume of outbound liquidity.
///
/// # Key Encoding
/// The lookup key is encoded as `prefix || asset`
/// # Value Encoding
/// The value is encoded as `BE(Amount)`
pub(crate) fn _volume_by_pair(epoch_index: u64, asset: asset::Id) -> [u8; 74] {
let prefix_bytes = _prefix(epoch_index);
let mut key = [0u8; 74];
key[0..42].copy_from_slice(prefix_bytes.as_bytes());
key[42..42 + 32].copy_from_slice(&asset.to_bytes());
key
}
}

pub mod by_volume {
use anyhow::{ensure, Result};
use penumbra_sdk_asset::asset;
use penumbra_sdk_num::Amount;

pub fn prefix(epoch_index: u64) -> String {
format!("dex/lqt/v1/lp/by_volume/{epoch_index:020}/")
}

/// Tracks the cumulative volume of outbound liquidity for a given pair.
/// The pair is always connected by the staking token, which is the implicit numeraire.
///
/// # Encoding
/// The full key is encoded as: `prefix || asset || BE(volume)`
pub(crate) fn _key(
epoch_index: u64,
asset: &asset::Id,
volume: Amount,
) -> [u8; 93] {
let prefix_bytes = prefix(epoch_index);
let mut key = [0u8; 93];
key[0..45].copy_from_slice(prefix_bytes.as_bytes());
key[45..45 + 32].copy_from_slice(&asset.to_bytes());
key[45 + 32..45 + 32 + 16].copy_from_slice(&(!volume).to_be_bytes());
key
}

/// Extract the cumulative amount of liquidity from a fully specified key.
///
/// # Errors
/// This function will return an error if the key is not 72 bytes. Or, if the
/// key contains an invalid asset identifier.
pub(crate) fn _parse_key(key: &[u8]) -> Result<(asset::Id, Amount)> {
ensure!(key.len() == 93, "key must be 93 bytes");

// skip the first 45 bytes of prefix
let raw_asset: [u8; 32] = key[45..45 + 32].try_into()?;
let asset: asset::Id = raw_asset.try_into()?;

let raw_amount: [u8; 16] = key[45 + 32..45 + 32 + 16].try_into()?;
let amount_complement = Amount::from_be_bytes(raw_amount);
let amount = !amount_complement;

Ok((asset, amount))
}
}
}
}
}

pub(crate) mod engine {
use super::*;
use crate::lp::BareTradingFunction;
Expand Down

0 comments on commit a5aadf1

Please sign in to comment.