Skip to content

[Performance] extend_ttl is permissionless and extends the contract instance TTL on every call #678

Description

@Calebux

Context

StellarWrapContract::extend_ttl(user, period) takes no authorization, checks has(...) before each extension, and unconditionally ends with:

e.storage().instance().extend_ttl(ttl, ttl);

Problem

Permissionless TTL extension is a deliberate and reasonable design choice — anyone should be able to keep a user's records alive. But the current shape has two rough edges:

  1. Calling it with a (user, period) that does not exist performs three has lookups, extends nothing, and still extends the contract instance TTL — so an attacker can drive instance-rent writes with calls that accomplish nothing else.
  2. There is no batch form. Keeping N historical periods alive costs N transactions, which is precisely the "expiry risk" scenario the doc comment on extend_ttl warns about.

Proposed change

  • Return early (or panic with WrapNotFound) when no matching entry exists, before touching instance storage.
  • Add extend_ttl_batch(user, periods: Vec<u64>) with a bounded length so a renewal bot can cover a user in one transaction.

Acceptance criteria

  • extend_ttl on a non-existent record does not extend the instance TTL.
  • A bounded batch variant exists.
  • Tests cover the no-op case and a full batch.
  • The TTL-lifecycle doc comment in lib.rs is updated to describe the batch entrypoint.

Activity

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

Metadata

Metadata

Assignees

Labels

Stellar WaveperformanceGas optimization and efficiencypriority:lowNice to havesecuritySecurity vulnerabilities or hardeningsorobanSoroban SDK specific

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions