Policy & Compliance
Programmable Compliance Layer (PCL) — covers policy structure, templates, enforcement, and precompile interfaces.
Compliance
Maroo processes transactions through two distinct paths: the Open Path for standard, low-risk activities, and the Regulated Path for high-value or compliant asset transfers. The PCL automatically determines the correct path.
Regulations change. Travel-Rule thresholds shift, sanctions lists update, jurisdictional rules evolve. Maroo separates the policy engine (PCL — stable, rarely changes) from the parameter supply (Legal Oracle — updated as laws and regulations evolve). New regulatory requirements are absorbed by adding a parameter — or, at most, registering a new PolicyTemplate — without touching chain core code. The Legal Oracle's authority to update parameters is itself governance-controlled — every change is visible on-chain and auditable.
Maroo's PCL enables a dual-track system for smart contract interactions. The 'Open Track' consists of standard, direct EVM calls that bypass PCL checks. The 'Regulated Track' is an opt-in model where interactions are routed through the IPcl.runOnPcl function, which enforces all applicable compliance policies before executing the intended logic. This provides developers with the flexibility to design applications with both permissionless and permissioned components.
The Programmable Compliance Layer (PCL) is a core module of the Maroo network that enables the creation and enforcement of compliance policies directly on the blockchain. It intercepts transactions before they are processed, validating them against a set of global and contract-specific rules. This allows for the implementation of complex regulatory requirements, such as KYC/AML checks, transfer restrictions, and volume limits, without altering the core logic of smart contracts.
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.
Every Maroo transaction is filtered through PCL before any state-changing work runs. Global policies (a GlobalPolicyConfig set by the policy admin) are evaluated for all transactions. Contract-scoped policies (a ContractPolicyConfig registered by a contract admin) only apply when a call targets that contract through the regulated path. A failure on any single policy rejects the whole transaction with a typed PCL ReasonCode — no compliance check can be silently skipped.
PCL stores compliance rules as Solidity-defined ABI tuples, not as JSON objects. The hierarchy has three tiers: a PolicyTemplate (the type of rule, registered by the policy admin) is instantiated as a PolicySet (the type ID plus an ABI-encoded parameters blob plus an optional function selector) and bundled into a PolicyConfig (either the global config or a per-contract config). Earlier PCL drafts called the middle tier PolicyRef; the canonical name in the IPcl interface is PolicySet (with its policy field being the ABI-encoded parameter bytes).
Maroo's PCL ships with seven built-in policy templates that cover the most common regulatory and business compliance gates. Each template defines a Solidity parameter struct (encoded into PolicySet.policy via abi.encode) and an evaluation rule. Administrators instantiate them as PolicySet entries and group them under a GlobalPolicyConfig (network-wide) or ContractPolicyConfig (per-contract). New templates can be registered by governance without touching chain core for use of an existing evaluator; new evaluators require a chain upgrade.
The Programmable Compliance Layer (PCL) precompile lives at the fixed address 0x1000000000000000000000000000000000000005 and is the canonical surface for everything compliance-related: registering policy templates, registering per-contract PolicySets, querying current rules, and dry-running an EVM call against policies via runOnPcl. Its module parameters are now reachable through a single getParams() view that returns a PclParams struct containing the policyAdmin (the chain-wide admin authorized to register templates and global policies) and entrypoints (the contract addresses that, when called, route a transaction through the regulated EVM path).
Every PCL rejection carries one of the typed Solidity errors defined on IPcl. Wallet and dApp code should decode the revert payload against the IPcl ABI and key UX off the error name + arguments — never off a free-form string. Codes break into three groups: policy-violation codes (the user's transaction failed a compliance check; some can be cleared by user action), template-management codes (admin tooling errors raised on register… / set… calls; never seen by end users on the regulated path), and internal codes (chain misconfiguration; surface to operators).
Caps a single OKRW transfer made by an agent wallet using a limit value stored as on-chain metadata on the ERC-8004 IdentityRegistry — specifically getMetadata(agentId, "TransferLimit"). The policy struct itself has no configurable fields; the cap is whatever the agent's owner has put in metadata. Skipped for non-agent senders. Used to bound how much value an agent (an automated key) can move per transaction without holding it back from human-controlled accounts.
The simplest PCL template — checks the caller (and, in the global config, often the recipient) against a static list of blocked addresses. Used for sanctions enforcement and frozen-account routing.
Gates a transaction on whether the sender holds a valid (non-expired, non-revoked) attestation issued under a specific EAS schema. The canonical primitive for KYC, KYB, accreditation, and any credential-based gate. Resolves attestations through the EAS precompile so lookups stay cheap during AnteHandler evaluation.
Combines PERIODIC_VOLUME_POLICY's reset-period cumulative tracking with EAS attestation conditioning, giving un-attested senders a strict daily/monthly OKRW cap and exempting attested senders entirely from this template's accounting. The standard primitive for Travel-Rule-style thresholds.
Combines the EAS attestation check with a per-transaction OKRW cap that only fires for un-attested senders. Attested senders are admitted regardless of amount (subject to whatever other policies apply). The most common production pattern for KYC-tiered access — un-attested users can transact small amounts; attested users get unrestricted (or otherwise-bounded) transfers.
Tracks cumulative transaction volume per sender per denom over a configured reset period and rejects transactions that would push the running total above the limit. Distinct from VOLUME_POLICY, which checks each transaction independently. Used for daily / monthly transfer caps and Travel-Rule–style thresholds.
Enforces per-transaction min/max amount limits for one or more token denoms. Each transaction is evaluated independently against the limits — no rolling window, no cumulative tracking. For period-based cumulative limits, see PERIODIC_VOLUME_POLICY.
Maroo is a permissionless chain where anyone can create a wallet. However, it dynamically routes transactions through a Regulated Path or an Open Path based on counterparty identity, transaction size, and asset type.
Hacks, phishing, and clearly illegal fund flows happen in real-world payment systems. Maroo provides three bounded recovery primitives — freeze, burn, reissue — that correct state without rolling back the chain. All three operate only when there's a documented legal basis and the prescribed procedure has been followed; every invocation is logged to Observer Nodes and the governance audit trail. These are not always-on intervention tools, and Maroo prefers forward correction (new transactions that override prior state) over backward rewriting wherever the legal basis allows.