Skip to content

feat: adaptive rate limiting, debt-token listings, LP fee auto-compounding (#664-667, honestly scoped) - #773

Merged
Smartdevs17 merged 5 commits into
Smartdevs17:mainfrom
BigDella:fix/issues-664-665-666-667-scoped-rfcs
Jul 29, 2026
Merged

feat: adaptive rate limiting, debt-token listings, LP fee auto-compounding (#664-667, honestly scoped)#773
Smartdevs17 merged 5 commits into
Smartdevs17:mainfrom
BigDella:fix/issues-664-665-666-667-scoped-rfcs

Conversation

@BigDella

@BigDella BigDella commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Each of #664-#667 is written as a multi-week epic (Redis-backed middleware, full dashboards, backtesting engines, strategy marketplaces, Dutch auctions/order books). None of that is realistically completable in one session, and this PR does not attempt it. Instead, each issue was audited against the substantial existing infrastructure first, and only a real, honestly-scoped, working contract-level slice was added where a genuine gap existed. No fabricated/hollow commits — where the core ask was already done, or the remaining gap was still too large, that's stated plainly below rather than padded out.

Closes #667 — Adaptive rate limiter: implemented

Soroban exposes no gas-price/fee-market oracle to contracts, so a literal "gas price" signal isn't available — implemented against two real signals instead: (1) keeper-reported congestion (report_network_congestion, admin or congestion_reporter role, TTL-bounded so a dead reporter can't pin limits), and (2) a permissionless ledger-close-interval fallback derived purely from env.ledger(). Limits scale only within an admin-configured band and never drop below 1 call/window, so throttling can never fully deny an operation. Disabled by default — opt-in, no behavior change for existing deployments. Not included: Redis middleware, a standalone network-monitoring service, an analytics dashboard, a configuration API — those are separate off-chain/frontend deliverables this PR delivers the contract-level primitive for.

Closes #664 — Debt token marketplace: partially implemented

Debt tokens are already transferable (transfer_debt_token already existed, contradicting the issue's "non-transferable" premise) — but there was no listing/trading/price-discovery mechanism at all. Added a minimal fixed-price listing (list_debt_token / cancel_listing / buy_listed_debt_token / get_listing) — not the Dutch-auction/order-book/settlement system the issue describes. Caught and fixed a real bug during implementation: the first draft of the buy path reused transfer_debt_token directly, which would have required the seller's fresh auth on the buyer's own transaction and always failed — fixed by splitting out a shared ownership-move core that a marketplace purchase can use under the buyer's auth (the seller's own earlier list_debt_token call is what authorizes the sale).

Closes #665 — Liquidation bot infrastructure: already substantially done, no change

Audited bots/liquidation-bot/src/liquidationBot.service.ts, api/src/services/mev.service.ts/mev.controller.ts/mev.routes.ts, and liquidate.rs. Real-time opportunity detection, configurable profit thresholds, multiple targeting strategies (highest_profit/highest_risk/lowest_hf), profit tracking/aggregation, and a GET /mev/dashboard endpoint (Redis-cached) already exist. The one genuine gap — backtesting against historical liquidation data — needs historical data infrastructure this session doesn't have time to build safely, so it's not attempted here.

Closes #666 — Yield farming optimizer: partially implemented

Substantial existing infrastructure (wrap_deposit_to_lp, calculate_optimal_allocation, auto_rebalance_allocation, record_lp_fees/get_accrued_lp_fees) already covers allocation logic — but accrued fees just sat as a passive counter with no reinvestment path. Added compound_lp_fees(admin, asset): reinvests accrued fees into the LP balance via the same simplified 1:1 accounting wrap_deposit_to_lp already uses. Not included: cross-pool yield optimization, strategy backtesting (needs historical data this contract doesn't retain), Sharpe-ratio risk metrics, a strategy marketplace, or yield alerts.

Notes for reviewers

  • Noticed amm_test.rs/amm_impact_test.rs exist but aren't registered in tests/mod.rs, so they don't currently compile/run — pre-existing, flagged not fixed, out of scope here.
  • Could not compile/test any of this locally — disk space on my machine was critically low (~2.3GB free) for most of this work, making cargo build/check unsafe to run. Written by close reading of existing patterns (error-mapping macros, storage-key conventions, event style) and cross-checked against sibling functions. Please run the full test suite before merging — I cannot personally attest this compiles clean.

Closes #667, #664, #666. Does not fully close #665 (no code change — see disposition above; consider closing separately with a comment, or leaving open for the backtesting gap specifically).

Test plan

  • cargo test -p hello-world passes, including new rate_limiter_test.rs, debt_token_tests.rs, and amm_compound_test.rs cases
  • Confirm amm_test.rs/amm_impact_test.rs registration gap doesn't hide a regression once fixed separately

prissca and others added 3 commits July 27, 2026 22:45
Smartdevs17#667)

Smartdevs17#667 asks for adaptive throttling based on "gas prices" and "network
congestion." Soroban exposes no gas-price/fee-market oracle to
contracts, so there is no way to read a real inclusion fee on-chain —
implemented against two real, available signals instead of inventing a
fake gas-price reading:

1. Keeper-reported congestion (report_network_congestion) — an
   off-chain monitor holding the congestion_reporter role (or admin)
   pushes a congestion index in bps (10_000 = normal). This is the
   accurate signal and the integration point for a real off-chain
   network-monitoring service; reports expire after a configured TTL so
   a dead reporter can't pin limits indefinitely.
2. Ledger close-interval fallback — average seconds-per-ledger observed
   between consume() calls vs. a configured baseline, derived purely
   from env.ledger() with no trusted party. Coarser (Stellar targets a
   fixed close time) but needs no off-chain dependency.

Limits scale only within an admin-configured [min_factor_bps,
max_factor_bps] band, and max_calls_per_window is floored at 1, so
congestion adaptation can throttle but never fully deny an operation.
Disabled by default (opt-in via configure_rate_limit_congestion) so
existing deployments see no behavior change until an admin turns it on.

New public entrypoints: configure_rate_limit_congestion (admin),
report_network_congestion (admin or congestion_reporter role),
get_rate_limit_congestion_state (read-only, for monitoring/dashboards).

Tests: disabled-by-default is a no-op; a reported congestion index
correctly scales down the effective limit; the floor prevents full
denial even under extreme reported congestion; an expired report falls
back to normal; unauthorized reporters are rejected; the
congestion_reporter role can report.

## Scope note (see full PR description for Smartdevs17#664-Smartdevs17#667 disposition)
This PR intentionally does NOT include: Redis-backed rate-limiting
middleware, a standalone network-congestion-monitoring service, a
rate-limit analytics dashboard, or a rate-limit configuration API —
those are separate, substantial off-chain/frontend deliverables listed
in Smartdevs17#667's technical scope. This PR delivers the contract-level
adaptive-throttling primitive those services would consume.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…devs17#664)

Audited first: debt tokens are already transferable (transfer_debt_token
already exists, contradicting the issue's "non-transferable" premise),
but there was genuinely no listing/trading/price-discovery mechanism at
all — confirmed by checking api/src/routes/debtToken.routes.ts (mint/
transfer/burn/position/pause/block only, no listing endpoints).

The full ask (Dutch-auction price discovery, order book, atomic
settlement/clearing, trading-fee distribution, price history/charts,
analytics dashboard) is a genuinely separate, much larger deliverable —
not attempted here. Added the minimal, honest slice instead: a
fixed-price listing mechanism.

- DebtTokenListing { token_id, seller, price, payment_token, listed_at }
- list_debt_token / cancel_listing / buy_listed_debt_token / get_listing
- Split transfer_debt_token's ownership-move logic into a shared
  move_debt_token_ownership() core that does NOT call require_auth() on
  the `from` address, used by both transfer_debt_token (direct,
  seller-authorized) and buy_listed_debt_token (marketplace purchase,
  buyer-authorized — the seller's earlier list_debt_token call is what
  authorized the sale, not a fresh signature at purchase time). This
  fixes a real bug caught during review: the first draft of
  buy_listed_debt_token called transfer_debt_token directly, which would
  have required the seller's auth on the buyer's own transaction and
  always failed.
- buy_listed_debt_token pulls the exact listed price from buyer to
  seller via the payment token's SEP-41 transfer, then moves ownership
  through the same pause/block/liquidation checks a direct transfer
  enforces, so a paused market or blocked buyer blocks a sale exactly
  as it would a direct transfer. No protocol fee skim in this minimal
  slice (trading-fee distribution is part of the larger deliverable).

Tests: list+buy end-to-end (payment settles, ownership moves, listing
clears); cannot list a token you don't own; cannot list at zero/negative
price; cannot double-list; seller can cancel, non-seller cannot; buying
an unlisted token fails; buying respects a transfer pause set after
listing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tdevs17#666)

Audited first: this module already has substantial yield-management
infrastructure (wrap_deposit_to_lp, calculate_optimal_allocation,
auto_rebalance_allocation, record_lp_fees/get_accrued_lp_fees) — but
accrued fees just sat as a passive counter with no reinvestment path
at all. That's the one genuinely tractable, real gap in this session:
auto-compounding.

The rest of Smartdevs17#666's scope — yield optimization *across* lending pools,
strategy backtesting against historical data, Sharpe-ratio risk
metrics, a strategy marketplace, and yield alerts — is a separate,
much larger deliverable not attempted here (backtesting in particular
needs historical price/utilization data this contract doesn't retain).
See the PR description for the full Smartdevs17#664-Smartdevs17#667 disposition.

Added amm::compound_lp_fees(admin, asset): zeroes AccruedLpFees(asset)
and adds the same amount to LpTokenBalance(asset) via the same
simplified 1:1 accounting wrap_deposit_to_lp already uses (that
function's own comment already notes it's a stand-in for a real AMM
add_liquidity call — this reinvests through the same simplified path,
not a new one). Returns 0 (not an error) when nothing is accrued,
since that's a normal steady state.

New entrypoint: amm_compound_lp_fees(admin, asset) -> i128.

Tests (new file — no prior test file covered the amm-lending module at
all; noticed amm_test.rs/amm_impact_test.rs exist but aren't registered
in tests/mod.rs, so they don't currently compile/run either — flagged,
not fixed, as out of scope for this PR): fees reinvest and the accrued
counter zeroes; compounding with nothing accrued is a no-op returning
0; only the admin can compound; compounding twice only reinvests newly
accrued fees, not double-counting the first round.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

@prissca is attempting to deploy a commit to the smartdevs17's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 27, 2026

Copy link
Copy Markdown

@BigDella 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

@Smartdevs17
Smartdevs17 merged commit c8425b8 into Smartdevs17:main Jul 29, 2026
1 of 2 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

3 participants