PROVEITLocal · 31337

Due-diligence panel

0xECe656A2Bc49D2D0C1eA74046DFdc8A5a7a89dd7 · chain 31337 · read at block 175 · 2027-10-28 18:06 UTC

Automated checks passed
7 / 7
clean
Failed
0
n/a
Require a human
3
human needed
What this panel is worth. Checks 6 and 7 are the ones normally hand-waved, so they are done properly here: a PUSH-aware walk of the deployed bytecode rather than a byte search that would report a delegatecall in a contract that has none, and a real comparison of the deployed runtime code against a local build with constructor immutables masked out. Two rows are marked manual because an RPC call cannot answer them, and the panel says so.

See the donor-facing view of this claim →

The ten checks

01The escrow holds what it still owes
Balance 0.00 EURC covers 0.00 EURC of outstanding obligations.
PASS

The raw balance on its own only means something before settlement, so this row checks the invariant that has to hold at every block: balance ≥ unsettled tranches + unpaid refunds + bonds in custody. At the moment of the advance, that reduces to the full target.

token.balanceOf(escrow)
0.00 EURC
Assigned to the funder
52,000.00 EURC
Tranches not yet settled
0 · 0.00 EURC
Refund pool, unpaid
0.00 EURC
Total contributed
52,000.00 EURC
02The token is a euro stablecoin you recognise
Mock demonstration token EURC. Not a real issuer, on purpose, so nothing here implies we integrated a regulated EMI.
MANUAL

escrow.token() compared against a hard-coded list of euro stablecoin addresses per chain. An address that is not on the list is reported as unknown, never as acceptable.

escrow.token()
0x5FbDB2315678afecb367f032d93F642f64180aa3
Symbol / decimals
EURC / 6
Chain ID
31337
03You are the registered payee
Payee is 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC. Confirm it is your own address, and check the IBAN commitment below.
MANUAL

escrow.payee() is read from the chain. The IBAN is stored as a salted commitment, never in the clear, so you confirm it by recomputing keccak256(iban ‖ salt) in your own browser. The panel never sends your preimage anywhere.

escrow.payee()
0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
ibanCommitment
0xb660957a88337f61a1a581257a24e17d4a6430439945a2250599a3fde65adf2a
assignedAmount
52,000.00 EURC
Pledged at
2026-11-02 18:05 UTC

This component issues no network requests. Open your devtools and watch if you like. Checking it in the browser means you never send us a bank account number.

04The payee cannot be changed
No function in the ABI can reassign the payee, and a live re-registration attempt reverts.
PASS

Two independent tests: an ABI scan for any state-mutating function naming the payee other than the one-time registration, and an eth_call simulation of registerPayee from the payee's own address. Neither depends on trusting the source code.

Functions that write payee
none
Simulated re-registration
reverts (The contract function "registerPayee" reverted.)
Note
A funder-signed onward transfer is designed-only. We would rather defend “impossible” than “requires your signature”.
05There is no withdrawal backdoor
18 state-mutating functions, none of them administrative. No owner, no pause, no sweep, no receive, no fallback.
PASS

Every state-mutating entry in the ABI is matched against a list of administrative names, and the set of fund-moving functions is compared against the declared list of movers. ETH is not accepted at all, so a stray transfer is impossible rather than stuck.

Admin-shaped functions found
none
receive / fallback
absent
Functions that move tokens
contribute, withdraw, claimRefund, release, challenge, claimBond, assertOutcome, claimAssertionBond
All state-mutating functions
abortUnpledged, assertOutcome, challenge, claimAssertionBond, claimBond, claimRefund, close, confirmAdvance, contribute, expireUnfunded, finalize, flag, postDischargeReceipt, registerPayee, release, resolveChallenge, submitVerdict, withdraw
06It is not upgradeable and not a proxy
EIP-1967 implementation slot is empty and the deployed code contains no DELEGATECALL.
PASS

eth_getStorageAt on the EIP-1967 implementation slot, plus a PUSH-aware walk of the deployed bytecode. The opcode walk skips PUSHn immediate data; a naive byte search for 0xF4 finds dozens of matches inside constants and would report a delegatecall in a contract that has none.

EIP-1967 impl slot
0x0000000000000000000000000000000000000000000000000000000000000000
DELEGATECALL (0xF4)
0 occurrences
SELFDESTRUCT (0xFF)
0 occurrences
Runtime code size
19648 bytes
07The deployed code is the code in this repository
Byte-for-byte identical to a local build of contracts/AidEscrow.sol, once constructor immutables are masked.
PASS

