Skip to content

Conversation

@zahorodnyi
Copy link
Collaborator

Implement a basic feature to display users’ active options positions.

Resolve: #41 (comment)

@zahorodnyi zahorodnyi requested a review from KyrylR as a code owner February 11, 2026 16:57
@zahorodnyi zahorodnyi self-assigned this Feb 11, 2026
@zahorodnyi zahorodnyi added the greptile Mark this PR to be reviewed by Greptile label Feb 11, 2026
@zahorodnyi
Copy link
Collaborator Author

@greptile review the PR according to the CONTRIBUTION.md

@greptile-apps
Copy link

greptile-apps bot commented Feb 11, 2026

Greptile Overview

Greptile Summary

This PR adds a new “Active Options Positions” section to the CLI positions command. It fetches an optional BTC/USD price, queries option/grantor token UTXOs for the user, derives per-contract “Maker” and “Taker” active positions, and renders them in a new table. It also refactors timestamp formatting helpers in interactive.rs to use a shared current_timestamp().

Main issue: the new maker-position calculation attempts to account for “option tokens in offers” by querying OPTION_OFFER_SOURCE, but option-offer contracts lock collateral/premium (and later settlement), not option tokens. The code therefore sums collateral amounts and then treats them as unsold option tokens, which makes the displayed Maker sold/unsold values incorrect.

Confidence Score: 2/5

  • This PR should not be merged until the active positions accounting bug is fixed.
  • The new active positions logic misinterprets assets held in option-offer contracts (collateral/premium/settlement) as if they were option tokens, which will produce incorrect Maker sold/unsold figures in the CLI output. Other changes (timestamp refactor, table rendering) look safe.
  • crates/cli-client/src/cli/positions.rs

Important Files Changed

Filename Overview
crates/cli-client/src/cli/interactive.rs Refactors time formatting helpers to use shared current_timestamp(); no behavioral issues found.
crates/cli-client/src/cli/positions.rs Adds active options positions table and logic; found a correctness bug where option-offer collateral is counted as if it were option tokens, breaking Maker sold/unsold calculations.
crates/cli-client/src/cli/tables.rs Adds table rendering for active options positions; formatting is straightforward and safe.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as cli-client
    participant Wallet
    participant Store as coin_store
    participant PF as price_fetcher

    User->>CLI: positions
    CLI->>Wallet: open wallet
    CLI->>PF: fetch BTC/USD
    PF-->>CLI: btc_price (optional)

    CLI->>Wallet: derive user script_pubkey
    CLI->>Store: query token-tagged UTXOs (option)
    Store-->>CLI: option_tokens
    CLI->>Store: query token-tagged UTXOs (grantor)
    Store-->>CLI: grantor_tokens

    CLI->>CLI: build active positions
    par check collateral per contract
        CLI->>Store: query contract UTXOs (options contract + collateral asset)
        Store-->>CLI: has_collateral map
    and sum offer-held amounts
        CLI->>Store: list offer contracts
        Store-->>CLI: offer contracts
        CLI->>Store: query offer UTXOs (offer contract + collateral asset)
        Store-->>CLI: totals by asset
    end

    CLI-->>User: render active options table
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +213 to +215
/// Query all option tokens locked in option-offer contracts for multiple asset IDs
async fn query_all_option_tokens_in_offers(
wallet: &crate::wallet::Wallet,
Copy link

Choose a reason for hiding this comment

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

Incorrect offer token accounting

query_all_option_tokens_in_offers is described/used as summing “option tokens locked in option-offer contracts”, but option-offer contracts lock collateral/premium (and later settlement), not option tokens. In this function you filter and sum using OptionOfferArguments::get_collateral_asset_id() and UtxoFilter::asset_id(collateral_id) (positions.rs:237-248), so option_tokens_in_offers is actually collateral-in-offers keyed by the collateral asset id. Downstream, build_maker_positions treats that map as “unsold option tokens” (option_tokens_in_offers.get(&option_asset_id) at positions.rs:371-372), so Maker “sold of total” will be wrong (typically under/over-counting depending on assets).

Also appears at positions.rs:213-274 and positions.rs:367-383.

Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/cli-client/src/cli/positions.rs
Line: 213:215

Comment:
**Incorrect offer token accounting**

`query_all_option_tokens_in_offers` is described/used as summing “option tokens locked in option-offer contracts”, but option-offer contracts lock *collateral/premium* (and later settlement), not option tokens. In this function you filter and sum using `OptionOfferArguments::get_collateral_asset_id()` and `UtxoFilter::asset_id(collateral_id)` (positions.rs:237-248), so `option_tokens_in_offers` is actually *collateral-in-offers* keyed by the collateral asset id. Downstream, `build_maker_positions` treats that map as “unsold option tokens” (`option_tokens_in_offers.get(&option_asset_id)` at positions.rs:371-372), so Maker “sold of total” will be wrong (typically under/over-counting depending on assets).

Also appears at positions.rs:213-274 and positions.rs:367-383.

How can I resolve this? If you propose a fix, please make it concise.

@zahorodnyi zahorodnyi marked this pull request as draft February 12, 2026 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

greptile Mark this PR to be reviewed by Greptile

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add draft profit calculator for a user

1 participant