@clonegod/ttd-bsc-common 3.0.54 → 3.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,6 @@ export * from './event';
2
2
  export * from './pricing';
3
3
  export * from './tick';
4
4
  export * from './depth';
5
- export * from './accuracy';
5
+ export * from './verify';
6
6
  export * from './price_feed_handler';
7
7
  export * from './quote_amount';
@@ -18,6 +18,6 @@ __exportStar(require("./event"), exports);
18
18
  __exportStar(require("./pricing"), exports);
19
19
  __exportStar(require("./tick"), exports);
20
20
  __exportStar(require("./depth"), exports);
21
- __exportStar(require("./accuracy"), exports);
21
+ __exportStar(require("./verify"), exports);
22
22
  __exportStar(require("./price_feed_handler"), exports);
23
23
  __exportStar(require("./quote_amount"), exports);
@@ -0,0 +1,2 @@
1
+ export { QuotePriceVerify } from './quote_price_verify';
2
+ export type { CheckSwapParams, CheckSyncParams } from './quote_price_verify';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuotePriceVerify = void 0;
4
+ var quote_price_verify_1 = require("./quote_price_verify");
5
+ Object.defineProperty(exports, "QuotePriceVerify", { enumerable: true, get: function () { return quote_price_verify_1.QuotePriceVerify; } });
@@ -0,0 +1,42 @@
1
+ export interface CheckSwapParams {
2
+ poolAddress: string;
3
+ poolName: string;
4
+ blockNumber: number;
5
+ txHash: string;
6
+ amount0: string;
7
+ amount1: string;
8
+ token0Address: string;
9
+ token1Address: string;
10
+ token0Decimals: number;
11
+ token1Decimals: number;
12
+ poolInfo: {
13
+ tokenA: any;
14
+ tokenB: any;
15
+ quote_token: string;
16
+ };
17
+ }
18
+ export interface CheckSyncParams {
19
+ poolAddress: string;
20
+ poolName: string;
21
+ blockNumber: number;
22
+ reserve0: string;
23
+ reserve1: string;
24
+ token0Address: string;
25
+ token1Address: string;
26
+ token0Decimals: number;
27
+ token1Decimals: number;
28
+ poolInfo: {
29
+ tokenA: any;
30
+ tokenB: any;
31
+ quote_token: string;
32
+ };
33
+ }
34
+ export declare class QuotePriceVerify {
35
+ private quoteCache;
36
+ private reserveCache;
37
+ private get enabled();
38
+ cacheQuote(poolAddress: string, priceId: string, source: string, askPrice: number, bidPrice: number, blockNumber: number, quoteAmountUsd: number, token0PriceUsd?: number, token1PriceUsd?: number): void;
39
+ checkSwap(params: CheckSwapParams): void;
40
+ checkSync(params: CheckSyncParams): void;
41
+ private compareAndLog;
42
+ }
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuotePriceVerify = void 0;
4
+ const trade_direction_1 = require("../../utils/trade_direction");
5
+ class QuotePriceVerify {
6
+ constructor() {
7
+ this.quoteCache = new Map();
8
+ this.reserveCache = new Map();
9
+ }
10
+ get enabled() {
11
+ return process.env.VERIFY_QUOTE_PRICE === 'true';
12
+ }
13
+ cacheQuote(poolAddress, priceId, source, askPrice, bidPrice, blockNumber, quoteAmountUsd, token0PriceUsd = 0, token1PriceUsd = 0) {
14
+ if (!this.enabled)
15
+ return;
16
+ this.quoteCache.set(poolAddress, {
17
+ priceId, source, askPrice, bidPrice, blockNumber, quoteAmountUsd,
18
+ verifiedBlock: 0,
19
+ token0PriceUsd, token1PriceUsd,
20
+ });
21
+ }
22
+ checkSwap(params) {
23
+ if (!this.enabled)
24
+ return;
25
+ const { poolAddress, poolName, blockNumber, txHash, amount0, amount1, poolInfo } = params;
26
+ const { token0Address, token1Address, token0Decimals, token1Decimals } = params;
27
+ const cached = this.quoteCache.get(poolAddress);
28
+ if (!cached)
29
+ return;
30
+ if (blockNumber <= cached.blockNumber)
31
+ return;
32
+ if (blockNumber <= cached.verifiedBlock)
33
+ return;
34
+ cached.verifiedBlock = blockNumber;
35
+ const amt0 = BigInt(amount0);
36
+ const amt1 = BigInt(amount1);
37
+ if (amt0 === 0n && amt1 === 0n)
38
+ return;
39
+ let inputTokenAddress;
40
+ let outputTokenAddress;
41
+ let inputAmountUi;
42
+ let outputAmountUi;
43
+ if (amt0 > 0n && amt1 < 0n) {
44
+ inputTokenAddress = token0Address;
45
+ outputTokenAddress = token1Address;
46
+ inputAmountUi = Number(amt0) / Math.pow(10, token0Decimals);
47
+ outputAmountUi = Number(-amt1) / Math.pow(10, token1Decimals);
48
+ }
49
+ else if (amt0 < 0n && amt1 > 0n) {
50
+ inputTokenAddress = token1Address;
51
+ outputTokenAddress = token0Address;
52
+ inputAmountUi = Number(amt1) / Math.pow(10, token1Decimals);
53
+ outputAmountUi = Number(-amt0) / Math.pow(10, token0Decimals);
54
+ }
55
+ else {
56
+ return;
57
+ }
58
+ this.compareAndLog(poolAddress, poolName, poolInfo, cached, inputTokenAddress, outputTokenAddress, inputAmountUi, outputAmountUi, cached.token0PriceUsd, cached.token1PriceUsd, token0Address, blockNumber, txHash);
59
+ }
60
+ checkSync(params) {
61
+ if (!this.enabled)
62
+ return;
63
+ const { poolAddress, poolName, blockNumber, reserve0, reserve1, poolInfo } = params;
64
+ const { token0Address, token1Address, token0Decimals, token1Decimals } = params;
65
+ const cached = this.quoteCache.get(poolAddress);
66
+ if (!cached)
67
+ return;
68
+ if (blockNumber <= cached.blockNumber)
69
+ return;
70
+ if (blockNumber <= cached.verifiedBlock)
71
+ return;
72
+ const newR0 = BigInt(reserve0);
73
+ const newR1 = BigInt(reserve1);
74
+ const oldReserves = this.reserveCache.get(poolAddress);
75
+ this.reserveCache.set(poolAddress, { reserve0: newR0, reserve1: newR1 });
76
+ if (!oldReserves)
77
+ return;
78
+ const delta0 = newR0 - oldReserves.reserve0;
79
+ const delta1 = newR1 - oldReserves.reserve1;
80
+ if ((delta0 > 0n && delta1 > 0n) || (delta0 < 0n && delta1 < 0n) || (delta0 === 0n && delta1 === 0n)) {
81
+ return;
82
+ }
83
+ cached.verifiedBlock = blockNumber;
84
+ let inputTokenAddress;
85
+ let outputTokenAddress;
86
+ let inputAmountUi;
87
+ let outputAmountUi;
88
+ if (delta0 > 0n && delta1 < 0n) {
89
+ inputTokenAddress = token0Address;
90
+ outputTokenAddress = token1Address;
91
+ inputAmountUi = Number(delta0) / Math.pow(10, token0Decimals);
92
+ outputAmountUi = Number(-delta1) / Math.pow(10, token1Decimals);
93
+ }
94
+ else {
95
+ inputTokenAddress = token1Address;
96
+ outputTokenAddress = token0Address;
97
+ inputAmountUi = Number(delta1) / Math.pow(10, token1Decimals);
98
+ outputAmountUi = Number(-delta0) / Math.pow(10, token0Decimals);
99
+ }
100
+ this.compareAndLog(poolAddress, poolName, poolInfo, cached, inputTokenAddress, outputTokenAddress, inputAmountUi, outputAmountUi, cached.token0PriceUsd, cached.token1PriceUsd, token0Address, blockNumber);
101
+ }
102
+ compareAndLog(poolAddress, poolName, poolInfo, cached, inputTokenAddress, outputTokenAddress, inputAmountUi, outputAmountUi, token0PriceUsd, token1PriceUsd, token0Address, swapBlockNumber, txHash) {
103
+ if (inputAmountUi <= 0 || outputAmountUi <= 0)
104
+ return;
105
+ let swapUsd = 0;
106
+ if (token0PriceUsd && token1PriceUsd && token0Address) {
107
+ const inputIsToken0 = inputTokenAddress.toLowerCase() === token0Address.toLowerCase();
108
+ swapUsd = inputIsToken0
109
+ ? inputAmountUi * token0PriceUsd
110
+ : inputAmountUi * token1PriceUsd;
111
+ }
112
+ const direction = (0, trade_direction_1.resolveTradeDirection)(poolInfo, true);
113
+ const baseToken = direction.baseToken;
114
+ const quoteToken = direction.quoteToken;
115
+ const inputIsQuoteToken = inputTokenAddress.toLowerCase() === quoteToken.address.toLowerCase();
116
+ const isBuy = inputIsQuoteToken;
117
+ const execPrice = (0, trade_direction_1.calculateStandardPrice)(inputAmountUi, outputAmountUi, isBuy);
118
+ const execPriceNum = Number(execPrice);
119
+ const refPrice = isBuy ? cached.askPrice : cached.bidPrice;
120
+ const side = isBuy ? 'BUY' : 'SELL';
121
+ if (refPrice <= 0 || execPriceNum <= 0)
122
+ return;
123
+ const diffBps = (execPriceNum - refPrice) / refPrice * 10000;
124
+ const absDiffBps = Math.abs(diffBps);
125
+ const status = absDiffBps < 10 ? '✅' : absDiffBps < 30 ? '⚠️' : '❌';
126
+ const usdStr = swapUsd > 0 ? `$${swapUsd.toFixed(0)}` : '$?';
127
+ const minUsd = cached.quoteAmountUsd * 0.5;
128
+ const maxUsd = cached.quoteAmountUsd * 2;
129
+ const inRange = swapUsd <= 0 || (swapUsd >= minUsd && swapUsd <= maxUsd);
130
+ const rangeTag = inRange ? '' : ' [out]';
131
+ const tradeFlow = isBuy
132
+ ? `${inputAmountUi.toFixed(4)} ${quoteToken.symbol} -> ${outputAmountUi.toFixed(4)} ${baseToken.symbol}`
133
+ : `${inputAmountUi.toFixed(4)} ${baseToken.symbol} -> ${outputAmountUi.toFixed(4)} ${quoteToken.symbol}`;
134
+ const quoteSrc = cached.source || '?';
135
+ const quoteTag = `quote[${quoteSrc} blk:${cached.blockNumber}]`;
136
+ const swapBlk = swapBlockNumber || '?';
137
+ const swapTx = txHash ? ` ${txHash.slice(0, 10)}` : '';
138
+ const swapTag = `swap[blk:${swapBlk}${swapTx}]`;
139
+ const priceLabel = isBuy ? 'ask' : 'bid';
140
+ const msg = ` ↳ [Verify] ${side} ${usdStr} (${tradeFlow}) ${quoteTag} ${priceLabel}=${refPrice.toFixed(12)} vs ${swapTag} exec=${execPriceNum.toFixed(12)} diff=${diffBps > 0 ? '+' : ''}${diffBps.toFixed(1)}bps ${status}${rangeTag}`;
141
+ console.log(msg);
142
+ }
143
+ }
144
+ exports.QuotePriceVerify = QuotePriceVerify;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clonegod/ttd-bsc-common",
3
- "version": "3.0.54",
3
+ "version": "3.0.55",
4
4
  "description": "BSC common library",
5
5
  "license": "UNLICENSED",
6
6
  "main": "dist/index.js",