From e7494cfd4183fee575efd6d416d8b9578eb5a2a1 Mon Sep 17 00:00:00 2001 From: samlogy1 Date: Mon, 29 Jun 2026 19:48:32 +0100 Subject: [PATCH] #444 [SC-040] Allbridge: prevent double processing via transaction hashes --- .../contracts/allbridge_receiver/src/lib.rs | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/contracts/contracts/allbridge_receiver/src/lib.rs b/contracts/contracts/allbridge_receiver/src/lib.rs index 3c45aef..1d3d06b 100644 --- a/contracts/contracts/allbridge_receiver/src/lib.rs +++ b/contracts/contracts/allbridge_receiver/src/lib.rs @@ -1,11 +1,19 @@ #![no_std] #![allow(dead_code, unused_variables, unused_imports, unexpected_cfgs)] -use soroban_sdk::{contract, contractimpl, symbol_short, token, Address, BytesN, Env, Symbol}; +use soroban_sdk::{ + contract, contractimpl, symbol_short, token, Address, BytesN, Env, Symbol, +}; const ADMIN_KEY: Symbol = symbol_short!("admin"); const RELAYER_KEY: Symbol = symbol_short!("relayer"); const BRIDGE_TOK_KEY: Symbol = symbol_short!("brdg_tok"); +#[contracttype] +#[derive(Clone)] +pub enum DataKey { + Processed(BytesN<32>), +} + #[contract] pub struct AllbridgeReceiverContract; @@ -52,12 +60,29 @@ impl AllbridgeReceiverContract { ) { bridge_authority.require_auth(); Self::require_relayer(&env, &bridge_authority); - panic!("unimplemented: receive_deposit"); + + assert!( + !Self::is_tx_processed(env.clone(), source_tx_hash.clone()), + "source tx already processed" + ); + + let key = DataKey::Processed(source_tx_hash); + env.storage().persistent().set(&key, &true); + + let contract_addr = env.current_contract_address(); + let token_client = token::Client::new(&env, &token); + token_client.transfer(&contract_addr, &recipient, &amount); + + env.events().publish( + (Symbol::new(&env, "DepositReceived"),), + (recipient, token, amount, source_chain_id), + ); } /// Query bridging status/state pub fn is_tx_processed(env: Env, source_tx_hash: BytesN<32>) -> bool { - panic!("unimplemented: is_tx_processed"); + let key = DataKey::Processed(source_tx_hash); + env.storage().persistent().get(&key).unwrap_or(false) } /// SC-042: Sweep any unsupported token accidentally sent to this receiver