Merge pull request 'fix: Ponder: fix mintNextHourProjected divisor, dead param, dead code (#308)' (#333) from fix/issue-308 into master

This commit is contained in:
johba 2026-02-27 07:20:02 +01:00
commit 9341673a1a
6 changed files with 31 additions and 32 deletions

View file

@ -226,6 +226,7 @@
"integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.24.2",
@ -2742,6 +2743,7 @@
"integrity": "sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.13.0"
}
@ -2802,6 +2804,7 @@
"integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/types": "8.45.0",
@ -3413,6 +3416,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -3737,6 +3741,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001587",
"electron-to-chromium": "^1.4.668",
@ -4525,6 +4530,7 @@
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@ -5222,6 +5228,7 @@
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz",
"integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==",
"license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
@ -5304,8 +5311,9 @@
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz",
"integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==",
"dev": true,
"devOptional": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
},
@ -7212,6 +7220,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -8146,8 +8155,9 @@
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
"dev": true,
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -8354,6 +8364,7 @@
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@ -8452,6 +8463,7 @@
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4",
@ -8667,6 +8679,7 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.0.0"
},

View file

@ -1,10 +1,4 @@
export function bytesToUint256LittleEndian(bytes: Uint8Array): bigint {
// console.log(hexString);
// const cleanHexString = hexString.startsWith('0x') ? hexString.substring(2) : hexString;
// const bytes = new Uint8Array(Math.ceil(cleanHexString.length / 2));
// for (let i = 0, j = 0; i < cleanHexString.length; i += 2, j++) {
// bytes[j] = parseInt(cleanHexString.slice(i, i + 2), 16);
// }
let value: bigint = 0n;
for (let i = bytes.length - 1; i >= 0; i--) {
@ -20,12 +14,4 @@ export function uint256ToBytesLittleEndian(value: bigint): Uint8Array {
bytes[i] = Number((value >> (8n * BigInt(i))) & 0xffn);
}
return bytes;
// let hexString = '0x';
// for (let i = 0; i < bytes.length; i++) {
// // Convert each byte to a hexadecimal string and pad with zero if needed
// hexString += bytes[i].toString(16).padStart(2, '0');
// }
// return hexString;
}

View file

@ -45,17 +45,17 @@
"@graphql-codegen/typescript": "^4.0.6",
"@graphql-codegen/typescript-operations": "^4.2.0",
"@graphql-typed-document-node/core": "^3.2.0",
"@types/jest": "^29.5.12",
"@types/node": "^24.6.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.45.0",
"@vitest/coverage-v8": "^3.0.0",
"eslint": "^9.36.0",
"husky": "^9.1.7",
"jest": "^29.7.0",
"lint-staged": "^16.2.3",
"picomatch": "^4.0.3",
"prettier": "^3.6.2",
"ts-jest": "^29.1.2",
"typescript": "^5.4.3"
"typescript": "^5.4.3",
"vitest": "^3.0.0"
}
},
"node_modules/@adraffy/ens-normalize": {

View file

@ -92,11 +92,11 @@ function computeProjections(ringBuffer: bigint[], pointer: number, timestamp: bi
const project = (current: bigint, previous: bigint, weekly: bigint) => {
if (elapsedSeconds === 0n) {
return weekly / 7n;
return weekly / 168n;
}
const projectedTotal = (current * BigInt(SECONDS_IN_HOUR)) / elapsedSeconds;
const medium = (previous + projectedTotal) / 2n;
return medium > 0n ? medium : weekly / 7n;
return medium > 0n ? medium : weekly / 168n;
};
const mintProjection = project(ringBuffer[currentBase + 1], ringBuffer[previousBase + 1], metrics.mintedWeek);
@ -259,8 +259,8 @@ export async function updateHourlyData(context: StatsContext, timestamp: bigint)
ethReserveLastWeek: metrics.ethReserveLatest > 0n ? metrics.ethReserveLatest - metrics.ethReserve7dAgo : 0n,
netSupplyChangeDay: metrics.mintedDay - metrics.burnedDay,
netSupplyChangeWeek: metrics.mintedWeek - metrics.burnedWeek,
mintNextHourProjected: metrics.mintedWeek / 7n,
burnNextHourProjected: metrics.burnedWeek / 7n,
mintNextHourProjected: metrics.mintedWeek / 168n,
burnNextHourProjected: metrics.burnedWeek / 168n,
});
} else {
const metrics = computeMetrics(ringBuffer, pointer);
@ -325,7 +325,7 @@ export async function refreshOutstandingStake(context: StatsContext) {
* Record ETH reserve snapshot in ring buffer slot 0.
* Called from lm.ts on Recentered events (where we know the pool's ETH balance).
*/
export async function recordEthReserveSnapshot(context: StatsContext, timestamp: bigint, ethBalance: bigint) {
export async function recordEthReserveSnapshot(context: StatsContext, ethBalance: bigint) {
const statsData = await context.db.find(stats, { id: STATS_ID });
if (!statsData) return;

View file

@ -189,7 +189,7 @@ async function updateReserveStats(
vwapTick: number | bigint
) {
// Record ETH reserve in ring buffer for hourly time-series
await recordEthReserveSnapshot(context, event.block.timestamp, ethBalance);
await recordEthReserveSnapshot(context, ethBalance);
// Compute 7d growth from ring buffer (slot 0 = ethReserve snapshots)
const statsData = await context.db.find(stats, { id: STATS_ID });

View file

@ -291,14 +291,14 @@ describe('updateHourlyData', () => {
// Filled slots: i=2..49 from pointer=7 (48 slots × 10n minted / 5n burned).
// mintedLastDay: i<24 → i=2..23 = 22 slots × 10n = 220n
// mintedLastWeek: 48 × 10n = 480n
// mintNextHourProjected = mintedWeek / 7n = 480n / 7n = 68n (BigInt truncation)
// burnNextHourProjected = burnedWeek / 7n = 240n / 7n = 34n
// mintNextHourProjected = mintedWeek / 168n = 480n / 168n = 2n (BigInt truncation)
// burnNextHourProjected = burnedWeek / 168n = 240n / 168n = 1n
expect(setArg.mintedLastWeek).toBe(480n);
expect(setArg.mintedLastDay).toBe(220n);
expect(setArg.burnedLastWeek).toBe(240n);
expect(setArg.burnedLastDay).toBe(110n);
expect(setArg.mintNextHourProjected).toBe(68n);
expect(setArg.burnNextHourProjected).toBe(34n);
expect(setArg.mintNextHourProjected).toBe(2n);
expect(setArg.burnNextHourProjected).toBe(1n);
expect(setArg.netSupplyChangeDay).toBe(110n);
expect(setArg.netSupplyChangeWeek).toBe(240n);
});
@ -399,7 +399,7 @@ describe('updateHourlyData', () => {
describe('recordEthReserveSnapshot', () => {
it('returns early when no stats row exists', async () => {
const ctx = createMockContext(null);
await recordEthReserveSnapshot(ctx, 1000n, 500n);
await recordEthReserveSnapshot(ctx, 500n);
expect((ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } }).db.update).not.toHaveBeenCalled();
});
@ -409,7 +409,7 @@ describe('recordEthReserveSnapshot', () => {
const ctx = createMockContext(row);
const ethBalance = 12345678n;
await recordEthReserveSnapshot(ctx, 1000n, ethBalance);
await recordEthReserveSnapshot(ctx, ethBalance);
const dbMock = ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } };
const setArg = (dbMock.db.update as ReturnType<typeof vi.fn>).mock.results[0].value.set.mock.calls[0][0];