October 21, 2026
Auditing Smart Contracts on Canton Network
Authorization, contract references, locks and accounting across Canton workflows.
Author:
Tigran PiliposyanIn short: Canton applications are written in Daml and run on a ledger where each party sees only the parts of a transaction it is entitled to see. A smart contract audit on Canton checks the Daml authorization logic, which parties receive which information, and the Canton configuration that decides which nodes act for each party. Recurring findings from Certora's Canton reviews involve authorization, contract references, locks and accounting across multi-step workflows. In one, a redemption choice checked who was calling it and did not check who owned the holding being redeemed.
A party submits a redemption by calling a choice, Daml's name for an action a contract allows. The choice confirms that the party is allowed to call it, then accepts the holding contract the party points to. Nothing checks that the holding belongs to that party. In one Canton review, Certora found a redemption flow that never verified that holding.owner matched the expected holding party.

Canton applications use Daml contracts to model workflows between organizations, such as issuing, settling and redeeming tokenized assets. The ledger is built around privacy. Each party sees the parts of a transaction it is entitled to see, and no single contract state is visible to everyone.
Bugs of this kind follow from Canton's design. Authorization is written into Daml, and the security model also depends on contract stakeholders, observers, participant permissions, topology, and the way contracts are referenced from one step of a workflow to the next. An audit covers all of these together with the business logic.
Certora has reviewed Canton applications for tokenized assets and settlement. It also received a Canton Foundation grant to build an open-source static analysis tool for Daml cross-package interactions. The patterns below come from that work. For how the same questions play out on a public chain, see Auditing Smart Contracts on Stellar.
How is authorization enforced in Daml contracts?
Daml writes authorization into the contract itself and splits it across three roles.
Signatories authorize the creation and archival of a contract. Choice controllers authorize the exercise of choices, Daml's term for running them. Observers receive information about contracts or specific actions without necessarily having authority to modify the contract.
An audit should check the complete authorization path. For example, consider a redemption choice that receives both a holdingCid (the contract ID of the holding) and a holdingParty. Checking that the caller controls the redemption choice does not prove that the referenced holding belongs to that party. The contract should establish the relationship between the caller, the holding, and the operation being performed. A redemption flow did not verify that holding.owner matched the expected holding party.
The same applies to administrative choices. An admin may be authorized to perform an operation, but the operation can still violate application rules if it ignores whitelist membership, instrument identity, lock state, or redemption limits.
How does Canton privacy affect smart contract security?
Canton uses a need-to-know privacy model. Parties receive the transaction information required for contracts in which they have a stake. Signatories and observers, together a contract's stakeholders, therefore affect both authorization and who receives contract and transaction information.
This needs to be checked during an audit.
Adding an observer can expose contract information to another party. Removing an observer can also break an application if that party needs the information to validate or operate a workflow.
Choice observers are also different from contract observers. A party that observes a contract is not automatically informed about every non-consuming exercise on that contract.
- For financial applications, the audit should therefore establish which parties learn that a contract was created, which learn that it was consumed and which see a particular choice. It should also check whether a party can learn information about another organization's holdings through an observer or choice, and whether the privacy model matches the intended business relationship.
Privacy should be treated as part of the application's security properties, not as a separate infrastructure concern.
What are the security implications of contract IDs in Daml?
Canton workflows frequently pass contract IDs (CIDs) between choices. A contract ID identifies a specific contract instance, so the application needs to validate that the referenced contract is the one expected by the workflow.
A valid contract ID is not necessarily the correct contract ID.
For example, a settlement choice may receive an order contract and a holding contract. Fetching the holding proves that the contract exists and is active. It does not by itself prove that the holding belongs to the order, the expected party, or the expected instrument.
This is particularly important for workflows where one operation consumes a contract and creates another contract representing the new state. References stored elsewhere can then become stale.
Canton 3.x documentation also needs to be considered when designing applications around contract references. Contract key support has changed across Canton versions and should not be assumed from older Daml documentation.
- For an audit, every externally supplied CID should raise the same basic questions. Why is this contract being referenced, who is allowed to reference it, and what proves that it belongs to the expected workflow? Can the referenced contract be replaced, what happens when the original contract is consumed, and can an optional or missing reference change the authorization result?
How do consuming and non-consuming choices in Daml affect security?
A consuming choice archives the contract it is exercised on. A non-consuming choice leaves the contract active and can be exercised again.The distinction matters for security.
A choice that changes a limit, records an action, or updates application state may need to consume the contract. If it is non-consuming, the same state can potentially be used again.
The opposite mistake is also possible. A choice intended to perform a read or validation can accidentally be consuming and archive a contract.
Audits should review the consuming behavior of every choice that changes or validates an important state.
How should token and asset accounting be verified in Canton audit?
Financial applications usually have accounting properties that must hold across the entire workflow.
- For a tokenized asset, total supply should match the outstanding holdings, and minting and burning should each change supply exactly once. Transfers should not create or destroy value, and a settlement should never be counted twice. Locked holdings should not be usable by incompatible operations, and cancellation should return the system to a valid state.
These properties cannot always be checked by looking at the mint and burn choices alone.
Every transition that creates, consumes, locks, unlocks, or recreates the asset needs to preserve the accounting invariants.
How should locks, pledges, and time restrictions be audited in Daml?
Locks are only useful if every operation that can consume or recreate the locked state respects them.
A holding may be locked for settlement, pledged as collateral, or restricted by another workflow. It is not enough to check the lock in the obvious transfer path.
- The audit should look for every choice that can consume the holding or create a new holding from it. That includes choices that split, merge or redeem holdings, transfer ownership, or release or modify the lock.
The audit should take every field that represents a restriction, find every choice that can change the state it protects, and check that the restriction survives each transition.
How should multi-party settlement flows on Canton be audited?
Canton is designed for workflows involving multiple parties. Daml transactions can atomically create and consume contracts across those parties, while the privacy model limits which parts of the transaction each party receives.
The security problem in these applications is often the relationship between contracts.
Suppose an order creates a settlement instruction, which later causes a token transfer. The settlement step should be tied to the exact order and the exact asset state that the order authorized.
If the final step accepts a caller supplied holding CID without checking its relationship to the order, the workflow can settle a different holding from the one that was originally approved.
For multi-party applications, the audit should trace the state from the first authorization to the final settlement. Each step should identify the contracts created by the previous step and verify that they are the contracts expected by the workflow.

