use carbon_core::{
account::AccountMetadata,
postgres::{
metadata::AccountRowMetadata,
primitives::{Pubkey, I128, U128, U16, U64, U8},
},
};
#[derive(sqlx::FromRow, Debug, Clone)]
pub struct LPPoolRow {
#[sqlx(flatten)]
pub account_metadata: AccountRowMetadata,
pub pubkey: Pubkey,
pub mint: Pubkey,
pub whitelist_mint: Pubkey,
pub constituent_target_base: Pubkey,
pub constituent_correlations: Pubkey,
pub max_aum: U128,
pub last_aum: U128,
pub cumulative_quote_sent_to_perp_markets: U128,
pub cumulative_quote_received_from_perp_markets: U128,
pub total_mint_redeem_fees_paid: I128,
pub last_aum_slot: U64,
pub max_settle_quote_amount: U64,
pub padding: U64,
pub mint_redeem_id: U64,
pub settle_id: U64,
pub min_mint_fee: i64,
pub token_supply: U64,
pub volatility: U64,
pub constituents: U16,
pub quote_consituent_index: U16,
pub bump: U8,
pub gamma_execution: U8,
pub xi: U8,
pub target_oracle_delay_fee_bps_per10_slots: U8,
pub target_position_delay_fee_bps_per10_slots: U8,
pub lp_pool_id: U8,
pub padding_1: Vec<u8>,
}
impl LPPoolRow {
pub fn from_parts(
source: crate::accounts::l_p_pool::LPPool,
metadata: AccountMetadata,
) -> Self {
Self {
account_metadata: metadata.into(),
pubkey: source.pubkey.into(),
mint: source.mint.into(),
whitelist_mint: source.whitelist_mint.into(),
constituent_target_base: source.constituent_target_base.into(),
constituent_correlations: source.constituent_correlations.into(),
max_aum: source.max_aum.into(),
last_aum: source.last_aum.into(),
cumulative_quote_sent_to_perp_markets: source
.cumulative_quote_sent_to_perp_markets
.into(),
cumulative_quote_received_from_perp_markets: source
.cumulative_quote_received_from_perp_markets
.into(),
total_mint_redeem_fees_paid: source.total_mint_redeem_fees_paid.into(),
last_aum_slot: source.last_aum_slot.into(),
max_settle_quote_amount: source.max_settle_quote_amount.into(),
padding: source._padding.into(),
mint_redeem_id: source.mint_redeem_id.into(),
settle_id: source.settle_id.into(),
min_mint_fee: source.min_mint_fee,
token_supply: source.token_supply.into(),
volatility: source.volatility.into(),
constituents: source.constituents.into(),
quote_consituent_index: source.quote_consituent_index.into(),
bump: source.bump.into(),
gamma_execution: source.gamma_execution.into(),
xi: source.xi.into(),
target_oracle_delay_fee_bps_per10_slots: source
.target_oracle_delay_fee_bps_per10_slots
.into(),
target_position_delay_fee_bps_per10_slots: source
.target_position_delay_fee_bps_per10_slots
.into(),
lp_pool_id: source.lp_pool_id.into(),
padding_1: source.padding.to_vec(),
}
}
}
impl TryFrom<LPPoolRow> for crate::accounts::l_p_pool::LPPool {
type Error = carbon_core::error::Error;
fn try_from(source: LPPoolRow) -> Result<Self, Self::Error> {
Ok(Self {
pubkey: *source.pubkey,
mint: *source.mint,
whitelist_mint: *source.whitelist_mint,
constituent_target_base: *source.constituent_target_base,
constituent_correlations: *source.constituent_correlations,
max_aum: *source.max_aum,
last_aum: *source.last_aum,
cumulative_quote_sent_to_perp_markets: *source.cumulative_quote_sent_to_perp_markets,
cumulative_quote_received_from_perp_markets: *source
.cumulative_quote_received_from_perp_markets,
total_mint_redeem_fees_paid: *source.total_mint_redeem_fees_paid,
last_aum_slot: *source.last_aum_slot,
max_settle_quote_amount: *source.max_settle_quote_amount,
_padding: *source.padding,
mint_redeem_id: *source.mint_redeem_id,
settle_id: *source.settle_id,
min_mint_fee: source.min_mint_fee,
token_supply: *source.token_supply,
volatility: *source.volatility,
constituents: source.constituents.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
quote_consituent_index: source.quote_consituent_index.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
bump: source.bump.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
gamma_execution: source.gamma_execution.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
xi: source.xi.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
target_oracle_delay_fee_bps_per10_slots: source
.target_oracle_delay_fee_bps_per10_slots
.try_into()
.map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
target_position_delay_fee_bps_per10_slots: source
.target_position_delay_fee_bps_per10_slots
.try_into()
.map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
lp_pool_id: source.lp_pool_id.try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert value from postgres primitive".to_string(),
)
})?,
padding: source.padding_1.as_slice().try_into().map_err(|_| {
carbon_core::error::Error::Custom(
"Failed to convert padding from postgres primitive: expected 174 bytes"
.to_string(),
)
})?,
})
}
}
impl carbon_core::postgres::operations::Table for crate::accounts::l_p_pool::LPPool {
fn table() -> &'static str {
"l_p_pool_account"
}
fn columns() -> Vec<&'static str> {
vec![
"__pubkey",
"__slot",
"pubkey",
"mint",
"whitelist_mint",
"constituent_target_base",
"constituent_correlations",
"max_aum",
"last_aum",
"cumulative_quote_sent_to_perp_markets",
"cumulative_quote_received_from_perp_markets",
"total_mint_redeem_fees_paid",
"last_aum_slot",
"max_settle_quote_amount",
"padding",
"mint_redeem_id",
"settle_id",
"min_mint_fee",
"token_supply",
"volatility",
"constituents",
"quote_consituent_index",
"bump",
"gamma_execution",
"xi",
"target_oracle_delay_fee_bps_per10_slots",
"target_position_delay_fee_bps_per10_slots",
"lp_pool_id",
"padding_1",
]
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Insert for LPPoolRow {
async fn insert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
sqlx::query(r#"
INSERT INTO l_p_pool_account (
"pubkey",
"mint",
"whitelist_mint",
"constituent_target_base",
"constituent_correlations",
"max_aum",
"last_aum",
"cumulative_quote_sent_to_perp_markets",
"cumulative_quote_received_from_perp_markets",
"total_mint_redeem_fees_paid",
"last_aum_slot",
"max_settle_quote_amount",
"padding",
"mint_redeem_id",
"settle_id",
"min_mint_fee",
"token_supply",
"volatility",
"constituents",
"quote_consituent_index",
"bump",
"gamma_execution",
"xi",
"target_oracle_delay_fee_bps_per10_slots",
"target_position_delay_fee_bps_per10_slots",
"lp_pool_id",
"padding_1",
__pubkey, __slot
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29
)"#)
.bind(self.pubkey)
.bind(self.mint)
.bind(self.whitelist_mint)
.bind(self.constituent_target_base)
.bind(self.constituent_correlations)
.bind(&self.max_aum)
.bind(&self.last_aum)
.bind(&self.cumulative_quote_sent_to_perp_markets)
.bind(&self.cumulative_quote_received_from_perp_markets)
.bind(&self.total_mint_redeem_fees_paid)
.bind(&self.last_aum_slot)
.bind(&self.max_settle_quote_amount)
.bind(&self.padding)
.bind(&self.mint_redeem_id)
.bind(&self.settle_id)
.bind(self.min_mint_fee)
.bind(&self.token_supply)
.bind(&self.volatility)
.bind(self.constituents)
.bind(self.quote_consituent_index)
.bind(self.bump)
.bind(self.gamma_execution)
.bind(self.xi)
.bind(self.target_oracle_delay_fee_bps_per10_slots)
.bind(self.target_position_delay_fee_bps_per10_slots)
.bind(self.lp_pool_id)
.bind(&self.padding_1)
.bind(self.account_metadata.pubkey)
.bind(&self.account_metadata.slot)
.execute(pool).await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(())
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Upsert for LPPoolRow {
async fn upsert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
sqlx::query(r#"INSERT INTO l_p_pool_account (
"pubkey",
"mint",
"whitelist_mint",
"constituent_target_base",
"constituent_correlations",
"max_aum",
"last_aum",
"cumulative_quote_sent_to_perp_markets",
"cumulative_quote_received_from_perp_markets",
"total_mint_redeem_fees_paid",
"last_aum_slot",
"max_settle_quote_amount",
"padding",
"mint_redeem_id",
"settle_id",
"min_mint_fee",
"token_supply",
"volatility",
"constituents",
"quote_consituent_index",
"bump",
"gamma_execution",
"xi",
"target_oracle_delay_fee_bps_per10_slots",
"target_position_delay_fee_bps_per10_slots",
"lp_pool_id",
"padding_1",
__pubkey, __slot
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29
) ON CONFLICT (
__pubkey
) DO UPDATE SET
"pubkey" = EXCLUDED."pubkey",
"mint" = EXCLUDED."mint",
"whitelist_mint" = EXCLUDED."whitelist_mint",
"constituent_target_base" = EXCLUDED."constituent_target_base",
"constituent_correlations" = EXCLUDED."constituent_correlations",
"max_aum" = EXCLUDED."max_aum",
"last_aum" = EXCLUDED."last_aum",
"cumulative_quote_sent_to_perp_markets" = EXCLUDED."cumulative_quote_sent_to_perp_markets",
"cumulative_quote_received_from_perp_markets" = EXCLUDED."cumulative_quote_received_from_perp_markets",
"total_mint_redeem_fees_paid" = EXCLUDED."total_mint_redeem_fees_paid",
"last_aum_slot" = EXCLUDED."last_aum_slot",
"max_settle_quote_amount" = EXCLUDED."max_settle_quote_amount",
"padding" = EXCLUDED."padding",
"mint_redeem_id" = EXCLUDED."mint_redeem_id",
"settle_id" = EXCLUDED."settle_id",
"min_mint_fee" = EXCLUDED."min_mint_fee",
"token_supply" = EXCLUDED."token_supply",
"volatility" = EXCLUDED."volatility",
"constituents" = EXCLUDED."constituents",
"quote_consituent_index" = EXCLUDED."quote_consituent_index",
"bump" = EXCLUDED."bump",
"gamma_execution" = EXCLUDED."gamma_execution",
"xi" = EXCLUDED."xi",
"target_oracle_delay_fee_bps_per10_slots" = EXCLUDED."target_oracle_delay_fee_bps_per10_slots",
"target_position_delay_fee_bps_per10_slots" = EXCLUDED."target_position_delay_fee_bps_per10_slots",
"lp_pool_id" = EXCLUDED."lp_pool_id",
"padding_1" = EXCLUDED."padding_1",
__slot = EXCLUDED.__slot
"#)
.bind(self.pubkey)
.bind(self.mint)
.bind(self.whitelist_mint)
.bind(self.constituent_target_base)
.bind(self.constituent_correlations)
.bind(&self.max_aum)
.bind(&self.last_aum)
.bind(&self.cumulative_quote_sent_to_perp_markets)
.bind(&self.cumulative_quote_received_from_perp_markets)
.bind(&self.total_mint_redeem_fees_paid)
.bind(&self.last_aum_slot)
.bind(&self.max_settle_quote_amount)
.bind(&self.padding)
.bind(&self.mint_redeem_id)
.bind(&self.settle_id)
.bind(self.min_mint_fee)
.bind(&self.token_supply)
.bind(&self.volatility)
.bind(self.constituents)
.bind(self.quote_consituent_index)
.bind(self.bump)
.bind(self.gamma_execution)
.bind(self.xi)
.bind(self.target_oracle_delay_fee_bps_per10_slots)
.bind(self.target_position_delay_fee_bps_per10_slots)
.bind(self.lp_pool_id)
.bind(&self.padding_1)
.bind(self.account_metadata.pubkey)
.bind(&self.account_metadata.slot)
.execute(pool).await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(())
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Delete for LPPoolRow {
type Key = carbon_core::postgres::primitives::Pubkey;
async fn delete(key: Self::Key, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
sqlx::query(
r#"DELETE FROM l_p_pool_account WHERE
__pubkey = $1
"#,
)
.bind(key)
.execute(pool)
.await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(())
}
}
#[async_trait::async_trait]
impl carbon_core::postgres::operations::Lookup for LPPoolRow {
type Key = carbon_core::postgres::primitives::Pubkey;
async fn lookup(
key: Self::Key,
pool: &sqlx::PgPool,
) -> carbon_core::error::CarbonResult<Option<Self>> {
let row = sqlx::query_as(
r#"SELECT * FROM l_p_pool_account WHERE
__pubkey = $1
"#,
)
.bind(key)
.fetch_optional(pool)
.await
.map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
Ok(row)
}
}
pub struct LPPoolMigrationOperation;
#[async_trait::async_trait]
impl sqlx_migrator::Operation<sqlx::Postgres> for LPPoolMigrationOperation {
async fn up(
&self,
connection: &mut sqlx::PgConnection,
) -> Result<(), sqlx_migrator::error::Error> {
sqlx::query(
r#"CREATE TABLE IF NOT EXISTS l_p_pool_account (
-- Account data
"pubkey" BYTEA NOT NULL,
"mint" BYTEA NOT NULL,
"whitelist_mint" BYTEA NOT NULL,
"constituent_target_base" BYTEA NOT NULL,
"constituent_correlations" BYTEA NOT NULL,
"max_aum" NUMERIC(39) NOT NULL,
"last_aum" NUMERIC(39) NOT NULL,
"cumulative_quote_sent_to_perp_markets" NUMERIC(39) NOT NULL,
"cumulative_quote_received_from_perp_markets" NUMERIC(39) NOT NULL,
"total_mint_redeem_fees_paid" NUMERIC(38) NOT NULL,
"last_aum_slot" NUMERIC(20) NOT NULL,
"max_settle_quote_amount" NUMERIC(20) NOT NULL,
"padding" NUMERIC(20) NOT NULL,
"mint_redeem_id" NUMERIC(20) NOT NULL,
"settle_id" NUMERIC(20) NOT NULL,
"min_mint_fee" INT8 NOT NULL,
"token_supply" NUMERIC(20) NOT NULL,
"volatility" NUMERIC(20) NOT NULL,
"constituents" INT4 NOT NULL,
"quote_consituent_index" INT4 NOT NULL,
"bump" INT2 NOT NULL,
"gamma_execution" INT2 NOT NULL,
"xi" INT2 NOT NULL,
"target_oracle_delay_fee_bps_per10_slots" INT2 NOT NULL,
"target_position_delay_fee_bps_per10_slots" INT2 NOT NULL,
"lp_pool_id" INT2 NOT NULL,
"padding_1" BYTEA NOT NULL,
-- Account metadata
__pubkey BYTEA NOT NULL,
__slot NUMERIC(20),
PRIMARY KEY (__pubkey)
)"#,
)
.execute(connection)
.await?;
Ok(())
}
async fn down(
&self,
connection: &mut sqlx::PgConnection,
) -> Result<(), sqlx_migrator::error::Error> {
sqlx::query(r#"DROP TABLE IF EXISTS l_p_pool_account"#)
.execute(connection)
.await?;
Ok(())
}
}