Documentation

Prove the history. Keep the collateral.

Meritr is an autonomous credit protocol on Creditcoin. It reads a borrower's real repayment history from another chain through Attestcoin, scores it into portable credit, and when a position falls into distress it restructures the debt instead of liquidating it. The borrower keeps every unit of their collateral.

Every credit fact in the system arrived as a proof the Creditcoin runtime itself validated. There is no oracle operator, no multisig relayer and no trusted price poster anywhere in that path - not as a design goal, but as a property you can test in one command.

What Meritr is

Onchain credit is amnesiac and brutal, and Meritr answers both halves.

Amnesiac: a borrower with three years of flawless Aave repayments on Ethereum arrives on a new chain as a stranger. Their history is real and public, but no contract on the destination chain can verify it without trusting somebody to report it faithfully.

Brutal: every major lending market answers distress with exactly one action - liquidation. A temporary drawdown ends the borrower's equity, dumps collateral into a falling market and pays a bonus to a bot. Traditional finance restructures distressed debt every day. DeFi seizes it.

How it works

Ethereum mainnet                 Creditcoin testnet (102031)
────────────────                 ───────────────────────────────
Aave V3 repayment    ──proof──▶  Attestcoin precompile 0x…0FD2
Aave V3 supply                          │  verifies inclusion
Aave V3 liquidation                     ▼  and continuity
                                 MeritrAttestor ──▶ credit memory
                                        │
                                        ▼
                                 MeritrVault ◀── agent triggers
                                        │        restructuring
                                        ▼
                                 MeritrPassport (soulbound)

A relayer watches Aave V3 on Ethereum, asks Creditcoin's proof-builder for a proof of each relevant transaction, and submits it to MeritrAttestor. The contract hands the proof to the precompile, and only what the precompile accepts becomes a credit fact.

Where everything lives

Network
Creditcoin CC3 testnet, chain id 102031
BlockProver precompile
0x0000000000000000000000000000000000000FD2
ChainInfo precompile
0x0000000000000000000000000000000000000FD3
Proof-builder
https://proof-gen-api.cc3-testnet.creditcoin.network
Source chain
Ethereum mainnet, Aave V3 - chainKey 3
Live console
/app
Project deck
deck.pdf
Creditcoin docs
docs.creditcoin.org
Source verification
every contract above is source-verified on Blockscout - the links open the code, not the bytecode

Attestcoin integration

Attestcoin is Creditcoin's decentralised oracle: attesters watch a source chain, reach quorum, and submit attestations to an attestation chain. A smart contract can then hand a proof to the BlockProver precompile and trust the fields it decodes. Creditcoin calls this half of the protocol readability, and it is what Meritr uses.

Readability is live; writeability is not. The Creditcoin team confirmed in the season kickoff AMA that readability is available on testnet and mainnet today, while writeability - acting on a foreign chain through the protocol - is in its final phase of development and out of scope for this season. Meritr claims readability only. Reads carry no protocol fee; ATC covers staking, slashing, rewards and future writeability fees, while CTC pays gas.

MeritrAttestor inherits ASCBase from @gluwa/asc-contracts. Ingestion sets the active chain key, then self-calls execute so that a direct call to the inherited entry point reverts with DirectExecuteForbidden - the contract will not process a payload that did not come through its own front door.

Which logs count is not hardcoded. An onchain schema registry keyed by (chainKey, emitter, topic0) decides whether a log is a repayment, a collateral supply, a borrow or a liquidation, so a new market can be registered without redeploying the contract.

Chain keys

A chainKey is not an EVM chain id, and its value differs per Creditcoin network. This is the single easiest way to get an Attestcoin integration silently wrong: a mismatched key fails no assertion, it simply means no proof ever matches a schema and the credit history stays empty forever.

Ethereum mainnet, on Creditcoin testnet
chainKey 3
Sepolia, on Creditcoin testnet
chainKey 1
Ethereum mainnet, on Creditcoin mainnet
chainKey 1
Base, Solana, anything else
not registered - Attestcoin cannot prove it

Meritr does not trust its own table. scripts/verifyChainKeys.js reads the ChainInfo precompile at 0x…0FD3 and compares it against the catalogue, and deployment aborts on a mismatch.

Credit scoring

