#43222 [BC-High] A transaction with sequence number 0 can be submitted multiple times
Submitted on Apr 3rd 2025 at 19:48:29 UTC by @KlosMitSoss for Attackathon | Movement Labs
Report ID: #43222
Report Type: Blockchain/DLT
Report severity: High
Target: https://github.com/immunefi-team/attackathon-movement/tree/main/protocol-units/execution/maptos/opt-executor
Impacts:
Causing network processing nodes to process transactions from the mempool beyond set parameters
Description
Brief/Intro
When checking if a transaction's sequence number has been used before using the has_invalid_sequence_number()
function, the case when the sequence number is 0 is not properly handled.
As a result, a transaction with sequence number 0 can be submitted multiple times.
Vulnerability Details
When the previously used sequence number for the transaction sender is retrieved from the used_sequence_number_pool
, it defaults to 0 if no sequence number is found.
fn has_invalid_sequence_number(
&self,
transaction: &SignedTransaction,
) -> Result<SequenceNumberValidity, Error> {
// check against the used sequence number pool
let used_sequence_number = self
.used_sequence_number_pool
.get_sequence_number(&transaction.sender())
>> .unwrap_or(0);
... ...
}
https://github.com/immunefi-team/attackathon-movement/blob/a2790c6ac17b7cf02a69aea172c2b38d2be8ce00/protocol-units/execution/maptos/opt-executor/src/background/transaction_pipe.rs#L164-L218
Later in the function, if the last used sequence number was 0 (or none was found), the minimum allowed sequence number also becomes 0.
fn has_invalid_sequence_number(
&self,
transaction: &SignedTransaction,
) -> Result<SequenceNumberValidity, Error> {
... ...
>> let min_used_sequence_number =
if used_sequence_number > 0 { used_sequence_number + 1 } else { 0 };
... ...
}
This means that transactions with sequence number 0 can be submitted multiple times to the mempool, bypassing the normal sequence number check.
To mitigate this, a distinction should be made between the absence of a used sequence number and the used sequence number being 0. If no used sequence number exists, 0 should be allowed. However, if 0 is the last used sequence number, it should not be allowed (only 1,2 and so on should be allowed).
Impact Details
A transaction with the sequence number being 0 could be submitted multiple times.
While technically the impact matches "Causing network processing nodes to process transactions from the mempool beyond set parameters" which is a "High" impact, we belive the issue should be "Low".
References
Code references are provided throughout the report.
Proof of Concept
Proof of Concept
The
used_sequence_number_pool
is currently empty and a transaction with sequence number 0 is submitted.The transaction with sequence number 0 can be submitted again.
Was this helpful?