Assertions
Make every condition count.
Read live state, follow nested data, and build calls from resolved arguments. The core checks ERC-8211 constraints and reverts when they fail.
0xa55e47C835ACD377da79D57162117D9B5Ecf3496Assertions check what has to be true the moment your transaction runs. If one fails, nothing happens.
For DAO proposals, Safe batches, and EIP-7702 wallets.
Adding assertions to a vote
A DAO proposal upgrades a vault and hands admin to a council Safe. Each concern becomes an assertion that runs right after both actions, in the same transaction. If any assertion fails, the entire transaction reverts.
We’re voting to upgrade the vault and hand admin to the council Safe. It executes in seven days. How do I know it lands the way we voted?
Once the actions run, the council Safe owns the vault.
If it doesn’t, the whole proposal reverts.
assert $vault::!{owner()(address)} == $councilSafe "handover didn't land"The owner’s right. But the vault is a proxy. What code is it actually running?
The implementation behind the proxy, read at execution time, matches the audited build.
One call’s answer feeds the next: read the address, then hash its code.
assert @codeHash!($vault::!{implementation()(address)}) == 0xdfff…9ca9 "unaudited code"We’re handing the keys to a Safe. Who holds its keys?
Every signer on the council Safe is on the approved list, and at least three must sign.
The owner list is read live and checked one by one, however long it is.
def @onCouncil! "$o: address -> bool" @includes!($council $o)assert @all!(@safe:owners!($councilSafe) @onCouncil!) "unknown signer"assert @safe:threshold!($councilSafe) >= 3 "threshold too low"●4 assertions · appended to the proposal’s batch
Use cases
Every proposal raises its own questions. Each one becomes a check.
Is there still enough left after this pays out?
Is the oracle price still where it was when we voted?
Is this landing inside the window we agreed on?
Do all our balances, added together, still cover what we owe?
Is the field buried in that struct what we expect?
Is this the token we think it is, by name and not just by address?
The toolkit
We use the main contract to check your conditions. We add a pack when a condition needs math, lists, or a value used more than once.
Make every condition count.
Read live state, follow nested data, and build calls from resolved arguments. The core checks ERC-8211 constraints and reverts when they fail.
0xa55e47C835ACD377da79D57162117D9B5Ecf3496Put numbers to your rules.
The most used expansion pack. Turn live values into precise checks with arithmetic, comparisons, fixed-point math, bytes, strings, and ABI encoding.
0x09e4a7eF82674BaDD27a02E19f3D3e5a1903eA1fCheck the whole set.
Array management: check every or any element, find, filter, sort, deduplicate, and total the lists that contracts return, in one call instead of one read per element.
0xc011ec7f6fAAaa37DE5923D2c6206C9597D16bc7Compute once. Reuse it.
Define a read or a calculation once and reuse the result across a claim, so repeated work is paid for once. Adds lazy branches and guarded fallbacks.
0xe5594e55aCa44ac271209612FA57866130edC9e5Case study
On Jan 29, 2026, TheDAO’s curator multisig moved 71,202 ETH in a single transaction, and nine assertions decided whether it landed.
Assertions 1.0 - Codename: Argos
The same multisig that curated TheDAO in 2016 batched ten calls through a Safe: 69,183 ETH into the staking vault that now endows TheDAO Security Fund, 1,300 ETH re-funding the ExtraBalance withdraw contract for open claims, its last DAO tokens swept, DGD and SAI whitelisted for recovery. A decade of dormant history moved in one shot.
The batch ends with nine calls to assertions.eth: exact balances at every destination, drained sources, whitelist flags set. Had any single check failed, all nineteen calls would have reverted together: no partial transfer, nothing to clean up, try again tomorrow.
Tell the builder what to watch. It turns each condition into an assertion, previews the live value, and adds it to your batch.
Every function on all four contracts →