Skip to content

Commit 4d7b0d4

Browse files
committed
fix: use correct account lookup and atomic units in deposit verification
SOL detector now finds treasury by address in staticAccountKeys instead of assuming last balance index. USDC detector uses atomic amount string with BigInt comparison instead of float uiAmount.
1 parent f225090 commit 4d7b0d4

4 files changed

Lines changed: 40 additions & 27 deletions

File tree

src/services/buy-deposit.test.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ describe('BuyDepositDetector', () => {
1111
getTransaction: vi.fn(() => ({
1212
send: vi.fn(async () => ({
1313
meta: {
14-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
15-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
14+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
15+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
1616
},
1717
})),
1818
})),
@@ -40,8 +40,8 @@ describe('BuyDepositDetector', () => {
4040
getTransaction: vi.fn(() => ({
4141
send: vi.fn(async () => ({
4242
meta: {
43-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
44-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
43+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
44+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
4545
},
4646
})),
4747
})),
@@ -88,8 +88,8 @@ describe('BuyDepositDetector', () => {
8888
getTransaction: vi.fn(() => ({
8989
send: vi.fn(async () => ({
9090
meta: {
91-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
92-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
91+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
92+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
9393
},
9494
})),
9595
})),
@@ -119,8 +119,8 @@ describe('BuyDepositDetector', () => {
119119
getTransaction: vi.fn(() => ({
120120
send: vi.fn(async () => ({
121121
meta: {
122-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
123-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
122+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
123+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
124124
},
125125
})),
126126
})),
@@ -153,8 +153,8 @@ describe('BuyDepositDetector', () => {
153153
getTransaction: vi.fn(() => ({
154154
send: vi.fn(async () => ({
155155
meta: {
156-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
157-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
156+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
157+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
158158
},
159159
})),
160160
})),
@@ -190,8 +190,8 @@ describe('BuyDepositDetector', () => {
190190
getTransaction: vi.fn(() => ({
191191
send: vi.fn(async () => ({
192192
meta: {
193-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
194-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
193+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
194+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
195195
},
196196
})),
197197
})),
@@ -222,8 +222,8 @@ describe('BuyDepositDetector', () => {
222222
getTransaction: vi.fn(() => ({
223223
send: vi.fn(async () => ({
224224
meta: {
225-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
226-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
225+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
226+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
227227
},
228228
})),
229229
})),
@@ -250,8 +250,8 @@ describe('BuyDepositDetector', () => {
250250
getTransaction: vi.fn(() => ({
251251
send: vi.fn(async () => ({
252252
meta: {
253-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 0 } }],
254-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 100 } }],
253+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '0' } }],
254+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '100000000' } }],
255255
},
256256
})),
257257
})),
@@ -280,8 +280,8 @@ describe('BuyDepositDetector', () => {
280280
getTransaction: vi.fn(() => ({
281281
send: vi.fn(async () => ({
282282
meta: {
283-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 10 } }],
284-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 11.05 } }],
283+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '10000000' } }],
284+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '11050000' } }],
285285
},
286286
})),
287287
})),
@@ -310,8 +310,8 @@ describe('BuyDepositDetector', () => {
310310
getTransaction: vi.fn(() => ({
311311
send: vi.fn(async () => ({
312312
meta: {
313-
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 10 } }],
314-
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { uiAmount: 10.01 } }],
313+
preTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '10000000' } }],
314+
postTokenBalances: [{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', uiTokenAmount: { amount: '10010000' } }],
315315
},
316316
})),
317317
})),

src/services/buy-deposit.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ interface SolanaRpc {
1111
getTransaction(signature: any, opts: any): {
1212
send(): Promise<{
1313
meta: {
14-
preTokenBalances: Array<{ mint: string; uiTokenAmount: { uiAmount: number } }>;
15-
postTokenBalances: Array<{ mint: string; uiTokenAmount: { uiAmount: number } }>;
14+
preTokenBalances: Array<{ mint: string; uiTokenAmount: { amount: string } }>;
15+
postTokenBalances: Array<{ mint: string; uiTokenAmount: { amount: string } }>;
1616
} | null;
1717
} | null>;
1818
};
@@ -56,10 +56,12 @@ export class BuyDepositDetector {
5656
}).send();
5757
if (!txDetail?.meta) return false;
5858
const { preTokenBalances, postTokenBalances } = txDetail.meta;
59-
const preBal = preTokenBalances.find(b => b.mint === USDC_MINT)?.uiTokenAmount.uiAmount ?? 0;
60-
const postBal = postTokenBalances.find(b => b.mint === USDC_MINT)?.uiTokenAmount.uiAmount ?? 0;
59+
const preBal = BigInt(preTokenBalances.find(b => b.mint === USDC_MINT)?.uiTokenAmount.amount ?? '0');
60+
const postBal = BigInt(postTokenBalances.find(b => b.mint === USDC_MINT)?.uiTokenAmount.amount ?? '0');
6161
const received = postBal - preBal;
62-
return received >= expectedUsdc;
62+
// Compare in atomic units (USDC has 6 decimals)
63+
const expectedAtomic = BigInt(Math.round(expectedUsdc * 1_000_000));
64+
return received >= expectedAtomic;
6365
} catch {
6466
return false;
6567
}

