85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
import { onchainTable, primaryKey, index } from "ponder";
|
|
|
|
export const HOURS_IN_RING_BUFFER = 168; // 7 days * 24 hours
|
|
const RING_BUFFER_SEGMENTS = 4; // ubi, minted, burned, tax
|
|
|
|
// Global protocol stats - singleton with id "0x01"
|
|
export const stats = onchainTable(
|
|
"stats",
|
|
(t) => ({
|
|
id: t.text().primaryKey(), // Always "0x01"
|
|
kraikenTotalSupply: t.bigint().notNull().$default(() => 0n),
|
|
stakeTotalSupply: t.bigint().notNull().$default(() => 0n),
|
|
outstandingStake: t.bigint().notNull().$default(() => 0n),
|
|
|
|
// Totals
|
|
totalMinted: t.bigint().notNull().$default(() => 0n),
|
|
totalBurned: t.bigint().notNull().$default(() => 0n),
|
|
totalTaxPaid: t.bigint().notNull().$default(() => 0n),
|
|
totalUbiClaimed: t.bigint().notNull().$default(() => 0n),
|
|
|
|
// Rolling windows - calculated from ring buffer
|
|
mintedLastWeek: t.bigint().notNull().$default(() => 0n),
|
|
mintedLastDay: t.bigint().notNull().$default(() => 0n),
|
|
mintNextHourProjected: t.bigint().notNull().$default(() => 0n),
|
|
|
|
burnedLastWeek: t.bigint().notNull().$default(() => 0n),
|
|
burnedLastDay: t.bigint().notNull().$default(() => 0n),
|
|
burnNextHourProjected: t.bigint().notNull().$default(() => 0n),
|
|
|
|
taxPaidLastWeek: t.bigint().notNull().$default(() => 0n),
|
|
taxPaidLastDay: t.bigint().notNull().$default(() => 0n),
|
|
taxPaidNextHourProjected: t.bigint().notNull().$default(() => 0n),
|
|
|
|
ubiClaimedLastWeek: t.bigint().notNull().$default(() => 0n),
|
|
ubiClaimedLastDay: t.bigint().notNull().$default(() => 0n),
|
|
ubiClaimedNextHourProjected: t.bigint().notNull().$default(() => 0n),
|
|
|
|
// Ring buffer state (flattened array of length HOURS_IN_RING_BUFFER * 4)
|
|
ringBufferPointer: t.integer().notNull().$default(() => 0),
|
|
lastHourlyUpdateTimestamp: t.bigint().notNull().$default(() => 0n),
|
|
ringBuffer: t
|
|
.jsonb()
|
|
.$type<string[]>()
|
|
.notNull()
|
|
.$default(() => Array(HOURS_IN_RING_BUFFER * RING_BUFFER_SEGMENTS).fill("0")),
|
|
})
|
|
);
|
|
|
|
// Individual staking positions
|
|
export const positions = onchainTable(
|
|
"positions",
|
|
(t) => ({
|
|
id: t.text().primaryKey(), // Position ID from contract
|
|
owner: t.hex().notNull(),
|
|
share: t.real().notNull(), // Share as decimal (0-1)
|
|
taxRate: t.real().notNull(), // Tax rate as decimal (e.g., 0.01 for 1%)
|
|
kraikenDeposit: t.bigint().notNull(),
|
|
stakeDeposit: t.bigint().notNull(),
|
|
taxPaid: t.bigint().notNull().$default(() => 0n),
|
|
snatched: t.integer().notNull().$default(() => 0),
|
|
creationTime: t.bigint().notNull(),
|
|
lastTaxTime: t.bigint().notNull(),
|
|
status: t.text().notNull().$default(() => "Active"), // "Active" or "Closed"
|
|
createdAt: t.bigint().notNull(),
|
|
closedAt: t.bigint(),
|
|
totalSupplyInit: t.bigint().notNull(),
|
|
totalSupplyEnd: t.bigint(),
|
|
payout: t.bigint().notNull().$default(() => 0n),
|
|
}),
|
|
(table) => ({
|
|
ownerIdx: index().on(table.owner),
|
|
statusIdx: index().on(table.status),
|
|
})
|
|
);
|
|
|
|
// Constants for tax rates (matches subgraph)
|
|
export const TAX_RATES = [
|
|
0.01, 0.03, 0.05, 0.07, 0.09, 0.11, 0.13, 0.15, 0.17, 0.19,
|
|
0.21, 0.25, 0.29, 0.33, 0.37, 0.41, 0.45, 0.49, 0.53, 0.57,
|
|
0.61, 0.65, 0.69, 0.73, 0.77, 0.81, 0.85, 0.89, 0.93, 0.97
|
|
];
|
|
|
|
// Helper constants
|
|
export const STATS_ID = "0x01";
|
|
export const SECONDS_IN_HOUR = 3600;
|