Demo
New to B20? See the B20 Token Standard for the concepts and a full launch walkthrough. These samples target
base-std@be6d045, viem@2.55.11, and Base Foundry v1.1.1.How Policies Work
The Policy Registry is a singleton precompile that stores each member list once. A token stores only auint64 policy ID per scope. When a gated function runs, the token calls isAuthorized(policyId, account) on the registry. Many tokens can share one policy; an update to the policy is immediately visible to every token that references it.
Scopes gate specific functions. TRANSFER_SENDER_POLICY and TRANSFER_RECEIVER_POLICY check the sender and recipient on every transfer and transferFrom. MINT_RECEIVER_POLICY checks the recipient on every mint. All three default to ALWAYS_ALLOW (0) until you bind a policy.
An allowlist authorizes only accounts in the set. An empty allowlist authorizes nobody, so seed your intended holders before binding the policy.
Create and Bind a Holder Allowlist
The token returns the new policy ID for both transfer policy scopes.
Update Membership
After creation, only the policy admin can add or remove accounts. CallupdateAllowlist(policyId, true, accounts) to add and updateAllowlist(policyId, false, accounts) to remove. The change is visible to every token that references the policy on the next call. No second updatePolicy is needed on the token.
To combine a KYC allowlist with a sanctions blocklist, create an INTERSECT composite policy referencing both simple policies, then bind the composite ID to the token’s scopes. See the B20 token standard for the full policy type reference.
See Also
Block an Account
Deny a specific address.
Policy Integration (B20 Standard)
Policy hooks in the B20 standard.