Fundamentals

Chapter 4 / 15

Guards

only, when, given — declarative access control and invariants.


Covenant's guard system replaces ad-hoc require() chains with declared pre- and post-conditions. Guards appear in the function signature — they are part of the interface, not buried in the body.

Security note: OMEGA V4 finding KSR-CVN-011 (Critical) discovered that a prior compiler version silently dropped only() clauses during IR lowering — every deployed contract was wide open. V0.7 fixes this and adds an integration test that verifies guard bytecode is emitted.

guards.cov
record Multisig {
    owner:    address;
    guardian: address;
    locked:   bool;
    nonce:    u64;

    error Unauthorized();
    error AlreadyLocked();

    // only(expr) — caller must satisfy expr, else revert
    action change_owner(new_owner: address) only(msg.sender == self.owner) {
        self.owner = new_owner;
    }

    // when(cond) — precondition checked before body runs
    action lock() only(msg.sender == self.owner) when(!self.locked) {
        self.locked = true;
    }

    // Multiple guards compose with AND semantics
    action unlock(sig: bytes)
        only(msg.sender == self.guardian)
        when(self.locked)
    {
        self.locked = false;
        self.nonce += 1;
    }

    // given(cond) — postcondition checked after body runs
    // Reverts the entire action if the condition is false after execution
    action set_guardian(g: address)
        only(msg.sender == self.owner)
        given(g != address(0))
        given(g != self.owner)
    {
        self.guardian = g;
    }

    // Shorthand: only(self.owner) === only(msg.sender == self.owner)
    action emergency_reset() only(self.owner) {
        self.locked = false;
        self.nonce += 1;
    }
}

Annotations

only(expr)emits a JUMPI at function entry that reverts if expr is false. Shorthand only(self.owner) expands to only(msg.sender == self.owner).
when(cond)a precondition: checked at the start of the action body, before any state changes.
given(cond)a postcondition: checked after the body executes. Reverts (and undoes state changes) if false.
Multiple guardscompose with AND semantics — all conditions must hold.
KSR-CVN-011was critical because guards look present in source but produced zero bytecode. Always run covenant audit before deployment.

Key takeaways