blog · cleanverse · updated 2026-10-04

Money that cannot reach a wallet that is not cleared

Most compliance checks are a flag the application could skip. Ours sits in the settlement path itself: the escrow reads the worker's Cleanverse identity on chain at the moment it pays. If the identity is not there, it reverts.

Identity coupled to the money, not beside it

An agent marketplace pays workers for jobs. The compliance question is simple: is the wallet about to receive this money cleared to receive it? An off-chain check answers it once, somewhere else. The payment then trusts that answer. We put the check where the money moves. Our gate contract asks the Cleanverse validator for the recipient's identity status inside settle. If the answer is not an active, verified identity, the transaction reverts and the escrow keeps the funds.

Live CVI status: testnet worker verified, our deployer not cleared on testnet, our deployer not checkable on mainnetLive CVI status: testnet worker verified, our deployer not cleared on testnet, our deployer not checkable on mainnet
The compliance page reads each gate's cviStatus on every request. Nothing here is typed in. The three states are different answers and the page keeps them apart.

The pass and the refuse, as real transactions

We registered our gate as a compliance pool with the Cleanverse validator on Monad testnet, set its rule and had a tier-20 identity issued to a test worker. No personal data was sent: the identity field is optional. Then we ran the same job twice.

register the gate0x1fde7e51…64cce
is_register returns true
issue a CVI0x6ae7f07b…aef057
worker 0xaA51…0936, tier 20, active
pass: settle to the verified worker0xea913ac3…95174f
status 1, worker balance 0 then 1,000,000 tUSDC units
refuse: settle to a wallet with no CVI0xd381c3e1…0539d0
status 0, reverted CviNotVerified(), the escrow still holds the job
Each step is a transaction on Monad testnet (chain 10143). Open any of them.

The compliance asset on mainnet

Cleanverse also issues Verified Assets. Access USDC is the one on Monad mainnet: an ERC-20 whose every transfer goes through a policy contract first. Before wiring it into the escrow we read, off the chain, exactly what that policy does. Asking it whether our house wallet may send one unit answers with a revert, before any balance check:

$ cast call 0x36489bE45fa84f70a0c2BDB11D824Be608CB12Dd 'canTransfer(address,address,address,uint256)(bool)' \
  0xaC0893567D43C3E7e6e35a72803df05416C1f20D 0xDB6c6340342e71A63cD11Ebac2185204b7777777 \
  0xaA514cD6573f95DdD0df78ec1Fdcb8dA05E70936 1 --rpc-url https://rpc.monad.xyz
Error: server returned an error response: error code 3: execution reverted, data: "0xa6725971000000000000000000000000db6c6340342e71a63cd11ebac2185204b7777777"
The revert data names the sender that is not cleared. The policy checks both ends of every transfer and requires a tier-5 identity on each.

That rule applies to every hop. An escrow holding aUSDC moves it from the buyer to the gate to the escrow contract on the way in, then back out to the worker. Each of those four addresses needs its own tier-5 identity. A contract can hold one. Until all four are issued, a mainnet settlement in aUSDC reverts on the first hop and nothing moves. That is the asset working as designed.