diff --git a/packages/escrow-swap/src/contract.rs b/packages/escrow-swap/src/contract.rs index 836055d..2b2d71d 100644 --- a/packages/escrow-swap/src/contract.rs +++ b/packages/escrow-swap/src/contract.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{token::Client as TokenClient, Address, BytesN, Env, Vec}; +use soroban_sdk::{token::Client as TokenClient, Address, BytesN, Env, Map, Vec}; use crate::types::*; use common::pause; @@ -12,7 +12,7 @@ pub fn init(env: &Env, admin: &Address) -> Result<(), EscrowError> { } env.storage().instance().set(&DataKey::Admin, admin); env.storage().instance().set(&DataKey::NextSwapId, &0u64); - env.storage().persistent().set(&DataKey::SwapRequests, &Vec::::new(env)); + env.storage().persistent().set(&DataKey::SwapRequests, &Map::::new(env)); Ok(()) } @@ -84,8 +84,8 @@ pub fn create_swap( created_at: now, }; - let mut swaps: Vec = env.storage().persistent().get(&DataKey::SwapRequests).unwrap_or_else(|| Vec::new(env)); - swaps.push_back(swap); + let mut swaps: Map = env.storage().persistent().get(&DataKey::SwapRequests).unwrap_or_else(|| Map::new(env)); + swaps.set(next_id, swap); env.storage().persistent().set(&DataKey::SwapRequests, &swaps); env.storage().instance().set(&DataKey::NextSwapId, &next_id.checked_add(1).ok_or(EscrowError::InvalidAmount)?); @@ -133,43 +133,32 @@ pub fn accept_swap(env: &Env, id: u64, responder: &Address, secret: BytesN<32>) let _guard = common::reentrancy::ReentrancyGuard::new(env).map_err(|_| EscrowError::NotInitialized)?; responder.require_auth(); - let mut swaps: Vec = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; - let mut found = false; - - for i in 0..swaps.len() { - let mut s = swaps.get(i).ok_or(EscrowError::VecAccessError)?; - if s.id == id { - if s.status != STATUS_PENDING { - return Err(EscrowError::SwapNotActive); - } - if s.responder != *responder { - return Err(EscrowError::Unauthorized); - } - let secret_bytes = soroban_sdk::Bytes::from_array(env, &secret.to_array()); - let computed_hash: BytesN<32> = env.crypto().sha256(&secret_bytes).into(); - if computed_hash != s.hash_lock { - return Err(EscrowError::HashLockMismatch); - } - let now = env.ledger().timestamp(); - if now >= s.time_lock { - return Err(EscrowError::TimeLockExpired); - } + let mut swaps: Map = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; + let mut s = swaps.get(id).ok_or(EscrowError::SwapNotFound)?; + if s.status != STATUS_PENDING { + return Err(EscrowError::SwapNotActive); + } + if s.responder != *responder { + return Err(EscrowError::Unauthorized); + } + let secret_bytes = soroban_sdk::Bytes::from_array(env, &secret.to_array()); + let computed_hash: BytesN<32> = env.crypto().sha256(&secret_bytes).into(); + if computed_hash != s.hash_lock { + return Err(EscrowError::HashLockMismatch); + } + let now = env.ledger().timestamp(); + if now >= s.time_lock { + return Err(EscrowError::TimeLockExpired); + } - s.status = STATUS_ACTIVE; - swaps.set(i, s.clone()); - found = true; + s.status = STATUS_ACTIVE; + swaps.set(id, s.clone()); - let token_b_client = TokenClient::new(env, &s.token_b); - token_b_client.transfer(responder, &env.current_contract_address(), &s.responder_amount); + let token_b_client = TokenClient::new(env, &s.token_b); + token_b_client.transfer(responder, &env.current_contract_address(), &s.responder_amount); - SwapAccepted { id, responder: responder.clone() }.publish(env); - break; - } - } + SwapAccepted { id, responder: responder.clone() }.publish(env); - if !found { - return Err(EscrowError::SwapNotFound); - } env.storage().persistent().set(&DataKey::SwapRequests, &swaps); Ok(()) } @@ -179,36 +168,25 @@ pub fn complete_swap(env: &Env, id: u64, caller: &Address) -> Result<(), EscrowE let _guard = common::reentrancy::ReentrancyGuard::new(env).map_err(|_| EscrowError::NotInitialized)?; caller.require_auth(); - let mut swaps: Vec = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; - let mut found = false; - - for i in 0..swaps.len() { - let mut s = swaps.get(i).ok_or(EscrowError::VecAccessError)?; - if s.id == id { - if s.status != STATUS_ACTIVE { - return Err(EscrowError::SwapNotActive); - } - if *caller != s.initiator && *caller != s.responder { - return Err(EscrowError::Unauthorized); - } - s.status = STATUS_COMPLETED; - swaps.set(i, s.clone()); - found = true; + let mut swaps: Map = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; + let mut s = swaps.get(id).ok_or(EscrowError::SwapNotFound)?; + if s.status != STATUS_ACTIVE { + return Err(EscrowError::SwapNotActive); + } + if *caller != s.initiator && *caller != s.responder { + return Err(EscrowError::Unauthorized); + } + s.status = STATUS_COMPLETED; + swaps.set(id, s.clone()); - let token_a_client = TokenClient::new(env, &s.token_a); - token_a_client.transfer(&env.current_contract_address(), &s.responder, &s.initiator_amount); + let token_a_client = TokenClient::new(env, &s.token_a); + token_a_client.transfer(&env.current_contract_address(), &s.responder, &s.initiator_amount); - let token_b_client = TokenClient::new(env, &s.token_b); - token_b_client.transfer(&env.current_contract_address(), &s.initiator, &s.responder_amount); + let token_b_client = TokenClient::new(env, &s.token_b); + token_b_client.transfer(&env.current_contract_address(), &s.initiator, &s.responder_amount); - SwapCompleted { id, initiator: s.initiator.clone(), responder: s.responder.clone() }.publish(env); - break; - } - } + SwapCompleted { id, initiator: s.initiator.clone(), responder: s.responder.clone() }.publish(env); - if !found { - return Err(EscrowError::SwapNotFound); - } env.storage().persistent().set(&DataKey::SwapRequests, &swaps); Ok(()) } @@ -218,58 +196,41 @@ pub fn cancel_swap(env: &Env, id: u64, caller: &Address) -> Result<(), EscrowErr let _guard = common::reentrancy::ReentrancyGuard::new(env).map_err(|_| EscrowError::NotInitialized)?; caller.require_auth(); - let mut swaps: Vec = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; - let mut found = false; - - for i in 0..swaps.len() { - let mut s = swaps.get(i).ok_or(EscrowError::VecAccessError)?; - if s.id == id { - if s.status == STATUS_COMPLETED || s.status == STATUS_CANCELLED { - return Err(EscrowError::SwapNotActive); - } - if *caller != s.initiator && *caller != s.responder { - return Err(EscrowError::Unauthorized); - } - - let previous_status = s.status; - s.status = STATUS_CANCELLED; - swaps.set(i, s.clone()); - found = true; - - let token_a_client = TokenClient::new(env, &s.token_a); - token_a_client.transfer(&env.current_contract_address(), &s.initiator, &s.initiator_amount); + let mut swaps: Map = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; + let mut s = swaps.get(id).ok_or(EscrowError::SwapNotFound)?; + if s.status == STATUS_COMPLETED || s.status == STATUS_CANCELLED { + return Err(EscrowError::SwapNotActive); + } + if *caller != s.initiator && *caller != s.responder { + return Err(EscrowError::Unauthorized); + } + + let previous_status = s.status; + s.status = STATUS_CANCELLED; + swaps.set(id, s.clone()); - if previous_status == STATUS_ACTIVE { - let token_b_client = TokenClient::new(env, &s.token_b); - token_b_client.transfer(&env.current_contract_address(), &s.responder, &s.responder_amount); - } + let token_a_client = TokenClient::new(env, &s.token_a); + token_a_client.transfer(&env.current_contract_address(), &s.initiator, &s.initiator_amount); - SwapCancelled { id }.publish(env); - break; - } + if previous_status == STATUS_ACTIVE { + let token_b_client = TokenClient::new(env, &s.token_b); + token_b_client.transfer(&env.current_contract_address(), &s.responder, &s.responder_amount); } - if !found { - return Err(EscrowError::SwapNotFound); - } + SwapCancelled { id }.publish(env); + env.storage().persistent().set(&DataKey::SwapRequests, &swaps); Ok(()) } pub fn get_swap(env: &Env, id: u64) -> Result { - let swaps: Vec = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; - for i in 0..swaps.len() { - if let Some(s) = swaps.get(i) { - if s.id == id { - return Ok(s); - } - } - } - Err(EscrowError::SwapNotFound) + let swaps: Map = env.storage().persistent().get(&DataKey::SwapRequests).ok_or(EscrowError::NotInitialized)?; + swaps.get(id).ok_or(EscrowError::SwapNotFound) } pub fn get_swaps(env: &Env) -> Vec { - env.storage().persistent().get(&DataKey::SwapRequests).unwrap_or_else(|| Vec::new(env)) + let swaps: Map = env.storage().persistent().get(&DataKey::SwapRequests).unwrap_or_else(|| Map::new(env)); + swaps.values() } pub fn pause(env: &Env, admin: &Address) -> Result<(), EscrowError> { diff --git a/packages/governance-token/src/contract.rs b/packages/governance-token/src/contract.rs index 8cf032f..9ba0709 100644 --- a/packages/governance-token/src/contract.rs +++ b/packages/governance-token/src/contract.rs @@ -16,7 +16,7 @@ pub fn initialize( decimals: u32, ) -> Result<(), TokenError> { if env.storage().instance().has(&ADMIN_KEY) { - return Err(TokenError::NotInitialized); + return Err(TokenError::AlreadyInitialized); } env.storage().instance().set(&ADMIN_KEY, admin); env.storage().instance().set(&META_KEY, &TokenMetadata { diff --git a/packages/governance-token/src/test.rs b/packages/governance-token/src/test.rs index 0c6316f..efe5b6b 100644 --- a/packages/governance-token/src/test.rs +++ b/packages/governance-token/src/test.rs @@ -49,7 +49,7 @@ mod tests { &String::from_str(&env, "TK2"), &7u32, ); - assert!(result.is_err()); + assert_eq!(result, Err(Ok(crate::types::TokenError::AlreadyInitialized))); } #[test] diff --git a/packages/governance-token/src/types.rs b/packages/governance-token/src/types.rs index 9596c5b..44338df 100644 --- a/packages/governance-token/src/types.rs +++ b/packages/governance-token/src/types.rs @@ -30,6 +30,7 @@ pub enum TokenError { ContractPaused = 10, Underflow = 11, Frozen = 12, + AlreadyInitialized = 13, } #[contractevent] diff --git a/packages/treasury/src/contract.rs b/packages/treasury/src/contract.rs index 36f3909..2cd80ce 100644 --- a/packages/treasury/src/contract.rs +++ b/packages/treasury/src/contract.rs @@ -176,6 +176,10 @@ pub fn rescue_tokens( return Err(TreasuryError::InvalidAmount); } + if !env.has_contract(token) { + return Err(TreasuryError::InvalidAmount); + } + let treasury_token: Address = env .storage() .instance()