Skip to content

Fixed TTL extension thresholds risk archival/fund-inaccessibility for long-lived escrows and pools #11

Description

@chonilius

Background / Context

All three contracts call extend_ttl (escrow/src/lib.rs:266-268, milestones/src/lib.rs:284-286, maintenance-pool/src/lib.rs:175-177), each identically: env.storage().persistent().extend_ttl(key, 100_000, 500_000) — a hardcoded threshold and extend-to value in ledger count, applied uniformly regardless of the entry's actual expected lifetime. The escrow's own doc comment says these values are "conservative defaults suitable for a multi-month bounty lifecycle," but maintenance pools are explicitly designed to be open-ended/long-lived ("it never 'finishes'" per the README), and milestones can plausibly span longer release cycles too.

Problem Statement

Soroban archives (evicts) persistent entries whose TTL expires, and restoring an archived entry requires an explicit (and non-trivial) restoration transaction — if even possible depending on how long past expiry it is and network policy. extend_ttl is only called on the "active" write paths (fund, release, refund, allocate, release_issue, deposit, withdraw) — meaning an escrow/pool/milestone that receives no writes for longer than the TTL window (e.g., a maintenance pool for a quiet repo that goes a year without a maintainer draw-down, or an escrow whose deadline is far in the future and nobody touches it) can have its TTL lapse and its entry archived with no explicit warning or contract-level safeguard, potentially requiring off-chain intervention (a restore transaction) before funds become accessible again, or in the worst case (if restoration policy/tooling isn't in place) creating genuinely stuck funds.

Requirements

  • Research Soroban's exact TTL/archival/restoration mechanics: what happens on a call against an archived entry, what's required to restore it, whether restoration requires the original writer or can be done permissionlessly, and what the actual eviction/rent-bump costs look like at current network parameters.
  • Compute, for each contract, the real-world time window 100_000/500_000 ledgers corresponds to (ledger close time is roughly, but not exactly, constant — pin down the current approximate figure and note it can change) and compare it against the stated multi-month/open-ended lifecycle expectations.
  • Implement a fix appropriate to each contract's lifecycle: for maintenance pools specifically, consider whether any interaction (even a permissionless "ping"/extend_ttl-only view-adjacent call, or a longer default threshold) should be exposed so a pool can be kept alive without requiring a deposit/withdrawal; for escrow/milestones, consider whether the threshold should scale with the stored deadline/milestone duration rather than being a fixed constant.
  • Add tests simulating ledger-sequence advancement past the TTL threshold (Soroban's testutils::Ledger supports manipulating ledger sequence) to prove the fix actually prevents archival within realistic usage patterns.

Acceptance Criteria

  • Written research on Soroban TTL/archival/restoration mechanics and current network parameters
  • Quantified real-world time-window analysis per contract
  • Implemented fix (dynamic threshold, permissionless keep-alive call, or equivalent) per contract as warranted
  • Tests using testutils::Ledger sequence manipulation proving entries survive realistic long-idle periods post-fix
  • No unnecessary cost increase for the common case (active escrows/pools)

Technical Notes / Hints

  • soroban_sdk::testutils::Ledger trait exposes ledger sequence manipulation for tests — use it to simulate long idle periods without waiting in real time.
  • Consider especially the maintenance-pool contract, whose entire premise ("never finishes," "recurring") is in the most direct tension with a fixed-TTL model designed around bounded bounty lifecycles.

Difficulty Justification

Requires specialized knowledge of Soroban's state-expiration/archival system (a Stellar-specific mechanism with no direct EVM analog), careful time-window arithmetic tied to network-specific ledger-close-time assumptions that themselves can shift, and a fix that must be tailored differently per contract given their genuinely different lifecycle models rather than a single uniform patch.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Stellar WaveIssues in the Stellar wave programarchitectureArchitecture/design issuebugSomething isn't workingvery hardVery difficult task, expert-level effort required

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions