PROVEITLocal · 31337

Due-diligence panel

0x5cf0BA38567Bf75E7Ff710Add8064c1fE083a095 · 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.000001 EURC covers 0.000001 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.000001 EURC
Assigned to the funder
52,000.00 EURC
Tranches not yet settled
0 · 0.00 EURC
Refund pool, unpaid
0.000001 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
0x6434f69babee57688b7ec836dd492e0ce108c00211361494c92ec54aabf3ec03
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)
0xe5f202e91b1487f011684c0f7fed9f89cdd508b2b18a03899f3c24e944d712f1
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 / 30,000.00 EURC
conditionsHash
0xce4f1451c6cf12e67c3d4d8f8b57f746860d8365ce1856cce4dca9eaf84154d6
termsHash
0xe2ef8dfd479f9bc044711984b1acaf1d1e91fe1523b15151e79bd8612dcf6d60 ✓ 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
0x98bc6b095e517532386f0328514b44408b9a2b111cabbce5fe4c17ce0fb95651
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
0x5cf0BA38567Bf75E7Ff710Add8064c1fE083a095
Chain
31337
Status
CLOSED
Token
0x5FbDB2315678afecb367f032d93F642f64180aa3 (EURC, 6 dp)
Target
52,000.00 EURC
Balance
0.000001 EURC
Total contributed
52,000.00 EURC
Released to payee
0.00 EURC
Refund pool
52,250.00 EURC
Payee
0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
Assigned amount
52,000.00 EURC
NGO (never a recipient)
0x70997970C51812dc3A010C7d01b50e0d17dc79C8
claimId
0x77656c6c2d6661696c7572650000000000000000000000000000000000000000
conditionsHash
0xce4f1451c6cf12e67c3d4d8f8b57f746860d8365ce1856cce4dca9eaf84154d6
verifierSetHash
0xa461005f714fe8113e5f4d899a347d004b281c1d9ce375e64a2531045d464f2d
termsHash
0xe2ef8dfd479f9bc044711984b1acaf1d1e91fe1523b15151e79bd8612dcf6d60
Read at block
175