> For the complete documentation index, see [llms.txt](https://alameen.gitbook.io/streamwage/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alameen.gitbook.io/streamwage/treasury-and-term-negotiation.md).

# Treasury & Term Negotiation

## Treasury

###

## Managing the treasury

The treasury is the ETH balance held by the payroll contract. It is the source of all worker payouts. The contract gives operators visibility into how healthy it is and protects it from being accidentally drained.

### Funding

ETH can be deposited in two ways: by calling `fundTreasury()` as an operator, or by sending ETH directly to the contract address via the `receive()` fallback. Both paths emit a `TreasuryFunded` event so deposits are always traceable on-chain.

### Runway

The contract distinguishes between two portions of its ETH balance: funds already earned by workers but not yet claimed, and funds that are genuinely free to sustain future accrual. The `treasuryRunway()` function returns how long the free balance can sustain the current combined pay rate across all active workers.

Earned but unclaimed balances are treated as a liability and subtracted before the runway is calculated, they are already owed and cannot be counted as available runway. Per-worker runway is also available via `workerRunway()`, which estimates a worker's fair share of the free balance based on their proportion of the total pay rate.

When a worker claims and the remaining runway for any active worker falls below the configured threshold, a `LowTreasury` event is emitted. This gives off-chain systems a signal to top up before workers are affected.

### Withdrawing excess funds

`withdrawExcess()` lets an operator pull surplus ETH out of the treasury, for example if the payroll was overfunded or a worker was removed.

Before processing the withdrawal, the contract settles all active workers and calculates the minimum reserve required to cover one hour of pay at the current combined rate. The withdrawal is blocked if it would bring the balance below that reserve.

{% hint style="info" %}
The one-hour minimum reserve is a hard floor. Any withdrawal that would breach it reverts with `WithdrawalExceedsSafeLimit`, even if the requested amount is technically less than the total balance.
{% endhint %}

This means the operator cannot accidentally drain the treasury down to zero while workers are actively accruing. The reserve is intentionally minimal :- one hour, so it does not lock up a significant amount of capital, but it does ensure workers are never left with zero runway mid-accrual.

### Term Negotiation

## How term negotiation works

Term negotiation is the mechanism for changing a worker's pay rate or timeline in a way that requires the worker's explicit consent. Rather than the operator unilaterally updating terms, a proposal is made on-chain and the worker must accept or reject it within a time window.

### Why it exists

An operator can already update a worker's rate directly via `updateWorkerRate()`. Term negotiation is a different tool :- it is for situations where the operator wants the worker to acknowledge and agree to the change before it takes effect. It protects the worker from having their rate silently cut, and it gives the operator a formal on-chain record of consent.

The `terminateOnReject` flag also lets an operator signal upfront: accept these terms or the engagement ends. That outcome is recorded in the proposal itself, so it is visible to the worker before they decide.

### The full flow

{% stepper %}
{% step %}

### Operator calls `proposeTerms()`

The worker's earnings are fully settled first :- whole intervals and fractional remainder. The worker is then paused and a `PendingTerms` record is written with the proposed rate, timeline, expiry timestamp, and the `terminateOnReject` flag. A `proposalNote` string can be attached :- it is emitted in the event log but not stored on-chain, keeping gas costs low.
{% endstep %}

{% step %}

### Worker is paused during the proposal window

While the proposal is pending, the worker does not accrue. Their already-settled balance remains claimable. The proposal window defaults to 7 days and is configurable by the operator via `setProposalWindow()`.
{% endstep %}

{% step %}

### Worker accepts : `acceptTerms()`

The new rate and timeline are applied. The worker is reactivated and the accrual clock resets from `block.timestamp`. The proposal record is deleted.
{% endstep %}

{% step %}

### Worker rejects : `rejectTerms()`

The outcome depends on the `terminateOnReject` flag set by the operator. If false, the worker is restored under their prior terms and reactivated. If true, the worker is permanently deactivated. Either way, any earned balance remains intact and claimable.
{% endstep %}

{% step %}

### Proposal expires : `expireProposal()`

If the window passes with no response, anyone can call `expireProposal()` to resolve the stale proposal. The outcome is identical to rejection,the `terminateOnReject` flag determines whether the worker is restored or terminated. The worker cannot be left in a permanently paused limbo.
{% endstep %}

{% step %}

### Operator cancels : `cancelProposal()`

The operator can withdraw a proposal at any time before it expires or is acted on. The worker is restored to their prior active status and the accrual clock resets from now.
{% endstep %}
{% endstepper %}

### Possible outcomes

* **accepted**\
  New terms applied\
  Worker resumes under the proposed rate and timeline. Prior earned balance untouched.
* **rejected / expired :**- **terminateOnReject: false**\
  Restored under prior terms\
  Worker reactivates with their original rate and timeline. Accrual resumes from now.
* **rejected / expired :**- **terminateOnReject: true**\
  Worker terminated\
  Worker is permanently deactivated. Any accrued balance remains claimable:- termination does not forfeit earned pay.
* **cancelled by operator**\
  Proposal withdrawn\
  Worker restored to prior active status. Accrual clock resets from the cancellation timestamp.

### What the worker is protected from

Accrual is fully settled before the proposal is raised, so the worker does not lose any time earned under their current terms. Even if they reject and get terminated, the balance accumulated up to the proposal point is still theirs to claim. The contract does not have a mechanism to claw back earned pay.

{% hint style="info" %}
Termination deactivates a worker, it does not delete their record or zero their balance. A terminated worker can still call `claim()` to collect anything they earned before the termination.
{% endhint %}


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alameen.gitbook.io/streamwage/treasury-and-term-negotiation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
