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
4 changes: 2 additions & 2 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { configVariable, defineConfig } from "hardhat/config";
import hardhatToolboxViem from "@nomicfoundation/hardhat-toolbox-viem";
import codegenPlugin from "./plugins/codegen/index.ts";
import hardhatViemAbi from "hardhat-viem-abi";
import { tryLoadEnvFile } from "./lib/env.ts";

tryLoadEnvFile("./../.env");
tryLoadEnvFile(".env");

export default defineConfig({
plugins: [hardhatToolboxViem, codegenPlugin],
plugins: [hardhatToolboxViem, hardhatViemAbi],
codegen: {
contracts: [
"CollateralVault",
Expand Down
8 changes: 7 additions & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@types/node": "^22.0.0",
"@typescript/native-preview": "7.0.0-dev.20260707.2",
"hardhat": "^3.9.1",
"hardhat-viem-abi": "https://github.com/lsheva/hardhat-viem-abi.git#v1.0.0-alpha.1&path:packages/hardhat-viem-abi",
"typescript": "^5.8.0"
},
"dependencies": {
Expand All @@ -35,5 +36,10 @@
"dotenv": "^16.4.1",
"viem": "^2.52.2"
},
"packageManager": "pnpm@10.28.1"
"packageManager": "pnpm@10.28.1",
"pnpm": {
"onlyBuiltDependencies": [
"hardhat-viem-abi"
]
}
}
13 changes: 0 additions & 13 deletions contracts/plugins/codegen/compile-action.ts

This file was deleted.

161 changes: 0 additions & 161 deletions contracts/plugins/codegen/export-abi.ts

This file was deleted.

31 changes: 0 additions & 31 deletions contracts/plugins/codegen/index.ts

This file was deleted.

18 changes: 0 additions & 18 deletions contracts/plugins/codegen/type-extensions.ts

This file was deleted.

16 changes: 16 additions & 0 deletions contracts/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion keeper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ Suites cover:
- `discovery/tracker` — checksum dedupe, `onAdded` / `onChanged` listeners, startup backfill
- `discovery/webhook` — payload extraction across `data` / `records` / array shapes
- `runtime/scheduler` — alert ladder thresholds, queue upsert + executor kick wiring
- `oracle/priceFeed` — rebase to token decimals + contract-size unit (`CONTRACT_SIZE_HPS_DAY / ORACLE_UNIT_HPS_DAY`, ×10 at defaults), dispatch, no-op on unchanged answer
- `oracle/priceFeed` — rebase to token decimals (oracle already quotes 1 PH/s·day), dispatch, no-op on unchanged answer
- `predict/mm` — net delta, stress, perp/futures unrealized loss, mm/im surplus
- `predict/solve` — long/short downside & upside thresholds, drag from orderMargin/funding
- `predict/predictiveIndex` — upsert/invalidate, sorted crossings on rise & drop
Expand Down
43 changes: 4 additions & 39 deletions keeper/src/oracle/priceFeed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { HashPowerPerpsDEXAbi } from "derivatives-marketplace-abi/HashPowerPerpsDEX.ts";
import type pino from "pino";
import type { Chain } from "../chain.ts";
import type { Config } from "../config.ts";
Expand Down Expand Up @@ -39,13 +38,8 @@ export type PriceListener = (update: PriceUpdate) => void;
* The feed also handles the upstream-decimals → token-decimals rebase: the
* aggregator answer is `oracle.decimals()` (typically 8 for HashpriceUSD);
* we rescale to the perps/futures token decimals (USDC = 6) so consumers
* compare apples to apples with `getMarketPrice()`.
*
* The oracle quotes the price of `ORACLE_UNIT_HPS_DAY` (100 TH/s over a day), but the
* venues denominate one contract in `contractSizeHpsDay` (default 1e15 = 1 PH/s over a
* day). We read that contract-size multiplier from the perps venue once at `start()` and
* apply `contractSizeHpsDay / ORACLE_UNIT_HPS_DAY` so the streamed price matches on-chain
* `getMarketPrice()`. Both venues are assumed to share the same contract size.
* compare apples to apples with `getMarketPrice()`. The oracle already quotes
* 1 PH/s per day (= venue `CONTRACT_SIZE_HPS_DAY`), so no unit rebase is applied.
*
* Lifecycle:
* - `start()`: read decimals, prime `current` via one `latestRoundData`,
Expand All @@ -60,10 +54,6 @@ export class PriceFeed {
private unwatch: (() => void) | undefined;
/** 10^(oracleDecimals - tokenDecimals). Set during `start()`. */
private rescaleDivisor: bigint = 1n;
/** Contract size in hashes/s·day (`contractSizeHpsDay`). Set during `start()`. */
private contractSizeHpsDay: bigint = 1n;
/** Oracle quote basis in hashes/s·day (`ORACLE_UNIT_HPS_DAY`). Set during `start()`. */
private oracleUnitHpsDay: bigint = 1n;

private readonly chain: Chain;
private readonly config: Config;
Expand Down Expand Up @@ -102,28 +92,6 @@ export class PriceFeed {
}
this.rescaleDivisor = 10n ** BigInt(oracleDecimals - this.tokenDecimals);

// Rebase from the oracle's quote basis (100 TH/s/day) to one contract unit
// (contractSizeHpsDay/day), matching `getMarketPrice()` on-chain.
const [contractSizeHpsDay, oracleUnitHpsDay] = await Promise.all([
this.chain.publicClient.readContract({
address: this.config.perps.address,
abi: HashPowerPerpsDEXAbi,
functionName: "CONTRACT_SIZE_HPS_DAY",
}) as Promise<bigint>,
this.chain.publicClient.readContract({
address: this.config.perps.address,
abi: HashPowerPerpsDEXAbi,
functionName: "ORACLE_UNIT_HPS_DAY",
}) as Promise<bigint>,
]);
if (contractSizeHpsDay <= 0n || oracleUnitHpsDay <= 0n) {
throw new Error(
`PriceFeed: invalid contract size (contractSizeHpsDay=${contractSizeHpsDay}, ORACLE_UNIT_HPS_DAY=${oracleUnitHpsDay})`,
);
}
this.contractSizeHpsDay = contractSizeHpsDay;
this.oracleUnitHpsDay = oracleUnitHpsDay;

await this.refresh("start");

// We watch BTC/USDC (not HashpriceUSD) because HashpriceUSD is a pure
Expand All @@ -147,8 +115,6 @@ export class PriceFeed {
btcUsdcFeed: this.config.oracle.btcUsdcFeedAddress,
oracleDecimals,
tokenDecimals: this.tokenDecimals,
contractSizeHpsDay: this.contractSizeHpsDay,
oracleUnitHpsDay: this.oracleUnitHpsDay,
currentPrice: this.currentPrice,
},
"PriceFeed started",
Expand Down Expand Up @@ -199,9 +165,8 @@ export class PriceFeed {
return;
}

// Mirror on-chain `getMarketPrice()`: rebase decimals first, then apply the
// contract-size multiplier (contractSizeHpsDay / ORACLE_UNIT_HPS_DAY).
const next = ((answer / this.rescaleDivisor) * this.contractSizeHpsDay) / this.oracleUnitHpsDay;
// Mirror on-chain `getMarketPrice()`: rebase decimals only (oracle quotes 1 PH/s/day).
const next = answer / this.rescaleDivisor;
const prev = this.currentPrice;
if (prev === next) return;

Expand Down
Loading
Loading