Request Whitelist
The Request Whitelist is a periphery contract that sits next to the core protocol. It is not part of the Facility / Request / Fund / Position Manager pipeline that moves capital — it exists so that integrators (most importantly bridge facilitators) can verify on-chain that a given Request contract was deployed as part of the 3F flow rather than spoofed by a third party.
What it is
Section titled “What it is”RequestWhitelist is a single-purpose attestation registry. For any address a, it returns one of four states through isWhitelisted(address):
enum WhitelistStatus { NotWhitelisted, Whitelisted, PausedNotWhitelisted, PausedWhitelisted}Only Whitelisted should be treated as authorised. The two Paused* variants are returned while a circuit-breaker pause is active and exist so integrators can distinguish “never listed” from “temporarily gated” when surfacing the state to a user.
A Request contract is itself fully self-contained — bridge facilitators settle through it via signed offers and EIP-1271 checks. The whitelist is a separate layer of attestation: it does not change the Request’s behaviour, it lets external parties decide whether they trust this particular Request as an officially-issued one before sending funds or signatures to it.
Why it exists
Section titled “Why it exists”The Facility deploys a new Request per intent through a factory, so the address of any given Request is not predictable in advance. Without an on-chain attestation, a bridge facilitator integrating programmatically would have to trust an off-chain channel to learn which addresses are legitimate. The whitelist replaces that off-chain trust with an on-chain check that any contract or off-chain script can perform.
In practice, the registry is updated when 3F governance attests that a freshly-deployed Request belongs to a real intent. From that point on, integrators can gate their interaction strictly on isWhitelisted(request) == Whitelisted.
How governance writes to it
Section titled “How governance writes to it”The contract has two parallel write paths that converge on the same storage bit:
- Owner-direct — a trusted multisig owner can call
whitelist(address[])andunwhitelist(address[])directly. This is the bootstrap lane. - Validator quorum — a configured set of validators can flip the same bit by submitting a quorum of EIP-712 signatures (
whitelistBySig/unwhitelistBySig). This is the distributed automation lane.
The registry is built to graduate from the first path to the second: while the owner is set, both paths are live; once renounceOwnership() is called, the owner-direct paths become permanently unreachable and only the quorum path remains. Admin operations on the validator set itself (add, remove, set quorum, set compliance officer) follow the same pattern — direct while the owner is set, quorum-signed afterwards.
A separate compliance officer role can pause the registry for a bounded window. While paused, isWhitelisted reports the Paused* variants and new whitelisting calls revert; revoking attestations stays available so the pause is a circuit breaker rather than a lockout.
Security properties
Section titled “Security properties”A few properties are worth highlighting without going into the full implementation:
- Single source of truth. Both write paths funnel through the same storage bit and emit the same
Whitelisted/Unwhitelistedevents, so consumers only ever readisWhitelisted(a). - Replay-resistant signatures. Each validator signature is bound to the validator address, a per-validator nonce, and a deadline. A raisable per-validator nonce floor lets a validator mass-invalidate every signature they ever produced below a chosen value, which is the recovery lever if a key is suspected compromised.
- Removal is permanent. Removing a validator saturates their nonce floor to
type(uint256).max, which combined with the bitmap’s “consumed nonces stay consumed” property makes every signature that address ever produced unusable forever — re-admitting the same key cannot resurrect old signatures. - One-step capture is blocked. The set always satisfies
quorum < validators.length, so a quorum-sized coalition cannot in a single step shrink the validator set down to its own membership. - Pause is bounded and one-way extendable.
pauseFor(seconds)can only pushpausedUntilstrictly forward; shortening a pause requires an explicitunpausefrom the compliance role. Recovery levers (unwhitelist, validator self-invalidate, post-renounce admin paths, owner-onlyrevokeAllRoles) intentionally remain reachable while paused so the breaker cannot lock out the recovery it was built to enable.
Integration
Section titled “Integration”Bridge facilitators are the primary consumer of this registry — see Verifying a Request on-chain on the settlement page for the integration recipe and current deployment address.