Copyright Tweag I/O 2026
cooked-validators is a Haskell library for writing reliable, concise, and
expressive off-chain code for Cardano smart contracts, with a primary focus on
testing, auditing, and behavioral exploration.
It allows you to describe transactions at a high level (via what we call transaction skeletons) and automatically turn them into complete, valid transactions by handling all mechanical aspects such UTxO selection, balancing, minimum-Ada constraints, collaterals or fees.
The library is designed to:
Importantly, cooked-validators is non-opinionated: everything it automates can
also be done manually if needed, allowing users to retain full control over
transaction construction when desired.
With cooked-validators, you can:
cooked-validators in a projectThere are two ways for this integration:
cooked-validators, and all its dependencies, are available on
cardano-haskel-packages
(CHaP). To rely
on a release available there, add the following stanza to your
cabal.project:
repository cardano-haskell-packages
url: https://chap.intersectmbo.org/
secure: True
root-keys:
3e0cce471cf09815f930210f7827266fd09045445d65923e6d0238a6cd15126f
443abb7fb497a134c343faf52f0b659bd7999bc06b7f63fa76dc99d631f9bea1
a86a1f6ce86c449c46666bda44268677abf29b5b2d2eb5ec7af903ec2f117a82
bcec67e8e99cabfa7764d75ad9b158d72bfacf70ca1d0ec8bc6b4406d1bf8413
c00aae8461a256275598500ea0e187588c35a5d5d7454fb57eac18d9edb86a56
d4a35cd3121aa00d18544bb0ac01c3e1691d618f462c46129271bccf39f7e8ee
index-state:
, cardano-haskell-packages 2026-02-13T00:00:02Z
To find the appropriate index state to fill above, look for
cooked-validators on CHaP's packages
list.
Alternatively, if you want to rely on a specific commit or branch not
available on CHaP, you can import cooked-validators directly from GitHub
with the following stanza:
source-repository-package
type: git
location: https://github.com/tweag/cooked-validators
tag: myTag
subdir:
.
where myTag is either a commit hash in the repo, or a tag, such as v10.0.0
(see available
releases).
Note that, should you do that, you would likely still need CHaP for all the other dependencies.
Each release of cooked-validators is pinned to a specific version of
cardano-api which in turn pins
the versions of all other Cardano-related dependencies (including Plutus). Make
sure your project relies on the same version.
This example shows how to create and validate a simple transaction that transfers 10 Ada from Alice (wallet 1) to Bob (wallet 2), without manually handling fees or balancing.
Create a new Haskell module, for example Demo.hs
Import your required dependencies
import Cooked
import Plutus.Script.Utils.Value qualified as Script
Start the definition of a MockChain run:
myDemoRun :: StagedMockChain ()
myDemoRun = do
Define aliases for Alice and Bob:
alice <- define "Alice" $ wallet 1
bob <- define "Bob" $ wallet 2
Give some initial funds to Alice:
forceOutputs_ $ replicate 3 $ alice `receives` Value (Script.ada 10)
Take some notes:
noteS "Alice is sending 10 ADA to Bob"
noteS "I let cooked-validators do the heavy lifting for me"
Submit the transaction:
validateTxSkel_
txSkelTemplate
{ txSkelOuts = [bob `receives` Value (Script.ada 10)],
txSkelSignatories = txSkelSignatoriesFromList [wallet 1]
}
Lookup for the UTxOs now owned by Bob, and assert that he indeed possesses 1:
bobUtxos <- utxosAt bob
assert "Bob now has 1 utxo" $ length bobUtxos == 1
Enter a cabal repl, run and print the trace:
> printCooked $ runMockChainDef myDemoRun
Observe the output of printing the run, including:
π Notes:
- Alice is going to send 10 ADA to Bob
- I let cooked-validators do the heavy lifting for me
π MockChain run log:
β New raw skeleton submitted to the adjustment pipeline:
- Validity interval: (-β , +β)
- Signatories:
- Alice [balancing]
- Outputs:
- Pays to pubkey Bob
- Lovelace: 10_000_000
β New adjusted skeleton submitted for validation:
- Validity interval: (-β , +β)
- Signatories:
- Alice [balancing]
- Inputs:
- Spends #d769532!1 from pubkey Alice
- Redeemer ()
- Lovelace: 10_000_000
- Spends #d769532!2 from pubkey Alice
- Redeemer ()
- Lovelace: 10_000_000
- Outputs:
- Pays to pubkey Bob
- Lovelace: 10_000_000
- Pays to pubkey Alice
- Lovelace: 9_826_799
- Fee: Lovelace: 173_201
- No collateral required
β New transaction successfully validated:
- Transaction id: #bff7a56
- Number of new outputs: 2
β
Assertions:
- β Bob now has 1 utxo
π° UTxO state:
β’ pubkey Alice
- Lovelace: 9_826_799
- Lovelace: 10_000_000
β’ pubkey Bob
- Lovelace: 10_000_000
π’ Success with returned value: ()
The rendered Haddock for the current main branch can be found
here.
The CHEATSHEET contains many code snippets to quickly get
an intuition of how to do things. Use it to discover or search for how to use
features of cooked-validators. Note that this is not a tutorial nor a
ready-to-use recipes book.
The IMPORTS file describes and helps to understand our dependencies and naming conventions for imports.
The BALANCING file thorougly describes cooked-validator's automated balancing mechanism and associated options (including options revolving around fees and collaterals).
The OPTICS file describes our usage of optics to navigate our data structures.
The TWEAKS file describes the conventions our tweaks (the building blocks of the attack DSL) follow, regarding naming and branching behavior.
Several blog posts have been written about cooked-validators. As the library
evolves, some code snippets in these posts may have become outdated. However,
the core philosophy remains unchanged, and these articles still provide valuable
insight into how to use the library.
An article
explaining how we use cooked-validators to conduct smart contract audits.
An
article
describing how transaction skeletons are built in cooked-validators and how
the library constructs complete transactions from them.
An article presenting the original idea of using temporal modalities to modify sequences of transactions.
An article explaining
how linear temporal
logic is used in
cooked-validators to deploy modifications over time.
We have a repository of
example contracts with offchain code and tests written using
cooked-validators. Note that these examples are not maintained and thus
written using older versions of the library.
Feel free to visit our issue tracker to seek help about known problems, or report new issues!
cooked-validators is regularly used to audit Cardano smart contracts. You
can see some of the products with have audited on this
page and can get access to a sample of our
audit reports on this
repository.
cooked-validators comes with a template
repository which can be used to
develop offchain code and/or audit code with the tool.
You are free to copy, modify, and distribute cooked-validators under the terms
of the MIT license. We provide cooked-validators as a research prototype under
active development, and it comes as is with no guarantees whatsoever. Check
the license for details.
Haskell
99.1%
Copyright Tweag I/O 2026
cooked-validators is a Haskell library for writing reliable, concise, and
expressive off-chain code for Cardano smart contracts, with a primary focus on
testing, auditing, and behavioral exploration.
It allows you to describe transactions at a high level (via what we call transaction skeletons) and automatically turn them into complete, valid transactions by handling all mechanical aspects such UTxO selection, balancing, minimum-Ada constraints, collaterals or fees.
The library is designed to:
Importantly, cooked-validators is non-opinionated: everything it automates can
also be done manually if needed, allowing users to retain full control over
transaction construction when desired.
With cooked-validators, you can:
cooked-validators in a projectThere are two ways for this integration:
cooked-validators, and all its dependencies, are available on
cardano-haskel-packages
(CHaP). To rely
on a release available there, add the following stanza to your
cabal.project:
repository cardano-haskell-packages
url: https://chap.intersectmbo.org/
secure: True
root-keys:
3e0cce471cf09815f930210f7827266fd09045445d65923e6d0238a6cd15126f
443abb7fb497a134c343faf52f0b659bd7999bc06b7f63fa76dc99d631f9bea1
a86a1f6ce86c449c46666bda44268677abf29b5b2d2eb5ec7af903ec2f117a82
bcec67e8e99cabfa7764d75ad9b158d72bfacf70ca1d0ec8bc6b4406d1bf8413
c00aae8461a256275598500ea0e187588c35a5d5d7454fb57eac18d9edb86a56
d4a35cd3121aa00d18544bb0ac01c3e1691d618f462c46129271bccf39f7e8ee
index-state:
, cardano-haskell-packages 2026-02-13T00:00:02Z
To find the appropriate index state to fill above, look for
cooked-validators on CHaP's packages
list.
Alternatively, if you want to rely on a specific commit or branch not
available on CHaP, you can import cooked-validators directly from GitHub
with the following stanza:
source-repository-package
type: git
location: https://github.com/tweag/cooked-validators
tag: myTag
subdir:
.
where myTag is either a commit hash in the repo, or a tag, such as v10.0.0
(see available
releases).
Note that, should you do that, you would likely still need CHaP for all the other dependencies.
Each release of cooked-validators is pinned to a specific version of
cardano-api which in turn pins
the versions of all other Cardano-related dependencies (including Plutus). Make
sure your project relies on the same version.
This example shows how to create and validate a simple transaction that transfers 10 Ada from Alice (wallet 1) to Bob (wallet 2), without manually handling fees or balancing.
Create a new Haskell module, for example Demo.hs
Import your required dependencies
import Cooked
import Plutus.Script.Utils.Value qualified as Script
Start the definition of a MockChain run:
myDemoRun :: StagedMockChain ()
myDemoRun = do
Define aliases for Alice and Bob:
alice <- define "Alice" $ wallet 1
bob <- define "Bob" $ wallet 2
Give some initial funds to Alice:
forceOutputs_ $ replicate 3 $ alice `receives` Value (Script.ada 10)
Take some notes:
noteS "Alice is sending 10 ADA to Bob"
noteS "I let cooked-validators do the heavy lifting for me"
Submit the transaction:
validateTxSkel_
txSkelTemplate
{ txSkelOuts = [bob `receives` Value (Script.ada 10)],
txSkelSignatories = txSkelSignatoriesFromList [wallet 1]
}
Lookup for the UTxOs now owned by Bob, and assert that he indeed possesses 1:
bobUtxos <- utxosAt bob
assert "Bob now has 1 utxo" $ length bobUtxos == 1
Enter a cabal repl, run and print the trace:
> printCooked $ runMockChainDef myDemoRun
Observe the output of printing the run, including:
π Notes:
- Alice is going to send 10 ADA to Bob
- I let cooked-validators do the heavy lifting for me
π MockChain run log:
β New raw skeleton submitted to the adjustment pipeline:
- Validity interval: (-β , +β)
- Signatories:
- Alice [balancing]
- Outputs:
- Pays to pubkey Bob
- Lovelace: 10_000_000
β New adjusted skeleton submitted for validation:
- Validity interval: (-β , +β)
- Signatories:
- Alice [balancing]
- Inputs:
- Spends #d769532!1 from pubkey Alice
- Redeemer ()
- Lovelace: 10_000_000
- Spends #d769532!2 from pubkey Alice
- Redeemer ()
- Lovelace: 10_000_000
- Outputs:
- Pays to pubkey Bob
- Lovelace: 10_000_000
- Pays to pubkey Alice
- Lovelace: 9_826_799
- Fee: Lovelace: 173_201
- No collateral required
β New transaction successfully validated:
- Transaction id: #bff7a56
- Number of new outputs: 2
β
Assertions:
- β Bob now has 1 utxo
π° UTxO state:
β’ pubkey Alice
- Lovelace: 9_826_799
- Lovelace: 10_000_000
β’ pubkey Bob
- Lovelace: 10_000_000
π’ Success with returned value: ()
The rendered Haddock for the current main branch can be found
here.
The CHEATSHEET contains many code snippets to quickly get
an intuition of how to do things. Use it to discover or search for how to use
features of cooked-validators. Note that this is not a tutorial nor a
ready-to-use recipes book.
The IMPORTS file describes and helps to understand our dependencies and naming conventions for imports.
The BALANCING file thorougly describes cooked-validator's automated balancing mechanism and associated options (including options revolving around fees and collaterals).
The OPTICS file describes our usage of optics to navigate our data structures.
The TWEAKS file describes the conventions our tweaks (the building blocks of the attack DSL) follow, regarding naming and branching behavior.
Several blog posts have been written about cooked-validators. As the library
evolves, some code snippets in these posts may have become outdated. However,
the core philosophy remains unchanged, and these articles still provide valuable
insight into how to use the library.
An article
explaining how we use cooked-validators to conduct smart contract audits.
An
article
describing how transaction skeletons are built in cooked-validators and how
the library constructs complete transactions from them.
An article presenting the original idea of using temporal modalities to modify sequences of transactions.
An article explaining
how linear temporal
logic is used in
cooked-validators to deploy modifications over time.
We have a repository of
example contracts with offchain code and tests written using
cooked-validators. Note that these examples are not maintained and thus
written using older versions of the library.
Feel free to visit our issue tracker to seek help about known problems, or report new issues!
cooked-validators is regularly used to audit Cardano smart contracts. You
can see some of the products with have audited on this
page and can get access to a sample of our
audit reports on this
repository.
cooked-validators comes with a template
repository which can be used to
develop offchain code and/or audit code with the tool.
You are free to copy, modify, and distribute cooked-validators under the terms
of the MIT license. We provide cooked-validators as a research prototype under
active development, and it comes as is with no guarantees whatsoever. Check
the license for details.
Haskell
99.1%