1 · Ask the chain
Ctx — the caller pins every one of these. None is inferred.
2 · What came back
| Gate | Condition | Violated | Unreadable |
|---|
3 · Decode a reasonBits value by hand
The same decoder, with no network in the way. Paste any value the guard produced — from a reverted transaction, a log, or a test run.
How this page decides
Deny-by-default. Each row above is a reason bit.
A signal the guard cannot read is a BLOCK, not a pass —
an unreadable condition is not a satisfied condition. The decoder on this page implements
the decoding contract from GuardBits.sol in full, because a decoder that gets
it wrong recreates the exact “could not determine, therefore allow” path the
contract exists to close:
ok == (reasonBits == 0). The verdict is never re-derived from a subset of the bits.- Any bit set outside
KNOWN_MASKmeans the payload came from a newer version than this decoder. An old decoder must block, never silently ignore it. reasonBits & RESERVED_MASKmust be zero. Bits 7 and 23 are permanently reserved; non-zero means this payload was not produced by this version.- Bit 255 is an aggregate, not a ninth gate: it is set if and only if at least one bit on
the unreadable plane is set. The check uses
UNREADABLE_MASK, never a bit range. - Per gate, the violated bit and that gate's own unreadable bit are mutually exclusive. Two different gates may each contribute one.
- When bit 0 (G0) is set, bits 1, 3 and 4 are true statements about that canonical control plane — not necessarily statements about this token's actual controller.
- A failed call is a failed judgement, never
reasonBits == 0. An empty return, a revert this page cannot decode, or a transport error is reported as undetermined, and undetermined is treated as a block.
The control arm, and why it is here
Every run first asks the endpoint for eth_chainId. A rejected or unreachable
RPC makes every call fail, which reads exactly like “the contract has none of
these functions” or “every gate is blocking”. The tell is that the failures
are uniform. Keeping a call that is known to succeed in the same run is what separates a
transport symptom from a contract fact.
On a chain where the token and control plane do not exist
Both chains receive the same build artifact, deployed with a plain CREATE,
never CREATE2 — different addresses on each chain are expected, not a
defect. On a chain where the token and the control plane do not exist, every call returns
ok == false with at least the unreadable bits of G0 through G5 and the
aggregate bit set. That is the designed consequence, not a bug. On Arbitrum
Sepolia only G0, G6 and G8 have anything to read.
Time of check, time of use
An off-chain answer from this page is advisory and carries a time-of-check to time-of-use window; it can be stale as soon as the next block. Only in-transaction evaluation through the integration library, reverting on failure, is atomic. This page is a window onto the guard, not a substitute for calling it.
Known limitations
The guard reports the absence of eight named conditions, plus an unreadable bit when it could not check one. It does not check the integrator's own accounting.
Once a ratio transition has completed, the ratio condition reads clean; with every other condition clear, reasonBits is exactly 0 and the guard lets a redeem through. Both demo vaults pay one token per share and never use the multiplier in that payout, so after the transition both pay the wrong amount. In the tested case the ratio halves: each vault pays twice the fair amount, and the first redeem empties the guarded vault, so the next holder's redeem reverts. This exposure is declared, not fixed: test/Integration.t.sol measures it (AS-29d).
G7 was withdrawn on 2026-09-04; its bit stays permanently reserved. This page is not an audit and carries no warranty.