This is a joint post from Nomadic Labs, TriliTech & Functori.
On May 16 2026, at level #43,535,109, the Etherlink 6.3 kernel upgrade activated successfully on Etherlink Mainnet, following a fast governance vote earlier that week. This new kernel from commit a7575d83f8a37e6339359dbb7d2548e5e9a5d8fc addresses two security vulnerabilities that were reported by third-party security researchers via the Tezos Foundation bug bounty program.
In this blogpost, we provide a comprehensive, technical description of each vulnerability and its associated patch.
The security vulnerabilities detailed in this post were never exploited.
Etherlink 6.3 Changelog
Etherlink 6.3 is a security upgrade addressing 2 vulnerabilities that were affecting Etherlink Mainnet.
- A malicious sequencer operator could “double spend” deposits: more specifically, the Etherlink sequencer could inject any deposit an arbitrary number of times in the same blueprint, leading to its effects being applied as many times. While this vulnerability was present on mainnet since the first Etherlink kernel release, we can confirm there is no evidence of any exploitation attempt by either the current or former Etherlink sequencer operators.
- The baker proposing an Etherlink kernel upgrade on Tezos L1 could double their voting power during the Proposal phase: this could potentially lead to a proposal being illegitimately chosen as a winner in the Proposal period, and advancing to the Promotion period. Critically, this flaw did not affect the voting power for the Promotion period, and was hence not exploitable.
Double-spending deposits
TL;DR: A malicious sequencer could have inflated arbitrary balances by injecting the same deposits several times in given blueprints, enabling them to drain the funds locked on Etherlink.
One of the key components of Etherlink is the delayed inbox. It is the cornerstone of the bridge connecting Tezos L1 and Etherlink together. The exact workflow proceeds as follows.
When a user on Tezos L1 deposits funds (either tez or FA tokens) to Etherlink, two events are triggered.
- The funds are locked on Tezos L1, under the custody of Etherlink’s smart rollup.
- A message is appended to the smart rollup’s global inbox.
This message is then interpreted by Etherlink’s kernel as a deposit request, clearly identifying the asset, amount and recipient. Instead of acting on this request, the kernel safely stores it in the delayed inbox, and waits for the sequencer to decide when to inject it. This intermediate delay is necessary to ensure the sequencer can always predict the state of Etherlink’s ledger when it creates new blocks. If the balance of an Etherlink’s account could change without the sequencer knowing, it would invalidate blocks yet to be posted on Tezos L1.
The sequencer is required to inject the content of the delayed inbox under a specified time frame. Failing to do so would be akin to censorship, which is against the fairness commitment of Etherlink. To do that, it includes the hashes of items it intends to include in the appropriate field of the blueprints it posts on Tezos L1.
pub struct BlueprintWithDelayedHashes {
pub version: u8,
pub parent_hash: H256,
pub delayed_hashes: Vec<Hash>,
pub transactions: Vec<Vec<u8>>,
pub timestamp: Timestamp,
}
It is also expected that a given item of the delayed inbox can only be injected once, but this invariant was not correctly implemented in Etherlink before the 6.3 kernel. There was no protection against duplicated hash in delayed_hashes, neither in the parsing of the structure nor in its interpretation.
As a result, deposits would be wrongly interpreted as many times as the sequencer would have included them in a given blueprint. After the application of the blueprint, the item would be removed from the delayed inbox, meaning that it could not be executed anymore. Still, one blueprint can be up to ~500KBytes, and a single hash is only 32 bytes. This double spend attack would enable the recipient of the deposit to withdraw more assets from Etherlink than they rightfully own, leading to a drain of Etherlink liquidity.
The patch (implemented in commit 5e4bcff96b7c2e0d90e7c2fd8f0c75ff09473f2b) leads the kernel to reject blueprints with duplicated delayed_hashes entries.
As mentioned above, neither MIDL.dev (Etherlink’s first sequencer operator) nor Optimistic Labs (the current one) have tried to exploit this flaw to their advantage.
“Ballot stuffing” in the Proposal period
TL;DR: A malicious baker could have doubled their voting power when injecting a kernel upgrade proposal in the Proposal period, potentially affecting the outcome of the first stage of the governance vote.
Since its inception in May 2025, Etherlink has been a non-custodial rollup with on-chain governance. Its governance mechanism is implemented via Michelson smart contracts deployed on Tezos L1 Mainnet, and it is open to all Tezos bakers (L1 validators). There is no participation whitelist: any active baker can participate in Etherlink governance, and any Tezos user can become a validator (subject to minimal stake and operation requirements).
As Etherlink and Tezos L1 evolve, it is sometimes necessary to update the governance mechanism and modify its underlying governance contracts accordingly. As these contracts cannot be modified in place, new updated versions need to be redeployed, effectively creating new governance contracts, with fresh addresses. As a result, the change of governance contracts needs to be bundled with a kernel upgrade proposal. This has been done multiple times so far, for instance to update governance contracts to reflect minimal block time reductions on Tezos L1.
Last year, we implemented a significant overhaul of the governance process, improving user experience for bakers. In particular, we introduced the concept of a voting key, which enables a baker to specify a different user (a.k.a implicit) account, and its associated private key, to interact with Etherlink governance contracts—in addition to the baker’s baking (a.k.a manager) key.
To improve the voting experience further for users operating several bakers (and/or multiple baking keys), we have enabled that several baking keys specify the same voting key. This allows for grouping multiple votes in a single voting action.
However, this change made the logic behind computing the voting power of an arbitrary user account slightly more complex. Critically, our implementation was flawed for the %new_proposal entrypoint of the governance contracts. Specifically, bakers could set their voting key to their own addresses in order to double its voting power.
The flaw originated from this function in voting.mligo.
let get_voters (delegation_contract : address) : key_hash list =
match
Tezos.call_view "list_voters"
(Tezos.get_sender (), Some (Tezos.get_self_address ()))
delegation_contract
with
| None -> failwith Errors.no_delegate_contract
| Some l -> (Converters.address_to_key_hash (Tezos.get_sender ())) :: l
Here, the key thing to note is that the implicit account’s own address (Tezos.get_sender ()) is appended to whatever the voting key contract returns. For the aforementioned edge case, this means the same key is returned twice, and the consumer of this function (filter_proposers in the same file) does not handle this case correctly.
Note that this flaw affected only the %new_proposal entry point, used in the Proposal period. It did not affect the %upvote_proposal entrypoint of the Proposal period, thus limiting the scope of the vulnerability to a malicious proposer only.
Moreover the %vote entry-point used in the Promotion period was not affected either. This is crucial, as it significantly reduced the risk of any tampering of the Proposal effectively materializing into an illegitimate kernel activation.
Commit 9428287067f12d99322a84fb63a2ab4c3c35e39e addresses this shortcoming by making sure duplicated voter entries are removed.
Keeping Etherlink Mainnet secure
Both vulnerabilities patched by Etherlink 6.3 were responsibly disclosed by third-party security researchers through the Tezos Foundation bug bounty program, and neither was exploited prior to the activation of the upgrade. We are grateful to the researchers who took the time to investigate Etherlink and report their findings through this channel.
These reports matter especially now, as we approach the crucial moment that would make Tezos X a reality. As announced earlier, we plan to propose this step via our next major kernel upgrade for Etherlink. This upgrade would increase the surface area exposed by its underlying critical infrastructure, including the sequencer and the governance contracts. The deposit double-spend vulnerability was present since the very first Etherlink kernel. The flaw in the governance contracts originates from a recent UX improvement. Both are reminders that security work has to span the full history of the codebase and every new feature added on top.
If you are a security researcher, we strongly encourage you to look into Etherlink and other Tezos ecosystem projects. The bug bounty program is the right channel, and your scrutiny will be fundamental to allowing Etherlink and Tezos X to keep evolving safely.