PROVEITLocal · 31337

Due-diligence panel

0x245611C250C55716cC6CB2B37394599F86D79379 · 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
0x1cfd4488f9e8106e067acd45ded64fed5a36c1e400912c99f0c88947d3adb5be
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)
0x55cc5b88578c1814c5576419312f55918e7e6cf772c884965f4ad781a75b15c4
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
0xc17a3c4c46b1b3629b08a7b6d94b505d82009677c9a83a9ead5893eca337b905
termsHash
0x2bb7424d04b66f2312e3c7c77b49842fa50c45b8fce2851b99f678857ffcfe1f ✓ 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
0xb6af6a0ae47166e145cc594fdf5c83d00c6ed6e9d62920329a7ccd4689fe47ba
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
0x245611C250C55716cC6CB2B37394599F86D79379
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
41,600.00 EURC
Refund pool
10,400.00 EURC
Payee
0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
Assigned amount
52,000.00 EURC
NGO (never a recipient)
0x70997970C51812dc3A010C7d01b50e0d17dc79C8
claimId
0x77656c6c2d7061727469616c0000000000000000000000000000000000000000
conditionsHash
0xc17a3c4c46b1b3629b08a7b6d94b505d82009677c9a83a9ead5893eca337b905
verifierSetHash
0xa461005f714fe8113e5f4d899a347d004b281c1d9ce375e64a2531045d464f2d
termsHash
0x2bb7424d04b66f2312e3c7c77b49842fa50c45b8fce2851b99f678857ffcfe1f
Read at block
175