Skip to content

feat(escrow_manager): reclaim idle escrow via thaw and withdraw - #21

Open
tmigone wants to merge 9 commits into
mainfrom
tmigone/escrow-withdraw
Open

tmigone wants to merge 9 commits into
mainfrom
tmigone/escrow-withdraw

Conversation

@tmigone

@tmigone tmigone commented Sep 18, 2026

Copy link
Copy Markdown
Member

Overview

The manager only deposited, so balances were a high-water mark of past debt. It can now reclaim idle escrow to the payer wallet, behind withdraw_enabled (default false).

One action per receiver per cycle, first match wins:

target = next_balance(...)                           # calculate
effective = balance - thawing                    # what the contract's getBalance reports
floor     = target × (1 + withdraw_margin)

# for each account only one of the following ops, evaluated in this order:
previous thawing matured                                  → Withdraw
effective < target                                        → Deposit(target - effective)
not thawing and balance - floor ≥ min_withdraw_grt        → Thaw(balance - floor)
otherwise                                                 → Nothing

Approach

  • A running thaw is never resized. The contract cannot grow one without resetting its 28-day timer, so debt growth during a thaw is answered by a deposit — the full amount leaves at maturity and the deposit covers the gap.
  • adjustThaw and cancelThaw stay unused. These are new interfaces in the contract but for simplicity thaws only start from zero, so plain thaw suffices.
  • Maturity uses the latest block timestamp, not wall clock. Timestamps are non-decreasing, so planning can be late but never early, and early reverts the whole batch.

Configuration

  • withdraw_enabled — new, defaults to false. No action needed; set true to reclaim escrow.
  • withdraw_margin — new, defaults to 0.25. No action needed.
  • min_withdraw_grt — new, defaults to 500. No action needed.

Motivation

#18 measured the escrow at ~2.87M GRT against ~1M GRT of debt and noted the algorithm targets ~1.67x but has no way to withdraw. This closes that gap.

Cross-component

The escrow accounts query now selects totalAmountThawing and thawEndTimestamp — an upstream dependency on the network subgraph exposing both. The query fails if a deployed version lacks them. Not verified; confirm against the deployed subgraph before merging.

Risk assessment

  • blast_radius: protocol — thaws and withdrawals are on-chain state receivers observe on their own escrow accounts; the default keeps it off until deliberately enabled.
  • reviewer_effort: deep — the decision logic is small and tested, but its correctness rests on PaymentsEscrow semantics this repo only vendors an ABI for.
  • primary_concern — with no cancel path, a thaw's full amount leaves at maturity, so the compensating deposit must fit the payer allowance and the 10,000 GRT MAX_ADJUSTMENT cap.
  • irreversible — not the merge, which is deposit-only at the defaults, but the enablement: a thaw is a 28-day on-chain commitment that reverting the code does not cancel.

Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
@coveralls

coveralls commented Sep 18, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 35639218640

Coverage decreased (-2.1%) to 44.083%

Details

  • Coverage decreased (-2.1%) from the base build.
  • Patch coverage: 309 uncovered changes across 5 files (111 of 420 lines covered, 26.43%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
crates/bin/escrow_manager/src/main.rs 313 111 35.46%
crates/bin/escrow_manager/src/contracts.rs 69 0 0.0%
crates/bin/escrow_manager/src/metrics.rs 18 0 0.0%
crates/bin/escrow_manager/src/subgraphs.rs 14 0 0.0%
crates/bin/escrow_manager/src/config.rs 6 0 0.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 2552
Covered Lines: 1125
Line Coverage: 44.08%
Coverage Strength: 143.38 hits per line

💛 - Coveralls

@tmigone tmigone changed the title feat(escrow_manager): add withdraw functionality feat(escrow_manager): reclaim idle escrow via thaw and withdraw Sep 18, 2026
Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
Comment thread crates/bin/escrow_manager/src/config.rs Outdated
Signed-off-by: Tomás Migone <tomas@thegraph.foundation>
Comment thread crates/bin/escrow_manager/src/contracts.rs Outdated
Comment thread crates/bin/escrow_manager/src/main.rs Outdated
tmigone and others added 5 commits September 21, 2026 15:33
@tmigone
tmigone force-pushed the tmigone/escrow-withdraw branch from aac87b1 to 71c72d1 Compare September 21, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants