# aiken-escrow > ⚠️ **WIP — UNAUDITED.** Preprod testing only. Do **NOT** route mainnet > funds through this validator. No third-party security review has been > performed. Two-party agreement-with-veto escrow validator (Plutus V3, Aiken v1.1.21). The off-chain (Rust) side lives in `crates/aldabra-dao` behind the `escrow_wip` feature flag. ## Spec `aiken-escrow/README.md` documents the state machine, datum shape, and redeemer invariants. State machine: ``` Open ──(both sign Agree)──▶ Agreed{at} ──(lock_period elapsed, no veto)──▶ Settle (→ recipient) │ │ │ └──(A or B fires Veto)─────────────▶ Refund (per-contributor) │ └──(open_deadline passed, no agreement)─────────────────────────▶ Refund (per-contributor) ``` ## Build ```bash cd aiken-escrow aiken check # type check + tests aiken build # produces plutus.json blueprint ``` The blueprint at `plutus.json` is consumed by aldabra's escrow builders to construct script addresses + spending witnesses. ## Threat model (out-of-scope for v1) These are KNOWN gaps the validator does not protect against. They inform the WIP designation: - **Datum CBOR canonicality.** The Deposit redeemer compares `cbor.serialise(expected) == cbor.serialise(new.deposits)`. If the Aiken stdlib's CBOR encoder is non-canonical for any input shape (e.g. map ordering), an attacker could submit a continuing output with the same logical content but byte-different and bypass the check. We mitigate by using `List` (not Map) which has deterministic order, but external review should re-confirm. - **Stake credential preservation on refund outputs.** Refund outputs are derived from contributor PKHs as null-stake base addresses. If a contributor's wallet uses a custom stake credential, refund value bypasses their stake-delegation pool. Acceptable v1 tradeoff; documented in spec. - **Min-utxo per refund leg.** Validator does not enforce min-utxo per refund output — assumes the off-chain builder has already ensured each deposit cleared min-utxo at deposit time. A pathological multi-asset deposit that splits below min-utxo on refund would brick the escrow until manual recovery. - **Multi-script-input attack.** If a single tx spends multiple escrow UTxOs simultaneously with overlapping signers, the per-UTxO validator runs independently. Cross-UTxO consistency is not enforced. ## Status - [x] Validator compiles (`aiken build` produces `plutus.json`). - [x] Off-chain codecs in `aldabra-dao::agora::escrow`. - [ ] Off-chain unsigned-tx builders (5 paths). - [ ] MCP tool wrappers. - [ ] Preprod E2E (open → both deposit → agree → settle). - [ ] Preprod E2E (open → agree → veto). - [ ] Preprod E2E (open → refund-timeout). - [ ] External audit. - [ ] Mainnet release gate.