Maroo Architecture

core external-dapp

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

Maroo combines an EVM execution environment (provided by 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

A precompile is a smart contract whose logic is implemented in the chain client's native language (Go) instead of EVM bytecode, deployed at a fixed reserved address. From a Solidity caller's perspective it is called almost like a regular contract — the same 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

Every transaction flows through the same gate before execution.

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

PrecompileAddressWhat it bridges toDetail
OKRW0x...001x/okrw + x/bankokrw-precompile-overview
PCL0x...005x/pclpcl-precompile-overview
EAS0x...009x/eas (bridge to Ethereum Attestation Service)eas-precompile-overview
Agent0x...00Ax/agent + ERC-8004 IdentityRegistry preinstallagent-precompile-overview
Privacy0x...00bx/privacy — shielded OKRWprivacy-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.

Next Steps

ESC
Type to search