Skip to content

Commit c6e5084

Browse files
authored
Use Pool Created Events to verify VIP Uni v2 Events (#131)
* Use Pool Created Events to verify VIP Uni v2 Events
1 parent 3a3c29d commit c6e5084

8 files changed

+133
-65
lines changed

src/events.ts

+37
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ import {
138138
} from './parsers/events/onchain_governance_events';
139139

140140
import { TokenMetadataMap } from './scripts/utils/web3_utils';
141+
import { UniV2PoolSingleton } from './uniV2PoolSingleton';
142+
143+
function uniV2PoolSingletonCallback(pools: UniswapV2PairCreatedEvent[]) {
144+
const uniV2PoolSingleton = UniV2PoolSingleton.getInstance();
145+
uniV2PoolSingleton.addNewPools(pools);
146+
}
141147

142148
export type CommonEventParams = {
143149
connection: Connection;
@@ -156,6 +162,7 @@ export type EventScraperProps = {
156162
parser: (decodedLog: RawLogEntry) => any;
157163
deleteOptions: DeleteOptions;
158164
tokenMetadataMap: TokenMetadataMap;
165+
callback: any | null;
159166
};
160167

161168
export const eventScrperProps: EventScraperProps[] = [
@@ -170,6 +177,7 @@ export const eventScrperProps: EventScraperProps[] = [
170177
parser: parseTransformedERC20Event,
171178
deleteOptions: {},
172179
tokenMetadataMap: null,
180+
callback: null,
173181
},
174182
{
175183
enabled: FEAT_UNISWAP_V3_VIP_SWAP_EVENT,
@@ -182,6 +190,7 @@ export const eventScrperProps: EventScraperProps[] = [
182190
parser: parseUniswapV3VIPSwapEvent,
183191
deleteOptions: { isDirectTrade: true, directProtocol: ['UniswapV3'] },
184192
tokenMetadataMap: { tokenA: 'fromToken', tokenB: 'toToken' },
193+
callback: null,
185194
},
186195
{
187196
enabled: FEAT_ERC20_BRIDGE_TRANSFER_FLASHWALLET,
@@ -194,6 +203,7 @@ export const eventScrperProps: EventScraperProps[] = [
194203
parser: parseBridgeFill,
195204
deleteOptions: { isDirectTrade: false },
196205
tokenMetadataMap: { tokenA: 'fromToken', tokenB: 'toToken' },
206+
callback: null,
197207
},
198208
{
199209
enabled: FEAT_UNISWAP_V2_VIP_SWAP_EVENT,
@@ -206,6 +216,7 @@ export const eventScrperProps: EventScraperProps[] = [
206216
parser: parseUniswapV2SwapEvent,
207217
deleteOptions: { isDirectTrade: true, directProtocol: UNISWAP_V2_VIP_SWAP_SOURCES },
208218
tokenMetadataMap: { tokenA: 'fromToken', tokenB: 'toToken' },
219+
callback: null,
209220
},
210221
{
211222
enabled: FEAT_UNISWAP_V3_VIP_SWAP_EVENT,
@@ -218,6 +229,7 @@ export const eventScrperProps: EventScraperProps[] = [
218229
parser: parseUniswapV3SwapEvent,
219230
deleteOptions: { isDirectTrade: true, directProtocol: ['UniswapV3'] },
220231
tokenMetadataMap: { tokenA: 'fromToken', tokenB: 'toToken' },
232+
callback: null,
221233
},
222234
{
223235
enabled: FEAT_RFQ_EVENT,
@@ -230,6 +242,7 @@ export const eventScrperProps: EventScraperProps[] = [
230242
parser: parseV4RfqOrderFilledEvent,
231243
deleteOptions: {},
232244
tokenMetadataMap: { tokenA: 'makerToken', tokenB: 'takerToken' },
245+
callback: null,
233246
},
234247
{
235248
enabled: FEAT_RFQ_EVENT,
@@ -242,6 +255,7 @@ export const eventScrperProps: EventScraperProps[] = [
242255
parser: parseNativeFillFromV4RfqOrderFilledEvent,
243256
deleteOptions: { protocolVersion: 'v4', nativeOrderType: 'RFQ Order' },
244257
tokenMetadataMap: null,
258+
callback: null,
245259
},
246260
{
247261
enabled: FEAT_RFQ_EVENT,
@@ -254,6 +268,7 @@ export const eventScrperProps: EventScraperProps[] = [
254268
parser: parseExpiredRfqOrderEvent,
255269
deleteOptions: {},
256270
tokenMetadataMap: null,
271+
callback: null,
257272
},
258273
{
259274
enabled: FEAT_LIMIT_ORDERS,
@@ -266,6 +281,7 @@ export const eventScrperProps: EventScraperProps[] = [
266281
parser: parseV4LimitOrderFilledEvent,
267282
deleteOptions: {},
268283
tokenMetadataMap: { tokenA: 'makerToken', tokenB: 'takerToken' },
284+
callback: null,
269285
},
270286
{
271287
enabled: FEAT_LIMIT_ORDERS,
@@ -278,6 +294,7 @@ export const eventScrperProps: EventScraperProps[] = [
278294
parser: parseNativeFillFromV4LimitOrderFilledEvent,
279295
deleteOptions: { protocolVersion: 'v4', nativeOrderType: 'Limit Order' },
280296
tokenMetadataMap: null,
297+
callback: null,
281298
},
282299
{
283300
enabled: FEAT_RFQ_EVENT || FEAT_LIMIT_ORDERS,
@@ -290,6 +307,7 @@ export const eventScrperProps: EventScraperProps[] = [
290307
parser: parseV4CancelEvent,
291308
deleteOptions: {},
292309
tokenMetadataMap: null,
310+
callback: null,
293311
},
294312
{
295313
enabled: FEAT_OTC_ORDERS,
@@ -302,6 +320,7 @@ export const eventScrperProps: EventScraperProps[] = [
302320
parser: parseOtcOrderFilledEvent,
303321
deleteOptions: {},
304322
tokenMetadataMap: { tokenA: 'makerTokenAddress', tokenB: 'takerTokenAddress' },
323+
callback: null,
305324
},
306325
{
307326
enabled: FEAT_OTC_ORDERS,
@@ -314,6 +333,7 @@ export const eventScrperProps: EventScraperProps[] = [
314333
parser: parseNativeFillFromV4OtcOrderFilledEvent,
315334
deleteOptions: { protocolVersion: 'v4', nativeOrderType: 'OTC Order' },
316335
tokenMetadataMap: null,
336+
callback: null,
317337
},
318338
{
319339
enabled: FEAT_V3_FILL_EVENT,
@@ -326,6 +346,7 @@ export const eventScrperProps: EventScraperProps[] = [
326346
parser: parseFillEvent,
327347
deleteOptions: {},
328348
tokenMetadataMap: { tokenA: 'makerTokenAddress', tokenB: 'takerTokenAddress' },
349+
callback: null,
329350
},
330351
{
331352
enabled: FEAT_V3_NATIVE_FILL,
@@ -338,6 +359,7 @@ export const eventScrperProps: EventScraperProps[] = [
338359
parser: parseNativeFillFromFillEvent,
339360
deleteOptions: { protocolVersion: 'v3' },
340361
tokenMetadataMap: null,
362+
callback: null,
341363
},
342364
{
343365
enabled: FEAT_NFT,
@@ -350,6 +372,7 @@ export const eventScrperProps: EventScraperProps[] = [
350372
parser: parseErc721OrderFilledEvent,
351373
deleteOptions: {},
352374
tokenMetadataMap: { tokenA: 'erc20Token', tokenB: 'erc721Token' },
375+
callback: null,
353376
},
354377
{
355378
enabled: FEAT_NFT,
@@ -362,6 +385,7 @@ export const eventScrperProps: EventScraperProps[] = [
362385
parser: parseErc721OrderCancelledEvent,
363386
deleteOptions: {},
364387
tokenMetadataMap: null,
388+
callback: null,
365389
},
366390
{
367391
enabled: FEAT_NFT,
@@ -374,6 +398,7 @@ export const eventScrperProps: EventScraperProps[] = [
374398
parser: parseErc721OrderPresignedEvent,
375399
deleteOptions: {},
376400
tokenMetadataMap: { tokenA: 'erc20Token', tokenB: 'erc721Token' },
401+
callback: null,
377402
},
378403
{
379404
enabled: FEAT_NFT,
@@ -386,6 +411,7 @@ export const eventScrperProps: EventScraperProps[] = [
386411
parser: parseErc1155OrderFilledEvent,
387412
deleteOptions: {},
388413
tokenMetadataMap: { tokenA: 'erc20Token', tokenB: 'erc1155Token' },
414+
callback: null,
389415
},
390416
{
391417
enabled: FEAT_NFT,
@@ -398,6 +424,7 @@ export const eventScrperProps: EventScraperProps[] = [
398424
parser: parseErc1155OrderCancelledEvent,
399425
deleteOptions: {},
400426
tokenMetadataMap: null,
427+
callback: null,
401428
},
402429
{
403430
enabled: FEAT_NFT,
@@ -410,6 +437,7 @@ export const eventScrperProps: EventScraperProps[] = [
410437
parser: parseErc1155OrderPresignedEvent,
411438
deleteOptions: {},
412439
tokenMetadataMap: { tokenA: 'erc20Token', tokenB: 'erc1155Token' },
440+
callback: null,
413441
},
414442
{
415443
enabled: FEAT_UNISWAP_V2_SYNC_EVENT,
@@ -422,6 +450,7 @@ export const eventScrperProps: EventScraperProps[] = [
422450
parser: parseUniswapV2SyncEvent,
423451
deleteOptions: {},
424452
tokenMetadataMap: null,
453+
callback: null,
425454
},
426455
{
427456
enabled: FEAT_META_TRANSACTION_EXECUTED_EVENT,
@@ -434,6 +463,7 @@ export const eventScrperProps: EventScraperProps[] = [
434463
parser: parseMetaTransactionExecutedEvent,
435464
deleteOptions: {},
436465
tokenMetadataMap: null,
466+
callback: null,
437467
},
438468
{
439469
enabled: FEAT_UNISWAP_V3_SWAP_EVENT,
@@ -446,6 +476,7 @@ export const eventScrperProps: EventScraperProps[] = [
446476
parser: parseUniswapV3SwapEvent,
447477
deleteOptions: {},
448478
tokenMetadataMap: null,
479+
callback: null,
449480
},
450481
{
451482
enabled: FEAT_ONCHAIN_GOVERNANCE,
@@ -459,6 +490,7 @@ export const eventScrperProps: EventScraperProps[] = [
459490
parseOnchainGovernanceProposalCreatedEvent(decodedLog, 'ZeroexTreasuryGovernor'),
460491
deleteOptions: {},
461492
tokenMetadataMap: null,
493+
callback: null,
462494
},
463495
{
464496
enabled: FEAT_ONCHAIN_GOVERNANCE,
@@ -473,6 +505,7 @@ export const eventScrperProps: EventScraperProps[] = [
473505
parseOnchainGovernanceProposalCreatedEvent(decodedLog, 'ZeroexProtocolGovernor'),
474506
deleteOptions: {},
475507
tokenMetadataMap: null,
508+
callback: null,
476509
},
477510
{
478511
enabled: FEAT_ONCHAIN_GOVERNANCE,
@@ -486,6 +519,7 @@ export const eventScrperProps: EventScraperProps[] = [
486519
parseOnchainGovernanceCallScheduledEvent(decodedLog, 'TreasuryZeroexTimelock'),
487520
deleteOptions: {},
488521
tokenMetadataMap: null,
522+
callback: null,
489523
},
490524
{
491525
enabled: FEAT_ONCHAIN_GOVERNANCE,
@@ -499,6 +533,7 @@ export const eventScrperProps: EventScraperProps[] = [
499533
parseOnchainGovernanceCallScheduledEvent(decodedLog, 'ProtocolZeroexTimelock'),
500534
deleteOptions: {},
501535
tokenMetadataMap: null,
536+
callback: null,
502537
},
503538
];
504539

@@ -519,6 +554,7 @@ for (const payment_recipient of POLYGON_RFQM_PAYMENTS_ADDRESSES) {
519554
parser: parseLogTransferEvent,
520555
deleteOptions: { recipient: payment_recipient },
521556
tokenMetadataMap: null,
557+
callback: null,
522558
});
523559
}
524560

@@ -534,6 +570,7 @@ for (const protocol of UNISWAP_V2_PAIR_CREATED_PROTOCOL_CONTRACT_ADDRESSES_AND_S
534570
parser: (decodedLog: RawLogEntry) => parseUniswapV2PairCreatedEvent(decodedLog, protocol.name),
535571
deleteOptions: { protocol: protocol.name },
536572
tokenMetadataMap: { tokenA: 'token0', tokenB: 'token1' },
573+
callback: uniV2PoolSingletonCallback,
537574
});
538575
}
539576

src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { ChainIdChecker } from './scripts/check_chain_id';
3030
import { CurrentBlockMonitor } from './scripts/monitor_current_block';
3131
import { startMetricsServer } from './utils/metrics';
3232
import { TokenMetadataSingleton } from './tokenMetadataSingleton';
33+
import { UniV2PoolSingleton } from './uniV2PoolSingleton';
3334

3435
const kafka = new Kafka({
3536
clientId: 'event-pipeline',
@@ -69,8 +70,8 @@ createConnection(ormConfig as ConnectionOptions)
6970
.then(async (connection) => {
7071
await producer.connect();
7172
await TokenMetadataSingleton.getInstance(connection, producer);
73+
await UniV2PoolSingleton.initInstance(connection);
7274
schedule(null, null, currentBlockMonitor.monitor, 'Current Block');
73-
7475
schedule(connection, producer, blockScraper.getParseSaveEventsAsync, 'Pull and Save Blocks');
7576
schedule(connection, producer, eventsByTopicScraper.getParseSaveEventsAsync, 'Pull and Save Events by Topic');
7677
schedule(connection, producer, eventsBackfillScraper.getParseSaveEventsAsync, 'Backfill Events by Topic');

src/parsers/events/uniswap_v2_events.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
const abiCoder = require('web3-eth-abi');
22
import { RawLogEntry } from 'ethereum-types';
3+
import { logger } from '../../utils/logger';
34
import { ERC20BridgeTransferEvent, UniswapV2PairCreatedEvent, UniswapV2SyncEvent } from '../../entities';
45

56
import { parseEvent } from './parse_event';
67
import { UNISWAP_V2_SWAP_ABI, UNISWAP_V2_SYNC_ABI, UNISWAP_V2_PAIR_CREATED_ABI } from '../../constants';
78
import { BigNumber } from '@0x/utils';
9+
import { UniV2PoolSingleton } from '../../uniV2PoolSingleton';
810

9-
export function parseUniswapV2SwapEvent(eventLog: RawLogEntry): ERC20BridgeTransferEvent {
11+
export function parseUniswapV2SwapEvent(eventLog: RawLogEntry): ERC20BridgeTransferEvent | null {
1012
const eRC20BridgeTransferEvent = new ERC20BridgeTransferEvent();
1113
parseEvent(eventLog, eRC20BridgeTransferEvent);
1214
// decode the basic info directly into eRC20BridgeTransferEvent
@@ -15,24 +17,36 @@ export function parseUniswapV2SwapEvent(eventLog: RawLogEntry): ERC20BridgeTrans
1517
eventLog.topics[2],
1618
]);
1719

20+
const uniV2PoolSingleton = UniV2PoolSingleton.getInstance();
21+
22+
const poolInfo = uniV2PoolSingleton.getPool(eRC20BridgeTransferEvent.contractAddress);
23+
24+
if (poolInfo === undefined) {
25+
logger.error(
26+
`Got a Uni v2 VIP trade from an unknown pool, ignoring. Tx: ${eRC20BridgeTransferEvent.transactionHash}, Pool: ${eRC20BridgeTransferEvent.contractAddress}`,
27+
);
28+
return null;
29+
}
30+
const { token0, token1, protocol } = poolInfo;
31+
1832
const amount0In = new BigNumber(decodedLog.amount0In);
1933
const amount1In = new BigNumber(decodedLog.amount1In);
2034
const amount0Out = new BigNumber(decodedLog.amount0Out);
2135
const amount1Out = new BigNumber(decodedLog.amount1Out);
2236

23-
eRC20BridgeTransferEvent.fromToken = amount0In.gt(amount0Out) ? '0' : '1'; // taker_token
24-
eRC20BridgeTransferEvent.toToken = amount0In.gt(amount0Out) ? '1' : '0'; // maker_token
37+
eRC20BridgeTransferEvent.fromToken = amount0In.gt(amount0Out) ? token0 : token1; // taker_token
38+
eRC20BridgeTransferEvent.toToken = amount0In.gt(amount0Out) ? token1 : token0; // maker_token
2539

2640
eRC20BridgeTransferEvent.fromTokenAmount = new BigNumber(
2741
amount0In.gt(amount0Out) ? amount0In.minus(amount0Out) : amount1In.minus(amount1Out),
2842
); // taker_token_amount
2943
eRC20BridgeTransferEvent.toTokenAmount = new BigNumber(
3044
amount0In.gt(amount0Out) ? amount1Out.minus(amount1In) : amount0Out.minus(amount0In),
3145
); // maker_token_amount
32-
eRC20BridgeTransferEvent.from = ''; // maker
46+
eRC20BridgeTransferEvent.from = protocol; // maker TODO(jorge): Replace with pool address, after checking downstream impact
3347
eRC20BridgeTransferEvent.to = decodedLog.to.toLowerCase(); // taker
3448
eRC20BridgeTransferEvent.directFlag = true;
35-
eRC20BridgeTransferEvent.directProtocol = '';
49+
eRC20BridgeTransferEvent.directProtocol = protocol;
3650

3751
return eRC20BridgeTransferEvent;
3852
}

src/scripts/backfill_events.ts

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export class EventsBackfillScraper {
6969
props.parser,
7070
props.deleteOptions,
7171
props.tokenMetadataMap,
72+
props.callback,
7273
backfillEventsOldestBlock.get(props.name)!,
7374
)
7475
.then(async ({ transactionHashes, startBlockNumber, endBlockNumber }) => {

src/scripts/pull_and_save_events_by_topic.ts

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export class EventsByTopicScraper {
5353
props.parser,
5454
props.deleteOptions,
5555
props.tokenMetadataMap,
56+
props.callback,
5657
),
5758
);
5859
}

0 commit comments

Comments
 (0)