What invariants should a Canton audit check?
An invariant is a property that must hold at all times, whatever parties or other contracts do. "A consumed contract cannot be reused" is one. The exact invariants depend on the application, but financial Canton applications commonly need properties such as:
- Only the intended parties can authorize an operation.
- A referenced contract belongs to the expected party, instrument, and workflow.
- A consumed contract cannot be reused.
- Locked or pledged holdings cannot bypass the restrictions protecting them.
- Minting and burning preserve total supply.
- Transfers and settlements do not create or destroy value.
- Redemption limits include all relevant redeemed state.
- Expired allocations cannot be executed.
- Cancelling an order removes or restores all state created by that order.
- Configuration changes cannot leave active workflows pointing to invalid state.
- Observer relationships do not disclose information to unintended parties.
How should Canton applications be tested and verified?
Tests should cover both valid and invalid paths.
For example:
- Exercise every privileged choice with an unauthorized party.
- Supply a valid but unrelated contract ID.
- Supply a consumed or stale contract ID.
- Split and merge locked holdings.
- Redeem pledged holdings.
- Execute a choice after its deadline.
- Repeat a non-consuming choice that changes an important limit.
- Cancel an order after tokens have been allocated or locked.
- Change configuration while an existing workflow is in progress.
- Attempt to settle using a holding that was not created for the relevant order.
- Check observer visibility for each important transaction path.
- Test workflows involving multiple Participant Nodes and parties.
For financial applications, state transition tests are particularly important. The same invariant should be checked before and after every operation that can modify the relevant state.
Formal reasoning can also be useful for properties that must hold across many possible execution paths, especially accounting and authorization invariants.
What should a team building on Canton prepare before an audit?
A Canton audit has to follow the application state through the complete workflow. There is no single globally visible contract state, privacy is part of the ledger model, authorization is split between Daml contracts and Canton topology, and contract IDs are explicit references between state transitions. Teams that write down their invariants before the audit starts give reviewers a precise target: which parties can authorize each operation, which contract each reference must point to, which restrictions every choice must respect, and who should see each transaction. A choice can have the correct controller and still operate on the wrong holding. A lock can exist and still be bypassed by another choice. A settlement can be authorized and still reference the wrong asset. A time limit can exist in the data and never be enforced.
These are the properties that matter when auditing Canton applications.
Further reading
Certora was awarded a Canton Foundation grant to build an open-source static analysis tool for Daml cross-package interactions:
https://www.certora.com/blog/certora-wins-canton-foundation-grant
Frequently asked questions
What is a Canton smart contract audit? A security review of Daml applications running on Canton. It checks the application's logic, how authorization is split between signatories, controllers and observers, which parties receive which information, and the Canton topology around the application.
How is auditing Canton applications different from auditing public smart contracts? Canton has no single globally visible contract state. Privacy is part of the ledger model, authorization is split between Daml contracts and Canton topology, and workflows pass explicit contract IDs between state transitions.
What is the difference between a consuming and a non-consuming choice? A consuming choice archives the contract it is exercised on. A non-consuming choice leaves the contract active, and it can be exercised again.
Does Certora audit Canton applications? Yes. Certora has reviewed Canton applications involving tokenized assets and settlement workflows, and received a Canton Foundation grant to build an open-source static analysis tool for Daml cross-package interactions.
