From a118535bbf31671331a4eed9d807d32938955dfb Mon Sep 17 00:00:00 2001 From: composable-kvn Date: Thu, 19 Dec 2024 23:14:45 +0100 Subject: [PATCH] fix: native sol out in sendFundsToUser --- Cargo.lock | 1 + Cargo.toml | 2 +- .../programs/bridge-escrow/Cargo.toml | 1 + .../programs/bridge-escrow/src/lib.rs | 13 +++- .../programs/bridge-escrow/src/tests.rs | 62 ++++++++++--------- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 282676f4..0b96d5e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1027,6 +1027,7 @@ dependencies = [ "anchor-spl", "anyhow", "base64 0.21.7", + "bs58 0.5.1", "bytemuck", "cf-guest", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index 4995027c..7c26eb1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ ascii = "1.1.0" base64 = { version = "0.21", default-features = false, features = ["alloc"] } blake3 = { version = "1.3.3", default-features = false } borsh = { version = "0.10.3", default-features = false } -bs58 = { version = "0.5.0", default-features = false } +bs58 = { version = "0.5.0", features = ["alloc"] } bytemuck = { version = "1.14", default-features = false } chrono = { version = "0.4", default-features = false } clap = { version = "4.4.18", features = ["derive"] } diff --git a/solana/bridge-escrow/programs/bridge-escrow/Cargo.toml b/solana/bridge-escrow/programs/bridge-escrow/Cargo.toml index a61403b7..d5b9e7c3 100644 --- a/solana/bridge-escrow/programs/bridge-escrow/Cargo.toml +++ b/solana/bridge-escrow/programs/bridge-escrow/Cargo.toml @@ -53,6 +53,7 @@ trie-ids = { workspace = true, features = ["borsh"] } wasm = { workspace = true } itertools = "0.10.5" solana-ibc = { workspace = true, features = ["cpi"] } +bs58.workspace = true [dev-dependencies] anchor-client.workspace = true diff --git a/solana/bridge-escrow/programs/bridge-escrow/src/lib.rs b/solana/bridge-escrow/programs/bridge-escrow/src/lib.rs index 2d0ea892..76dc2023 100644 --- a/solana/bridge-escrow/programs/bridge-escrow/src/lib.rs +++ b/solana/bridge-escrow/programs/bridge-escrow/src/lib.rs @@ -313,9 +313,16 @@ pub mod bridge_escrow { // Handle Native SOL Transfer if intent.token_out == System::id().to_string() { // Perform SOL transfer from Solver to User + + let solver = accounts.solver.clone(); + let out_user_account = accounts.receiver.clone().unwrap(); + + // check `receiver` address if it is same as `intent.user_out` + require!(intent.user_out == out_user_account.key.to_string(), ErrorCode::InvalidSolOut); + let ix = solana_program::system_instruction::transfer( solver.key, - &intent.user_in, + out_user_account.key, amount_out, ); @@ -323,7 +330,7 @@ pub mod bridge_escrow { &ix, &[ solver.to_account_info(), - accounts.user_token_out_account.to_account_info(), + out_user_account.to_account_info(), accounts.system_program.to_account_info(), ], )?; @@ -1007,6 +1014,8 @@ pub enum ErrorCode { InvalidMemoFormat, #[msg("Invalid token out")] InvalidTokenOut, + #[msg("Invalid Sol Receiver")] + InvalidSolOut, #[msg("Auctioneer cannot update an amountOut less than current amountOut")] InvalidAmountOut, #[msg("new_intent.token_in != ctx.accounts.user_token_account.mint")] diff --git a/solana/bridge-escrow/programs/bridge-escrow/src/tests.rs b/solana/bridge-escrow/programs/bridge-escrow/src/tests.rs index 8ec37bc9..4d694afe 100644 --- a/solana/bridge-escrow/programs/bridge-escrow/src/tests.rs +++ b/solana/bridge-escrow/programs/bridge-escrow/src/tests.rs @@ -18,6 +18,7 @@ use anchor_spl::associated_token::{self, get_associated_token_address}; use anyhow::Result; use spl_token::instruction::initialize_mint2; use spl_token::solana_program::system_instruction::create_account; +use bs58; use crate::IntentPayload; @@ -58,14 +59,24 @@ fn simulate_tx(client: RpcClient, transaction: Transaction) { } #[test] -//#[ignore = "Requires local validator to run"] +// test on devnet fn test_native_mint_transfer() -> Result<()> { // Setup the client and wallet - let auctioneer = - Rc::new(read_keypair_file("../../../solana-ibc/keypair.json").unwrap()); + + let private_key_bytes = bs58::decode("").into_vec()?; + let auctioneer = Rc::new(Keypair::from_bytes(&private_key_bytes)?); + + let private_key_bytes = bs58::decode("").into_vec()?; + let solver = Rc::new(Keypair::from_bytes(&private_key_bytes)?); + + let private_key_bytes = bs58::decode("").into_vec()?; + let user = Rc::new(Keypair::from_bytes(&private_key_bytes)?); + + // let auctioneer = + // Rc::new(read_keypair_file("../../../solana-ibc/keypair.json").unwrap()); let client = Client::new_with_options( - Cluster::from_str("http://127.0.0.1:8899").unwrap(),//Cluster::Localnet, + Cluster::from_str("https://late-bitter-panorama.solana-devnet.quiknode.pro/702f2ed5c8c7efeee31dd889a5653d0ec218ceb9/").unwrap(),//Cluster::Localnet, auctioneer.clone(), CommitmentConfig::processed(), ); @@ -73,10 +84,9 @@ fn test_native_mint_transfer() -> Result<()> { let program = client.program(crate::ID)?; let sol_rpc_client = program.rpc(); - let lamports = 20_000_000_000; - - let solver = Rc::new(Keypair::new()); - let user = Rc::new(Keypair::new()); + // let lamports = 20_000_000_000; + // let solver = Rc::new(Keypair::new()); + // let user = Rc::new(Keypair::new()); let token_in_keypair = Keypair::new(); let token_in = token_in_keypair.pubkey(); let token_out_keypair = Keypair::new(); @@ -89,9 +99,9 @@ fn test_native_mint_transfer() -> Result<()> { println!("User {:?}", user.to_bytes()); println!("Solver {:?}", solver.to_bytes()); - airdrop(&program_rpc, auctioneer.pubkey(), lamports); - airdrop(&program_rpc, user.pubkey(), lamports); - airdrop(&program_rpc, solver.pubkey(), lamports); + // airdrop(&program_rpc, auctioneer.pubkey(), lamports); + // airdrop(&program_rpc, user.pubkey(), lamports); + // airdrop(&program_rpc, solver.pubkey(), lamports); let auctioneer_state = Pubkey::find_program_address(&[crate::AUCTIONEER_SEED], &crate::ID).0; @@ -208,8 +218,7 @@ fn test_native_mint_transfer() -> Result<()> { // Initialize the program to define the auctioneer println!("\nInitializing the program"); - if !program_rpc.get_account(&auctioneer_state).is_ok() { - let sig = program + let sig = program .request() .accounts(crate::accounts::Initialize { authority: auctioneer.pubkey(), @@ -226,12 +235,11 @@ fn test_native_mint_transfer() -> Result<()> { skip_preflight: true, ..Default::default() }) + // .signed_transaction() .unwrap(); - println!("Signature: {}", sig); - } else { - println!("Program already initialized. Skipping Initialization ..."); - } + println!("Signature: {}", sig); + let token_in_escrow_addr = @@ -260,7 +268,7 @@ fn test_native_mint_transfer() -> Result<()> { intent_id: intent_id.clone(), user_in: user.pubkey(), // Must match the ctx.accounts.user key in the contract user_out: user.pubkey().to_string(), - token_in: Pubkey::default(), // token_in, + token_in: token_in, amount_in: TRANSFER_AMOUNT, token_out: Pubkey::default().to_string(),// token_out.to_string(), amount_out: amount_out.to_string(), // Amount out as a string @@ -273,10 +281,10 @@ fn test_native_mint_transfer() -> Result<()> { .request() .accounts(crate::accounts::EscrowAndStoreIntent { user: user.pubkey(), - user_token_account: Some(user_token_in_addr), + user_token_account: user_token_in_addr, auctioneer_state, - token_mint: Some(token_in), - escrow_token_account: Some(token_in_escrow_addr), + token_mint: token_in, + escrow_token_account: token_in_escrow_addr, intent: intent_state, token_program: anchor_spl::token::ID, associated_token_program: associated_token::ID, @@ -347,13 +355,12 @@ fn test_native_mint_transfer() -> Result<()> { solver_token_in_account: Some(solver_token_in_addr), solver_token_out_account: solver_token_out_addr, user_token_out_account: user_token_out_addr, - user_account: Some(user.pubkey()), token_program: anchor_spl::token::ID, associated_token_program: anchor_spl::associated_token::ID, system_program: anchor_lang::solana_program::system_program::ID, // Cross-chain related fields, set to None since it's single domain ibc_program: None, - receiver: None, + receiver: Some(user.pubkey()), storage: None, trie: None, chain: None, @@ -615,10 +622,10 @@ fn escrow_bridge_program() -> Result<()> { .request() .accounts(crate::accounts::EscrowAndStoreIntent { user: user.pubkey(), - user_token_account: Some(user_token_in_addr), + user_token_account: user_token_in_addr, auctioneer_state, - token_mint: Some(token_in), - escrow_token_account: Some(token_in_escrow_addr), + token_mint: token_in, + escrow_token_account: token_in_escrow_addr, intent: intent_state, token_program: anchor_spl::token::ID, associated_token_program: associated_token::ID, @@ -689,13 +696,12 @@ fn escrow_bridge_program() -> Result<()> { solver_token_in_account: Some(solver_token_in_addr), solver_token_out_account: solver_token_out_addr, user_token_out_account: user_token_out_addr, - user_account: Some(user.pubkey()), token_program: anchor_spl::token::ID, associated_token_program: anchor_spl::associated_token::ID, system_program: anchor_lang::solana_program::system_program::ID, // Cross-chain related fields, set to None since it's single domain ibc_program: None, - receiver: None, + receiver: Some(user.pubkey()), storage: None, trie: None, chain: None,