Proven facts fold into a 300-900 score through CreditMath.sol, across five weighted components: repayment volume, repayment count, collateral history, wallet maturity and liquidation penalty. The weights sum to basis-point precision so no component can silently dominate.

The score sets the borrower's interest rate band and borrowing capacity. It is recomputed onchain from attested facts, never supplied as an argument.

Vault & restructuring

The load-bearing design decision in the entire protocol is this signature:

function restructure(address borrower)
    external
    returns (uint256, uint256, uint256);

No rate. No amount. No score. No signature over off-chain numbers. The vault re-reads the score from MeritrAttestor - whose every input carries an Attestcoin proof - and recomputes each term through the same library the agent used. The agent decides whether and whom. The chain decides how much.

Restructuring cuts the rate, extends the term and retires debt from a protocol reserve toward a health factor of 1.35 - drawing at most 25% of the reserve in one event, and nothing at all when the reserve is empty, in which case it degrades to rate relief and a term extension. It has no code path that moves collateral at all; seizure exists only in the separate liquidation backstop, which activates below a health factor of 1.

Credit passport

MeritrPassport is a soulbound ERC-721: transfers revert in the _update hook, and approve and setApprovalForAll revert outright. Artwork is generated fully onchain as SVG, so the token depends on no external host.

On the name. "ZK-Credit" describes a commitment scheme today, not a SNARK. The passport commits to a score without republishing the underlying facts; it does not yet prove statements about that score in zero knowledge. Said plainly here rather than implied by the branding.

What the agent decides

The DeAI risk agent watches every open position, ranks them by expected loss averted, and triggers restructuring on the position where intervention is worth the most. That ranking is the entire scope of its discretion.

Its arithmetic is checked against the chain's. agents/scoring.py mirrors CreditMath.sol exactly, including integer truncation, and a parity suite runs vectors generated from the deployed library asserting every component of every score matches. A one-wei divergence fails the build.

Safety model

A compromised agent key can
trigger restructurings the protocol would already have approved
It cannot
invent a score, grant itself a rate, choose an amount, or drain the reserve
If the agent goes offline
anyone may trigger the identical restructuring after a 6-hour grace period
Per-loan limits
a cooldown between interventions and a hard cap on their number
Deployer key
never placed on the server that runs the agent

Borrower protection does not hinge on a server staying up, and the agent is not a liveness dependency for the protocol.

Run it yourself

git clone https://github.com/mrnetwork0001/Meritr
cd Meritr && npm install
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt

npx hardhat test        # 50 Solidity tests
.venv/bin/pytest -q     # 39 Python tests, incl. score parity

npm run backend         # risk API
npm run dev             # console

Verify the proofs

The claim that no key can insert a credit fact is worth exactly what the precompile's refusal is worth, so you can make it refuse on demand. This fetches a real Aave repayment proof, asks the live precompile to judge it, flips a single byte inside the proven transaction, and asks again:

npm run verify:proof

genuine proof      -> ACCEPTED
one byte altered   -> REJECTED (Merkle proof validation failed)

verify is a view function, so this costs no gas and needs no funded account. Every fact in MeritrAttestor cleared that same gate.

What is real

Creditcoin testnet has no canonical stablecoin, so the lending market trades a demo pair Meritr deployed itself. Both tokens have an open mint and are worth nothing. That is disclosed rather than papered over - and it does not reach the credit data.

Credit facts
proof-verified - nobody can create one without the precompile
Borrowed asset (mUSD)
synthetic, ungated mint, price pinned at $1.00
Collateral (mWETH)
synthetic unit, marked with a live Chainlink ETH/USD feed

The separation is checkable in one command:

grep -ci 'vault' contracts/MeritrAttestor.sol contracts/MeritrPassport.sol
# → 0

The credit layer holds no reference to the market layer. Swapping the demo market for real assets would leave every score unchanged.

Limitations

Stated because a credit protocol that hides its assumptions is not one anyone should use.

Collateral pricing is governance-fed
the single trusted input in the risk path; production needs a real feed
Source timestamps are approximated
the prover exposes a verified height, not a verified timestamp
The contracts are unaudited
treat any mainnet deployment accordingly
The demo market tokens are freely mintable
and immutable in the vault, so swapping them needs a new deployment
“ZK-Credit” is a commitment scheme
not a SNARK, today