The runtime bytecode is fetched with eth_getCode and compared against the artifact solc 0.8.24 produces from contracts/AidEscrow.sol. The 24 constructor immutables are written into the runtime code at deployment, so their byte ranges are masked on both sides using solc's immutableReferences map before hashing. On a public chain this is the same comparison Basescan performs for source verification.

keccak256(on-chain code)
0x00e54eb1c5ff404fd53b9c35167afad1b44fd8ba078e714e9bde8d8f121025b0
keccak256(masked, on-chain)
0x7ce05f769ed742a5927780c14a559d2406b80145c1a99aa211846586179fe209
keccak256(masked, local build)
0x7ce05f769ed742a5927780c14a559d2406b80145c1a99aa211846586179fe209
Immutable ranges masked
91
Compiler
solc 0.8.24, optimizer on, 200 runs, bytecode_hash=none
08The release conditions are the ones represented to you
2-of-3 verifiers, 3 tranches, 1 hour challenge window. Verifier set hash recomputes; the published fee schedule hashes to the on-chain termsHash.
PASS

Everything here is a constructor immutable, so it was fixed before the first euro was contributed. Because the parameters are constructor arguments, they are inside the CREATE2 init-code hash, which means the address itself already commits to them. verifierSetHash is recomputed from verifiers() and threshold(); termsHash is recomputed from the project's published terms: its title, implementer, location, summary, cover photograph hash and fee schedule.

Verifiers
0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 0xBcd4042DE499D14e55001CcbB24a551F3b954096
Threshold
2 of 3
verifierSetHash (on-chain)
0xa461005f714fe8113e5f4d899a347d004b281c1d9ce375e64a2531045d464f2d
verifierSetHash (recomputed)
0xa461005f714fe8113e5f4d899a347d004b281c1d9ce375e64a2531045d464f2d
Dispute panel
0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
Windows
challenge 1 hour · release 2 hours · panel 2 hours
Challenge bond / flag threshold
500.00 EURC / 5,200.00 EURC
conditionsHash
0x7cf6b23744d96a6d08d5fecb021725573dc782ac1bf835977bcb82c558592285
termsHash
0xe84ddfc29bbf00b3ecb240b9c0a17af78c0e152670fc5374a9c11f66e96ee057 ✓ matches the project's published terms
Tranches
1. 20,800.00 EURC by 2027-03-02 18:05 UTC 2. 20,800.00 EURC by 2027-06-30 18:05 UTC 3. 10,400.00 EURC by 2027-10-28 18:05 UTC
09It is not already assigned to someone else
Exactly one payee registration in the entire event history, and check 4 shows a second is impossible.
PASS

The full PayeeRegistered log from block 0 to head. Double assignment is the classic factoring fraud; here it is structural rather than procedural, which is why check 4 is the one that settles it.

PayeeRegistered events
1
Claim status
CLOSED
advanceRef
0x42c3b0e2dc32a393391abcba4ac4d7a1f648b66d146eabd7b3ab1883de37f16e
10The payee is the licensed institution it claims to be
Licence reference on-chain: BdE-EDE-6801. Check it against the supervisor's public register yourself.
MANUAL

This check cannot be automated. The contract stores whatever reference the payee wrote; whether that reference is real, current and belongs to the address you are looking at is a question for the Banco de España / EBA register, not for an RPC call.

licenceRef
BdE-EDE-6801
Raw bytes32
0x4264452d4544452d363830310000000000000000000000000000000000000000
Register
Banco de España, Registro de entidades de dinero electrónico

Locked funds certificate

The same values, in the shape a credit committee files. The chain is the source of truth; this is a convenience, and it is not signed: a signature over it would only tell you that we said it.

Escrow
0xECe656A2Bc49D2D0C1eA74046DFdc8A5a7a89dd7
Chain
31337
Status
CLOSED
Token
0x5FbDB2315678afecb367f032d93F642f64180aa3 (EURC, 6 dp)
Target
52,000.00 EURC
Balance
0.00 EURC
Total contributed
52,000.00 EURC
Released to payee
52,000.00 EURC
Refund pool
0.00 EURC
Payee
0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
Assigned amount
52,000.00 EURC
NGO (never a recipient)
0x61097BA76cD906d2ba4FD106E757f7Eb455fc295
claimId
0x69646c69622d686f6d6573000000000000000000000000000000000000000000
conditionsHash
0x7cf6b23744d96a6d08d5fecb021725573dc782ac1bf835977bcb82c558592285
verifierSetHash
0xa461005f714fe8113e5f4d899a347d004b281c1d9ce375e64a2531045d464f2d
termsHash
0xe84ddfc29bbf00b3ecb240b9c0a17af78c0e152670fc5374a9c11f66e96ee057
Read at block
175