src/services/deposit.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ describe('DepositDetector', () => {
1111
getTransaction: vi.fn(() => ({
1212
send: vi.fn(async () => ({
1313
meta: { preBalances: [10_000_000_000, 0], postBalances: [5_000_000_000, 5_000_000_000] },
14+
transaction: { message: { staticAccountKeys: ['sender', 'treasury'] } },
1415
})),
1516
})),
1617
};
@@ -126,6 +127,7 @@ describe('DepositDetector', () => {
126127
getTransaction: vi.fn(() => ({
127128
send: vi.fn(async () => ({
128129
meta: { preBalances: [10_000_000_000, 0], postBalances: [5_000_000_000, 5_000_000_000] },
130+
transaction: { message: { staticAccountKeys: ['sender', 'TreasuryAddr'] } },
129131
})),
130132
})),
131133
};
@@ -164,6 +166,7 @@ describe('DepositDetector', () => {
164166
getTransaction: vi.fn(() => ({
165167
send: vi.fn(async () => ({
166168
meta: { preBalances: [10_000_000_000, 0], postBalances: [5_000_000_000, 5_000_000_000] },
169+
transaction: { message: { staticAccountKeys: ['sender', 'T'] } },
167170
})),
168171
})),
169172
};
@@ -193,6 +196,7 @@ describe('DepositDetector', () => {
193196
getTransaction: vi.fn(() => ({
194197
send: vi.fn(async () => ({
195198
meta: { preBalances: [10_000_000_000, 0], postBalances: [5_000_000_000, 5_000_000_000] },
199+
transaction: { message: { staticAccountKeys: ['sender', 'T'] } },
196200
})),
197201
})),
198202
};
@@ -224,6 +228,7 @@ describe('DepositDetector', () => {
224228
getTransaction: vi.fn(() => ({
225229
send: vi.fn(async () => ({
226230
meta: { preBalances: [10_000_000_000, 0], postBalances: [5_000_000_000, 5_000_000_000] },
231+
transaction: { message: { staticAccountKeys: ['sender', 'T'] } },
227232
})),
228233
})),
229234
};
@@ -252,6 +257,7 @@ describe('DepositDetector', () => {
252257
getTransaction: vi.fn(() => ({
253258
send: vi.fn(async () => ({
254259
meta: { preBalances: [10_000_000_000, 0], postBalances: [5_000_000_000, 5_000_000_000] },
260+
transaction: { message: { staticAccountKeys: ['sender', 'T'] } },
255261
})),
256262
})),
257263
};
@@ -279,6 +285,7 @@ describe('DepositDetector', () => {
279285
getTransaction: vi.fn(() => ({
280286
send: vi.fn(async () => ({
281287
meta: { preBalances: [10_000_000_000, 0], postBalances: [4_999_000_000, 5_000_000_000] },
288+
transaction: { message: { staticAccountKeys: ['sender', 'T'] } },
282289
})),
283290
})),
284291
};
@@ -306,6 +313,7 @@ describe('DepositDetector', () => {
306313
getTransaction: vi.fn(() => ({
307314
send: vi.fn(async () => ({
308315
meta: { preBalances: [1_000_000_000, 0], postBalances: [999_000_000, 1_000_000] },
316+
transaction: { message: { staticAccountKeys: ['sender', 'T'] } },
309317
})),
310318
})),
311319
};

src/services/deposit.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface SolanaRpc {
1111
getTransaction(signature: any, opts: any): {
1212
send(): Promise<{
1313
meta: { preBalances: number[]; postBalances: number[] } | null;
14+
transaction: { message: { staticAccountKeys: string[] } };
1415
} | null>;
1516
};
1617
}
@@ -51,8 +52,10 @@ export class DepositDetector {
5152
}).send();
5253
if (!txDetail?.meta) return false;
5354
const { preBalances, postBalances } = txDetail.meta;
54-
const lastIdx = postBalances.length - 1;
55-
const received = (postBalances[lastIdx] - preBalances[lastIdx]) / 1_000_000_000;
55+
const accountKeys = txDetail.transaction.message.staticAccountKeys;
56+
const treasuryIdx = accountKeys.findIndex(k => k === this.cfg.treasuryAddress);
57+
if (treasuryIdx === -1) return false;
58+
const received = (postBalances[treasuryIdx] - preBalances[treasuryIdx]) / 1_000_000_000;
5659
return received >= expectedSol * 0.999;
5760
} catch {
5861
return false;

0 commit comments

Comments
 (0)