Skip to content

Conversation

@hildobby
Copy link
Collaborator

@hildobby hildobby commented Dec 9, 2025

added columns to existing tables (needed for much more efficient queries) and created 3 tables:

  • one for protocol tvl
  • one for user balance changes
  • one for currently open positions (view)

@github-actions github-actions bot marked this pull request as draft December 9, 2025 18:48
@github-actions github-actions bot added WIP work in progress dbt: daily covers the Daily dbt subproject labels Dec 9, 2025
@hildobby hildobby marked this pull request as ready for review December 9, 2025 18:50
@github-actions github-actions bot added ready-for-review this PR development is complete, please review and removed WIP work in progress labels Dec 9, 2025
@cursor
Copy link

cursor bot commented Dec 11, 2025

PR Summary

Introduces new analytics surfaces and enriches existing Polymarket models for better querying and pricing.

  • Adds new incremental models: polymarket_polygon_protocol_tvl (hourly TVL/net flow from USDC.e transfers) and polymarket_polygon_users_balance_changes (inflow/outflow/internal per wallet); adds polymarket_polygon_open_positions view (latest positions with latest_price/open_interest)
  • Enhances polymarket_polygon_market_details with polymarket_link_slug, parsed start/end timestamps, and computed final_price
  • Extends trades: polymarket_polygon_market_trades_raw and ..._market_trades now include maker_asset_id/taker_asset_id and expose polymarket_link_slug
  • Upgrades polymarket_polygon_positions to incremental, adds daily pricing join and price/usd_value, and filters late/partial days
  • Refactors polymarket_polygon_market_prices_daily forward-fill to use utils_days and date bounds
  • Updates _schema.yml to document new columns/models and add tests

Written by Cursor Bugbot for commit d775b77. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Comment @cursor review or bugbot run to trigger another review on this PR

@hildobby
Copy link
Collaborator Author

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Comment @cursor review or bugbot run to trigger another review on this PR

@hildobby
Copy link
Collaborator Author

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no bugs!


Comment @cursor review or bugbot run to trigger another review on this PR

@hildobby
Copy link
Collaborator Author

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Comment @cursor review or bugbot run to trigger another review on this PR

@hildobby
Copy link
Collaborator Author

https://github.com/cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Comment @cursor review or bugbot run to trigger another review on this PR

SELECT *,
CASE WHEN outcome = '50/50' THEN 0.5
WHEN LOWER(token_outcome) = outcome THEN 1
ELSE 0 END AS price_modifier
Copy link

Choose a reason for hiding this comment

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

Bug: Unresolved markets incorrectly get zero price modifier

The price_modifier calculation returns 0 for markets with outcome = 'unresolved' because neither the '50/50' check nor LOWER(token_outcome) = outcome matches when outcome is 'unresolved'. This differs from the existing behavior in polymarket_polygon_market_prices_daily.sql which preserves the original market price (ELSE ff.price) for unresolved markets. When used in polymarket_polygon_positions.sql, markets past their end time but not yet resolved will incorrectly show positions as worthless (price = 0) instead of using the last traded price.

Additional Locations (1)

Fix in Cursor Fix in Web

@hildobby
Copy link
Collaborator Author

hildobby commented Jan 9, 2026

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Comment @cursor review or bugbot run to trigger another review on this PR

, unique_key
FROM relevant_transfers
WHERE from_polymarket_wallet IS NOT NULL AND to_polymarket_wallet IS NOT NULL
AND (from_first_funded_block IS NULL OR from_first_funded_block <= block_number)
Copy link

Choose a reason for hiding this comment

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

Internal transfers create duplicate records for sender wallet

Medium Severity

When a transfer occurs between two polymarket wallets (A→B), the sender wallet A gets recorded twice: once with direction='outflow' (lines 96-98) and again with direction='internal' (lines 117-119). Both records use from_polymarket_wallet AS polymarket_wallet and capture the same amount. The outflow WHERE clause (from_polymarket_wallet IS NOT NULL) doesn't exclude internal transfers, so there's an overlap with the internal clause (from_polymarket_wallet IS NOT NULL AND to_polymarket_wallet IS NOT NULL). This could lead to double-counting in downstream aggregations that sum balance changes by wallet.

Fix in Cursor Fix in Web

LEFT JOIN {{ ref('polymarket_polygon_users') }} to_user ON t."to" = to_user.polymarket_wallet
LEFT JOIN {{ ref('polymarket_polygon_users') }} from_user ON t."from" = from_user.polymarket_wallet
INNER JOIN {{ source('addresses_events_polygon', 'first_funded_by')}} to_ffb ON t."to" = to_ffb.address
INNER JOIN {{ source('addresses_events_polygon', 'first_funded_by')}} from_ffb ON t."from" = from_ffb.address
Copy link

Choose a reason for hiding this comment

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

INNER JOINs make NULL checks unreachable dead code

Medium Severity

The INNER JOIN on first_funded_by (lines 34-35) filters out any transfers where either the sender or receiver address doesn't exist in that table. However, the subsequent WHERE clauses include to_first_funded_block IS NULL OR ... and from_first_funded_block IS NULL OR ... checks (lines 77, 98, 119), which can never evaluate to true because the INNER JOIN guarantees these values are non-NULL. This suggests LEFT JOINs were intended, and the current INNER JOINs may silently exclude legitimate transfers involving addresses not yet in first_funded_by.

Additional Locations (1)

Fix in Cursor Fix in Web

FROM {{ ref('polymarket_polygon_positions_raw') }} p
INNER JOIN latest_day ld ON p.day = ld.day
INNER JOIN {{ ref('polymarket_polygon_market_details') }} mm ON p.token_id = mm.token_id
)
Copy link

Choose a reason for hiding this comment

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

Open positions view includes zero-balance closed positions

Medium Severity

The open_positions CTE joins with positions_raw without filtering out positions where balance = 0. Since positions_raw includes all balances (including zero balances from fully exited positions), the view will return closed positions as "open." The schema describes this as "Polymarket: open positions in markets," but users who have completely sold their positions will still appear in the results. A filter like WHERE p.balance > 0 is needed in the open_positions CTE to match the semantic meaning of the table.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dbt: daily covers the Daily dbt subproject ready-for-review this PR development is complete, please review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant