mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-05 06:43:08 +00:00
fix: public swaps
This commit is contained in:
parent
b3dca76b67
commit
92b5dffec2
@ -2042,7 +2042,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
|
||||
// Create new account for the token definition
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: definition_account_id,
|
||||
account_id: definition_account_id_1,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
@ -2053,7 +2053,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
};
|
||||
// Create new account for the token supply holder
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: supply_account_id,
|
||||
account_id: supply_account_id_1,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
@ -2073,6 +2073,28 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for the token definition
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: definition_account_id_2,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
.await
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for the token supply holder
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: supply_account_id_2,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
.await
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for receiving a token transaction
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: recipient_account_id_2,
|
||||
@ -2088,10 +2110,10 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
// Create new token
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: make_public_account_input_from_str(
|
||||
&definition_account_id.to_string(),
|
||||
&definition_account_id_1.to_string(),
|
||||
),
|
||||
supply_account_id: make_public_account_input_from_str(&supply_account_id.to_string()),
|
||||
name: "A NAME".to_string(),
|
||||
supply_account_id: make_public_account_input_from_str(&supply_account_id_1.to_string()),
|
||||
name: "A NAM1".to_string(),
|
||||
total_supply: 37,
|
||||
};
|
||||
wallet::cli::execute_subcommand(Command::Token(subcommand))
|
||||
@ -2100,11 +2122,9 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
|
||||
|
||||
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_1`
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: make_public_account_input_from_str(&supply_account_id.to_string()),
|
||||
from: make_public_account_input_from_str(&supply_account_id_1.to_string()),
|
||||
to: Some(make_public_account_input_from_str(
|
||||
&recipient_account_id_1.to_string(),
|
||||
)),
|
||||
@ -2119,9 +2139,26 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_2`
|
||||
// Create new token
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: make_public_account_input_from_str(
|
||||
&definition_account_id_2.to_string(),
|
||||
),
|
||||
supply_account_id: make_public_account_input_from_str(&supply_account_id_2.to_string()),
|
||||
name: "A NAM2".to_string(),
|
||||
total_supply: 37,
|
||||
};
|
||||
wallet::cli::execute_subcommand(Command::Token(subcommand))
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
|
||||
|
||||
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_1`
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: make_public_account_input_from_str(&supply_account_id.to_string()),
|
||||
from: make_public_account_input_from_str(&supply_account_id_2.to_string()),
|
||||
to: Some(make_public_account_input_from_str(
|
||||
&recipient_account_id_2.to_string(),
|
||||
)),
|
||||
@ -2141,50 +2178,6 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
// Create new AMM
|
||||
|
||||
// Setup accounts
|
||||
// Create new account for the amm pool
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: amm_pool,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
.await
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for the vault a
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: vault_holding_a,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
.await
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for the vault b
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: vault_holding_b,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
.await
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for the pool lp
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: pool_lp,
|
||||
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||
NewSubcommand::Public { cci: None },
|
||||
)))
|
||||
.await
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid subcommand return value");
|
||||
};
|
||||
// Create new account for the user holding lp
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: user_holding_lp,
|
||||
@ -2199,10 +2192,6 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
|
||||
// Send creation tx
|
||||
let subcommand = AmmProgramAgnosticSubcommand::New {
|
||||
amm_pool: make_public_account_input_from_str(&amm_pool.to_string()),
|
||||
vault_holding_a: make_public_account_input_from_str(&vault_holding_a.to_string()),
|
||||
vault_holding_b: make_public_account_input_from_str(&vault_holding_b.to_string()),
|
||||
pool_lp: make_public_account_input_from_str(&pool_lp.to_string()),
|
||||
user_holding_a: make_public_account_input_from_str(&recipient_account_id_1.to_string()),
|
||||
user_holding_b: make_public_account_input_from_str(&recipient_account_id_2.to_string()),
|
||||
user_holding_lp: make_public_account_input_from_str(&user_holding_lp.to_string()),
|
||||
@ -2216,13 +2205,113 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let amm_pool_acc = seq_client
|
||||
.get_account(amm_pool.to_string())
|
||||
let user_holding_a_acc = seq_client
|
||||
.get_account(recipient_account_id_1.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
info!("AMM pool is {amm_pool_acc:#?}");
|
||||
let user_holding_b_acc = seq_client
|
||||
.get_account(recipient_account_id_2.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_lp_acc = seq_client
|
||||
.get_account(user_holding_lp.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
user_holding_a_acc.data.as_ref(),
|
||||
&[
|
||||
1, 216, 180, 23, 229, 146, 37, 77, 185, 234, 186, 245, 33, 228, 197, 251, 244, 10,
|
||||
137, 115, 157, 2, 246, 137, 52, 234, 64, 155, 199, 101, 15, 43, 83, 4, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_b_acc.data.as_ref(),
|
||||
&[
|
||||
1, 244, 191, 88, 67, 111, 12, 245, 25, 212, 169, 62, 209, 159, 73, 107, 101, 173,
|
||||
88, 13, 55, 71, 91, 113, 88, 208, 91, 136, 222, 139, 2, 97, 110, 4, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_lp_acc.data.as_ref(),
|
||||
&[
|
||||
1, 16, 61, 24, 200, 168, 141, 91, 149, 164, 35, 114, 25, 6, 40, 204, 181, 95, 39,
|
||||
59, 56, 56, 96, 222, 157, 226, 48, 111, 53, 30, 1, 41, 94, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
);
|
||||
|
||||
info!("=================== AMM DEFINITION FINISHED ===============");
|
||||
|
||||
// Make swap
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::Swap {
|
||||
user_holding_a: make_public_account_input_from_str(&recipient_account_id_1.to_string()),
|
||||
user_holding_b: make_public_account_input_from_str(&recipient_account_id_2.to_string()),
|
||||
amount_in: 2,
|
||||
min_amount_out: 1,
|
||||
token_definition: definition_account_id_1.to_string(),
|
||||
};
|
||||
|
||||
wallet::cli::execute_subcommand(Command::AMM(subcommand))
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let user_holding_a_acc = seq_client
|
||||
.get_account(recipient_account_id_1.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_b_acc = seq_client
|
||||
.get_account(recipient_account_id_2.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_lp_acc = seq_client
|
||||
.get_account(user_holding_lp.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
user_holding_a_acc.data.as_ref(),
|
||||
&[
|
||||
1, 216, 180, 23, 229, 146, 37, 77, 185, 234, 186, 245, 33, 228, 197, 251, 244, 10,
|
||||
137, 115, 157, 2, 246, 137, 52, 234, 64, 155, 199, 101, 15, 43, 83, 2, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_b_acc.data.as_ref(),
|
||||
&[
|
||||
1, 244, 191, 88, 67, 111, 12, 245, 25, 212, 169, 62, 209, 159, 73, 107, 101, 173,
|
||||
88, 13, 55, 71, 91, 113, 88, 208, 91, 136, 222, 139, 2, 97, 110, 5, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_lp_acc.data.as_ref(),
|
||||
&[
|
||||
1, 16, 61, 24, 200, 168, 141, 91, 149, 164, 35, 114, 25, 6, 40, 204, 181, 95, 39,
|
||||
59, 56, 56, 96, 222, 157, 226, 48, 111, 53, 30, 1, 41, 94, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
);
|
||||
|
||||
info!("Success!");
|
||||
}
|
||||
|
||||
@ -124,7 +124,6 @@ pub struct ProgramOutput {
|
||||
pub fn read_nssa_inputs<T: DeserializeOwned>() -> (ProgramInput<T>, InstructionData) {
|
||||
let pre_states: Vec<AccountWithMetadata> = env::read();
|
||||
let instruction_words: InstructionData = env::read();
|
||||
println!("INSTRUCTION WORKDS IS {instruction_words:?}");
|
||||
let instruction = T::deserialize(&mut Deserializer::new(instruction_words.as_ref())).unwrap();
|
||||
(
|
||||
ProgramInput {
|
||||
|
||||
@ -23,6 +23,7 @@ impl Message {
|
||||
instruction: T,
|
||||
) -> Result<Self, NssaError> {
|
||||
let instruction_data = Program::serialize_instruction(instruction)?;
|
||||
|
||||
Ok(Self {
|
||||
program_id,
|
||||
account_ids,
|
||||
|
||||
@ -99,6 +99,7 @@ impl V02State {
|
||||
|
||||
this.insert_program(Program::authenticated_transfer_program());
|
||||
this.insert_program(Program::token());
|
||||
this.insert_program(Program::amm());
|
||||
|
||||
this
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ sha2.workspace = true
|
||||
futures.workspace = true
|
||||
async-stream = "0.3.6"
|
||||
indicatif = { version = "0.18.3", features = ["improved_unicode"] }
|
||||
risc0-zkvm = { version = "3.0.3", features = ['std'] }
|
||||
|
||||
[dependencies.key_protocol]
|
||||
path = "../key_protocol"
|
||||
|
||||
@ -15,18 +15,6 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
///
|
||||
/// user_holding_a and user_holding_b must be owned.
|
||||
New {
|
||||
/// amm_pool - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
amm_pool: String,
|
||||
/// vault_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_a: String,
|
||||
/// vault_holding_b - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_b: String,
|
||||
/// pool_lp - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
pool_lp: String,
|
||||
/// user_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
@ -45,15 +33,6 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
///
|
||||
/// The account associated with swapping token must be owned
|
||||
Swap {
|
||||
/// amm_pool - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
amm_pool: String,
|
||||
/// vault_holding_1 - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_1: String,
|
||||
/// vault_holding_2 - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_2: String,
|
||||
/// user_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
@ -141,28 +120,12 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
) -> Result<SubcommandReturnValue> {
|
||||
match self {
|
||||
AmmProgramAgnosticSubcommand::New {
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_a,
|
||||
balance_b,
|
||||
} => {
|
||||
let amm_pool = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&amm_pool)?,
|
||||
)?;
|
||||
let vault_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_a)?,
|
||||
)?;
|
||||
let vault_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_b)?,
|
||||
)?;
|
||||
let pool_lp = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&pool_lp)?,
|
||||
)?;
|
||||
let user_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?,
|
||||
)?;
|
||||
@ -173,25 +136,13 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?,
|
||||
)?;
|
||||
|
||||
let is_public_tx = [
|
||||
&amm_pool,
|
||||
&vault_holding_a,
|
||||
&vault_holding_b,
|
||||
&pool_lp,
|
||||
&user_holding_a,
|
||||
&user_holding_b,
|
||||
&user_holding_lp,
|
||||
]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
let is_public_tx = [&user_holding_a, &user_holding_b, &user_holding_lp]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
|
||||
if is_public_tx {
|
||||
AMM(wallet_core)
|
||||
.send_new_amm_definition(
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
@ -203,10 +154,6 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
} else {
|
||||
AMM(wallet_core)
|
||||
.send_new_amm_definition_privacy_preserving(
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
@ -219,24 +166,12 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
}
|
||||
}
|
||||
AmmProgramAgnosticSubcommand::Swap {
|
||||
amm_pool,
|
||||
vault_holding_1,
|
||||
vault_holding_2,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
amount_in,
|
||||
min_amount_out,
|
||||
token_definition,
|
||||
} => {
|
||||
let amm_pool = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&amm_pool)?,
|
||||
)?;
|
||||
let vault_holding_1 = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_1)?,
|
||||
)?;
|
||||
let vault_holding_2 = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_2)?,
|
||||
)?;
|
||||
let user_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?,
|
||||
)?;
|
||||
@ -244,22 +179,13 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?,
|
||||
)?;
|
||||
|
||||
let is_public_tx = [
|
||||
&amm_pool,
|
||||
&vault_holding_1,
|
||||
&vault_holding_2,
|
||||
&user_holding_a,
|
||||
&user_holding_b,
|
||||
]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
let is_public_tx = [&user_holding_a, &user_holding_b]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
|
||||
if is_public_tx {
|
||||
AMM(wallet_core)
|
||||
.send_swap(
|
||||
amm_pool,
|
||||
vault_holding_1,
|
||||
vault_holding_2,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
amount_in,
|
||||
@ -271,9 +197,6 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
} else {
|
||||
AMM(wallet_core)
|
||||
.send_swap_privacy_preserving(
|
||||
amm_pool,
|
||||
vault_holding_1,
|
||||
vault_holding_2,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
amount_in,
|
||||
|
||||
@ -1,9 +1,103 @@
|
||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||
use nssa::{AccountId, program::Program};
|
||||
use nssa_core::{SharedSecretKey, program::InstructionData};
|
||||
use nssa::{AccountId, ProgramId, program::Program};
|
||||
use nssa_core::{SharedSecretKey, program::PdaSeed};
|
||||
use serde::{Serialize, ser::SerializeSeq};
|
||||
|
||||
use crate::{PrivacyPreservingAccount, WalletCore, cli::account::TokenHolding};
|
||||
|
||||
fn compute_pool_pda(
|
||||
amm_program_id: ProgramId,
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
) -> AccountId {
|
||||
AccountId::from((
|
||||
&amm_program_id,
|
||||
&compute_pool_pda_seed(definition_token_a_id, definition_token_b_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn compute_pool_pda_seed(
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut i: usize = 0;
|
||||
let (token_1, token_2) = loop {
|
||||
if definition_token_a_id.value()[i] > definition_token_b_id.value()[i] {
|
||||
let token_1 = definition_token_a_id;
|
||||
let token_2 = definition_token_b_id;
|
||||
break (token_1, token_2);
|
||||
} else if definition_token_a_id.value()[i] < definition_token_b_id.value()[i] {
|
||||
let token_1 = definition_token_b_id;
|
||||
let token_2 = definition_token_a_id;
|
||||
break (token_1, token_2);
|
||||
}
|
||||
|
||||
if i == 32 {
|
||||
panic!("Definitions match");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&token_1.to_bytes());
|
||||
bytes[32..].copy_from_slice(&token_2.to_bytes());
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_vault_pda(
|
||||
amm_program_id: ProgramId,
|
||||
pool_id: AccountId,
|
||||
definition_token_id: AccountId,
|
||||
) -> AccountId {
|
||||
AccountId::from((
|
||||
&amm_program_id,
|
||||
&compute_vault_pda_seed(pool_id, definition_token_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn compute_vault_pda_seed(pool_id: AccountId, definition_token_id: AccountId) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
||||
bytes[32..].copy_from_slice(&definition_token_id.to_bytes());
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_liquidity_token_pda(amm_program_id: ProgramId, pool_id: AccountId) -> AccountId {
|
||||
AccountId::from((&amm_program_id, &compute_liquidity_token_pda_seed(pool_id)))
|
||||
}
|
||||
|
||||
fn compute_liquidity_token_pda_seed(pool_id: AccountId) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
||||
bytes[32..].copy_from_slice(&[0; 32]);
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
struct OrphanHack65BytesInput([u32; 65]);
|
||||
|
||||
impl OrphanHack65BytesInput {
|
||||
@ -16,10 +110,19 @@ impl OrphanHack65BytesInput {
|
||||
|
||||
Self(res)
|
||||
}
|
||||
}
|
||||
|
||||
fn words(&self) -> Vec<u32> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
impl Serialize for OrphanHack65BytesInput {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(65))?;
|
||||
for word in self.0 {
|
||||
seq.serialize_element(&word)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
struct OrphanHack49BytesInput([u32; 49]);
|
||||
@ -37,7 +140,20 @@ impl OrphanHack49BytesInput {
|
||||
|
||||
fn words(&self) -> Vec<u32> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for OrphanHack49BytesInput {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(49))?;
|
||||
for word in self.0 {
|
||||
seq.serialize_element(&word)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AMM<'w>(pub &'w WalletCore);
|
||||
@ -46,10 +162,6 @@ impl AMM<'_> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_new_amm_definition(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_a: PrivacyPreservingAccount,
|
||||
vault_holding_b: PrivacyPreservingAccount,
|
||||
pool_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_lp: PrivacyPreservingAccount,
|
||||
@ -58,24 +170,36 @@ impl AMM<'_> {
|
||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||
let (instruction, program) = amm_program_preparation_definition(balance_a, balance_b);
|
||||
|
||||
match (
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
) {
|
||||
match (user_holding_a, user_holding_b, user_holding_lp) {
|
||||
(
|
||||
PrivacyPreservingAccount::Public(amm_pool),
|
||||
PrivacyPreservingAccount::Public(vault_holding_a),
|
||||
PrivacyPreservingAccount::Public(vault_holding_b),
|
||||
PrivacyPreservingAccount::Public(pool_lp),
|
||||
PrivacyPreservingAccount::Public(user_holding_a),
|
||||
PrivacyPreservingAccount::Public(user_holding_b),
|
||||
PrivacyPreservingAccount::Public(user_holding_lp),
|
||||
) => {
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool);
|
||||
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
@ -136,25 +260,18 @@ impl AMM<'_> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_new_amm_definition_privacy_preserving(
|
||||
&self,
|
||||
_amm_pool: PrivacyPreservingAccount,
|
||||
_vault_holding_a: PrivacyPreservingAccount,
|
||||
_vault_holding_b: PrivacyPreservingAccount,
|
||||
_pool_lp: PrivacyPreservingAccount,
|
||||
_user_holding_a: PrivacyPreservingAccount,
|
||||
_user_holding_b: PrivacyPreservingAccount,
|
||||
_user_holding_lp: PrivacyPreservingAccount,
|
||||
_balance_a: u128,
|
||||
_balance_b: u128,
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 7]), ExecutionFailureKind> {
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 3]), ExecutionFailureKind> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_swap(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_1: PrivacyPreservingAccount,
|
||||
vault_holding_2: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
amount_in: u128,
|
||||
@ -164,24 +281,38 @@ impl AMM<'_> {
|
||||
let (instruction, program) =
|
||||
amm_program_preparation_swap(amount_in, min_amount_out, token_definition_id);
|
||||
|
||||
match (
|
||||
amm_pool,
|
||||
vault_holding_1,
|
||||
vault_holding_2,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
) {
|
||||
match (user_holding_a, user_holding_b) {
|
||||
(
|
||||
PrivacyPreservingAccount::Public(amm_pool),
|
||||
PrivacyPreservingAccount::Public(vault_holding_1),
|
||||
PrivacyPreservingAccount::Public(vault_holding_2),
|
||||
PrivacyPreservingAccount::Public(user_holding_a),
|
||||
PrivacyPreservingAccount::Public(user_holding_b),
|
||||
) => {
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_1,
|
||||
vault_holding_2,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
];
|
||||
@ -226,12 +357,13 @@ impl AMM<'_> {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let message = nssa::public_transaction::Message::new_preserialized(
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set =
|
||||
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||
@ -247,54 +379,52 @@ impl AMM<'_> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_swap_privacy_preserving(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_1: PrivacyPreservingAccount,
|
||||
vault_holding_2: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
amount_in: u128,
|
||||
min_amount_out: u128,
|
||||
token_definition_id: AccountId,
|
||||
_user_holding_a: PrivacyPreservingAccount,
|
||||
_user_holding_b: PrivacyPreservingAccount,
|
||||
_amount_in: u128,
|
||||
_min_amount_out: u128,
|
||||
_token_definition_id: AccountId,
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 5]), ExecutionFailureKind> {
|
||||
let (instruction_data, program) =
|
||||
amm_program_preparation_swap(amount_in, min_amount_out, token_definition_id);
|
||||
todo!()
|
||||
// let (instruction_data, program) =
|
||||
// amm_program_preparation_swap(amount_in, min_amount_out, token_definition_id);
|
||||
|
||||
self.0
|
||||
.send_privacy_preserving_tx(
|
||||
vec![
|
||||
amm_pool.clone(),
|
||||
vault_holding_1.clone(),
|
||||
vault_holding_2.clone(),
|
||||
user_holding_a.clone(),
|
||||
user_holding_b.clone(),
|
||||
],
|
||||
&instruction_data,
|
||||
&program,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
let mut secrets = secrets.into_iter();
|
||||
let mut secrets_res = [None; 5];
|
||||
// self.0
|
||||
// .send_privacy_preserving_tx(
|
||||
// vec![
|
||||
// amm_pool.clone(),
|
||||
// vault_holding_1.clone(),
|
||||
// vault_holding_2.clone(),
|
||||
// user_holding_a.clone(),
|
||||
// user_holding_b.clone(),
|
||||
// ],
|
||||
// &instruction_data.words(),
|
||||
// &program,
|
||||
// )
|
||||
// .await
|
||||
// .map(|(resp, secrets)| {
|
||||
// let mut secrets = secrets.into_iter();
|
||||
// let mut secrets_res = [None; 5];
|
||||
|
||||
for acc_id in [
|
||||
amm_pool,
|
||||
vault_holding_1,
|
||||
vault_holding_2,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if acc_id.1.is_private() {
|
||||
let secret = secrets.next().expect("expected next secret");
|
||||
// for acc_id in [
|
||||
// amm_pool,
|
||||
// vault_holding_1,
|
||||
// vault_holding_2,
|
||||
// user_holding_a,
|
||||
// user_holding_b,
|
||||
// ]
|
||||
// .iter()
|
||||
// .enumerate()
|
||||
// {
|
||||
// if acc_id.1.is_private() {
|
||||
// let secret = secrets.next().expect("expected next secret");
|
||||
|
||||
secrets_res[acc_id.0] = Some(secret);
|
||||
}
|
||||
}
|
||||
// secrets_res[acc_id.0] = Some(secret);
|
||||
// }
|
||||
// }
|
||||
|
||||
(resp, secrets_res)
|
||||
})
|
||||
// (resp, secrets_res)
|
||||
// })
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -417,7 +547,7 @@ impl AMM<'_> {
|
||||
user_holding_b.clone(),
|
||||
user_holding_lp.clone(),
|
||||
],
|
||||
&instruction_data,
|
||||
&instruction_data.words(),
|
||||
&program,
|
||||
)
|
||||
.await
|
||||
@ -568,7 +698,7 @@ impl AMM<'_> {
|
||||
user_holding_b.clone(),
|
||||
user_holding_lp.clone(),
|
||||
],
|
||||
&instruction_data,
|
||||
&instruction_data.words(),
|
||||
&program,
|
||||
)
|
||||
.await
|
||||
@ -604,11 +734,11 @@ impl AMM<'_> {
|
||||
fn amm_program_preparation_definition(
|
||||
balance_a: u128,
|
||||
balance_b: u128,
|
||||
) -> (InstructionData, Program) {
|
||||
) -> (OrphanHack65BytesInput, Program) {
|
||||
// An instruction data of 65-bytes, indicating the initial amm reserves' balances and
|
||||
// token_program_id with the following layout:
|
||||
// [0x00 || array of balances (little-endian 16 bytes) || TOKEN_PROGRAM_ID)]
|
||||
let amm_program_id = Program::token().id();
|
||||
// [0x00 || array of balances (little-endian 16 bytes) || AMM_PROGRAM_ID)]
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let mut instruction = [0; 65];
|
||||
instruction[1..17].copy_from_slice(&balance_a.to_le_bytes());
|
||||
@ -624,7 +754,7 @@ fn amm_program_preparation_definition(
|
||||
instruction[57..61].copy_from_slice(&amm_program_id[6].to_le_bytes());
|
||||
instruction[61..].copy_from_slice(&amm_program_id[7].to_le_bytes());
|
||||
|
||||
let instruction_data = OrphanHack65BytesInput::expand(instruction).words();
|
||||
let instruction_data = OrphanHack65BytesInput::expand(instruction);
|
||||
let program = Program::amm();
|
||||
|
||||
(instruction_data, program)
|
||||
@ -634,19 +764,19 @@ fn amm_program_preparation_swap(
|
||||
amount_in: u128,
|
||||
min_amount_out: u128,
|
||||
token_definition_id: AccountId,
|
||||
) -> (InstructionData, Program) {
|
||||
) -> (OrphanHack65BytesInput, Program) {
|
||||
// An instruction data byte string of length 65, indicating which token type to swap, quantity
|
||||
// of tokens put into the swap (of type TOKEN_DEFINITION_ID) and min_amount_out.
|
||||
// [0x01 || amount (little-endian 16 bytes) || TOKEN_DEFINITION_ID].
|
||||
let mut instruction = [0; 65];
|
||||
instruction[0] = 0x01;
|
||||
instruction[1..17].copy_from_slice(&amount_in.to_le_bytes());
|
||||
instruction[17..33].copy_from_slice(&min_amount_out.to_le_bytes());
|
||||
|
||||
// This can be done less verbose, but it is better to use same way, as in amm program
|
||||
instruction[33..].copy_from_slice(&token_definition_id.to_bytes());
|
||||
|
||||
let instruction_data =
|
||||
OrphanHack65BytesInput::expand(instruction).words();
|
||||
let instruction_data = OrphanHack65BytesInput::expand(instruction);
|
||||
let program = Program::amm();
|
||||
|
||||
(instruction_data, program)
|
||||
@ -656,7 +786,7 @@ fn amm_program_preparation_add_liq(
|
||||
min_amount_lp: u128,
|
||||
max_amount_a: u128,
|
||||
max_amount_b: u128,
|
||||
) -> (InstructionData, Program) {
|
||||
) -> (OrphanHack49BytesInput, Program) {
|
||||
// An instruction data byte string of length 49, amounts for minimum amount of liquidity from
|
||||
// add (min_amount_lp), max amount added for each token (max_amount_a and max_amount_b);
|
||||
// indicate [0x02 || array of of balances (little-endian 16 bytes)].
|
||||
@ -667,7 +797,7 @@ fn amm_program_preparation_add_liq(
|
||||
instruction[17..33].copy_from_slice(&max_amount_a.to_le_bytes());
|
||||
instruction[33..49].copy_from_slice(&max_amount_b.to_le_bytes());
|
||||
|
||||
let instruction_data = OrphanHack49BytesInput::expand(instruction).words();
|
||||
let instruction_data = OrphanHack49BytesInput::expand(instruction);
|
||||
let program = Program::amm();
|
||||
|
||||
(instruction_data, program)
|
||||
@ -677,7 +807,7 @@ fn amm_program_preparation_remove_liq(
|
||||
balance_lp: u128,
|
||||
max_amount_a: u128,
|
||||
max_amount_b: u128,
|
||||
) -> (InstructionData, Program) {
|
||||
) -> (OrphanHack49BytesInput, Program) {
|
||||
// An instruction data byte string of length 49, amounts for minimum amount of liquidity to
|
||||
// redeem (balance_lp), minimum balance of each token to remove (min_amount_a and
|
||||
// min_amount_b); indicate [0x03 || array of balances (little-endian 16 bytes)].
|
||||
@ -688,7 +818,7 @@ fn amm_program_preparation_remove_liq(
|
||||
instruction[17..33].copy_from_slice(&max_amount_a.to_le_bytes());
|
||||
instruction[33..49].copy_from_slice(&max_amount_b.to_le_bytes());
|
||||
|
||||
let instruction_data = OrphanHack49BytesInput::expand(instruction).words();
|
||||
let instruction_data = OrphanHack49BytesInput::expand(instruction);
|
||||
let program = Program::amm();
|
||||
|
||||
(instruction_data, program)
|
||||
@ -698,20 +828,19 @@ fn amm_program_preparation_remove_liq(
|
||||
mod tests {
|
||||
use crate::program_facades::amm::OrphanHack65BytesInput;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_correct_ser() {
|
||||
let mut arr = [0u8; 65];
|
||||
|
||||
for i in 0..64 {
|
||||
arr[i] = i as u8;
|
||||
for (i, item) in arr.iter_mut().enumerate().take(64) {
|
||||
*item = i as u8;
|
||||
}
|
||||
|
||||
let hack = OrphanHack65BytesInput::expand(arr);
|
||||
let instruction_data = hack.words();
|
||||
let instruction_data = serde_json::to_string(&hack).unwrap();
|
||||
|
||||
println!("{instruction_data:?}");
|
||||
|
||||
//assert_eq!(serialization_res_1, serialization_res_2);
|
||||
// assert_eq!(serialization_res_1, serialization_res_2);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user