Skip to content

feat: vault redemption preview, OpenAPI examples, audit log filters, negative yield simulator support - #1455

Merged
github-actions[bot] merged 5 commits into
edehvictor:devfrom
Emeka-12:feat/1404-1407-redemption-preview-openapi-audit-filters-negative-yield
Oct 2, 2026
Merged

github-actions[bot] merged 5 commits into
edehvictor:devfrom
Emeka-12:feat/1404-1407-redemption-preview-openapi-audit-filters-negative-yield

Conversation

@Emeka-12

Copy link
Copy Markdown
Contributor

Summary

Test plan

  • Redemption preview: call with a partial share amount and verify estimated USDC output; call with 0 shares and verify typed error; call with more shares than held and verify typed error.
  • OpenAPI examples: run npm run test in server/; snapshot diff should show only the new examples.
  • Audit log filters: filter by wallet address, by action type, and by date range individually and in combination; verify empty-state message when no records match.
  • Negative yield simulator: run simulation with an interval whose APY is negative and verify net yield is negative but the simulation completes without error; run with mixed positive/negative intervals and verify correct aggregate.

Closes #1404
Closes #1405
Closes #1406
Closes #1407

Emeka-12 and others added 4 commits September 25, 2026 04:20
Server
- GET /api/admin/audit-logs and its CSV export accept `wallet`, `action`
  (one, comma-separated, or repeated) and `startDate`/`endDate`, validated
  once in utils/auditFilters.ts.
- Invalid filters answer 400 with a stable code (INVALID_WALLET,
  INVALID_ACTION, INVALID_DATE, INVALID_DATE_RANGE, INVALID_FILTER) instead
  of an empty page: an unparseable date used to become NaN, which made every
  comparison false and silently returned nothing.
- A wallet matches the acting identity, the target resource, or a wallet
  recorded under a wallet-like key of `changes`. A date-only endDate covers
  the whole UTC day, and dates without a zone are rejected because they parse
  as local time.
- The list response echoes the normalised filters. The export now returns up
  to 10,000 matching rows instead of silently stopping at the default page of
  100, and sets X-Audit-Export-Truncated when it hits the cap.

Client
- New /admin/audit-logs page with wallet, action and date-range filters,
  client-side validation that mirrors the server, cursor paging, CSV export,
  and loading, empty, forbidden and unavailable states that never show raw
  server output.

Closes edehvictor#1406
…lators

The rebalance preview and backtest rejected any APY below zero, so users could
not model a depeg, a slashing event or a strategy that costs more than it
earns.

Server
- Accept a negative `apy` down to -100 (a total loss over a year) and negative
  `dailyApy` entries down to -36500, where the daily compounding factor
  reaches zero. `dailyApy` was not validated at all before; it now rejects
  NaN, Infinity, non-numbers, non-arrays and oversized series, naming the
  offending index.
- The engine floors the daily factor at zero, skips rebalancing when nothing is
  left, and no longer produces NaN weights or blended APY for a wiped-out
  portfolio.
- The backtest result adds negativeYieldDays, maxDrawdownPct and
  passiveMaxDrawdownPct. New structured warnings: NEGATIVE_YIELD_PERIOD (per
  allocation, and per leg in the preview) and CAPITAL_LOSS.
- The vault contract already charges its performance fee only on positive
  yield, so no contract change is needed; the simulator models turnover fees
  only.

Client
- The APY field keeps the raw text, so a lone "-" can be typed on the way to
  "-5" (the old number input with a `|| 0` fallback swallowed it, and had
  min=0). Values are parsed and bounds-checked on submit with a message that
  names the allocation.
- Show max drawdown and negative-yield days, and surface the server's 400
  `details` instead of only "Invalid backtest parameters".

Closes edehvictor#1407
Before signing a partial withdrawal the user now sees how many shares are
burned, what they receive, the share price, and what is left.

Shared
- shared/types/vaultRedemption.ts holds the math once, in BigInt so amounts
  beyond 2^53 stay exact. Rounding favours the vault (ERC-4626): redeeming
  shares rounds the assets down, withdrawing an exact asset amount rounds the
  shares up, and the burned shares' surplus is reported as rounding dust.

Server
- POST /api/vaults/:vaultId/redemption-preview accepts shares, assets, or a
  percentage of the position, plus an optional exit fee and dust threshold.
  Amounts travel as integers or digit strings and come back as strings.
- Typed errors (INVALID_VAULT_STATE, INVALID_REQUEST, INVALID_AMOUNT,
  INVALID_PERCENT, INSUFFICIENT_SHARES with the maximum, REDEMPTION_TOO_SMALL,
  VAULT_EMPTY) instead of raw provider output; DUST_REMAINDER and
  REMAINDER_WORTHLESS warnings.

Client
- The withdraw panel gains 25/50/75/100% presets and a preview that updates as
  the amount changes, using the same math against the vault's on-chain
  totals. If the totals cannot be read it says so and does not block the
  withdrawal.

Closes edehvictor#1404
…saction intent endpoints

Add OpenAPI request/response examples for all transaction intent endpoints:
- /api/onramp/quote (step 1: get fiat-to-USDC conversion quote)
- /api/onramp/intent (step 2: confirm quote and create pending transaction)
- /api/onramp/status/{txId} (step 3: poll for transaction completion)
- /api/onramp/cancel (cancel pending transaction)
- /api/offramp/* endpoints (withdrawal flow)

Examples cover normal paths and meaningful edge cases (invalid amounts,
missing currencies, quote expiration). Improves API documentation clarity
for integrators. Updated OpenAPI schema snapshot.

Closes edehvictor#1405
@vercel

vercel Bot commented Sep 28, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Edeh Victor's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

Copy link
Copy Markdown

@Emeka-12 this PR currently has merge conflicts.

Please resolve the conflicts before it can be merged automatically.

@edehvictor edehvictor left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

Good job.

@github-actions
github-actions Bot merged commit c93f9fe into edehvictor:dev Oct 2, 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

2 participants