Skip to content

feat(factory, farming-pool): report refreshed pool IDs, add get_pool_info, verify credit-rate event (#393, #394, #395, #396) - #423

Merged
ritaifeoluwa merged 5 commits into
SmartDropLabs:mainfrom
aurorabini:fix/393-396-pool-ttl-and-stats
Sep 27, 2026
Merged

ritaifeoluwa merged 5 commits into
SmartDropLabs:mainfrom
aurorabini:fix/393-396-pool-ttl-and-stats

Conversation

@aurorabini

Copy link
Copy Markdown
Contributor

Closes #393
Closes #394
Closes #395
Closes #396

Summary

One commit per issue. Two factory TTL changes and two farming-pool
readability/coverage changes, with no behaviour change beyond the two
additive return values described below.

#393 — refresh_pool_ttls reports what it refreshed (ddf4646)

The existence check was already in place, so IDs without a record were
skipped — but the entry point returned Ok(()), leaving callers no way to
tell which IDs were actually kept alive versus skipped. A keeper
reconciling a sweep against a known registry had to guess.

  • New RefreshPoolTtlsResponse: refreshed (ascending IDs that existed and
    were bumped), end_id (clamped resume point) and missing (count skipped
    for an absent record).
  • refresh_pool_ttls now returns it. The existence check and the ttl_ref
    event payload are unchanged, so the event contract stays stable.
  • The two existing refresh_pool_ttls tests were asserting Ok(Ok(())) and
    are updated to the new return value.

#394 — coverage for missing pool records (52413c9)

  • test_refresh_pool_ttls_reports_only_existing_pools_and_counts_gaps: pool
    IDs are handed out sequentially from PoolCount, so a hole inside the
    sweep range means a record was removed from storage (TTL lapse /
    archival) — the same case list_pools reports as pool_gap. The test
    archives the middle record, ages the survivors, and asserts the sweep
    returns only the survivors, reports missing == 1, extends their TTLs to
    TTL_EXTEND_TO, and does not materialise the archived record.
  • test_refresh_pool_ttls_reports_empty_sweep_past_the_registry: a
    start_id beyond the count sweeps nothing and reports an empty result with
    end_id clamped, instead of an ambiguous unit return.

#395 — get_pool_info aggregate query (bbcb745)

A pool overview needed up to six separate calls (total_staked,
credit_rate, global multiplier, min lock period, min stake amount, paused
flag), each paying its own invocation cost and TTL bump.

  • New PoolInfo contract type and get_pool_info(), reading instance
    storage directly behind require_initialized + bump_instance like every
    other getter.
  • Tests assert the aggregate agrees with every individual getter it
    replaces
    , and that an uninitialized pool returns NotInitialized rather
    than a zeroed PoolInfo that would be indistinguishable from an empty pool.

One deliberate deviation: the issue also lists "number of stakers". There
is no staker-count entry in storage — it is derived by paging get_positions
— so a field here would report a value nothing maintains. The two maintained
credit counters (total_banked_credits, total_distributed_credits) are
included instead, so the overview is still a single round trip. This is
noted in the code comment and the commit message.

#396 — verify the set_credit_rate event (dfd04ba)

The issue asks to verify the event already includes both rates. It does:
set_credit_rate publishes (old_rate, new_rate, ledger_sequence). This
adds the missing verification, and it verifies the property that actually
matters — across a sequence, not a single change. Three consecutive
changes (10 → 25 → 40 → 5) are pinned as three rate_set events, where each
event's old_rate equals the previous event's new_rate. That chain is what
lets an indexer reconstruct rate history and compute deltas without reading
storage. The final value is also asserted against the credit_rate getter.

Notes for maintainers

  • Both contract changes are additive: a new response type on an existing
    entry point and a new read-only entry point. No storage keys, no
    authorization changes, and no existing call sites outside the tests.
  • min_lock_period is returned in ledgers, matching the internal
    read_min_lock_period and the existing min_lock_period() getter, rather
    than the seconds variant.
  • Verified by reading in this environment (no cargo builds or test runs
    performed here, per the contribution constraints) — CI should compile and
    execute the suites.

…tDropLabs#393)

The sweep already guarded each bump with a storage existence check, so
non-existent IDs were skipped — but the entry point returned Ok(()), and
callers had no way to learn which IDs were actually kept alive versus
which were skipped. A keeper reconciling a sweep against a known registry
had to guess.

- New RefreshPoolTtlsResponse contract type: refreshed (ascending IDs that
  existed and were bumped), end_id (clamped resume point) and missing
  (count of IDs skipped for an absent record).
- refresh_pool_ttls now returns it. The existence check and the ttl_ref
  event payload are unchanged, so the event contract is stable.
- Existing refresh tests updated to the new return value.
…rtDropLabs#394)

Adds the coverage the TTL logic lacked:

- test_refresh_pool_ttls_reports_only_existing_pools_and_counts_gaps:
  pool IDs are handed out sequentially, so a hole inside the sweep range
  means a record was removed from storage (TTL lapse / archival) — the
  same case list_pools reports as pool_gap. The test archives the middle
  record, ages the survivors, then asserts the sweep returns only the two
  surviving IDs, reports missing == 1, extends the survivors' TTLs to
  TTL_EXTEND_TO, and does not materialise the archived record.
- test_refresh_pool_ttls_reports_empty_sweep_past_the_registry: a start_id
  beyond PoolCount sweeps nothing and reports an empty result with end_id
  clamped to the count, instead of an ambiguous unit return.
)

A pool overview needed up to six separate contract calls — total_staked,
credit_rate, the global multiplier, the min lock period, the min stake
amount and the paused flag — each paying its own invocation cost and TTL
bump, with no on-chain way to fetch the set together.

- New PoolInfo contract type carrying total_staked, total_banked_credits,
  total_distributed_credits, credit_rate, global_multiplier,
  min_lock_period, min_stake_amount and is_paused.
- get_pool_info() reads instance storage directly, guarded by
  require_initialized + bump_instance like every other getter.

The issue text also names 'number of stakers', which is deliberately not a
field: the pool keeps no staker-count entry (it is derived by paging
get_positions), so the field would report a value nothing maintains. The
two maintained credit counters are included instead so the overview is a
single round trip.

Tests: the aggregate agrees with every individual getter it replaces, and
an uninitialized pool returns NotInitialized rather than a zeroed
PoolInfo that would be indistinguishable from an empty pool.
…rate (SmartDropLabs#396)

The issue asks to verify the event already includes both rates. It does:
set_credit_rate publishes (old_rate, new_rate, ledger_sequence). This adds
the missing verification, which is a sequence rather than a single change —
each event's old_rate must equal the previous event's new_rate, which is
precisely the property an indexer needs to reconstruct rate history and
compute deltas without reading storage.

Pins three consecutive changes (10 -> 25 -> 40 -> 5) as three rate_set
events with those payloads, and asserts the final value still matches the
public credit_rate getter.
@drips-wave

drips-wave Bot commented Sep 27, 2026

Copy link
Copy Markdown

@aurorabini Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@netlify

netlify Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for sdcontracts ready!

Name Link
🔨 Latest commit 7cf73c4
🔍 Latest deploy log https://app.netlify.com/projects/sdcontracts/deploys/6ab961d35aec060008b4226c
😎 Deploy Preview https://deploy-preview-423--sdcontracts.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ritaifeoluwa
ritaifeoluwa merged commit 42dc9e0 into SmartDropLabs:main Sep 27, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants