PCL Policy Admin
The single privileged address that holds write authority over global PCL state — only it can change chain-wide PCL rules.
The Policy Admin is one address (visible to callers via IPcl.policyAdmin()) authorized to register/remove built-in PolicyTemplates and to set/remove the chain-wide GlobalPolicyConfig. Anything that affects every transaction on the network goes through this role. The admin slot is a chain parameter — a single keyholder can't claim or transfer it on their own.
What the admin can do (calls on IPcl)
Only the admin can invoke the following on the PCL precompile (
Note that contract-scoped policies (
0x1000…0005):registerPolicyTemplate(string templateId)— register a built-in template after the chain ships it.removePolicyTemplate(string templateId)— remove an unused template.setGlobalPolicies(GlobalPolicyConfig newConfig)— install or replace the chain-wide PolicySet array.removeGlobalPolicies()— wipe the global config (back to no chain-wide rules).
Note that contract-scoped policies (
registerContractPolicies / changeContractPolicies / removeContractPolicies) are not the policy admin's role — those are gated by the per-config admin field that each ContractPolicyConfig carries.The admin can rotate — don't hard-code it
The admin slot is a chain parameter, not something a single key can claim or transfer on its own. From a dApp builder's perspective the practical consequence is simple: don't hard-code the admin address. Read it on-chain via
IPcl.policyAdmin() whenever you need it. Code that caches a hard-coded value will silently break after a rotation.Reading the current admin
Any caller can verify the active admin without a transaction:
address admin = IPcl(0x1000000000000000000000000000000000000005).policyAdmin(); Wallets and dashboards should rely on this rather than caching a hard-coded address — admin rotations don't break correctly written code.
Blast radius
A compromised admin key could install a denylist that blocks every transaction or a permissive config that disables KYC enforcement chain-wide — so the blast radius is large. The chain-parameter design constrains that risk: a single key can't seize the slot, and any reassignment is visible on-chain. For your own code, the practical mitigation is to watch
setGlobalPolicies / removeGlobalPolicies events on the PCL precompile address if your dapp's behavior depends on a specific chain-wide rule being active.PolicyAdmin vs ContractPolicyConfig.admin
These are different roles. PolicyAdmin governs the global rules (one slot per chain). The
admin field on a ContractPolicyConfig governs the rules attached to one specific contract address and is held by whoever the contract owner chose at registration time. Rotating one does not affect the other.