@@ -745,17 +745,6 @@ impl Batcher {
745745 return Ok ( ( ) ) ;
746746 } ;
747747
748- if !self . verify_user_has_enough_balance ( user_balance, user_accumulated_fee, msg_max_fee) {
749- std:: mem:: drop ( batch_state_lock) ;
750- send_message (
751- ws_conn_sink. clone ( ) ,
752- SubmitProofResponseMessage :: InsufficientBalance ( addr) ,
753- )
754- . await ;
755- self . metrics . user_error ( & [ "insufficient_balance" , "" ] ) ;
756- return Ok ( ( ) ) ;
757- }
758-
759748 let cached_user_nonce = batch_state_lock. get_user_nonce ( & addr) . await ;
760749 let Some ( expected_nonce) = cached_user_nonce else {
761750 error ! ( "Failed to get cached user nonce: User not found in user states, but it should have been already inserted" ) ;
@@ -791,12 +780,26 @@ impl Batcher {
791780 ws_conn_sink. clone ( ) ,
792781 client_msg. signature ,
793782 addr,
783+ user_balance,
784+ user_accumulated_fee,
785+ msg_max_fee
794786 )
795787 . await ;
796788
797789 return Ok ( ( ) ) ;
798790 }
799791
792+ if !self . verify_user_has_enough_balance ( user_balance, user_accumulated_fee, msg_max_fee) {
793+ std:: mem:: drop ( batch_state_lock) ;
794+ send_message (
795+ ws_conn_sink. clone ( ) ,
796+ SubmitProofResponseMessage :: InsufficientBalance ( addr) ,
797+ )
798+ . await ;
799+ self . metrics . user_error ( & [ "insufficient_balance" , "" ] ) ;
800+ return Ok ( ( ) ) ;
801+ }
802+
800803 if msg_max_fee > user_last_max_fee_limit {
801804 std:: mem:: drop ( batch_state_lock) ;
802805 warn ! ( "Invalid max fee for address {addr}, had fee limit of {user_last_max_fee_limit:?}, sent {msg_max_fee:?}" ) ;
@@ -863,6 +866,9 @@ impl Batcher {
863866 ws_conn_sink : WsMessageSink ,
864867 signature : Signature ,
865868 addr : Address ,
869+ user_balance : U256 ,
870+ user_accumulated_fee : U256 ,
871+ msg_max_fee : U256 ,
866872 ) {
867873 let replacement_max_fee = nonced_verification_data. max_fee ;
868874 let nonce = nonced_verification_data. nonce ;
@@ -892,6 +898,18 @@ impl Batcher {
892898 return ;
893899 }
894900
901+ // For a replacement msg we must subtract the original_max_fee of the message from the user's accumulated max fee.
902+ if !self . verify_user_has_enough_balance ( user_balance, user_accumulated_fee - original_max_fee, msg_max_fee) {
903+ std:: mem:: drop ( batch_state_lock) ;
904+ send_message (
905+ ws_conn_sink. clone ( ) ,
906+ SubmitProofResponseMessage :: InsufficientBalance ( addr) ,
907+ )
908+ . await ;
909+ self . metrics . user_error ( & [ "insufficient_balance" , "" ] ) ;
910+ return ;
911+ }
912+
895913 info ! ( "Replacing message for address {addr} with nonce {nonce} and max fee {replacement_max_fee}" ) ;
896914
897915 // The replacement entry is built from the old entry and validated for then to be replaced
0 commit comments