@@ -5,6 +5,7 @@ use crate::events::{
55} ;
66use crate :: storage:: { ESCROWS , ESCROW_COUNT } ;
77use crate :: types:: { DisputeOutcome , Escrow , EscrowApprovalKey , EscrowStatus } ;
8+ use crate :: validation:: EscrowValidator ;
89use soroban_sdk:: { symbol_short, vec, Address , Bytes , Env , IntoVal , Map , Vec } ;
910
1011pub struct EscrowManager ;
@@ -24,32 +25,18 @@ impl EscrowManager {
2425 ) -> Result < u64 , EscrowError > {
2526 depositor. require_auth ( ) ;
2627
27- if amount <= 0 {
28- return Err ( EscrowError :: AmountMustBePositive ) ;
29- }
30-
31- if signers. len ( ) == 0 {
32- return Err ( EscrowError :: AtLeastOneSignerRequired ) ;
33- }
34-
35- if threshold == 0 || threshold > signers. len ( ) as u32 {
36- return Err ( EscrowError :: InvalidSignerThreshold ) ;
37- }
38-
39- let now = env. ledger ( ) . timestamp ( ) ;
40- if let Some ( refund_time) = refund_time {
41- if refund_time < now {
42- return Err ( EscrowError :: RefundTimeMustBeInFuture ) ;
43- }
44- }
45-
46- if let ( Some ( release) , Some ( refund) ) = ( release_time, refund_time) {
47- if refund < release {
48- return Err ( EscrowError :: RefundTimeMustBeAfterReleaseTime ) ;
49- }
50- }
51-
52- Self :: ensure_unique_signers ( env, & signers) ?;
28+ EscrowValidator :: validate_create_escrow (
29+ env,
30+ & depositor,
31+ & beneficiary,
32+ & token,
33+ amount,
34+ & signers,
35+ threshold,
36+ release_time,
37+ refund_time,
38+ & arbitrator,
39+ ) ?;
5340
5441 env. invoke_contract :: < ( ) > (
5542 & token,
@@ -62,10 +49,11 @@ impl EscrowManager {
6249 ] ,
6350 ) ;
6451
65- let mut escrow_count: u64 = env. storage ( ) . instance ( ) . get ( & ESCROW_COUNT ) . unwrap_or ( 0u64 ) ;
52+ let mut escrow_count: u64 = env. storage ( ) . instance ( ) . get ( & ESCROW_COUNT ) . unwrap_or ( 0 ) ;
6653 escrow_count += 1 ;
6754 env. storage ( ) . instance ( ) . set ( & ESCROW_COUNT , & escrow_count) ;
6855
56+ let now = env. ledger ( ) . timestamp ( ) ;
6957 let escrow = Escrow {
7058 id : escrow_count,
7159 depositor,
@@ -106,6 +94,7 @@ impl EscrowManager {
10694 escrow_id,
10795 signer : signer. clone ( ) ,
10896 } ;
97+
10998 if env. storage ( ) . persistent ( ) . has ( & approval_key) {
11099 return Err ( EscrowError :: SignerAlreadyApproved ) ;
111100 }
@@ -129,24 +118,11 @@ impl EscrowManager {
129118 caller. require_auth ( ) ;
130119
131120 let mut escrow = Self :: load_escrow ( env, escrow_id) ?;
132- Self :: ensure_pending ( & escrow) ?;
133121
134- if !Self :: is_release_caller ( & escrow, & caller) {
135- return Err ( EscrowError :: CallerNotAuthorized ) ;
136- }
137-
138- if escrow. approval_count < escrow. threshold {
139- return Err ( EscrowError :: InsufficientApprovals ) ;
140- }
141-
142- if let Some ( release_time) = escrow. release_time {
143- let now = env. ledger ( ) . timestamp ( ) ;
144- if now < release_time {
145- return Err ( EscrowError :: ReleaseTimeNotReached ) ;
146- }
147- }
122+ EscrowValidator :: validate_release_conditions ( & escrow, & caller, env. ledger ( ) . timestamp ( ) ) ?;
148123
149124 Self :: transfer_from_contract ( env, & escrow. token , & escrow. beneficiary , escrow. amount ) ;
125+
150126 escrow. status = EscrowStatus :: Released ;
151127 Self :: save_escrow ( env, escrow_id, escrow. clone ( ) ) ;
152128
@@ -173,11 +149,13 @@ impl EscrowManager {
173149 let refund_time = escrow. refund_time . ok_or ( EscrowError :: RefundNotEnabled ) ?;
174150
175151 let now = env. ledger ( ) . timestamp ( ) ;
152+
176153 if now < refund_time {
177154 return Err ( EscrowError :: RefundTimeNotReached ) ;
178155 }
179156
180157 Self :: transfer_from_contract ( env, & escrow. token , & escrow. depositor , escrow. amount ) ;
158+
181159 escrow. status = EscrowStatus :: Refunded ;
182160 Self :: save_escrow ( env, escrow_id, escrow. clone ( ) ) ;
183161
@@ -206,6 +184,7 @@ impl EscrowManager {
206184 }
207185
208186 Self :: transfer_from_contract ( env, & escrow. token , & escrow. depositor , escrow. amount ) ;
187+
209188 escrow. status = EscrowStatus :: Cancelled ;
210189 Self :: save_escrow ( env, escrow_id, escrow. clone ( ) ) ;
211190
@@ -250,6 +229,7 @@ impl EscrowManager {
250229 arbitrator. require_auth ( ) ;
251230
252231 let mut escrow = Self :: load_escrow ( env, escrow_id) ?;
232+
253233 if escrow. status != EscrowStatus :: Disputed {
254234 return Err ( EscrowError :: EscrowNotInDispute ) ;
255235 }
@@ -287,47 +267,32 @@ impl EscrowManager {
287267 Ok ( ( ) )
288268 }
289269
270+ // ---------- Views ----------
271+
290272 pub fn get_escrow ( env : & Env , escrow_id : u64 ) -> Option < Escrow > {
291- let escrows = Self :: load_escrows ( env) ;
292- escrows. get ( escrow_id)
273+ Self :: load_escrows ( env) . get ( escrow_id)
293274 }
294275
295276 pub fn get_escrow_count ( env : & Env ) -> u64 {
296- env. storage ( ) . instance ( ) . get ( & ESCROW_COUNT ) . unwrap_or ( 0u64 )
277+ env. storage ( ) . instance ( ) . get ( & ESCROW_COUNT ) . unwrap_or ( 0 )
297278 }
298279
299280 pub fn has_approved ( env : & Env , escrow_id : u64 , signer : Address ) -> bool {
300- let approval_key = EscrowApprovalKey { escrow_id, signer } ;
301- env. storage ( ) . persistent ( ) . has ( & approval_key )
281+ let key = EscrowApprovalKey { escrow_id, signer } ;
282+ env. storage ( ) . persistent ( ) . has ( & key )
302283 }
303284
304- fn ensure_unique_signers ( env : & Env , signers : & Vec < Address > ) -> Result < ( ) , EscrowError > {
305- let mut seen: Map < Address , bool > = Map :: new ( env) ;
306- for signer in signers. iter ( ) {
307- if seen. get ( signer. clone ( ) ) . unwrap_or ( false ) {
308- return Err ( EscrowError :: DuplicateSigner ) ;
309- }
310- seen. set ( signer. clone ( ) , true ) ;
311- }
312- Ok ( ( ) )
313- }
285+ // ---------- Internal Helpers ----------
314286
315287 fn is_signer ( signers : & Vec < Address > , signer : & Address ) -> bool {
316- for candidate in signers. iter ( ) {
317- if candidate == * signer {
288+ for s in signers. iter ( ) {
289+ if s == * signer {
318290 return true ;
319291 }
320292 }
321293 false
322294 }
323295
324- fn is_release_caller ( escrow : & Escrow , caller : & Address ) -> bool {
325- if * caller == escrow. depositor || * caller == escrow. beneficiary {
326- return true ;
327- }
328- Self :: is_signer ( & escrow. signers , caller)
329- }
330-
331296 fn ensure_pending ( escrow : & Escrow ) -> Result < ( ) , EscrowError > {
332297 if escrow. status != EscrowStatus :: Pending {
333298 return Err ( EscrowError :: EscrowNotPending ) ;
0 commit comments