mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-05 06:43:08 +00:00
Merge branch 'simple_amm' into Pravdyvy/amm-wallet-integration
This commit is contained in:
commit
c5cca4376e
@ -7,7 +7,7 @@ edition = "2024"
|
||||
risc0-zkvm = { version = "3.0.3", features = ['std'] }
|
||||
serde = { version = "1.0", default-features = false }
|
||||
thiserror = { version = "2.0.12" }
|
||||
bytemuck = { version = "1.13" }
|
||||
bytemuck = "1.24.0"
|
||||
chacha20 = { version = "0.9", default-features = false }
|
||||
k256 = { version = "0.13.3", optional = true }
|
||||
base58 = { version = "0.2.0", optional = true }
|
||||
|
||||
@ -32,6 +32,7 @@ pub struct AccountWithMetadata {
|
||||
pub is_authorized: bool,
|
||||
pub account_id: AccountId,
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
impl AccountWithMetadata {
|
||||
pub fn new(account: Account, is_authorized: bool, account_id: impl Into<AccountId>) -> Self {
|
||||
@ -44,7 +45,7 @@ impl AccountWithMetadata {
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Clone, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize, Default,
|
||||
Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize,
|
||||
)]
|
||||
#[cfg_attr(any(feature = "host", test), derive(Debug, Copy, PartialOrd, Ord))]
|
||||
pub struct AccountId {
|
||||
|
||||
@ -20,8 +20,8 @@ pub struct ProgramInput<T> {
|
||||
/// Each program can derive up to `2^256` unique account IDs by choosing different
|
||||
/// seeds. PDAs allow programs to control namespaced account identifiers without
|
||||
/// collisions between programs.
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(any(feature = "host", test), derive(Debug, Eq))]
|
||||
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(any(feature = "host", test), derive(Debug))]
|
||||
pub struct PdaSeed([u8; 32]);
|
||||
|
||||
impl PdaSeed {
|
||||
@ -51,8 +51,8 @@ impl From<(&ProgramId, &PdaSeed)> for AccountId {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(any(feature = "host", test), derive(Debug, Eq))]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(any(feature = "host", test), derive(Debug,))]
|
||||
pub struct ChainedCall {
|
||||
/// The program ID of the program to execute
|
||||
pub program_id: ProgramId,
|
||||
|
||||
@ -8,4 +8,4 @@ edition = "2024"
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "3.0.3", features = ['std'] }
|
||||
nssa-core = { path = "../../core" }
|
||||
serde = { version = "1.0.219", default-features = false }
|
||||
serde = { version = "1.0.219", default-features = false }
|
||||
|
||||
@ -73,7 +73,7 @@ struct PoolDefinition{
|
||||
}
|
||||
|
||||
impl PoolDefinition {
|
||||
fn into_data(self) -> Vec<u8> {
|
||||
fn into_data(self) -> Data {
|
||||
let mut bytes = [0; POOL_DEFINITION_DATA_SIZE];
|
||||
bytes[0..32].copy_from_slice(&self.definition_token_a_id.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.definition_token_b_id.to_bytes());
|
||||
@ -85,7 +85,11 @@ impl PoolDefinition {
|
||||
bytes[192..208].copy_from_slice(&self.reserve_b.to_le_bytes());
|
||||
bytes[208..224].copy_from_slice(&self.fees.to_le_bytes());
|
||||
bytes[224] = self.active as u8;
|
||||
bytes.into()
|
||||
|
||||
bytes
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("225 bytes should fit into Data")
|
||||
}
|
||||
|
||||
fn parse(data: &[u8]) -> Option<Self> {
|
||||
@ -144,14 +148,18 @@ struct TokenHolding {
|
||||
}
|
||||
|
||||
impl TokenDefinition {
|
||||
fn into_data(self) -> Vec<u8> {
|
||||
fn into_data(self) -> Data {
|
||||
let mut bytes = [0; TOKEN_DEFINITION_DATA_SIZE];
|
||||
bytes[0] = self.account_type;
|
||||
bytes[1..7].copy_from_slice(&self.name);
|
||||
bytes[7..].copy_from_slice(&self.total_supply.to_le_bytes());
|
||||
bytes.into()
|
||||
bytes
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("23 bytes should fit into Data")
|
||||
}
|
||||
|
||||
|
||||
fn parse(data: &[u8]) -> Option<Self> {
|
||||
if data.len() != TOKEN_DEFINITION_DATA_SIZE || data[0] != TOKEN_DEFINITION_TYPE {
|
||||
None
|
||||
@ -209,17 +217,21 @@ impl TokenHolding {
|
||||
bytes[0] = self.account_type;
|
||||
bytes[1..33].copy_from_slice(&self.definition_id.to_bytes());
|
||||
bytes[33..].copy_from_slice(&self.balance.to_le_bytes());
|
||||
bytes.to_vec().try_into().expect("Data too big")
|
||||
|
||||
bytes
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("49 bytes should fit into Data")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type Instruction = Vec<u8>;
|
||||
fn main() {
|
||||
let ( ProgramInput {
|
||||
let (ProgramInput {
|
||||
pre_states,
|
||||
instruction,
|
||||
}, instruction_data) = read_nssa_inputs::<Instruction>();
|
||||
}, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let (post_states, chained_calls) = match instruction[0] {
|
||||
0 => {
|
||||
@ -266,7 +278,7 @@ fn main() {
|
||||
_ => panic!("Invalid instruction"),
|
||||
};
|
||||
|
||||
write_nssa_outputs_with_chained_call(instruction_data, pre_states, post_states, chained_calls);
|
||||
write_nssa_outputs_with_chained_call(instruction_words, pre_states, post_states, chained_calls);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2241,14 +2241,16 @@ pub mod tests {
|
||||
definition_id: AccountId,
|
||||
balance: u128,
|
||||
}
|
||||
|
||||
impl TokenDefinition {
|
||||
fn into_data(self) -> Vec<u8> {
|
||||
fn into_data(self) -> Data {
|
||||
let mut bytes = [0; TOKEN_DEFINITION_DATA_SIZE];
|
||||
bytes[0] = self.account_type;
|
||||
bytes[1..7].copy_from_slice(&self.name);
|
||||
bytes[7..].copy_from_slice(&self.total_supply.to_le_bytes());
|
||||
bytes.into()
|
||||
bytes
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("23 bytes should fit into Data")
|
||||
}
|
||||
}
|
||||
|
||||
@ -2258,7 +2260,10 @@ pub mod tests {
|
||||
bytes[0] = self.account_type;
|
||||
bytes[1..33].copy_from_slice(&self.definition_id.to_bytes());
|
||||
bytes[33..].copy_from_slice(&self.balance.to_le_bytes());
|
||||
bytes.to_vec().try_into().expect("Data too big")
|
||||
bytes
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("33 bytes should fit into Data")
|
||||
}
|
||||
}
|
||||
|
||||
@ -2355,14 +2360,14 @@ pub mod tests {
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
const POOL_DEFINITION_DATA_SIZE: usize = 225;
|
||||
|
||||
#[derive(Default)]
|
||||
struct PoolDefinition {
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
vault_a_addr: AccountId,
|
||||
vault_b_addr: AccountId,
|
||||
vault_a_id: AccountId,
|
||||
vault_b_id: AccountId,
|
||||
liquidity_pool_id: AccountId,
|
||||
liquidity_pool_supply: u128,
|
||||
reserve_a: u128,
|
||||
@ -2372,19 +2377,69 @@ pub mod tests {
|
||||
}
|
||||
|
||||
impl PoolDefinition {
|
||||
fn into_data(self) -> Vec<u8> {
|
||||
fn into_data(self) -> Data {
|
||||
let mut bytes = [0; POOL_DEFINITION_DATA_SIZE];
|
||||
bytes[0..32].copy_from_slice(&self.definition_token_a_id.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.definition_token_b_id.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.vault_a_addr.to_bytes());
|
||||
bytes[96..128].copy_from_slice(&self.vault_b_addr.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.vault_a_id.to_bytes());
|
||||
bytes[96..128].copy_from_slice(&self.vault_b_id.to_bytes());
|
||||
bytes[128..160].copy_from_slice(&self.liquidity_pool_id.to_bytes());
|
||||
bytes[160..176].copy_from_slice(&self.liquidity_pool_supply.to_le_bytes());
|
||||
bytes[176..192].copy_from_slice(&self.reserve_a.to_le_bytes());
|
||||
bytes[192..208].copy_from_slice(&self.reserve_b.to_le_bytes());
|
||||
bytes[208..224].copy_from_slice(&self.fees.to_le_bytes());
|
||||
bytes[224] = self.active as u8;
|
||||
bytes.into()
|
||||
|
||||
bytes
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.expect("225 bytes should fit into Data")
|
||||
}
|
||||
|
||||
fn parse(data: &[u8]) -> Option<Self> {
|
||||
if data.len() != POOL_DEFINITION_DATA_SIZE {
|
||||
None
|
||||
} else {
|
||||
let definition_token_a_id = AccountId::new(data[0..32].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Token A definition"));
|
||||
let definition_token_b_id = AccountId::new(data[32..64].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Vault B definition"));
|
||||
let vault_a_id = AccountId::new(data[64..96].try_into().expect(
|
||||
"Parse data: The AMM program must be provided a valid AccountId for Vault A",
|
||||
));
|
||||
let vault_b_id = AccountId::new(data[96..128].try_into().expect(
|
||||
"Parse data: The AMM program must be provided a valid AccountId for Vault B",
|
||||
));
|
||||
let liquidity_pool_id = AccountId::new(data[128..160].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Token liquidity pool definition"));
|
||||
let liquidity_pool_supply = u128::from_le_bytes(data[160..176].try_into().expect(
|
||||
"Parse data: The AMM program must be provided a valid u128 for liquidity cap",
|
||||
));
|
||||
let reserve_a = u128::from_le_bytes(data[176..192].try_into().expect("Parse data: The AMM program must be provided a valid u128 for reserve A balance"));
|
||||
let reserve_b = u128::from_le_bytes(data[192..208].try_into().expect("Parse data: The AMM program must be provided a valid u128 for reserve B balance"));
|
||||
let fees =
|
||||
u128::from_le_bytes(data[208..224].try_into().expect(
|
||||
"Parse data: The AMM program must be provided a valid u128 for fees",
|
||||
));
|
||||
|
||||
let active = match data[224] {
|
||||
0 => false,
|
||||
1 => true,
|
||||
_ => panic!(
|
||||
"Parse data: The AMM program must be provided a valid bool for active"
|
||||
),
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
definition_token_a_id,
|
||||
definition_token_b_id,
|
||||
vault_a_id,
|
||||
vault_b_id,
|
||||
liquidity_pool_id,
|
||||
liquidity_pool_supply,
|
||||
reserve_a,
|
||||
reserve_b,
|
||||
fees,
|
||||
active,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2615,8 +2670,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: helper_balances_constructor(
|
||||
BalancesEnum::PoolLPSupplyInit,
|
||||
@ -2722,8 +2777,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: helper_balances_constructor(
|
||||
BalancesEnum::PoolLPSupplyInit,
|
||||
@ -2783,8 +2838,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: helper_balances_constructor(
|
||||
BalancesEnum::PoolLPSupplyInit,
|
||||
@ -2844,8 +2899,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: helper_balances_constructor(
|
||||
BalancesEnum::TokenLPSupplyAdd,
|
||||
@ -2927,8 +2982,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: helper_balances_constructor(
|
||||
BalancesEnum::TokenLPSupplyRemove,
|
||||
@ -3022,8 +3077,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: 0,
|
||||
reserve_a: 0,
|
||||
@ -3083,8 +3138,8 @@ pub mod tests {
|
||||
data: PoolDefinition::into_data(PoolDefinition {
|
||||
definition_token_a_id: helper_id_constructor(IdEnum::TokenADefinitionId),
|
||||
definition_token_b_id: helper_id_constructor(IdEnum::TokenBDefinitionId),
|
||||
vault_a_addr: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_addr: helper_id_constructor(IdEnum::VaultBId),
|
||||
vault_a_id: helper_id_constructor(IdEnum::VaultAId),
|
||||
vault_b_id: helper_id_constructor(IdEnum::VaultBId),
|
||||
liquidity_pool_id: helper_id_constructor(IdEnum::TokenLPDefinitionId),
|
||||
liquidity_pool_supply: helper_balances_constructor(
|
||||
BalancesEnum::UserTokenAHoldingNewDef,
|
||||
|
||||
8
nssa/test_program_methods/guest/Cargo.lock
generated
8
nssa/test_program_methods/guest/Cargo.lock
generated
@ -419,18 +419,18 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.23.1"
|
||||
version = "1.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
|
||||
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.8.1"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
|
||||
checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@ -14,7 +14,7 @@ tempfile.workspace = true
|
||||
clap.workspace = true
|
||||
nssa-core = { path = "../nssa/core" }
|
||||
base64.workspace = true
|
||||
bytemuck = "1.23.2"
|
||||
bytemuck = "1.24.0"
|
||||
borsh.workspace = true
|
||||
base58.workspace = true
|
||||
hex = "0.4.3"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user