#dusk $DUSK @Dusk I went looking for Dusk's audit history and ended up reading a disclosure instead.
On April 30 this year OtterSec published a soundness bug they found in dusk-plonk, the proof system that Dusk wrote itself, back when the PLONK paper was still new.
The short version: a Phoenix shielded transaction is gated by exactly one thing. Not a signature, not a second check — a single valid/invalid verdict from the proof verifier. Note ownership, note membership, balance integrity, nullifier correctness: every one of those claims lives inside the circuit, and the node just asks "did the proof verify?"
Four values in that proof were supplied by the prover and used in the final verification equation without ever being checked against the commitments already sitting in the verifier key. The commitments existed. They just weren't used for those four.
Two things stuck with me.
First, there was no second net. Rusk checks things like nullifier uniqueness before verification, but for the claims inside the proof there's no fallback path. One broken link, and every constraint in the circuit goes at once.
Second, this stack was audited. dusk-plonk in Dec 2023. Phoenix in Sep 2024. The Rusk node library by Oak Security in Sep 2024. OtterSec's own explanation for the miss is a mental model: in textbook PLONK selectors are public circuit data, so a reviewer thinks "verifier-side" and moves on — right past the place where Dusk's implementation had started consuming prover-supplied values instead.
Credit where it's due: reported Feb 13, acknowledged and fixed Feb 14, public release Feb 27. One day to acknowledge and patch is a serious response.
But it changed what "audited" means to me. An audit is a snapshot of attention, not a proof of correctness.
When you read that a chain is audited — do you check who, when, and which component?