Maroo Architecture
Cosmos SDK + EVM hybrid with native precompiles bridging Solidity to chain-level functionality.
Maroo is a Cosmos SDK + EVM hybrid chain with CometBFT consensus. Solidity contracts work as-is with standard tooling (Hardhat, Foundry, ethers/viem), and the Maroo precompiles — OKRW, PCL, EAS, Agent, Privacy — live at fixed EVM addresses and bridge those contracts to chain-specific functionality (stablecoin, compliance, identity, AI-agent registry, shielded transfers).
Key Features
EVM-Compatible
Standard Solidity, ABI, JSON-RPC. Hardhat / Foundry / ethers / viem work without Maroo-specific patches.
Native Precompiles
OKRW (gas + stablecoin ops), PCL (compliance), EAS (KYC/KYB attestation), Agent (ERC-8004 agent identity), Privacy (shielded OKRW).
Compliance at Consensus Level
PCL checks each transaction's own call against the global policies at submission and again in the chain's pre-execution checks, rejecting one that violates them before execution with a structured ReasonCode. A PCL-wrapped contract's policies run in its proxy hooks during execution, and the global policies run again after execution. A violation found there fails the transaction, which is still mined and charged gas.
OKRW-Denominated Gas (EIP-1559)
Base fee + priority tip both paid in atokrw. Fee market is EIP-1559–compatible, so standard tooling computes correct values.
Architecture
graph TB
subgraph EVM["EVM Execution Environment"]
SC["Solidity Smart Contract"]
end
subgraph PC["Native Precompiles (fixed addresses)"]
OKRW["OKRW<br/>0x..001"]
PCL["PCL<br/>0x..005"]
EAS["EAS<br/>0x..009"]
AGT["Agent<br/>0x..00A"]
PRV["Privacy<br/>0x..00b"]
end
STATE["Maroo chain state<br/>balances · policies · agents · shielded pool"]
EASC["EAS contracts<br/>SchemaRegistry 0x…006 · EAS 0x…007 · Indexer 0x…008"]
SC -->|call| OKRW
SC -->|call| PCL
SC -->|call| PRV
SC -->|call| EAS
SC -->|call| AGT
OKRW -->|reads · writes| STATE
PCL -->|reads · writes| STATE
PRV -->|reads · writes| STATE
EAS -.->|returns the EAS contract addresses| EASC
AGT -->|reads| STATE
classDef evm fill:#0096AA,stroke:#0096AA,color:#fff;
classDef precompile fill:#FF8C50,stroke:#FF8C50,color:#fff;
classDef module fill:#8CC3C3,stroke:#8CC3C3,color:#fff;
class SC,EASC evm;
class OKRW,PCL,EAS,AGT,PRV precompile;
class STATE module; Maroo's layered stack. Solidity contracts call native precompiles at fixed addresses. The OKRW, PCL and Privacy precompiles read and write the chain's native state — balances, policies, the shielded pool. The Agent precompile only reads it: it returns the agent index and its parameters. The EAS precompile only returns the addresses of the EAS contracts (SchemaRegistry, EAS, Indexer); attestations live in the EAS contract.
Architecture in one paragraph
x/vm plus an EIP-1559 fee market) with native modules for Maroo-specific functionality — x/okrw (stablecoin minting), x/pcl (compliance), x/agent (ERC-8004 agent index), x/privacy (shielded OKRW) — alongside standard chain modules (auth, bank, staking, gov). OKRW balances live in the bank module. x/eas stores only its parameters (the addresses of the three EAS contracts) and, on PCL's behalf, reads the EAS contract and Indexer that an EAS_POLICY names (typically the canonical preinstalls, as in the testnet's global policy). CometBFT consensus gives instant, fork-free finality.For an app developer the practical effect is: write Solidity, deploy it, call standard tooling. The Maroo-specific surface appears via the Maroo precompiles.
What is a precompile
interface IFoo { ... } import, the same IFoo(address).bar() syntax — with one difference that bites: a precompile has no EVM bytecode (eth_getCode returns 0x). Solidity checks the target's code size before a high-level call to a function that returns nothing, so such a call reverts with empty data before it reaches the precompile. Call those functions low-level — address(…).call(abi.encodeCall(IFoo.bar, (…))) — and bubble the revert data; functions that return values work with the normal syntax. The difference is that the precompile can read and write chain-level module state directly, bridging Solidity to functionality that wouldn't fit in EVM bytecode (e.g., minting OKRW, evaluating a PCL policy). EAS is not one of them: attestations live in the EAS contract preinstall at 0x1000000000000000000000000000000000000007, which is ordinary EVM bytecode, and the EAS precompile only returns the schemaRegistry, eas and indexer addresses (getParams).Maroo's precompile addresses are stable; you can hard-code them or import from
@maroo-chain/contracts. On Maroo Testnet they did not all exist from genesis: OKRW and PCL did, EAS and Agent arrived with the v0.4.0 upgrade (block 6,372,905) and Privacy with v0.8 (block 14,882,540), so a call or log filter against them at an earlier height finds nothing.Transaction lifecycle
1. Pre-execution checks: PCL preflight against the global policies, for direct calls and the regulated path alike → signature → fee deduction (in
atokrw) → nonce → gas-limit check.2. Execution: EVM runs the bytecode.
3. State commit: changes are persisted; events emitted.
The node's JSON-RPC runs this same check when a transaction is submitted, so
eth_sendRawTransaction refuses a violating transaction and never broadcasts it. Inside the chain, the PCL preflight is the first compliance gate: a transaction whose own call already violates an active global policy (denylist, attestation requirement, volume limit, etc.) is rejected here, before execution, with a structured ReasonCode. It is not the only one. A PCL-wrapped contract's own policies run in its proxy's preCall / postCall hooks during execution, and the global policies run again after execution over the transfers the transaction made; a violation found there fails the transaction, which is still mined and charged for its gas. See pcl-policy-enforcement and pcl-reason-codes.flowchart LR
Tx["Tx enters"] --> AH["Pre-execution checks<br/>PCL preflight · signature · fee · nonce · gas"]
AH -->|pass| Exec["EVM execution"]
AH -->|reject| Rej["Rejected before execution<br/>(PCL ReasonCode or SDK error)"]
Exec --> State["State updated, events emitted"]
classDef ok fill:#0096AA,stroke:#0096AA,color:#fff;
classDef gate fill:#FF8C50,stroke:#FF8C50,color:#fff;
classDef bad fill:#AA0019,stroke:#AA0019,color:#fff;
class AH gate;
class Exec,State ok;
class Rej bad; Transaction flow: every tx goes through the chain's pre-execution checks (including the PCL preflight) before execution.
The core precompiles
| Precompile | Address | What it bridges to | Detail |
|---|---|---|---|
| OKRW | 0x...001 | x/okrw + x/bank | okrw-precompile-overview |
| PCL | 0x...005 | x/pcl | pcl-precompile-overview |
| EAS | 0x...009 | x/eas (bridge to Ethereum Attestation Service) | eas-precompile-overview |
| Agent | 0x...00A | x/agent + ERC-8004 IdentityRegistry preinstall | agent-precompile-overview |
| Privacy | 0x...00b | x/privacy — shielded OKRW | privacy-precompile-overview |
Identity primitives are split into two precompiles intentionally: EAS is for human/corporate attestations (KYC/KYB), Agent is for ERC-8004 AI agent identity (KYA) — the attestation models differ enough that one bridge each is cleaner than a single combined surface.
Click through to each precompile page for the Solidity interface, fixed address, and call examples.