Skip to content

Interest-rate reserve-param timelock is queue-only — no UI to apply or cancel pending changes #286

Description

@grantfox-oss

Problem

The lending contract implements a proper 2-step governance timelock for interest-rate risk parameters: queue_set_reserve_params → wait out the unlock delay → apply_queued_reserve_params (or cancel_queued_reserve_params before it unlocks). The frontend only wires the first step:

  • InterestRateParamsForm.tsx (apps/web-app/src/features/admin/components/) only calls lendingService.setInterestRateParams(), which wraps queue_set_reserve_params.
  • apply_queued_reserve_params and cancel_queued_reserve_params are exposed on the generated contract client (packages/contracts/lending/src/index.ts) but are never called anywhere in the frontend.
  • There is no getter for QueuedReserveConfig { new_params, unlock_time } in the binding, and no UI surfaces whether a change is pending, when it unlocks, or lets an admin apply/cancel it.

Why this needs real judgment, not a quick patch

Once an admin queues a reserve-param change today, it is effectively stuck — there's no way to see it, wait it out, apply it, or cancel it from the app. Fixing this requires:

  • Deciding how to reconstruct pending-queue state given there's no direct getter — most plausibly by querying Soroban contract events by topic, mirroring the existing pattern in getActiveBadDebtAuctions() (apps/web-app/src/lib/helpers/stellar/lending.ts), or by reading contract instance/temporary storage directly.
  • Building unlock-time countdown + apply/cancel controls per pool/asset, analogous to the already-working backstop withdrawal-queue flow in apps/web-app/src/features/backstop/hooks/useBackstop.ts (a genuinely similar "queue then execute after a delay" UX, worth using as a pattern reference — not a template to copy verbatim since the domain differs).
  • Handling the case where the calling admin isn't the one who queued the change, and where a queued change has already unlocked vs. is still pending.

Scope

  • apps/web-app/src/features/admin/components/InterestRateParamsForm.tsx (add pending-queue table + apply/cancel controls)
  • A new hook, e.g. useQueuedReserveParams
  • apps/web-app/src/lib/services/lending.service.ts (add applyQueuedReserveParams/cancelQueuedReserveParams wrappers)
  • Possibly a small addition to apps/web-app/src/lib/helpers/stellar/lending.ts for event querying

Acceptance criteria

  • Admin UI shows any currently-queued reserve-param change per pool/asset, including unlock time
  • Admin can apply a queued change once unlocked
  • Admin can cancel a queued change before it unlocks
  • Clear state distinction between "no change queued," "queued but locked," and "queued and ready to apply"
  • No regression to the existing queue (setInterestRateParams) flow

This is cross-cutting architectural work (missing half of a contract's governance flow, requiring new state-reconstruction logic) — evaluated per the project's PR rubric as HARD complexity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions