Sitelet https://github.com/piekstra/lofty-cli/pull/4
Skip to content

Add lofty account coverage — reserved vs free-to-spend USDC - #4

Merged
piekstra merged 2 commits into
mainfrom
feat/account-coverage
Jul 28, 2026
Merged

piekstra merged 2 commits into
mainfrom
feat/account-coverage

Conversation

@piekstra

@piekstra piekstra commented Jul 28, 2026 •

Copy link
Copy Markdown
Owner

What

Adds lofty account coverage: how much of your USDC is reserved backing resting bids vs actually free to spend, plus a per-order coverage check and a --spend simulation.

Why

Lofty funds open orders from your live balances — buys need the USDC, sells need the shares, for as long as the order is open, across all your open orders on a property combined — and orders your wallet can't cover are canceled automatically.

That check is per property, not aggregate, which has two consequences your raw balance won't tell you:

  1. Several properties' bids can lean on the same USDC at once, so the wallet floor every bid must clear is your largest single-property bid total. That much is reserved; only the surplus above it is spendable.
  2. The sum of your bids can legitimately exceed your wallet while they rest (overCommitted) — but one fill spends cash the other properties were also counting on, cascading into automatic cancellations.

Spending USDC on new inventory is exactly how you accidentally trip #2. --spend simulates it and names the properties it would uncover, before you spend.

Usage

$ lofty account coverage
wallet $200.00 — $190.00 reserved (largest single-property bid), $10.00 free to spend
  note: $310.00 total bid exposure exceeds the wallet — fine while they rest
  (coverage is per property), but one fill spends cash the others also rely on

$ lofty account coverage --spend 50
spending $50.00 leaves $150.00 — EXCEEDS free capital
  ⚠ would uncover 01SAMPLEPROPERTY000000000A (bids $190.00)

--json emits account-coverage/v1: walletUsdc, reservedUsdc, freeUsdc, bidExposureUsdc, overCommitted, uncoveredBids/uncoveredAsks, a properties[] breakdown, and simulation when --spend is given.

Notes

  • Read-only. Three GETs (balance, orders, positions); places and cancels nothing.
  • Operates purely on the caller's own authed account — nothing account-specific is hardcoded, and the command encodes no strategy or tuning, just Lofty's documented coverage rule.

Testing

  • coverage() is a pure function with 9 unit tests over anonymized fixtures, covering the max-not-sum reserve, same-property combining, uncovered bids, asks-vs-held-tokens, non-active orders ignored, the spend cascade, and the empty account.
  • Also validated end-to-end against live API payloads: real response shapes parse, and reserved / exposure / free matched an independent computation to the cent.
  • cargo fmt --check, cargo clippy --all-targets -D warnings, and cargo test all clean.

piekstra added 2 commits July 28, 2026 12:10
Lofty funds open orders from live balances (buys need the USDC, sells need the
shares) across all open orders on a property COMBINED, and auto-cancels orders
the wallet can't cover. The check is per property, not aggregate, which has two
consequences a raw balance doesn't show:

- Several properties' bids lean on the same USDC, so the binding reserve is the
  LARGEST single-property bid total — only the surplus above it is spendable.
- The SUM of bids can legitimately exceed the wallet while they rest, but one
  fill spends cash the other properties relied on, cascading into cancellations.

`coverage` computes both, checks every order against its cover (bids vs USDC,
asks vs held tokens), and `--spend` simulates a purchase to report exactly which
properties it would uncover.

Pure `coverage()` fn with 9 unit tests over anonymized fixtures; also validated
against live API payloads (real shapes parse; reserve/exposure/free matched an
independent computation to the cent).

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
Adds a fixture contract test for the three payloads `account coverage` reads —
a missing numeric would silently read as 0 and quietly corrupt the math, so the
shapes are pinned rather than discovered live.

The orders fixture held only cancelled buy orders, so it could not exercise the
paths that matter: asks cover against held tokens, and only `active` orders
consume cover at all. Added two representative active orders (one buy, one sell)
alongside the captured rows, matching live shapes including
`paymentCurrency: "any"` on sells, and documented it in the fixtures README.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
@piekstra
piekstra requested a review from piekstra-dev July 28, 2026 18:15

@piekstra-dev piekstra-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Automated PR Review

Reviewed commit: 5269bba242db
Profile: reviewer - Posting as: piekstra-dev

Summary

Reviewer Findings
policies:conventions 0
documentation:docs 0

Reviewer Coverage

Reviewer Status Inspected Skipped Constraints
policies:conventions complete_broad README.md, src/commands/account.rs unavailable No .codereview/agents/ repo-local guidance and no ../cli-common/../.github sibling docs were present, so review relied on this repo's own AGENTS.md/CLAUDE.md conventions plus the code itself.
documentation:docs complete_broad README.md, tests/fixtures/README.md unavailable unavailable
unassigned incomplete_unassigned unavailable tests/fixture_shapes.rs, tests/fixtures/account/orders-list.json changed files were not assigned to a selected reviewer

0 PR discussion threads considered. 0 summarized; 0 resolved.


Completed in 1m 56s | $1.33 | claude-sonnet-5 | cr 0.10.268
Field Value
Model claude-sonnet-5
Reviewers policies:conventions, documentation:docs
Engine claude_cli · claude-sonnet-5
Reviewed by cr · piekstra-dev
Duration 1m 56s wall · 2m 49s compute
Cost $1.33
Tokens 66 in / 10.5k out

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost Duration
orchestrator-selection claude-sonnet-5 6 2.0k 27.0k 31.0k $0.22 24s
policies:conventions claude-sonnet-5 32 4.6k 499.0k 48.5k $0.51 1m 21s
documentation:docs claude-sonnet-5 22 3.5k 377.0k 51.1k $0.47 55s
orchestrator-rollup claude-sonnet-5 6 339 60.4k 16.3k $0.12 8s

@piekstra
piekstra merged commit be56367 into main Jul 28, 2026
2 checks passed
@piekstra
piekstra deleted the feat/account-coverage branch July 28, 2026 18:19
piekstra added a commit that referenced this pull request Jul 28, 2026
Three read-only commands for the questions the raw API can't answer directly,
plus one fee correctness fix:

- `account coverage`   — USDC reserved backing bids vs free to spend (#4)
- `account breakeven`  — fee-inclusive sell price; costBasis hides the buy fee (#5)
- `rewards eligibility`— are my orders earning right now, and if not why (#6)
- fix: AMM rates are platform + the pool's LP fee (#7)

All three verified against a live account before release.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
piekstra added a commit that referenced this pull request Jul 30, 2026
* Add lofty account coverage — reserved vs free-to-spend USDC

Lofty funds open orders from live balances (buys need the USDC, sells need the
shares) across all open orders on a property COMBINED, and auto-cancels orders
the wallet can't cover. The check is per property, not aggregate, which has two
consequences a raw balance doesn't show:

- Several properties' bids lean on the same USDC, so the binding reserve is the
  LARGEST single-property bid total — only the surplus above it is spendable.
- The SUM of bids can legitimately exceed the wallet while they rest, but one
  fill spends cash the other properties relied on, cascading into cancellations.

`coverage` computes both, checks every order against its cover (bids vs USDC,
asks vs held tokens), and `--spend` simulates a purchase to report exactly which
properties it would uncover.

Pure `coverage()` fn with 9 unit tests over anonymized fixtures; also validated
against live API payloads (real shapes parse; reserve/exposure/free matched an
independent computation to the cent).

* Pin coverage's API-shape contract; fill an orders-fixture gap

Adds a fixture contract test for the three payloads `account coverage` reads —
a missing numeric would silently read as 0 and quietly corrupt the math, so the
shapes are pinned rather than discovered live.

The orders fixture held only cancelled buy orders, so it could not exercise the
paths that matter: asks cover against held tokens, and only `active` orders
consume cover at all. Added two representative active orders (one buy, one sell)
alongside the captured rows, matching live shapes including
`paymentCurrency: "any"` on sells, and documented it in the fixtures README.
piekstra added a commit that referenced this pull request Jul 30, 2026
Three read-only commands for the questions the raw API can't answer directly,
plus one fee correctness fix:

- `account coverage`   — USDC reserved backing bids vs free to spend (#4)
- `account breakeven`  — fee-inclusive sell price; costBasis hides the buy fee (#5)
- `rewards eligibility`— are my orders earning right now, and if not why (#6)
- fix: AMM rates are platform + the pool's LP fee (#7)

All three verified against a live account before release.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants