Original source text
AEGIS shipped fixes for 39 findings from our internal audit, 7 of which were classified as critical. It was the largest and most consequential hard fork we've shipped since mainnet launch. The critical findings came down to 4 root causes: VM sandbox aliasing, unsafe host-side deserialization, Phoenix fee and refund binding failures, and BLS forgery.
Together, these issues affected deterministic execution, host-process memory safety, consensus authentication, supply integrity, and chain availability. We've been investigating whether any of the critical findings were exploited prior to AEGIS, and so far we've found no evidence of exploitation.
At a Glance39 fixes shipped in the AEGIS remediation wave7 critical findings plus 1 related high-severity finding from the same root cause31 additional hardening fixes across runtime, serialization, networking, consensus, cryptography, and wallet/client code4 critical root causes affecting execution, memory safety, fees, and signaturesSeveral critical findings shared the same root cause, so there were fewer unique failure modes than the raw finding count suggests.
The finding IDs are audit-local. P1 refers to Phase 1, the first audit pass of this kind across the Dusk stack. In P1.x-y, x identifies the subsystem group (such as Rusk or Plonk), and -y identifies the specific finding within that group.
The rest of this analysis breaks down each cluster: what broke, how it could be exploited, and what AEGIS changed.
Part I: Critical Findings in Depth1. VM Sandbox Aliasing: P1.1-1, P1.1-8Our findings
Two of the revised critical findings lived in piecrust, the VM sandbox layer that underpins contract execution, and both came from unsound ownership rather than business logic.
Mutation-capable session and instance state could be aliased in ways Rust is explicitly designed to prevent. The audit identified two critical manifestations of the same problem:
P1.1-1: session aliasing combined with Send/SyncP1.1-8: unconstrained lifetimes on instance references, allowing multiple simultaneous mutable referencesIn a blockchain runtime, this class of defect is worse than a normal crash. Crashes are visible. Undefined behavior can stay latent, appear only on certain paths, or surface as silently wrong computation. In a deterministic system, that means two honest nodes can execute the same code and still derive different internal outcomes. The execution boundary itself could no longer be trusted to behave deterministically.
How exploitation worked
This was not a simple one-shot remote exploit. Exploitability came from pushing the runtime into states where the code relied on ownership guarantees the type system was no longer actually providing.
A malicious contract, or just the wrong nested execution pattern, could push execution through alias-prone paths that Rust would normally rule out.
The audit also showed how hard this class of defect is to observe operationally. Without dedicated tooling, it can look fine right up until it stops being fine.
What changed in AEGIS
AEGIS reworked the affected session and instance ownership model in piecrust so the aliasing patterns the audit confirmed could no longer arise. This was a runtime correction rather than a narrow guard that only papers over one manifestation.
The same wave also shipped related runtime hardening:
Explicit call depth limits (P1.1-9)Fixes around instance reuse and reentrancy (P1.1-4)Cleanup of related aliasing-adjacent runtime behavior (P1.1-13)Once the ownership model is wrong, fixing one symptom is not enough. The remaining code still inherits the same invalid assumptions.
2. Host-Side Unsafe Deserialization: P1.2-1Our findings
The dusk-vm layer exposed host queries to contracts. Before AEGIS, those host queries deserialized contract-controlled arguments using unchecked rkyv::archived_root on bytes sourced directly from WASM linear memory. The bytes were controlled by the contract, but the deserialization ran in the host node process, not inside the sandboxed guest.
All 11 registered host queries inherited the same wrapper pattern. 8 of them deserialized types containing relative pointers and were directly exploitable via out-of-bounds reads. Once the node process is in scope, this stops being a contract-level bug and becomes a node-integrity bug.
How exploitation worked
Exploitation only required the ability to deploy a contract that called one of the affected host queries with malformed archived input.
Because archived data was interpreted without validation, crafted relative pointers could point outside the intended buffer.
The exact query was secondary. The real issue was the shared boundary assumption: untrusted bytes were being treated as structured data before validation.
What changed in AEGIS
AEGIS fixed the trust boundary, not just one query.
The host-query wrapper now validates archived input before deserializing it. In practice, that means using check_archived_root and returning a safe fallback if the archive is malformed, rather than invoking the host query on invalid data. For this boundary, validate first, deserialize second, execute last is the only defensible order.
AEGIS also used the same release wave to push related deserialization hardening across adjacent layers. The critical host-side issue was the priority, but it was treated as part of a broader unsafe-deserialization family rather than a one-off anomaly.
3. Phoenix Fee / Refund Chain: P1.5-1, P1.5-2, P1.6-1, P1.6-2Our findings
The Phoenix fee cluster mattered most because one root cause led to multiple catastrophic outcomes. The root cause was P1.5-1: the Phoenix Fee structure was not properly bound across proof generation, signing, and refund execution. The system proved one set of fee-related semantics while the execution path still trusted fee data that was not fully bound into the same security story. That gap enabled two separate critical exploit paths and a closely related high-severity attack:
P1.6-1: fee overflow in the Phoenix refund path could halt the chainP1.6-2: unvalidated fee data in the refund path could inflate supplyP1.5-2: fee malleability enabled gas refund redirection via man-in-the-middleThe cluster hit supply integrity, chain availability, and transaction authenticity at the same time. One missing invariant, three ways to break the protocol. That is why this issue sat at the center of the audit.
How exploitation worked
The exploit chain worked because the transaction skeleton and the fee semantics were not bound tightly enough across proof generation, signing, and refund execution.
In practice, an attacker could:
Commit to a legitimate max_fee in the proven part of the transactionProvide inconsistent or hostile fee parameters in the execution-facing partRely on the refund path to compute against the untrusted valuesFrom there, the attacker had three choices.
Silent inflation path (P1.6-2) Choose fee parameters that stay inside u64. Cause the refund logic to create far more value than the transaction legitimately committed to.
Chain-halt path (P1.6-1) Choose fee parameters that drive overflow in the refund arithmetic. Push validators into a deterministic failure path during block processing.
Refund theft path (P1.5-2) Intercept a Phoenix transaction on the P2P network. Replace Fee.stealth_address with an attacker-controlled address. Choose any factorization of max_fee for gas_limit and gas_price that still passes the consistency check. The gas refund note is minted to the attacker instead of the original sender.
These were three exploit outcomes of one broken invariant chain, not unrelated bugs that happened to land in the same subsystem.
What changed in AEGIS
AEGIS closed the exploitable critical paths first.
The shipped defense addressed the cluster from two directions.
For the inflation and chain-halt paths, AEGIS introduced a fee consistency check that enforced checked multiplication on gas_limit * gas_price and equality between that product and the transaction's proven max_fee. The check was enforced at two layers: mempool admission and VM execution. The split was deliberate. Mempool-only enforcement would not have been enough once a malicious proposer can bypass mempool assumptions. VM-side enforcement made the mitigation protocol-relevant rather than merely operational.
For the refund theft path, AEGIS bound the Fee.stealth_address into the transaction's security story so that modifying it would invalidate the transaction, closing the man-in-the-middle redirection vector.
AEGIS also shipped regression coverage for all three exploit classes, including tests for:
Refund inflation attemptsRefund overflow / halt attemptsFee tampering and redirection behavior4. BLS Forgery: P1.13-1Our findings
The BLS critical was a broken cryptographic construction choice, not a routine implementation bug.
The old h0 mapping used in the BLS signature path was not a secure hash-to-curve construction. That created a setting in which observing a valid signature was enough to enable forgery on arbitrary messages under the same key. BLS signatures sit directly on consensus authentication and every other trust path that treats BLS verification as reliable, so a break here doesn't stay contained inside one crate.
The severity was revised upward after deeper review because the exploit cost was low enough, and the authentication impact broad enough, that the issue crossed into critical territory.
How exploitation worked
The insecure h0 mapping reduced the message-to-curve story to something algebraically manipulable. That made signature forgery possible from a single observed valid signature.
The exact algebra matters less here than the location of the weakness: it lived in the construction itself, not in a length check or a bad conditional. The system was relying on security properties the design did not actually provide.
What changed in AEGIS
AEGIS moved the secure BLS v2 path onto a proper RFC 9380-style hash-to-curve construction with explicit domain separation. It also separated the multisig coefficient domain from the message hash domain, addressing the related collision issue (P1.13-2).
In practical terms, the secure path now uses:
RFC 9380-style hash-to-curve for h0Dedicated domain separation tags for the secure pathA legacy insecure path retained only where historical compatibility still mattersThe migration had to follow the same rule as the cryptography itself: use a correct construction for the secure path, handle older behavior explicitly, and don't assume that old and new verification semantics are interchangeable.
Part II: What Else AEGIS FixedAEGIS shipped 31 additional fixes beyond the criticals. The rest of the merged fixes mattered because they narrowed attack surface in adjacent areas even where the underlying findings were not critical.
Serialization and deserialization hardeningAEGIS removed or constrained multiple cases where untrusted bytes were being deserialized with too much trust and too little validation. That included P1.1-5, P1.3-3, P1.3-4, P1.4-3, P1.5-3, P1.12-3, P1.15-10, and P1.15-14.
The effect was broad: tighter trust boundaries across the VM, transaction parsing, prover-facing code, contract-returned data, and cross-layer serialization. Materially harder for malformed or adversarial data to trigger crashes, invalid parsing, or unsafe zero-copy assumptions.
Transaction and payload validation hardeningAEGIS tightened how transactions and execution envelopes are validated before and during execution. Around the VM/runtime boundary, AEGIS shipped execution-safety fixes (P1.1-4, P1.1-9), reducing the space for dangerous nested execution and runtime misuse.
The practical effect: more of the protocol's assumptions became explicit checks instead of implicit expectations.
Consensus correctness fixesOn the consensus side, AEGIS shipped fixes for P1.8-1, P1.8-2, and P1.8-5.
These were not catastrophic in the same way as the criticals, but consensus code has almost no room for ambiguity. The fixes tightened fault validation, corrected message behavior in open-consensus mode, and restored missing validation-result checks in ratification handling.
Net effect: a stricter definition of what the protocol accepts as a valid consensus transition.
Node and network input-bounds hardeningAEGIS closed a broad set of node-facing input issues: P1.9-1, P1.9-2, P1.9-3, P1.9-4, P1.9-5, P1.15-1, P1.15-2, and P1.15-12.
These findings were about unbounded allocation, malformed input handling, and amplification behavior across the node and networking surface.
The release made it harder to turn oversized or weakly validated network inputs into crashes, memory blowups, or avoidable propagation and amplification behavior.
Cryptographic correctness hardeningBeyond the BLS critical, AEGIS shipped a broader set of cryptographic correctness fixes in plonk, jubjub, jubjub-elgamal, and the BLS stack: P1.4-1, P1.12-1, P1.12-4, and P1.13-2. These covered transcript correctness, subgroup handling, malleability behavior, and domain separation. The same wave also included lower-severity cleanups in the same crates (P1.4-2, P1.4-4).
AEGIS tightened places where "close enough" cryptographic behavior is not acceptable.
Wallet and client-side untrusted-data hardeningAEGIS shipped client-side untrusted-data hardening through P1.16-4, which addressed unsafe handling of untrusted serialized node responses in the wallet stack.
The same trust-boundary discipline that mattered on the node side also had to be applied to clients.
The appendix includes the full AEGIS merged set, including lower-severity runtime cleanups (P1.1-13, P1.1-15, P1.1-16).
Cross-Cutting Lessons1. Unsafe code at trust boundaries needs a different review bar. The audit repeatedly found the same pattern: code near VM, serialization, or cryptographic boundaries carried more trust than it should have. In ordinary application code that may produce a local defect. In protocol code it becomes systemic risk.
2. Protocol invariants need to be enforced in multiple layers. The Phoenix fee cluster made this especially clear. It's not enough for one layer to "implicitly" constrain a value if another layer can still consume a divergent version of that value. If something matters to safety or economics, it needs to be checked at every boundary where it can be reintroduced or transformed.
3. Shared low-level patterns replicate across crates. The deserialization findings were a good example. One unsafe pattern at one boundary was bad enough, but similar assumptions also existed elsewhere in the stack. Patterns like that spread unless there's a clear default policy against them.
4. Cryptographic migrations are operational migrations. The BLS critical was not just about choosing a better formula. It was about safely moving a live protocol from one trust assumption to another: versioning, compatibility handling, rollout discipline, and explicit activation planning.
5. Mitigation and root-cause removal are not the same thing. The Phoenix fee cluster forced us to be explicit about this. AEGIS blocked the critical exploit paths, but that doesn't erase the difference between a robust mitigation and a deeper protocol-level redesign. Both matter. They're not the same thing.
What Changed in Our Engineering ProcessWe now treat serialization and deserialization boundaries as security boundaries by defaultunsafe in VM, cryptography, and host-boundary code gets a higher review bar and a narrower acceptable-use envelopeCritical remediation work is tracked as both exploit closure and root-cause closure so the two don't get conflatedSecurity fixes that change protocol behavior or verification semantics are treated as migration work, not just code patchesRegression coverage for critical findings now includes exploit-shaped tests, not just happy-path correctness testsAudit follow-up work is grouped by root cause where appropriate, because many seemingly separate findings are one systemic failure showing up in multiple placesAEGIS was the biggest release we've shipped. The protocol is stronger for it.
AppendixCritical Finding ClustersVM sandbox aliasing (P1.1-1, P1.1-8) Components: piecrust
Remediation: Reworked session/instance ownership and alias-prone runtime behavior
Host-side unsafe deserialization (P1.2-1) Components: dusk-vm / rusk
Remediation: Replaced unchecked host-query archive handling with validated deserialization
Phoenix fee / refund chain (P1.5-1, P1.5-2, P1.6-1, P1.6-2) Components: phoenix, transfer contract, VM integration
Remediation: Fee consistency checks at mempool and execution boundaries, plus regression tests
BLS forgery (P1.13-1) Components: bls12_381-bls, rusk integration
Remediation: RFC 9380-style hash-to-curve with explicit domain separation
Other Merged AEGIS FixesVM/runtime safety (P1.1-4, P1.1-9, P1.1-13, P1.1-15, P1.1-16) Components: piecrust
Effect: Hardened execution lifecycle, call-depth handling, and VM/runtime correctness
Serialization hardening (P1.1-5, P1.3-3, P1.3-4, P1.4-3, P1.5-3, P1.12-3, P1.15-10, P1.15-14) Components: piecrust, dusk-core, plonk, phoenix, jubjub-elgamal, rusk
Effect: Reduced panic, OOB, and unsafe zero-copy risks at trust boundaries
Consensus correctness (P1.8-1, P1.8-2, P1.8-5) Components: consensus, rusk
Effect: Tightened fault validation and message-handling correctness
Node/network input-bounds (P1.9-1, P1.9-2, P1.9-3, P1.9-4, P1.9-5, P1.15-1, P1.15-2, P1.15-12) Components: node-data, rusk
Effect: Reduced remote OOM, malformed-input crash, and amplification exposure
Cryptographic correctness (P1.4-1, P1.4-2, P1.4-4, P1.12-1, P1.12-4, P1.13-2) Components: plonk, jubjub, jubjub-elgamal, bls12_381-bls
Effect: Tightened transcript, subgroup, malleability, and domain-separation behavior
Wallet/client hardening (P1.16-4) Components: rusk-wallet
Effect: Hardened client handling of untrusted serialized node responses