#43303 [BC-Medium] The call to `commit_transaction()` includes the wrong sequence number
Submitted on Apr 4th 2025 at 12:16:17 UTC by @HollaDieWaldfee for Attackathon | Movement Labs
Report ID: #43303
Report Type: Blockchain/DLT
Report severity: Medium
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 a new transaction is submitted, commit_transaction()
is called with the account's sequence number. However, commit_transaction()
should be called with account_sequence_number - 1
instead such that all transactions with sequence number < account_sequence_number
will be deleted.
Vulnerability Details
When a transaction gets accepted, commit_transaction()
is called to handle the transaction commit. This includes deleting all transactions with a lower sequence number. However, the call to commit_transaction()
is done with the current account's sequence number.
pub fn commit_transaction(&mut self, account: &AccountAddress, sequence_number: u64) {
let current_seq_number = self.get_sequence_number(account).map_or(0, |v| *v);
let new_seq_number = max(current_seq_number, sequence_number + 1);
self.sequence_numbers.insert(*account, new_seq_number);
self.clean_committed_transactions(account, new_seq_number);
self.process_ready_transactions(account, new_seq_number);
}
As a result, clean_committed_transactions()
will be called with account_sequence_number + 1
which means that all transactions with sequence number <= account_sequence_number
will be deleted. But the current account_sequence_number
is already a new sequence number which means that it should not be deleted. And in process_ready_transactions()
, the mempool can prematurely delete the transaction with sequence_number
.
The solution is to call the commit_transaction()
function with sequence_number - 1
when the sequence number is greater than 0, and to not call commit_transaction()
at all when sequencer number is equal to 0.
Impact Details
Commiting a new transaction deletes too many transactions.
Although Immunefi classifies the impact of "Causing network processing nodes to process transactions from the mempool beyond set parameters" as a High severity issue, and we submit the issue with High severity according to Immunefi rules, we believe that it should be Low severity.
References
(1): https://github.com/immunefi-team/attackathon-movement/blob/a2790c6ac17b7cf02a69aea172c2b38d2be8ce00/protocol-units/execution/maptos/opt-executor/src/background/transaction_pipe.rs#L299
(2): https://github.com/immunefi-team/attackathon-movement-aptos-core/blob/627b4f9e0b63c33746fa5dae6cd672cbee3d8631/mempool/src/core_mempool/transaction_store.rs#L496-L502
Proof of Concept
Proof of Concept
submit_transaction()
is called which callscommit_transaction()
with the account's sequence number when the submitted transaction gets accepted (reference (1)).Inside of this function, the sequence number gets incremented by 1 and then
clean_committed_transactions()
gets called with the incremented sequence number (reference (2)). As a result, all transactions with sequence number <=account_sequence_number
will be deleted.
Was this helpful?