@@ -10,9 +10,16 @@ use scale_info::prelude::vec::Vec;
1010#[ ink:: contract]
1111mod bridge {
1212 use super :: * ;
13+ use propchain_contracts:: { non_reentrant, ReentrancyError , ReentrancyGuard } ;
1314
1415 include ! ( "errors.rs" ) ;
1516
17+ impl From < ReentrancyError > for Error {
18+ fn from ( _: ReentrancyError ) -> Self {
19+ Error :: ReentrantCall
20+ }
21+ }
22+
1623 /// Bridge contract for cross-chain property token transfers
1724 #[ ink( storage) ]
1825 pub struct PropertyBridge {
@@ -66,6 +73,9 @@ mod bridge {
6673
6774 /// Chain last reset day for rate limiting
6875 chain_last_reset_day : Mapping < ChainId , u64 > ,
76+
77+ /// Reentrancy protection
78+ reentrancy_guard : ReentrancyGuard ,
6979 }
7080
7181 /// Events for bridge operations
@@ -163,6 +173,7 @@ mod bridge {
163173 account_last_reset_day : Mapping :: default ( ) ,
164174 chain_daily_volume : Mapping :: default ( ) ,
165175 chain_last_reset_day : Mapping :: default ( ) ,
176+ reentrancy_guard : ReentrancyGuard :: new ( ) ,
166177 } ;
167178
168179 // Set up default chain information
@@ -351,66 +362,68 @@ mod bridge {
351362 /// Executes a bridge request after collecting required signatures
352363 #[ ink( message) ]
353364 pub fn execute_bridge ( & mut self , request_id : u64 ) -> Result < ( ) , Error > {
354- let caller = self . env ( ) . caller ( ) ;
365+ non_reentrant ! ( self , {
366+ let caller = self . env( ) . caller( ) ;
355367
356- // Check if caller is a bridge operator
357- if !self . bridge_operators . contains ( & caller) {
358- return Err ( Error :: Unauthorized ) ;
359- }
360-
361- let mut request = self
362- . bridge_requests
363- . get ( request_id)
364- . ok_or ( Error :: InvalidRequest ) ?;
368+ // Check if caller is a bridge operator
369+ if !self . bridge_operators. contains( & caller) {
370+ return Err ( Error :: Unauthorized ) ;
371+ }
365372
366- // Check if request is ready for execution
367- if request . status != BridgeOperationStatus :: Locked {
368- return Err ( Error :: InvalidRequest ) ;
369- }
373+ let mut request = self
374+ . bridge_requests
375+ . get ( request_id )
376+ . ok_or ( Error :: InvalidRequest ) ? ;
370377
371- // Check if enough signatures are collected
372- if request . signatures . len ( ) < request. required_signatures as usize {
373- return Err ( Error :: InsufficientSignatures ) ;
374- }
378+ // Check if request is ready for execution
379+ if request. status != BridgeOperationStatus :: Locked {
380+ return Err ( Error :: InvalidRequest ) ;
381+ }
375382
376- // Generate transaction hash
377- let transaction_hash = self . generate_transaction_hash ( & request) ;
383+ // Check if enough signatures are collected
384+ if request. signatures. len( ) < request. required_signatures as usize {
385+ return Err ( Error :: InsufficientSignatures ) ;
386+ }
378387
379- // Create bridge transaction record
380- self . transaction_counter += 1 ;
381- let transaction = BridgeTransaction {
382- transaction_id : self . transaction_counter ,
383- token_id : request. token_id ,
384- source_chain : request. source_chain ,
385- destination_chain : request. destination_chain ,
386- sender : request. sender ,
387- recipient : request. recipient ,
388- transaction_hash,
389- timestamp : self . env ( ) . block_timestamp ( ) ,
390- gas_used : self . estimate_gas_usage ( & request) ,
391- status : BridgeOperationStatus :: InTransit ,
392- metadata : request. metadata . clone ( ) ,
393- } ;
388+ // Generate transaction hash
389+ let transaction_hash = self . generate_transaction_hash( & request) ;
390+
391+ // Create bridge transaction record
392+ self . transaction_counter += 1 ;
393+ let transaction = BridgeTransaction {
394+ transaction_id: self . transaction_counter,
395+ token_id: request. token_id,
396+ source_chain: request. source_chain,
397+ destination_chain: request. destination_chain,
398+ sender: request. sender,
399+ recipient: request. recipient,
400+ transaction_hash,
401+ timestamp: self . env( ) . block_timestamp( ) ,
402+ gas_used: self . estimate_gas_usage( & request) ,
403+ status: BridgeOperationStatus :: InTransit ,
404+ metadata: request. metadata. clone( ) ,
405+ } ;
394406
395- // Update request status
396- request. status = BridgeOperationStatus :: Completed ;
397- self . bridge_requests . insert ( request_id, & request) ;
407+ // Update request status
408+ request. status = BridgeOperationStatus :: Completed ;
409+ self . bridge_requests. insert( request_id, & request) ;
398410
399- // Store transaction verification
400- self . verified_transactions . insert ( transaction_hash, & true ) ;
411+ // Store transaction verification
412+ self . verified_transactions. insert( transaction_hash, & true ) ;
401413
402- // Add to bridge history
403- let mut history = self . bridge_history . get ( request. sender ) . unwrap_or_default ( ) ;
404- history. push ( transaction. clone ( ) ) ;
405- self . bridge_history . insert ( request. sender , & history) ;
414+ // Add to bridge history
415+ let mut history = self . bridge_history. get( request. sender) . unwrap_or_default( ) ;
416+ history. push( transaction. clone( ) ) ;
417+ self . bridge_history. insert( request. sender, & history) ;
406418
407- self . env ( ) . emit_event ( BridgeExecuted {
408- request_id,
409- token_id : request. token_id ,
410- transaction_hash,
411- } ) ;
419+ self . env( ) . emit_event( BridgeExecuted {
420+ request_id,
421+ token_id: request. token_id,
422+ transaction_hash,
423+ } ) ;
412424
413- Ok ( ( ) )
425+ Ok ( ( ) )
426+ } )
414427 }
415428
416429 /// Recovers from a failed bridge operation
@@ -420,54 +433,56 @@ mod bridge {
420433 request_id : u64 ,
421434 recovery_action : RecoveryAction ,
422435 ) -> Result < ( ) , Error > {
423- let caller = self . env ( ) . caller ( ) ;
424-
425- // Only admin can recover failed bridges
426- if caller != self . admin {
427- return Err ( Error :: Unauthorized ) ;
428- }
429-
430- let mut request = self
431- . bridge_requests
432- . get ( request_id)
433- . ok_or ( Error :: InvalidRequest ) ?;
436+ non_reentrant ! ( self , {
437+ let caller = self . env( ) . caller( ) ;
434438
435- // Check if request is in a failed state
436- if !matches ! (
437- request. status,
438- BridgeOperationStatus :: Failed | BridgeOperationStatus :: Expired
439- ) {
440- return Err ( Error :: InvalidRequest ) ;
441- }
442-
443- // Execute recovery action
444- match recovery_action {
445- RecoveryAction :: UnlockToken => {
446- // Logic to unlock the token would be implemented here
447- // This would typically call back to the property token contract
448- }
449- RecoveryAction :: RefundGas => {
450- // Logic to refund gas costs would be implemented here
439+ // Only admin can recover failed bridges
440+ if caller != self . admin {
441+ return Err ( Error :: Unauthorized ) ;
451442 }
452- RecoveryAction :: RetryBridge => {
453- // Reset request to pending for retry
454- request. status = BridgeOperationStatus :: Pending ;
455- request. signatures . clear ( ) ;
443+
444+ let mut request = self
445+ . bridge_requests
446+ . get( request_id)
447+ . ok_or( Error :: InvalidRequest ) ?;
448+
449+ // Check if request is in a failed state
450+ if !matches!(
451+ request. status,
452+ BridgeOperationStatus :: Failed | BridgeOperationStatus :: Expired
453+ ) {
454+ return Err ( Error :: InvalidRequest ) ;
456455 }
457- RecoveryAction :: CancelBridge => {
458- // Mark as cancelled
459- request. status = BridgeOperationStatus :: Failed ;
456+
457+ // Execute recovery action
458+ match recovery_action {
459+ RecoveryAction :: UnlockToken => {
460+ // Logic to unlock the token would be implemented here
461+ // This would typically call back to the property token contract
462+ }
463+ RecoveryAction :: RefundGas => {
464+ // Logic to refund gas costs would be implemented here
465+ }
466+ RecoveryAction :: RetryBridge => {
467+ // Reset request to pending for retry
468+ request. status = BridgeOperationStatus :: Pending ;
469+ request. signatures. clear( ) ;
470+ }
471+ RecoveryAction :: CancelBridge => {
472+ // Mark as cancelled
473+ request. status = BridgeOperationStatus :: Failed ;
474+ }
460475 }
461- }
462476
463- self . bridge_requests . insert ( request_id, & request) ;
477+ self . bridge_requests. insert( request_id, & request) ;
464478
465- self . env ( ) . emit_event ( BridgeRecovered {
466- request_id,
467- recovery_action,
468- } ) ;
479+ self . env( ) . emit_event( BridgeRecovered {
480+ request_id,
481+ recovery_action,
482+ } ) ;
469483
470- Ok ( ( ) )
484+ Ok ( ( ) )
485+ } )
471486 }
472487
473488 /// Gets gas estimation for a bridge operation
0 commit comments