A working proof of concept for programmable environmental performance assurance on Arc. A project owner funds a USDC milestone, approves the underlying work, and pays the base amount immediately. A pre-agreed retainage remains locked until specific environmental obligations are resolved.
This is intentionally narrow: it does not claim to be a permit, statutory fine, bank guarantee, or scientific oracle.
Environmental promises often live in PDFs while project money moves independently. This contract connects a bounded share of a milestone payment to explicit obligations, evidence, deadlines, correction periods, and fixed settlement rules.
- Owner and contractor agree roles, retainage rate, review period, cure period, and remediation treasury.
- Owner creates a milestone and allocates its entire retainage across obligations.
- Owner funds the full milestone in USDC.
- Owner separately approves completed base work; only then is the base payment transferred.
- Contractor submits an evidence URI and hash for each obligation.
- Verifier approves, rejects for correction, or finalizes a breach.
- Approved retainage goes to the contractor. A breached obligation sends only its fixed deduction to the remediation treasury and returns any remainder to the contractor.
The verifier never chooses amounts. Financial terms lock once funding occurs. Timeout paths prevent a disappeared verifier from freezing funds forever.
contracts/EnvironmentalRetainage.sol— escrow and obligation state machinecontracts/mocks/MockUSDC.sol— six-decimal test tokentest/EnvironmentalRetainage.test.js— lifecycle, roles, accounting, timeout and fuzz-style amount testsscripts/deploy.js— Arc Testnet deploymentweb/— responsive Next.js contract console using viemdocs/ARCHITECTURE.md— trust model and state transitions
Requires Node.js 20+.
npm install
npm testFor the web console:
cd web
npm install
cp .env.example .env.local
npm run devWithout a deployed contract address, the interface runs in preview mode.
Arc Testnet uses chain ID 5042002, RPC https://rpc.testnet.arc.io, and the USDC ERC-20 address 0x3600000000000000000000000000000000000000.
cp .env.example .env
# Add PRIVATE_KEY to .env
npm run deploy:arcCopy the deployed address into web/.env.local:
NEXT_PUBLIC_RETAINAGE_ADDRESS=0x...
Then build the production interface with cd web && npm run build.
- Contract:
0x19fbf0B85e66d68D312cD18D04A1a789107387FF - Chain: Arc Testnet (
5042002) - Completed demo: project
1, milestone1, obligation1 - Demonstrated settlement:
20 USDC funded → 18 USDC base payment + 2 USDC verified retainage release
The transaction evidence and deployment metadata are recorded in deployments/arc-testnet.json.
- Evidence interpretation remains a human verifier responsibility.
- Governance for appointing the verifier and remediation treasury is offchain.
- No upgradeability, arbitration module, multisig enforcement, or external oracle is included.
- The contracts are tested but not independently audited; do not use with production funds.
MIT