Skip to content
Open
Changes from all 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
122 changes: 39 additions & 83 deletions solana/bridge-escrow/programs/bridge-escrow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const BRIDGE_CONTRACT_PUBKEY: &str =
"2HLLVco5HvwWriNbUhmVwA2pCetRkpgrqwnjcsZdyTKT";

const AUCTIONEER_SEED: &[u8] = b"auctioneer";
const FEE_VAULT_SEED: &[u8] = b"fee_vault";
const INTENT_SEED: &[u8] = b"intent";
const DUMMY_SEED: &[u8] = b"dummy";

Expand All @@ -26,6 +25,27 @@ mod tests;

declare_id!("AhfoGVmS19tvkEG2hBuZJ1D6qYEjyFmXZ1qPoFD6H4Mj");

pub fn check_solana_ibc_caller(ix_sysvar: &AccountInfo) -> Result<()> {
let caller_program_id =
solana_program::sysvar::instructions::get_instruction_relative(
0, ix_sysvar,
)?
.program_id;
check_staking_program(&caller_program_id)
}

pub fn check_solana_ibc_program(
program_id: &Pubkey
) -> Result<()> {
let expected_program_ids = [
Pubkey::from_str(BRIDGE_CONTRACT_PUBKEY).unwrap(),
];
match expected_program_ids.contains(program_id) {
false => Err(ErrorCode::InvalidCPICall.into()),
true => Ok(()),
}
}

#[program]
pub mod bridge_escrow {
// use anchor_client::solana_sdk::signer::Signer;
Expand Down Expand Up @@ -73,17 +93,8 @@ pub mod bridge_escrow {
ErrorCode::SrcUserNotUserIn
);


// Calculate the amount_in and fee_amount
let mut amount_in = new_intent.amount_in;
if new_intent.single_domain {
amount_in -= new_intent.amount_in / 1000; // 0.1% deduction
} else {
amount_in -= (new_intent.amount_in * 29) / 10000; // 0.29% deduction
}
let fee_amount = new_intent.amount_in - amount_in;
// Step 2: Escrow the funds (same as before)

// Step 2: Escrow the funds (same as before) : `amount_in`
let cpi_accounts = SplTransfer {
from: ctx.accounts.user_token_account.to_account_info(),
to: ctx.accounts.escrow_token_account.to_account_info(),
Expand All @@ -93,19 +104,7 @@ pub mod bridge_escrow {
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);

token::transfer(cpi_ctx, amount_in)?;

// Step 2.5: Store token fees (fee_amount) in the fee vault
token::transfer(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
SplTransfer {
from: ctx.accounts.user_token_account.to_account_info(),
to: ctx.accounts.fee_token_account.to_account_info(),
authority: ctx.accounts.user.to_account_info(),
}
), fee_amount
)?;
token::transfer(cpi_ctx, new_intent.amount_in)?;

events::emit(events::Event::EscrowFunds(events::EscrowFunds {
amount: new_intent.amount_in,
Expand All @@ -126,6 +125,13 @@ pub mod bridge_escrow {
ErrorCode::InvalidTimeout
);

let mut amount_in = new_intent.amount_in;
if new_intent.single_domain {
amount_in -= new_intent.amount_in / 1000; // 0.1% deduction
} else {
amount_in -= (new_intent.amount_in * 29) / 10000; // 0.29% deduction
}


intent.intent_id = new_intent.intent_id.clone();
intent.user_in = new_intent.user_in.key();
Expand Down Expand Up @@ -217,6 +223,8 @@ pub mod bridge_escrow {
intent_id: String,
memo: String,
) -> Result<()> {
check_staking_caller(&ctx.accounts.instruction)?;

// Split and extract memo fields
let parts: Vec<&str> = memo.split(',').collect();
require!(parts.len() == 5, ErrorCode::InvalidMemoFormat); // Ensure memo has 5 parts
Expand Down Expand Up @@ -596,30 +604,6 @@ pub mod bridge_escrow {

Ok(())
}

pub fn collect_fees(ctx: Context<CollectFees>) -> Result<()> {
// Create CPI accounts for the transfer
let cpi_accounts: SplTransfer<'_> = SplTransfer {
from: ctx.accounts.fee_token_account.to_account_info(),
to: ctx.accounts.auctioneer_token_account.to_account_info(),
authority: ctx.accounts.auctioneer_state.to_account_info(),
};

// Derive signer seeds for the PDA
let bump = ctx.bumps.auctioneer_state;
let seeds = &[AUCTIONEER_SEED, core::slice::from_ref(&bump)];
let seeds = seeds.as_ref();
let signer_seeds = core::slice::from_ref(&seeds);

// Create CPI context with the signer seeds
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer_seeds);

// Perform the token transfer
token::transfer(cpi_ctx, ctx.accounts.fee_token_account.amount)?;

Ok(())
}
}

// Define the Auctioneer account
Expand Down Expand Up @@ -686,6 +670,9 @@ pub struct Initialize<'info> {
#[derive(Accounts)]
#[instruction(intent_id: String, memo: String)]
pub struct ReceiveTransferContext<'info> {
#[account(address = Pubkey::from_str(BRIDGE_CONTRACT_PUBKEY).unwrap())]
/// CHECK:
pub ibc_program: Option<UncheckedAccount<'info>>,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need of this.

#[account(seeds = [AUCTIONEER_SEED], bump)]
pub auctioneer_state: Account<'info, Auctioneer>,

Expand Down Expand Up @@ -902,9 +889,6 @@ pub struct EscrowAndStoreIntent<'info> {
// 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>>,

#[account(init_if_needed, payer = user, seeds = [FEE_VAULT_SEED, token_mint.key().as_ref()], bump, token::mint = token_mint, token::authority = auctioneer_state)]
pub fee_token_account: Box<Account<'info, TokenAccount>>,

// From StoreIntent
// Box the intent account, as it's a new account with considerable space allocated
Expand Down Expand Up @@ -1003,36 +987,6 @@ pub struct OnTimeoutCrossChain<'info> {
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct CollectFees<'info> {
#[account(mut, signer)]
pub auctioneer: Signer<'info>, // The auctioneer must sign the transaction and act as the payer

#[account(
seeds = [AUCTIONEER_SEED],
bump,
constraint = auctioneer_state.authority == *auctioneer.key
)]
pub auctioneer_state: Account<'info, Auctioneer>, // PDA managing the escrow account

#[account(mut, seeds = [FEE_VAULT_SEED, token_mint.key().as_ref()], bump, token::mint = token_mint, token::authority = auctioneer_state)]
pub fee_token_account: Box<Account<'info, TokenAccount>>,

#[account(
init_if_needed,
payer = auctioneer, // Ensure payer is mutable
associated_token::mint = token_mint,
associated_token::authority = auctioneer
)]
pub auctioneer_token_account: Account<'info, TokenAccount>, // Auctioneer's USDC token account

pub token_mint: Account<'info, Mint>, // USDC token mint

pub token_program: Program<'info, Token>, // SPL Token program
pub associated_token_program: Program<'info, AssociatedToken>, // Associated Token program
pub system_program: Program<'info, System>, // System program for creating accounts
}

// Define custom errors
#[error_code]
pub enum ErrorCode {
Expand Down Expand Up @@ -1101,5 +1055,7 @@ pub enum ErrorCode {
#[msg("fee_collector != accounts.fee_collector.as_ref().unwrap().key")]
InvalidFeeCollector,
#[msg("User in (signer) is not intent.user_in")]
UserInNotIntentUserIn
}
UserInNotIntentUserIn,
#[msg("Invalid cpi call")]
InvalidCPICall
}
Loading