Nothing on this page asks you to trust the site. Each row is a value you can read off the chain, a command you can run, or a test you can execute.
Everything on Creditcoin CC3 testnet, chainId 102031. The table below is the reproducible deployment — the one you can run end to end with World's simulator. The Orb-tree deployment for real verified humans follows it.
| Contract | Address | Source |
|---|---|---|
| AttestedWorldID (Ethereum mainnet) | 0x1122…68ad | deployments.json |
| AttestedWorldID (Sepolia staging) | 0x3a7c…cef7 | deployments.json |
| HumanRegistry | 0x62c2…298d | deployments.json |
| CreditLine | 0x49d5…a2b9 | deployments.json |
| hUSD | 0x4bd7…9640 | deployments.json |
| HumanGate | 0xa3e0…776c | deployments.json |
| RelayReward | 0x9766…afe0 | deployments.json |
| BlockProver precompile | 0x0000…0FD2 | native |
| ChainInfo precompile | 0x0000…0fD3 | native |
| AttestorStash precompile | 0x0000…0fd4 | native |
| EvmV1Decoder library | 0x04B9…D18B | shared |
| World ID manager · Ethereum | 0xf713…ddEa | chainKey 3 |
| World ID manager · Sepolia | 0xb2Ea…7076 | chainKey 1 |
The same contracts verifying against the Ethereum mainnet identity tree instead of Sepolia staging — 30 days terms, for people with an Orb-verified World ID. Open /app?profile=production to use it. hUSD and both AttestedWorldID instances are shared with the table above.
| Contract | Address |
|---|---|
| HumanRegistry | 0x53fc…96af |
| CreditLine | 0x8063…c1cb |
| HumanGate | 0x5442…5b93 |
Not instructions — receipts. A real World ID identity verified on Creditcoin, and a full borrow-and-repay cycle, both with transaction hashes you can open.
The same verification AttestedWorldID performs, as a read-only call.
Copy, paste, run. `cast` is Foundry: curl -L https://foundry.paradigm.xyz | bash && foundryup.
Every attack in the security model, the guard that stops it, and the test that fires it.
| Attack | Reverts with | Test |
|---|---|---|
| Forged root | BatchProofRejected() | AttestedWorldID.t.sol :: test_SingleExecuteRevertsWhenTheProverRejectsTheProof |
| Tampered payload | BatchProofRejected() | AttestedWorldID.t.sol :: test_BatchRevertsWhenTheProverRejectsTheProof |
| Wrong source chain | WrongSourceChain(uint64,uint64) | AttestedWorldID.t.sol :: test_RevertsOnWrongSourceChain |
| Reverted source transaction |
What the widget is pinned to, and what the registry pinned itself to at deployment.
The worker's own log, committed to the repo at evidence/relay-log.jsonl.
31 entries in evidence/relay-log.jsonl.
hashToField(abi.encodePacked(wallet)) — the same value the widget below recomputes from the deployed contract.IDKit.request({... allow_legacy_proofs: true, environment: "staging"}).preset(orbLegacy({ signal: wallet })), rp_context signed with the Humanline RP key (rp_84b02642423cadf5).--recurse-submodules, then bun install && (cd contracts && bun install). Foundry is not vendored — install it with curl -L https://foundry.paradigm.xyz | bash && foundryup.Every contract test, including the negative paths
cd contracts && forge test -vv
Only the negative paths
52 tests. Each one should reject the attack listed below, most with a named custom error.
cd contracts && forge test --match-test "Revert|Rejects|Ignores|Cannot|Survives|Expire|Specific" -vvv
One row from the table below
Every test name in that table is checked against contracts/test/*.t.sol by web's own test suite, so none of them can be invented.
cd contracts && forge test --match-test "^test_RevertsOnThinAttestorQuorum$" -vvv
Fork tests against live CC3 state
Skipped unless CC3_FORK is set, so the default suite stays hermetic.
cd contracts && CC3_FORK=https://rpc.cc3-testnet.creditcoin.network forge test --match-contract Fork -vv
Web unit tests — World ID hashing and formatting
Reproduces hashToField and the external nullifier exactly as the Solidity does.
cd web && bun test
Build a proof for any Ethereum transaction
The same endpoint the widget above uses.
cast rpc --rpc-url https://rpc.cc3-testnet.creditcoin.network eth_blockNumber # proof builder (chainKey 3 = Ethereum mainnet) https://prover.cc3-testnet.creditcoin.network/api/v1/proof-by-tx/3/<txHash>
| SourceTxReverted() |
| AttestedWorldID.t.sol :: test_RevertsWhenTheSourceTxReverted |
| Transaction sent to another contract | NotIdentityManager(address) | AttestedWorldID.t.sol :: test_RevertsWhenTheCalleeIsNotTheIdentityManager |
| Decoy TreeChanged from another emitter | proof invalid | AttestedWorldID.t.sol :: test_IgnoresDecoyTreeChangedFromAnotherEmitter |
| Contract creation instead of a call | NotIdentityManager(address) | AttestedWorldID.t.sol :: test_RevertsWhenTheTransactionIsAContractCreation |
| No TreeChanged log at all | NoTreeChange() | AttestedWorldID.t.sol :: test_RevertsWhenThereIsNoTreeChange |
| Two genuine TreeChanged logs | AmbiguousTreeChange(uint256) | AttestedWorldID.t.sol :: test_RevertsOnTwoGenuineTreeChangedLogs |
| An unknown function selector | UnsupportedEntrypoint(bytes4) | AttestedWorldID.t.sol :: test_RevertsOnAnUnknownSelector |
| Truncated calldata | UnsupportedEntrypoint(bytes4) | AttestedWorldID.t.sol :: test_RevertsOnTruncatedCalldata |
| Calldata that disagrees with the log | CalldataLogMismatch() | AttestedWorldID.t.sol :: test_RevertsWhenCalldataRootsDisagreeWithTheLog |
| Out-of-order root | UnknownPreRoot(uint256) | AttestedWorldID.t.sol :: test_RevertsOnAnUnknownPreRootAfterBootstrap |
| Root from an unfinalised block | NotFinal(uint64,uint64) | AttestedWorldID.t.sol :: test_RevertsWhenTheSourceBlockIsNotFinalYet |
| Thin attestor set | ThinQuorum(uint32,uint32) | AttestedWorldID.t.sol :: test_RevertsOnThinAttestorQuorum |
| Replayed query | QueryAlreadyProcessed(bytes32) | AttestedWorldID.t.sol :: test_RevertsOnReplayOfTheSameQuery |
| A query replayed inside a batch | QueryAlreadyProcessed(bytes32) | AttestedWorldID.t.sol :: test_BatchRejectsARepeatedQueryInsideOneBatch |
| A batch replaying a root already relayed singly | QueryAlreadyProcessed(bytes32) | AttestedWorldID.t.sol :: test_BatchRejectsAQueryAlreadyRelayedSingly |
| Overwriting a recorded root | CannotOverwriteRoot() | AttestedWorldID.t.sol :: test_RevertsWhenARootWouldBeOverwritten |
| Oversized batch | BatchTooLarge(uint256) | AttestedWorldID.t.sol :: test_BatchRejectsMoreThanTen |
| Out-of-order batch | BatchOutOfOrder() | AttestedWorldID.t.sol :: test_BatchRejectsOutOfOrderHeights |
| Empty batch | EmptyBatch() | AttestedWorldID.t.sol :: test_BatchRejectsEmpty |
| Mismatched batch arrays | BatchLengthMismatch() | AttestedWorldID.t.sol :: test_BatchRejectsMismatchedLengths |
| Stale root past expiry | ExpiredRoot() | AttestedWorldID.t.sol :: test_RootsExpireAfterOneWeek |
| An ancient root side-filled for a fresh expiry | ExpiredRoot() | AttestedWorldID.t.sol :: test_AnAncientSideFilledRootArrivesAlreadyExpired |
| A proof against a root that was never relayed | NonExistentRoot() | AttestedWorldID.t.sol :: test_VerifyProofRejectsAnUnknownRootBeforeTouchingTheVerifier |
| A garbage zero-knowledge proof | proof invalid | AttestedWorldID.t.sol :: test_VerifyProofRejectsAGarbageProof |
| Proof for a different wallet, or reused across actions | proof invalid | HumanRegistry.t.sol :: test_RevertsWhenTheProofIsRejected |
| A signal that is not the caller | proof invalid | HumanRegistry.t.sol :: test_TheSignalHashIsCallerSpecific |
| Double registration | WalletAlreadyHuman(address,uint256) | HumanRegistry.t.sol :: test_RevertsWhenTheWalletAlreadyBelongsToAnotherHuman |
| Re-binding to the wallet already bound | SameWallet() | HumanRegistry.t.sol :: test_RevertsOnRegisteringTheSameWalletTwice |
| Registering a zero nullifier | ZeroNullifier() | HumanRegistry.t.sol :: test_RevertsOnAZeroNullifier |
| Acting from a non-human wallet | NotHuman(address) | CreditLine.t.sol :: test_NonHumansCannotTouchTheLine |
| Borrowing without a line | NoLine(uint256) | CreditLine.t.sol :: test_BorrowingWithoutALineReverts |
| Borrowing over the limit | OverLimit(uint256,uint256) | CreditLine.t.sol :: test_BorrowingPastTheLimitReverts |
| Borrowing more than the pool holds | InsufficientLiquidity(uint256,uint256) | CreditLine.t.sol :: test_BorrowingMoreThanTheIdleBalanceReverts |
| A second line for the same human | LineExists(uint256) | CreditLine.t.sol :: test_ASecondWalletCannotOpenASecondLine |
| Opening twice from one wallet | LineExists(uint256) | CreditLine.t.sol :: test_OpeningTwiceFromTheSameWalletReverts |
| Default freeze survives a re-bind | LineFrozen(uint256) | CreditLine.t.sol :: test_DefaultSurvivesAWalletRebind |
| Declaring a default too early | NotInDefault(uint256,uint64,uint64) | CreditLine.t.sol :: test_MarkDefaultBeforeGraceEndsReverts |
| Declaring a default on a clean line | NothingOwed(uint256) | CreditLine.t.sol :: test_MarkDefaultOnACleanLineReverts |
| Withdrawing more shares than you own | InsufficientShares(uint256,uint256) | CreditLine.t.sol :: test_WithdrawingMoreSharesThanHeldReverts |
| A first-depositor donation attack | proof invalid | CreditLine.t.sol :: test_ADonationAttackCannotSkimTheNextDepositor |
| Zero-value calls | ZeroAmount() | CreditLine.t.sol :: test_ZeroAmountsRevert |
{"production_status":"registered","staging_status":"registered"}