Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion jobs/coin_stats_onchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,11 @@ func (j *CoinStatsOnchainJob) queryAggregates(ctx context.Context, audioPrice fl
FROM artist_coin_prices
),
holders AS (
SELECT mint, COUNT(DISTINCT owner) AS holder
-- Count token accounts (not distinct owners) to match Birdeye's holder
-- metric. Distinct-owner would undercount: the claimable-tokens program
-- authority owns one account per user (the user-bank mechanism), so many
-- real holders share a single program owner.
SELECT mint, COUNT(*) AS holder
FROM sol_token_account_balances
WHERE balance > 0
GROUP BY mint
Expand Down
7 changes: 5 additions & 2 deletions jobs/coin_stats_onchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ func TestCoinStatsOnchainJob(t *testing.T) {
"artist_coin_pools": {
{"address": "pool1", "base_mint": coinMint, "price_usd": 4.0},
},
// Holders: 3 distinct owners with balance > 0, one with 0 (excluded).
// Holders = token accounts with balance > 0 (matches Birdeye; NOT distinct
// owners). acct1 and acct5 share owner1 (e.g. the claimable-tokens program
// authority holding for two users), so this counts 4, not 3 distinct owners.
"sol_token_account_balances": {
{"account": "acct1", "mint": coinMint, "owner": "owner1", "balance": 10, "slot": 1},
{"account": "acct2", "mint": coinMint, "owner": "owner2", "balance": 5, "slot": 1},
{"account": "acct3", "mint": coinMint, "owner": "owner3", "balance": 1, "slot": 1},
{"account": "acct5", "mint": coinMint, "owner": "owner1", "balance": 3, "slot": 1},
{"account": "acct4", "mint": coinMint, "owner": "owner4", "balance": 0, "slot": 1},
},
// Volume through the DBC quote vault (AUDIO leg): |1e8| + |-2e8| = 3e8 -> 3 AUDIO.
Expand Down Expand Up @@ -130,7 +133,7 @@ func TestCoinStatsOnchainJob(t *testing.T) {
require.NoError(t, err)

assert.InDelta(t, 4.0, price, 1e-9, "price from pools_price_usd")
assert.Equal(t, 3, holder, "distinct owners with balance > 0")
assert.Equal(t, 4, holder, "token accounts with balance > 0 (owner1 has two)")
assert.InDelta(t, 5000.0, liquidity, 1e-6, "TVL = base_usd + quote_usd")
assert.InDelta(t, 1000.0, totalSupply, 1e-9, "supply from RPC")
assert.InDelta(t, 4000.0, marketCap, 1e-6, "price * supply")
Expand Down
Loading