parent
76b2635e63
commit
66106077ba
4 changed files with 139 additions and 3 deletions
|
|
@ -259,12 +259,21 @@ export const recenters = onchainTable('recenters', t => ({
|
|||
vwapTick: t.integer(), // nullable
|
||||
}));
|
||||
|
||||
// Holders - track Kraiken token holders
|
||||
// Holders - track Kraiken token holders with cost basis for P&L
|
||||
export const holders = onchainTable(
|
||||
'holders',
|
||||
t => ({
|
||||
address: t.hex().primaryKey(),
|
||||
balance: t.bigint().notNull(),
|
||||
// Cost basis tracking (updated on swaps only, not wallet-to-wallet transfers)
|
||||
totalEthSpent: t
|
||||
.bigint()
|
||||
.notNull()
|
||||
.$default(() => 0n), // cumulative ETH spent buying KRK
|
||||
totalTokensAcquired: t
|
||||
.bigint()
|
||||
.notNull()
|
||||
.$default(() => 0n), // cumulative KRK received from buys
|
||||
}),
|
||||
table => ({
|
||||
addressIdx: index().on(table.address),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ import { validateContractVersion } from './helpers/version';
|
|||
|
||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' as const;
|
||||
|
||||
// Pool address for detecting swaps (buys/sells)
|
||||
// Computed deterministically from Uniswap V3 factory + WETH + Kraiken + 1% fee
|
||||
const POOL_ADDRESS = (process.env.POOL_ADDRESS || '0x1f69cbfc7d3529a4fb4eadf18ec5644b2603b5ab').toLowerCase() as `0x${string}`;
|
||||
|
||||
// Track if version has been validated
|
||||
let versionValidated = false;
|
||||
|
||||
|
|
@ -77,9 +81,25 @@ ponder.on('Kraiken:Transfer', async ({ event, context }) => {
|
|||
const oldBalance = toHolder?.balance ?? 0n;
|
||||
const newBalance = oldBalance + value;
|
||||
|
||||
// Detect buy: tokens coming FROM the pool = user bought KRK
|
||||
const isBuy = from.toLowerCase() === POOL_ADDRESS;
|
||||
let ethSpentDelta = 0n;
|
||||
|
||||
if (isBuy && value > 0n) {
|
||||
// Approximate ETH cost using current price from stats
|
||||
const currentPrice = statsData.currentPriceWei ?? 0n;
|
||||
if (currentPrice > 0n) {
|
||||
ethSpentDelta = (value * currentPrice) / 10n ** 18n;
|
||||
}
|
||||
}
|
||||
|
||||
if (toHolder) {
|
||||
await context.db.update(holders, { address: to }).set({
|
||||
balance: newBalance,
|
||||
...(isBuy && {
|
||||
totalEthSpent: (toHolder.totalEthSpent ?? 0n) + ethSpentDelta,
|
||||
totalTokensAcquired: (toHolder.totalTokensAcquired ?? 0n) + value,
|
||||
}),
|
||||
});
|
||||
// If this was a new holder (balance was 0), increment count
|
||||
if (oldBalance === 0n) {
|
||||
|
|
@ -90,6 +110,8 @@ ponder.on('Kraiken:Transfer', async ({ event, context }) => {
|
|||
await context.db.insert(holders).values({
|
||||
address: to,
|
||||
balance: newBalance,
|
||||
totalEthSpent: ethSpentDelta,
|
||||
totalTokensAcquired: isBuy ? value : 0n,
|
||||
});
|
||||
holderCountDelta += 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue