Cardano Smart Contract Audits
Independent security review of Cardano smart contracts in Aiken, Plutarch and Plinth, by the team that maintains Plutarch, Lambda Buffers and CTL.
Every vulnerability we find is demonstrated by a test, and that test becomes part of your suite when the audit is done. No unreproducible findings, no severity ratings you have to take on faith.
What we audit
On-chain code. Cardano smart contracts written in Aiken, Plutarch or Plinth: validators, minting policies, staking scripts, and the shared authorisation and helper modules they depend on.
Off-chain code. The transaction-building layer that actually puts your contracts on chain. Most exploitable gaps live at the boundary between the two, so we look at both.
Protocol design. Trust models, oracle assumptions, key rotation, the paths for upgrades and governance, and the transactions a design permits that its authors did not intend.
AI-generated code. Increasingly, some or all of a codebase is written by an LLM. That code is plausible but not necessarily correct: it compiles, it reads well, and it can be subtly wrong. The methods below are the ones that catch it. Tell us what was generated and we will scrutinise it accordingly.
How the audit works
Five phases. The span below is the audit itself; it excludes the time your team takes to apply fixes between Phase 3 and Phase 4, which is outside our control. End to end, expect to add one to two weeks for your turnaround.
Phase 1: Specification review and test coverage
We start with what the protocol is supposed to do: how each script should behave, which transactions should be possible, and which should be impossible. Where no written specification exists, this phase produces one, derived from your implementation and test suite, confirmed with your team, and used as the reference for everything that follows. We also analyse your test suite for coverage and important omissions, and raise implicit assumptions, inconsistencies and incomplete requirements as questions.
Phase 2: Manual source code scrutiny
Every file in scope is read against that specification, and against the coding patterns and mistakes that introduce exploitable vulnerabilities on Cardano specifically. Scripts are reviewed round-robin, with proportionate attention to whatever carries protocol-wide reach: shared authorisation modules, oracle trust models, redeemer paths. Each finding is recorded as an issue in your repository or a fork, and wherever possible demonstrated by extending your existing test suite.
Phase 3: Report consolidation
Findings are consolidated into a report listing every issue by severity, with recommendations to fix or mitigate. You get a draft first, so you can respond and counter-argue before anything is final.
Phase 4: Re-audit
After your fixes land, a second round confirms that nothing new was introduced. We send each issue as we find it, with a test that proves it, so your team can start before the report lands.
Phase 5: Report finalisation
The report is updated with the outcome of each vulnerability: whether it was fixed, and how. Where on-chain instantiation parameters are available, we review them and certify the corresponding script hashes in an appendix.
What you get
An audit report listing every finding by severity, with a recommendation to fix or mitigate each one, issued in draft first and finalised with the outcome of each item.
Tests. Every vulnerability we report comes with one or more tests demonstrating it. They stay in your suite after we leave, which means the audit permanently raises your coverage rather than just describing it.
Issues in your repository, filed as we go, so your developers can start on the critical ones before the report is written.
A written specification, if you did not have one. Phase 1 produces it as a by-product, and for many teams it is the most durable thing the audit leaves behind.
Certified script hashes, where instantiation parameters are available: an appendix tying the audited source to what is actually deployed.
How we scope and price
We measure effective lines of code, not files and not repositories.
Effective LoC counts only substantive on-chain code. Comments, blank lines, pragmas, module headers, imports, test code and off-chain code are all excluded, and unusually long lines are counted at their real weight rather than as one line each. We run the measurement with our own open tooling and show you the per-file breakdown, so the number behind your quote is one you can check rather than one you have to accept.
Why this rather than counting files? Because a repository can be reorganised without changing the work, and a file count says nothing about how much logic is in it. What drives audit effort is the amount of code that can actually be wrong, plus the number of distinct scripts and the complexity of the protocol connecting them. Two codebases of the same size can differ twofold in effort. One keeps its logic in a few places, the other spreads it across many interacting validators. So we read the code before we quote, and the measurement informs the price without setting it.
The quote is fixed. Once prerequisites are met and scope is agreed at a named commit, the price does not move. Growth of up to 10% in the submitted commit is absorbed without change. Beyond that, any surcharge is proportionate, agreed in writing before kickoff, and never applied retrospectively. If scope shrinks materially, the quote comes down on the same basis.
What speeds it up and brings it down. A written specification shortens Phase 1 and we revise the quote accordingly. A test suite we can extend, readable code, the off-chain code and a technical contact all shorten the audit. A shorter audit costs less.
What an audit costs
We quote after we read the code. The price depends on how much on-chain logic there is, how many scripts, and how much of the protocol lives in the connections between them. A price list would be either wrong or so wide as to be useless.
What we will do is get you to a fixed price quickly. It starts with a call: what the protocol does, what is in scope, what you need by when. Once an NDA is in place (or straight away, if the code is public), we read it and come back with a number, a duration and a start date.
Before we start
Three things must be in place at kickoff:
A specification: a document setting out what the protocol is intended to do. If you do not have one, say so; Phase 1 writes it, and we price that in.
A test suite covering the scripts in scope, which we can extend. Every finding we report is demonstrated by a test, and a suite we can add to is what makes that possible.
A fixed commit, agreed before kickoff and unchanged for the duration.
Helpful, but not blocking: off-chain code producing the transactions, enough commentary through the code to make it readable, and a technical point of contact available throughout.
Who does the work
Audits are led by our senior engineers, not delegated to a review queue. You are told who is on your engagement before you sign, and they are the people who write your report.
Why MLabs
We maintain the tools your code is written with. MLabs maintains Plutarch, Lambda Buffers and CTL, infrastructure used across the Cardano ecosystem. When we audit a Plutarch contract, we are not learning the framework from its documentation.
Every finding is demonstrated, not asserted. The industry norm is a report full of severity labels you cannot verify. Ours come with tests that fail on your codebase before the fix and pass after it. If we cannot demonstrate it, we do not claim it.
We audit systems where being wrong costs real money. The methods are the ones that hold up under that pressure: formal specification, property testing, and manual review by people who write this code for a living rather than only reading it.
Auditing is one line of a verification practice. The same muscle applies to high-assurance systems generally, and increasingly to AI-generated codebases. Fast code is easy to get now. Proving it is correct is not.
Not on Cardano? MLabs does the same work on any stack. See testing, QA and verification.
Ready to get your contracts audited?
Start with a conversation. Tell us what the protocol does and roughly how much is in scope, and we will tell you whether we are the right team for it. Unless the code is already open source, we sign a mutual NDA before we read a line of it. Then you get a fixed price against a named commit, and a start date.
Start a conversation
Tell us what the protocol does and roughly how much code is in scope. If it is not already open source, we will put a mutual NDA in place before we read anything.