RWA Guard

Today there is no on-chain primitive that answers the question “is this token safe to act on, right now?” RWA Guard makes that question a single call.

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.

1 · Ask the chain

Ctx — the caller pins every one of these. None is inferred.

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:

  1. ok == (reasonBits == 0). The verdict is never re-derived from a subset of the bits.
  2. Any bit set outside KNOWN_MASK means the payload came from a newer version than this decoder. An old decoder must block, never silently ignore it.
  3. reasonBits & RESERVED_MASK must be zero. Bits 7 and 23 are permanently reserved; non-zero means this payload was not produced by this version.
  4. 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.
  5. Per gate, the violated bit and that gate's own unreadable bit are mutually exclusive. Two different gates may each contribute one.
  6. 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.
  7. 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.