Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions bridge-escrow-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
rm -fr ./test-ledger

solana-test-validator > /dev/null 2>&1 &
VALIDATOR_PID=$!

echo "Solana test validator started in the background with PID $VALIDATOR_PID."

sleep 5

echo "Running Debug and Deployment"

# Default behavior
SKIP_DEPLOY=false

# Parse command-line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--skip-deploy) SKIP_DEPLOY=true ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done


solana config set --url http://127.0.0.1:8899

if [ "$SKIP_DEPLOY" = false ]; then
anchor build -p bridge_escrow
solana program deploy target/deploy/bridge_escrow.so --program-id target/deploy/bridge_escrow-keypair.json
else
echo "Skipping Deployment"
fi

cargo test -p bridge-escrow -- --nocapture

echo "Stopping solana-test-validator..."
kill $VALIDATOR_PID

wait $VALIDATOR_PID
echo "Solana test validator has been stopped."
151 changes: 106 additions & 45 deletions solana/bridge-escrow/programs/bridge-escrow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub mod events;
#[cfg(test)]
mod tests;

declare_id!("AhfoGVmS19tvkEG2hBuZJ1D6qYEjyFmXZ1qPoFD6H4Mj");
declare_id!("H3jfQXtiC3DW4bwMafKiiW2xhYjwZDkV21SMaYqEtMM8");

#[program]
pub mod bridge_escrow {
Expand Down Expand Up @@ -63,32 +63,57 @@ pub mod bridge_escrow {
);

require!(
new_intent.token_in == ctx.accounts.user_token_account.mint,
new_intent.token_in == System::id() || new_intent.token_in == ctx.accounts.user_token_account.clone().unwrap().mint,
ErrorCode::TokenInNotMint
);

require!(
new_intent.user_in == ctx.accounts.user_token_account.owner,
new_intent.user_in == ctx.accounts.user_token_account.clone().unwrap().owner,
ErrorCode::SrcUserNotUserIn
);

// Step 2: Escrow the funds (same as before)
// Handle Native SOL Transfer
if new_intent.token_in == System::id() {
// Perform SOL transfer from Solver to User
let src_user = ctx.accounts.user.clone();

let ix = solana_program::system_instruction::transfer(
src_user.key,
&ctx.accounts.auctioneer_state.key(),
new_intent.amount_in,
);

let cpi_accounts = SplTransfer {
from: ctx.accounts.user_token_account.to_account_info(),
to: ctx.accounts.escrow_token_account.to_account_info(),
authority: ctx.accounts.user.to_account_info(),
};

let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);

token::transfer(cpi_ctx, new_intent.amount_in)?;
invoke(
&ix,
&[
src_user.to_account_info(),
ctx.accounts.auctioneer_state.to_account_info(),
ctx.accounts.system_program.to_account_info(),
],
)?;

// **src_user.lamports.borrow_mut() -= new_intent.amount_in;
// **ctx.accounts.auctioneer_state.to_account_info().lamports.borrow_mut() += new_intent.amount_in;

} else {

let cpi_accounts = SplTransfer {
from: ctx.accounts.user_token_account.clone().unwrap().to_account_info(),
to: ctx.accounts.escrow_token_account.clone().unwrap().to_account_info(),
authority: ctx.accounts.user.to_account_info(),
};

let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);

token::transfer(cpi_ctx, new_intent.amount_in)?;
}

