This guide documents the entrypoints currently implemented by the escrow contract. Planned features are listed separately and linked to their tracking issues so integrators can distinguish live API from roadmap.
contracts/escrow/src/lib.rs: contract type, shared API surface, reads, controls, cancellation, reputation, and module wiring.contracts/escrow/src/create_contract.rs:create_contractlifecycle entrypoint.contracts/escrow/src/deposit.rs:deposit_fundslifecycle entrypoint.contracts/escrow/src/release.rs:release_milestonelifecycle entrypoint.contracts/escrow/src/refund.rs:refund_unreleased_milestoneslifecycle entrypoint.
Lifecycle and reputation:
create_contract(client, freelancer, milestone_amounts, deposit_mode) -> u32deposit_funds(contract_id, amount) -> boolrelease_milestone(contract_id, milestone_index) -> boolissue_reputation(contract_id, caller, freelancer, rating) -> boolcancel_contract(contract_id, caller) -> boolfinalize_contract(contract_id, finalizer) -> bool
Read-only queries:
get_contract(contract_id) -> EscrowContractDataget_finalization_record(contract_id) -> Option<FinalizationRecord>get_reputation(freelancer) -> Option<ReputationRecord>get_average_rating(freelancer) -> Option<i128>get_pending_reputation_credits(freelancer) -> u32get_admin() -> Option<Address>is_paused() -> boolis_emergency() -> boolget_mainnet_readiness_info() -> MainnetReadinessInfo
Operational controls:
initialize(admin) -> boolpause() -> boolunpause() -> boolactivate_emergency_pause() -> boolresolve_emergency() -> bool
escrow.initialize(&admin);initialize is single-use, requires admin.require_auth(), and stores the
admin used by pause and emergency controls.
let contract_id = escrow.create_contract(
&client_addr,
&freelancer_addr,
&vec![&env, 500_0000000_i128, 500_0000000_i128],
&DepositMode::ExactTotal,
);Creation requires client.require_auth(), rejects identical client/freelancer
addresses, rejects empty or non-positive milestones, caps milestone count at
MAX_MILESTONES, and caps total escrow value at MAX_TOTAL_ESCROW_STROOPS.
escrow.deposit_funds(&contract_id, &1000_0000000_i128);ExactTotal contracts require one exact deposit equal to the milestone total.
Incremental contracts allow partial deposits until the milestone total is
reached. Deposits that exceed the required total fail closed.
escrow.release_milestone(&contract_id, &0);Current implementation note: release_milestone does not yet authenticate the
client or an arbiter. It validates the contract id, milestone index, unreleased
state, available funded balance, and paused state, then marks the milestone as
released. This authorization gap is intentionally documented here until the auth
fix lands.
When the final milestone is released, status becomes Completed and one pending
reputation credit is added for the freelancer.
escrow.issue_reputation(&contract_id, &client_addr, &freelancer_addr, &5_i128);Reputation requires caller.require_auth(), the caller must be the stored
client, the freelancer argument must match the contract freelancer, the contract
must be Completed, rating must be 1..=5, and each contract can issue
reputation once.
escrow.cancel_contract(&contract_id, &caller);Cancellation requires caller.require_auth(). The caller must be the stored
client or freelancer. It is blocked after Completed and blocked if the
contract is already Cancelled.
escrow.finalize_contract(&contract_id, &finalizer);Finalization requires finalizer.require_auth(). The finalizer must be the
stored client, freelancer, or assigned arbiter. It is allowed only while the
contract status is Completed or Disputed.
The contract writes one immutable FinalizationRecord containing the finalizer,
ledger timestamp, and a ContractSummary snapshot. After the record exists,
contract-specific mutating calls reject with AlreadyFinalized.
pause, unpause, activate_emergency_pause, and resolve_emergency require
the stored admin's authorization. While paused or in emergency, mutating
lifecycle calls fail with ContractPaused; read-only queries remain available.
unpause fails while emergency mode is active.
Implemented events:
("init", "admin_set")oninitialize("paused", timestamp)onpause("unpaused", timestamp)onunpause("emergency", "activated")and("emergency", "resolved")("audit", contract_id)for lifecycle state transitions("created", contract_id)on contract creation("released", contract_id, milestone_index)on release("rep_issd", contract_id)on reputation issuance("cancelled", contract_id)on cancellation("finalized", contract_id)on finalization
There is no dedicated deposit event in the current implementation unless the deposit changes contract status and therefore emits an audit event. Structured deposit and fee events are planned in #336.
- Creation and reputation issue require explicit address authentication.
- Pause and emergency controls are admin-authenticated.
- Deposits cannot exceed the exact milestone total.
- Releases fail on duplicate milestone release, invalid milestone id, missing contract, paused state, and insufficient funded balance.
- Arithmetic for escrow totals, deposits, and releases uses checked helpers and
panics with
PotentialOverflowon overflow. - Accounting is checked after balance-changing operations.
- The contract stores accounting state only; token custody and token transfers
are not implemented in
lib.rsand must be handled by an audited integration. - Storage uses persistent keys. TTL constants exist for planned pending approval and migration flows, but no current public entrypoint writes those pending records.
These features are not implemented entrypoints today:
- Two-step admin transfer: planned in #318.
- Protocol fee deduction on release: planned in #313.
- Protocol fee treasury withdrawal: planned in #314.
- Governed parameter setter/readiness wiring: planned in #323.
- Structured deposit and fee events: planned in #336.
- Storage-key reference for declared-but-unused keys, including pending client migration and protocol fee keys: planned in #342.
migrate_state/StateV1/StateV2migration flow: not implemented; tracked by this reconciliation issue #341 until a dedicated implementation issue exists.
Any documentation that describes one of these items as available should be treated as roadmap text, not live integration guidance.