> For the complete documentation index, see [llms.txt](https://docs.trustlesswork.com/trustless-work/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.trustlesswork.com/trustless-work/v2-en/introduction/technology-overview/what-does-a-smart-escrow-look-like.md).

# Escrow Properties

Understand the core data structure of Trustless Work V2 escrows and how Single-Release and Multi-Release differ.

A Trustless Work escrow is a structured on-chain agreement.

Its properties define:

* what the agreement is
* who can act
* what milestones exist
* how approvals work
* what asset is held
* how much can be released
* who receives funds
* how disputes and releases are tracked

V2 uses the same core concepts across both escrow types, but **Single-Release and Multi-Release store some economic and state properties in different places**.

***

### Core escrow properties

#### Escrow ID / Contract ID

The **Contract ID** is the Soroban smart contract address representing the escrow on-chain.

It uniquely identifies the escrow and is used when:

* funding the escrow
* reading escrow state
* updating milestones
* approving
* releasing
* disputing
* querying the Viewer or API

The Contract ID is generated when the escrow contract is deployed.

***

#### Engagement ID

The **Engagement ID** is an application-defined reference that connects the escrow to your own system.

Examples:

```
ORDER_12345
INVOICE_2026_091
GRANT_ROUND_7
PROJECT_ALPHA
```

It can be used to associate an escrow with:

* an order
* an invoice
* a project
* a grant
* an agreement
* another external record

The Engagement ID is useful for indexing and application-level organization, but it is not the escrow's on-chain identity.

***

#### Title and Description

These fields provide human-readable context.

**Title** identifies the agreement.

**Description** explains what the escrow represents.

For example:

```
Title:
Website Redesign

Description:
Payment for the design and implementation of the new company website.
```

These properties make escrow data easier to understand in application interfaces, the Viewer, and operational workflows.

***

### Roles

The `roles` structure defines who can perform authorized actions.

V2 includes:

* `approvers`
* `service_providers`
* `release_signers`
* `dispute_resolvers`
* `observers`
* `admin`
* `platform`

Single-Release also includes:

* `receiver`

Multi-Release defines the Receiver at the **milestone level** instead.

Operational roles such as Approvers, Service Providers, Release Signers, and Dispute Resolvers can contain multiple addresses.

[Learn more about Roles and Permissions](/trustless-work/v2-en/oss-dapps/offerhub-marketplace/roles-and-permissions.md)

***

### Milestones

Milestones represent the conditions, deliverables, or checkpoints that the agreement tracks.

Every V2 milestone contains:

* **Description** — what is expected
* **Status** — the current application-defined state
* **Evidence** — supporting information or a reference to proof
* **Approvals** — the approval policy and votes for that milestone

A simple milestone might conceptually look like:

```json
{
  "description": "Deliver production-ready website",
  "status": "Ready for review",
  "evidence": "https://example.com/delivery",
  "approvals": {
    "target": 2,
    "approval_count": 1,
    "approved_by": ["G...ALICE"]
  }
}
```

The exact payload shape depends on the API or SDK surface you use, but these are the underlying V2 concepts.

***

### Status

`status` is a text field controlled by the application.

Trustless Work does not require a fixed status vocabulary.

Your application might use:

```
Pending
In Progress
Ready for Review
Delivered
Completed
```

or:

```
Order Received
Packed
Shipped
Delivered
```

The contract controls **who is authorized to change the status**, but the application controls what the status means.

A status does not automatically approve a milestone.

> **Status communicates progress. Approval validates it.**

***

### Evidence

A milestone can contain evidence associated with its latest progress update.

Evidence might reference:

* a pull request
* a delivery receipt
* a tracking URL
* an IPFS document
* an audit result
* an application record

Trustless Work does not need to define what evidence means for every use case.

The application decides:

* what qualifies as evidence
* where that evidence is stored
* how it is displayed
* whether it should be required before approval

***

### Approval structure

V2 replaces the V1 boolean approval model with **threshold approvals**.

Each milestone contains an approvals structure with three key concepts:

#### Target

How many approvals are required.

```
target = 2
```

#### Approval count

How many authorized Approvers have already approved.

```
approval_count = 1
```

#### Approved by

Which addresses submitted those approvals.

```
approved_by = [Alice]
```

For example:

```
Approvers:
Alice
Bob
Carol

Target: 2

Alice approves
approval_count = 1

Bob approves
approval_count = 2

Milestone approval requirement is now satisfied.
```

An Approver cannot approve the same milestone twice.

This structure makes approval policy explicit and auditable.

***

### Asset / Trustline

The escrow defines the asset it holds through its **Trustline** configuration.

At the contract level, the Trustline references the Stellar asset contract used by the escrow.

This determines which asset can be:

* deposited
* held
* released
* distributed during dispute resolution

For most integrations today, this is typically a stablecoin such as USDC.

***

### Platform Fee

The escrow can define an optional **Platform Fee**.

This is the fee paid to the configured Platform address when funds are released.

The Platform Fee is separate from the Trustless Work protocol fee.

At settlement, the contract calculates:

```
Gross amount
- Trustless Work protocol fee
- Platform fee
= Net receiver amount
```

The current Trustless Work protocol fee is **0.3%**.

The Platform Fee is configurable by the integrating platform within the contract's allowed limits.

***

## Single-Release properties

In a Single-Release Escrow, the economic outcome is defined at the **escrow level**.

The escrow contains:

* one total `amount`
* one `receiver`
* one escrow-level dispute state
* one escrow-level release state
* one or more milestones

Conceptually:

```
Escrow
├── amount
├── receiver
├── released
├── dispute
│
└── milestones
    ├── milestone 1
    ├── milestone 2
    └── milestone 3
```

The milestones define the conditions that must be satisfied.

The amount itself is released only once.

***

### Single-Release amount

The `amount` represents the total protected payment.

For example:

```
Escrow amount: 1,000 USDC
```

Even if the escrow contains five milestones, there is still only **one final payout**.

***

### Single-Release receiver

The Receiver is defined in the escrow's roles.

When release conditions are satisfied, the final net amount is sent to that Receiver.

***

### Single-Release dispute state

The dispute applies to the **whole escrow**.

V2 stores dispute state directly:

* whether the escrow is disputed
* the dispute reason
* whether the dispute has been resolved

Conceptually:

```json
{
  "is_disputed": true,
  "reason": "Final delivery does not match the agreed scope.",
  "resolved": false
}
```

V2 does not use the generic V1 `flags` object.

***

### Single-Release release state

The escrow stores whether the final payment has already been released.

```
released = false
```

Once release succeeds:

```
released = true
```

This state belongs to the entire escrow because Single Release has one final settlement.

***

## Multi-Release properties

In a Multi-Release Escrow, the economic outcome is defined primarily at the **milestone level**.

Each milestone adds:

* `amount`
* `receiver`
* `released`
* `dispute`

Conceptually:

```
Escrow
└── milestones
    │
    ├── Milestone 1
    │   ├── amount
    │   ├── receiver
    │   ├── approvals
    │   ├── released
    │   └── dispute
    │
    ├── Milestone 2
    │   └── ...
    │
    └── Milestone 3
        └── ...
```

This allows each milestone to behave as an independent settlement unit.

***

### Multi-Release amount

Each milestone defines its own amount.

For example:

| Milestone         |     Amount |
| ----------------- | ---------: |
| Research          | 1,000 USDC |
| Prototype         | 2,000 USDC |
| Production launch | 3,000 USDC |

Total intended value:

```
6,000 USDC
```

But each milestone can move through approval and release independently.

***

### Multi-Release receiver

Each milestone has its own Receiver.

That means the same escrow can pay different participants.

For example:

| Milestone                  | Receiver  |
| -------------------------- | --------- |
| Design                     | Designer  |
| Smart contract development | Developer |
| Security review            | Auditor   |

This makes Multi Release useful for projects involving multiple contributors or staged distributions.

***

### Multi-Release dispute state

Disputes are **milestone-specific**.

A dispute on Milestone 2 does not automatically mean Milestones 1 and 3 are disputed.

Each milestone tracks:

* whether it is disputed
* the dispute reason
* whether the dispute has been resolved

This allows independent workstreams to continue where appropriate.

***

### Multi-Release release state

Each milestone tracks whether its funds have already been released.

For example:

```
Milestone 1 → released
Milestone 2 → disputed
Milestone 3 → approved but not yet released
```

That independence is the main reason to use Multi Release.

***

## Single Release vs Multi Release

| Property                  | Single Release                  | Multi Release                |
| ------------------------- | ------------------------------- | ---------------------------- |
| **Amount**                | Escrow-level                    | Per milestone                |
| **Receiver**              | Escrow-level                    | Per milestone                |
| **Approvals**             | Per milestone                   | Per milestone                |
| **Release state**         | Escrow-level                    | Per milestone                |
| **Dispute state**         | Escrow-level                    | Per milestone                |
| **Final payment pattern** | One payout                      | Multiple payouts             |
| **Milestone role**        | Conditions for final settlement | Independent settlement units |

The key distinction is simple:

> **Single Release:** milestones collectively determine one settlement.

> **Multi Release:** milestones each represent their own settlement.

***

### Configuration changes

V2 separates escrow configuration from operational actions.

The **Admin** manages the configuration changes allowed by the contract.

An important lifecycle rule is:

> **Configure first. Fund second.**

Once the escrow holds funds, key economic and role configuration is restricted to protect participants from having the agreement materially changed after capital has been committed.

V2 also supports milestone management, allowing applications to add or update milestone definitions within the constraints enforced by the contract.

***

### What V2 no longer uses

If you are familiar with V1, two differences are especially important.

#### No singular operational roles

V1 used properties such as:

```
approver
service_provider
release_signer
dispute_resolver
```

V2 uses role lists:

```
approvers[]
service_providers[]
release_signers[]
dispute_resolvers[]
```

#### No generic `flags` object

V1 grouped state into flags such as:

```
disputed
released
resolved
approved
```

V2 represents these concepts directly where they belong.

Approval uses the `approvals` structure.

Release and dispute state live:

* at the escrow level for Single Release
* at the milestone level for Multi Release

This makes the state model more explicit and better aligned with the settlement behavior of each escrow type.

***

### Next

Now that you understand the structure of an escrow, the next decision is which settlement model fits your workflow.

[Compare Single-Release and Multi-Release Escrows](/trustless-work/v2-en/introduction/technology-overview/escrow-types.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.trustlesswork.com/trustless-work/v2-en/introduction/technology-overview/what-does-a-smart-escrow-look-like.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
