Tweag by Modus Create has been auditing Cardano smart contracts since late 2021. Mathieu Montin has written a retrospective on what more than 20 audits and 276 findings taught us: the patterns we keep seeing, what’s getting safer, and what still needs work.
A few highlights:
Whole classes of Cardano/eUTxO-specific vulnerabilities, such as double satisfaction attacks, are fading as the platform and its developers mature.
Design issues remain common and are arguably the hardest and most costly to fix.
Unclear specification was the second-largest category, accounting for 70 findings, including one critical.
It’s interesting that design and specification issues remain more common than some code-level vulnerabilities. From a wallet UX perspective, have you seen recurring findings where clearer transaction information at signing time could reduce user risk—for example, explicitly showing assets leaving the wallet, recipients, minimum received amounts, or unusual permissions?
It would be useful to understand which risks a wallet interface can reasonably help users identify and which must always be prevented at the smart-contract level.
From the perspective of smart contract auditing, we do not directly assess how wallet UX impacts user safety. In general, we advise enforcing as much as possible on-chain, without relying on the partial view that signing users may have of a transaction. After all, delegating part of the validation logic to one or more human operators, although sometimes hard to avoid, defeats the purpose of immutable on-chain verification.
That being said, many smart contract systems do rely on signing parties to make decisions. This could be a governance committee with a certain number of members and a signature threshold for approving important transactions, or simply a single administrator required to authorize critical operations. In both cases, assuming these parties are honest, the wallet UX becomes very important in ensuring they are presented with all the information they need to make an informed decision. For example, clearly displaying the assets leaving the wallet, the recipients, and any guarantees about the minimum amounts being received can help prevent users from authorizing transactions they did not fully understand. If signers are only shown a partial view of a transaction, they may unknowingly approve an action they would otherwise reject.
A good example is the class of vulnerabilities known as double satisfaction. These issues are notoriously difficult to eliminate entirely at the smart-contract level when several independently developed contracts are composed within the same transaction, since each contract can only validate its own spending conditions and has limited visibility into the assumptions made by the others. By contrast, they can often be made much more apparent through a wallet interface that presents the complete transaction. If a user expects a transaction to perform a single action but is shown that additional scripts are being executed, extra inputs are being consumed, or extra withdrawals are being issued, this provides valuable context that something unexpected is happening and deserves closer scrutiny before signing.
Ultimately, wallet UX can help users identify suspicious or unintended transactions, but it should be viewed as an additional layer of protection rather than a security boundary. Any property that can be enforced by the smart contract itself should be enforced on-chain, regardless of what information the wallet presents to the user.
Thank you for the detailed explanation. Framing wallet UX as an additional layer of protection rather than a security boundary is especially helpful.
The double-satisfaction example also shows why displaying only net balance changes may not be enough. Additional scripts being executed, inputs being consumed, withdrawals being issued, and minimum-received guarantees can all provide important context before signing. These are useful points for us to bring into internal discussions around transaction-review UX.
This is a valuable retrospective. One point that really stands out is that design and specification issues remain a major source of risk, even as the Cardano ecosystem becomes more mature.
It’s a good reminder that smart-contract security starts well before the code is written: clear specifications, sound architecture, and well-defined assumptions are just as important as the final implementation.
Thanks to Tweag for sharing these lessons from more than 20 audits and 276 findings. This kind of knowledge sharing can help the wider Cardano developer community build more secure applications.