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

Abierto
#11 9 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@avqor ya está trabajando en esto.

Desde el 30/8/2026.

  • #233 de @avqor — abierto

Evaluación

Este issue todavía no se ha evaluado.

Descripción

architecture bug GrantFox OSS Maybe Rewarded Official Campaign | FWC26 Stellar Wave very hard

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.

Lenguaje dominante
Rust
Estrellas
1
Forks
102
Merge medio
4 h 12 min
PR fusionados (30 d)
30

Preparar el entorno

  • Sin Dockerfile ni archivo de Docker Compose
  • Tiene una plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de MergeFi/contracts

Todos los issues de MergeFi/contracts

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.