Account Nonce Design issue reported by Certik

Certik’s latest Code Security report includes major issue which was declined by Massa Labs. The issue is in the absence of Account Nonce, which might result into block producers manipulating (re-ordering) single user’s transactions in a block. This is also commonly known as Maximum Extraction Value (MEV) in other blockchains wihch is also more general, i.e., not only related to manipulation of single user’s transactions in a block but all transactions.

What Certik suggests is that some kind of MEV is also possible by re-ordering single user’s transactions in a block. In EVM blockchains presense of Account Nonce makes it impossible to change single user’s transactions between themselves while still possible to put these transactions in between other users’ transactions that could result into MEV. In Massa, in addition to general MEV, it is also possible to re-order single user’s transactions.

While it is not an issue only for Massa, it is good to be aware of potential issues while sending your transactions. For interdependent transactions, it might be a good idea to:
(i) spread them across different blocks (one tx per block) but might result into waiting for 16sec until next blcok as a single user account belongs to a single thread due to Massa’s blocklique architecture; (ii) use Account Abstraction which is technically a smart contract that can handle multi-calls and execute in a single transaction a predefined order of execution, or implements Nonce tracking.

Please share your view on this!

Context

We mandated a new round of very large scale security audits that spanned multiple months to reinforce the security of Massa. The focus this time was on the Execution system (sequencing, transaction execution, VM and so on…).

The auditors found security details in the code that could be improved, which we did over multiple back-and-forths between our devs and the auditors. The fixes cumulated 10,000+ lines of code and were delivered partially in v2.5 and the rest was delivered in v3.0.

In the report we ended up in agreement with the auditors on almost all the 45 findings:

  • either we agreed they were right and we fixed the issue, then they re-audited the fix and accepted it (resolved: 36/45)
  • or we agreed with their findings and accepted that it is part of the design, added it to the documentation if necessary, and they agreed it was OK (acknowledged: 6/45)
  • or we disagreed with their interpretation (declined: 3/45) <== this is what we are talking about here

The disagreements are the following:

How it works in Ethereum

In Ethereum, nodes store the whole history of executed transactions and their execution conditions. Blocks are not parallel but sequential and are not very frequent, so this list does not grow quickly, and node storage space is expected to increase without cap over time as the history grows.
When a block is received by a node, its validity is checked, which includes checking that its hash does not belong to the full list of already-executed transactions. It also checks that the “nonce number” if present is consecutive to the previously registered one. This is useful for transaction sequencing from a single account. It also has another feature: replacing a transaction before it is included by another one (albeit there is no mathematical guarantee that this would happen).

Ethereum suffers from MEV (Miner Extractable Value) because actors in the network can observe that a transaction will happen before it is included in a block, and quickly send a transaction with a higher fee to be executed before it, in order to change the market conditions and make a profit (typically something called MEV Sandwich Attacks).

Why Massa has no nonces

Massa on the other hand is designed to process orders of magnitude more transactions per second than Ethereum (about 10,000 tx/s !), all while maintaining node hardware requirements constant and reasonable. To achieve this, blocks are very frequent in Massa (2 blocks per second), and 32 blocks are being produced and propagating simultaneously in the network at any given moment. This has two consequences:

  • if we required nodes to store the history of executed transactions and their nonces, it would quickly occupy too much space and break the low hardware requirements, hence break decentralization
  • Massa is designed with parallelization in mind: there are no guarantees in the order of execution of two given transactions. Adding a nonce would break this pattern.

In Massa, transactions contain an expiry period (see Detailed operation format and execution sequence | Massa Documentation ) after which if the transaction is included in a block it will be ignored. In a similar fashion, it can’t be executed if included earlier than 10 periods before that expiry period.

Before executing a transaction, we check that:

  • it is not part of the temporary rolling cache of non-expired executed transactions (transactions are removed from that list once they are expired because they can’t be included anymore anyway)
  • it is in its validity range in terms of periods (see above)

That way, Massa retains gains a lot in hardware strain and scalability at the same time, which is necessary to achieve such scaling without crippling decentralization.

Security considerations

In Ethereum, block producers are free to order transactions the way they want in their block.
Only one constraint applies: they need to respect the nonces when ordering transactions coming from a single given account. But transactions coming from different accounts are arbitrarily ordered by the node runners. This opens the well known MEV opportunities happening currently in essentially all L1 blockchains.

In Massa, block producers are also free to order transactions coming from different accounts within their block, but they are also free to order transactions coming from the same account within their block. Massa is massively parallel: there is no guarantee of ordering of concurrently emitted transactions.

We believe this is not a problem because:

  • the issue is only block-wise and there are 2 blocks per second in Massa. So unless you are spamming more than 2 transactions per second that all need to follow a certain sequence, it should not be an issue
  • if you are doing something sequence-critical, you should use a smart contract that ensures sequence numbering. This is much more powerful than nonces because it can ensure cross-account sequencing as well, and not just order the transactions coming from one given account.

Actually MEV might be harder in Massa than elsewhere because as a block is being produced, 31 other blocks are also being produced and propagating simultaneously, and MEV actors don’t necessarily know their contents in time.

1 Like

An address is linked to one thread, so it should be “more than 2 transactions in 16 seconds”

I agree with the rest.

1 Like

Makes sense — dropping nonces isn’t a bug, it’s a feature for scalability.

It keeps node requirements low, enables true parallel execution, and leaves ordering logic to smart contracts when needed. Much cleaner than forcing Ethereum’s sequential model.

1 Like