- Review AUDIT_SCOPE.md for function list and data flows
- Review THREAT_MODEL.md for known threat analysis
- Review INVARIANTS.md for correctness assumptions
- Review ARCHITECTURE.md for state machine and design
- Read all entry point functions in lib.rs
- Trace token transfer logic in helpers/
- Examine fee calculation in helpers/payout.rs
- Review storage schema in types.rs
- Check authorization pattern in all functions
- fund_escrow — Token transfer + role validation + state change
- resolve_dispute — Conditional payout + fee deduction + role check
- auto_release — Permissionless + time-based + state guard
- initialize — Admin setup; must be one-time only
- Fee calculation helpers — Arithmetic correctness
- ❌ State read after require_auth (potential confused deputy)
- ❌ Token transfer before state update (potential reentrancy)
- ❌ Unchecked arithmetic in fee calculations
- ❌ State transitions not validated against approved matrix
- ❌ Auth check missing from privileged function
- ❌ Storage key collision (two functions using same DataKey)
- ❌ TTL not extended before persistent write
- ❌ Role validation only at creation, not enforced elsewhere
-
Key Security
- Generate admin key via cold storage / HSM
- Use multi-sig for admin role if possible
- Never share or hardcode admin key
- Rotate admin key annually
-
Fee Configuration
- Protocol fee: recommend 100-300 BPS (1-3%) for sustainability
- Arbitration fee: recommend 0-50 BPS; inform users at creation
- Document fee rationale; communicate to stakeholders
- Set fees BEFORE opening to users
-
Contract Initialization
- Call
initialize()once after deployment - Set correct admin address
- Set fee_collector address (can be multi-sig)
- Verify initialization via get_fee_config query
- NEVER call initialize twice
- Call
-
Token Whitelisting (recommended)
- Audit all tokens before use
- Maintain allowlist of supported tokens
- Reject malicious tokens with false transfer callbacks
- Document token audit results
-
Monitoring
- Monitor all event logs for anomalies
- Track fee accumulation weekly
- Alert on pause events (rare)
- Verify resolver performance (response time, fair decisions)
-
Fee Withdrawal
- Withdraw accumulated fees monthly to avoid loss
- Verify fee_collector address before withdrawal
- Document all withdrawals for auditing
-
Admin Operations
- Change protocol fee only with advance notice
- Pause contract only in emergency (revert to unpause ASAP)
- Never update admin key without migration plan
- Log all admin actions for audit trail
-
Dispute Mediation
- Ensure resolver is neutral third party
- Document resolver selection criteria
- Require resolver SLA (response time: <24h)
- Escalate unresolved disputes to governance
-
Fund Verification
- Always verify
EscrowFundedevent before confirmation - Check buyer, seller, amount in event
- Use fund_escrow result, not event, as source of truth
- Always verify
-
Dispute Handling
- Evidence hash must be SHA-256 (32 bytes)
- Collect evidence off-chain before raising dispute
- Verify evidence_hash matches off-chain evidence
- Never modify evidence post-dispute
-
Token Safety
- Verify token address before fund_escrow
- Use only SEP-41 compliant tokens
- Test token with small amounts first
- Handle token transfer failures gracefully
-
Role Management
- Buyer and seller must be different accounts
- Resolver should be neutral (not buyer or seller)
- Use hardware wallet for high-value escrows
- Implement rate limiting on escrow creation
-
Front-End Security
- Validate all inputs client-side
- Sanitize evidence_hash before submission
- Show fee impact clearly to user
- Display dispute window duration prominently
- Implement transaction confirmation UI
try {
const escrowId = await client.fund_escrow(amount, buyer);
// Wait for on-chain confirmation
await client.get_escrow(escrowId);
} catch (e) {
if (e.code === 'ConflictingRoles') {
// Handle buyer == seller error
} else if (e.code === 'InvalidAmount') {
// Handle zero or negative amount
} else if (e.code === 'ContractPaused') {
// Retry later
}
}- No Escrow Cancellation Post-Fund — Once funded, only 3 paths: complete, refund (via dispute), or auto-release. Buyer cannot cancel alone.
- Fixed Dispute Window — 172800 seconds (2 days); not adjustable per-escrow.
- No Partial Releases — Full amount or nothing; no milestone-based split payments.
- Single Resolver — No multi-sig or voting for dispute resolution.
- No Token Whitelisting — Any SEP-41 token accepted; contract-level filtering not enforced.
- O(n) Lookups —
get_escrows_by_buyermust scan index; large indices may be slow. - Persistent Storage — All escrow history retained; storage grows unbounded.
- Single-Threaded — Soroban transactions are sequential; no parallel operations.
- Fee Cannot Be Retroactively Changed — Fees are frozen at creation; new fee applied only to new escrows.
- No Emergency Pause Mitigation — Pause stops all operations; unpause requires admin action.
- Use hardware wallets for buyer/seller roles
- Verify counterparty identity before funding
- Collect evidence before initiating disputes
- Don't fund escrows with entire amount; use smaller test amounts first
- Monitor event logs to confirm successful state transitions
- Rate-limit new user accounts
- Require email / KYC for high-value escrows
- Implement dispute escalation workflow
- Maintain off-chain evidence repository
- Implement refund insurance for users
- Audit all token pairs before use
- Audit fee structure quarterly
- Review resolver decisions monthly
- Maintain admin key in cold storage
- Rotate admin/fee-collector addresses annually
- Maintain incident response playbook
- Document all emergency pauses
- Assess root cause (config error, bug, attack)
- Notify all stakeholders
- Develop fix or mitigation
- Test on testnet
- Deploy fix to mainnet
- Call unpause_contract
- Calculate total loss
- Contact affected users
- Prepare insurance payout (if applicable)
- Post-mortem analysis
- Implement prevention measures
- Deploy patched contract (requires new deployment)
- Pause contract immediately
- Investigate logs and audit trail
- Calculate affected escrows
- If smart contract bug:
- Develop fix
- Test exhaustively
- Deploy new contract
- Migrate data (complex; requires governance)
- If account compromise:
- Rotate admin key
- Check audit trail for malicious actions
- Undo state if possible
- Contract assumes no custodial relationship (trustless)
- Disputes resolved by chosen neutral (not platform)
- Platform exempt from liability for escrow terms
- Recommend legal review before mainnet deployment
- Monitor AML/KYC requirements in deployment jurisdiction
- Implement transaction limits if required
- Document KYC procedures for auditors
- Maintain transaction logs for regulatory review
- Publish fee structure on website
- Document resolver selection and compensation
- Maintain public event log / block explorer link
- Publish security policy and incident response plan
- Provide transparency reports on disputes
Before mainnet deployment:
- All entry points tested
- All error conditions triggered
- All state transitions validated
- All fee calculations verified
- All authorization checks confirmed
- End-to-end escrow flow (create → fund → complete)
- Dispute flow (create → fund → dispute → resolve)
- Auto-release flow (fund → wait → release)
- Multiple concurrent escrows
- Large amounts (near i128 limits)
- Zero amounts (should fail)
- Multiple token types
- Random escrow creation parameters
- Random fee configurations
- Random dispute timing
- Random token amounts
- Invalid input combinations
- Rapid escrow creation
- Many concurrent escrows
- Large lookups (1000+ escrows per buyer)
- Storage size scaling
Contract: TrustLink Escrow Soroban SDK: 26.0.1 Rust Edition: 2021 Build Date: [DEPLOYMENT_DATE] WASM SHA256: [SHA256_HASH]
- Code review by auditor
- Testing verification
- Threat model review
- Invariant confirmation
- Legal review
- Deployment checklist
- Critical Bug: security@trustlink.dev
- Resolver Issues: disputes@trustlink.dev
- Operational: ops@trustlink.dev
| Version | Date | Changes |
|---|---|---|
| 1.0 | 2026-06-30 | Initial audit package |
- AUDIT_SCOPE.md — Detailed scoping and entry points
- THREAT_MODEL.md — Threat analysis with mitigations
- INVARIANTS.md — Correctness assumptions
- ARCHITECTURE.md — Design and state machine
- Source Code: contracts/escrow/src/
- Tests: contracts/escrow/src/test*.rs (60+ files)
- Fuzz Targets: contracts/escrow/fuzz/
This document should be reviewed by all auditors before beginning engagement.