events::emit(events::Event::EscrowFunds(events::EscrowFunds {
amount: new_intent.amount_in,
sender: ctx.accounts.user.key(),
token_mint: ctx.accounts.token_mint.key(),
token_mint: ctx.accounts.token_mint.clone().unwrap().key(),
})).map_err(|err| {
msg!("{}", err);
ErrorCode::InvalidEventFormat
Expand Down Expand Up @@ -318,20 +343,28 @@ 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();

let ix = solana_program::system_instruction::transfer(
solver.key,
&intent.user_in,
out_user_account.key,
amount_out,
);

invoke(
&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(),
],
)?;


// **solver.lamports.borrow_mut() -= amount_out;
// **out_user_account.lamports.borrow_mut() += amount_out;

} else {
// Perform SPL transfer from Solver to User
let cpi_accounts = SplTransfer {
Expand Down Expand Up @@ -368,26 +401,47 @@ pub mod bridge_escrow {
.as_ref()
.ok_or(ErrorCode::AccountsNotPresent)?;

require!(
intent.token_in == auctioneer_token_in_account.mint,
ErrorCode::MismatchTokenIn
);

let cpi_accounts = SplTransfer {
from: auctioneer_token_in_account.to_account_info(),
to: solver_token_in_account.to_account_info(),
authority: accounts.auctioneer_state.to_account_info(),
};
let cpi_program = token_program.to_account_info();
if intent.token_in == System::id() {

let solver = accounts.solver.clone();

let ix = solana_program::system_instruction::transfer(
&accounts.auctioneer_state.key(),
solver.key,
amount_out,
);

token::transfer(
CpiContext::new_with_signer(
cpi_program,
cpi_accounts,
signer_seeds,
),
intent.amount_in,
)?;
invoke(
&ix,
&[
accounts.auctioneer_state.to_account_info(),
solver.to_account_info(),
accounts.system_program.to_account_info(),
],
)?;

} else {
require!(
intent.token_in == auctioneer_token_in_account.mint,
ErrorCode::MismatchTokenIn
);

let cpi_accounts = SplTransfer {
from: auctioneer_token_in_account.to_account_info(),
to: solver_token_in_account.to_account_info(),
authority: accounts.auctioneer_state.to_account_info(),
};
let cpi_program = token_program.to_account_info();

token::transfer(
CpiContext::new_with_signer(
cpi_program,
cpi_accounts,
signer_seeds,
),
intent.amount_in,
)?;
}

events::emit(events::Event::SendFundsToUser(
events::SendFundsToUser {
Expand Down Expand Up @@ -430,20 +484,27 @@ pub mod bridge_escrow {
// Check if token_out is native SOL or SPL token
if accounts.token_out.key() == System::id() {
// Handle Native SOL Transfer
let out_user_account = accounts.receiver.clone().unwrap();

let solver = accounts.solver.clone();
let out_user_account = accounts.receiver.clone().unwrap();

let ix = solana_program::system_instruction::transfer(
solver.key,
&accounts.user_token_out_account.key(),
out_user_account.key,
amount_out,
);

invoke(
&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(),
],
)?;


} else {
// Perform SPL token transfer from Solver to User
let cpi_accounts = SplTransfer {
Expand Down Expand Up @@ -712,7 +773,7 @@ pub struct SplTokenTransferCrossChain<'info> {
pub solver_token_out_account: Box<Account<'info, TokenAccount>>,
#[account(mut, token::mint = token_out)]
pub user_token_out_account: Box<Account<'info, TokenAccount>>,

pub token_program: Program<'info, Token>,
pub associated_token_program: Program<'info, AssociatedToken>,
pub system_program: Program<'info, System>,
Expand All @@ -723,7 +784,7 @@ pub struct SplTokenTransferCrossChain<'info> {
#[account(address = Pubkey::from_str(BRIDGE_CONTRACT_PUBKEY).unwrap())]
/// CHECK:
pub ibc_program: Option<UncheckedAccount<'info>>,
#[account(mut)]
#[account(mut, address = user_token_out_account.owner)]
/// CHECK:
pub receiver: Option<AccountInfo<'info>>,
/// CHECK: validated by solana-ibc program
Expand Down Expand Up @@ -767,7 +828,7 @@ pub struct SplTokenTransfer<'info> {
#[account(mut, address = intent.clone().unwrap().user_in)]
/// CHECK:
pub intent_owner: UncheckedAccount<'info>,
#[account(seeds = [AUCTIONEER_SEED], bump)]
#[account(mut, seeds = [AUCTIONEER_SEED], bump)]
pub auctioneer_state: Box<Account<'info, Auctioneer>>,
#[account(mut)]
pub solver: Signer<'info>,
Expand Down Expand Up @@ -801,7 +862,7 @@ pub struct SplTokenTransfer<'info> {
#[account(address = Pubkey::from_str(BRIDGE_CONTRACT_PUBKEY).unwrap())]
/// CHECK:
pub ibc_program: Option<UncheckedAccount<'info>>,
#[account(mut)]
#[account(mut, address = user_token_out_account.owner)]
/// CHECK:
pub receiver: Option<AccountInfo<'info>>,
/// CHECK: validated by solana-ibc program
Expand Down Expand Up @@ -844,18 +905,18 @@ pub struct EscrowAndStoreIntent<'info> {

// Box this account to avoid copying large account data
#[account(mut, token::authority = user, token::mint = token_mint)]
pub user_token_account: Box<Account<'info, TokenAccount>>,
pub user_token_account: Option<Box<Account<'info, TokenAccount>>>,

// Box this account as it holds state that might be large
#[account(seeds = [AUCTIONEER_SEED], bump)]
#[account(mut, seeds = [AUCTIONEER_SEED], bump)]
pub auctioneer_state: Box<Account<'info, Auctioneer>>,

// Box the token mint account if it's large or for performance reasons
pub token_mint: Box<Account<'info, Mint>>,
pub token_mint: Option<Box<Account<'info, Mint>>>,

// Box the escrow token account as it's mutable and holds token data
#[account(init_if_needed, payer = user, associated_token::mint = token_mint, associated_token::authority = auctioneer_state)]
pub escrow_token_account: Box<Account<'info, TokenAccount>>,
pub escrow_token_account: Option<Box<Account<'info, TokenAccount>>>,

// From StoreIntent
// Box the intent account, as it's a new account with considerable space allocated
Expand Down
Loading