Hi everyone,
AI agents now take on paid work on-chain. The client locks the pay in an escrow, and the escrow pays the agent when the work is accepted. As this grows, each payment also has to cover others: a tax that funds public services, a fee to whoever referred the job, or the repayment of a loan the agent took to do the job.
This is a draft ERC for Settlement Deductions. It lets an escrow withhold these amounts from each payout. The escrow does not need to know the rules behind them. None of them can stall the payout. It works for any task escrow, not only those used by agents.
Example: a payout of 100, with a 1% tax, a 2% referral fee and a repayment of 30. The treasury gets 1, the referrer 2, the lender 30. The payee gets 67.
Repository (draft text, reference policy, example escrow, tests): GitHub - unicore-gpu/settlement-deductions: Draft ERC: settlement deductions for task escrows (tax, referral fees, repayments withheld at payout, never stalling settlement) · GitHub
The ERC text is ERC-draft.md in the repository. I will open the PR to ethereum/ERCs next, with this thread as its discussion link.
The slot this fills
Escrows for agent work end in one transfer to the payee. The token-bound task tender draft (ERC-8414) pays the fulfiller on acceptance, verification or timeout. ERC-8183 releases the budget to the provider when the evaluator completes the job.
But at that moment, others often have a claim on the money:
- A network may fund dispute resolution and monitoring with a small tax on settled work.
- An agent that referred the job may be owed a share of the pay.
- A lender may have advanced working capital against a task the payee already won. It wants to be repaid from that task’s payment.
Today these claims depend on the payee’s goodwill, or the escrow hard-codes one fee. Per-job hooks don’t solve it either. The client chooses the hook, so the client can leave it out. And a hook that reverts blocks the job.
So there is no tax that reaches every task, no repayment a lender can rely on, and no guarantee that the payee is paid when the deduction logic breaks.
What it specifies
- One policy, two calls. The policy has two functions:
onTaskCreated(taskId, asset, amountPerSettlement)anddeductions(taskId, settlementId, payee, amount) returns (uint256). The escrow names one policy for its whole lifetime. No one can choose, replace or bypass it per task. - Payouts cannot be stalled. Every payout asks the policy, including default and timeout payouts. Refunds never ask. The answer counts only if the call succeeds, returns exactly 32 bytes, and takes no more than the payout. Otherwise the payee is paid in full, and the escrow emits
DeductionsSkipped. The escrow should copy at most 32 bytes of return data, so that a policy cannot make settlement expensive. - No starvation. The policy runs on a fixed gas budget
G. The escrow reverts unlessgasleft()exceedsG * 64 / 63plus its own overhead. So no caller can give too little gas to make the policy fail and skip the deductions. - Credit, not push. The escrow keeps each deduction
das credit for the policy, and emitsSettlementDeducted. The payee receivesamount - d. No one else is called during settlement. Anyone can callwithdrawCredit(taskId, account), but it pays onlyaccount. So a policy must account for credit withdrawn by any caller. - Creation may revert, payouts may not. If the policy reverts in
onTaskCreated, the task is not created. A policy may refuse a task this way, for example when the tax rate is above the cap. No work has been done yet, so nobody loses anything. Once work is paid for, the payout must go through. - Reference policy profile (optional). A public tax schedule, with the rate locked per task at creation. Fees and repayments the payee agreed to are assignments. Only the payee can assign its own payouts. Only the recipient can release an assignment. All deductions together stay under one cap. Anyone can trigger a claim.
Fee-on-transfer and rebasing tokens are out of scope. A policy may refuse them at task creation.
What exists today
-
Reference implementation (Solidity 0.8.24, non-upgradeable).
SettlementDeductionPolicyis the reference policy.ExampleEscrowis the smallest escrow that meets the escrow requirements, with partial payouts and refunds. -
42 Foundry tests. Every normative requirement has at least one test. They cover:
- the worked example and cap carry-over;
- policies that revert, return two words, burn all their gas, or revert with 300 KB of data;
- a gas sweep showing that no gas limit skips the deductions;
- strangers withdrawing the policy’s credit;
- re-entry through the token;
- fuzzing of the cap, ordering and conservation;
- invariants (escrow solvency, per-task accounting, token conservation) over random sequences of actions.
Interface IDs and event topics are pinned as test vectors. I also checked the tests by mutation: removing the starvation check or the per-task accounting makes them fail.
-
Gas. The worst case for the reference policy is about 209,000 gas: a tax plus four fixed-sum assignments to new recipients. The example escrow uses
G = 300,000. -
First integration: ERC-8414. It adds about 60 lines to the reference kernel. With no policy set, the kernel behaves exactly as before. The kernel with the policy built in is 24,490 bytes, under the EIP-170 limit. There are 21 integration tests and 8 conformance tests against the escrow requirements: GitHub - unicore-gpu/task-token-standard at settlement-deductions · GitHub
The code is a draft. It has not been audited.
Questions I would value feedback on
- Gas budget. Each escrow fixes its own
G, but the ERC sets no minimum. Should it set one, so that a policy written for one escrow fits every escrow? - Creation vs payout. A policy may block task creation, but never a payout. Is that the right split? Or should a task still be created (untaxed) when the policy fails?
- Credit vs push. Deductions stay in the escrow until someone withdraws them. So each recipient sends a claim for each task. Does this fit the escrows you work on?
- Scope. Are there other escrows or payment flows this should cover? Are there deductions that one number per payout cannot express?