Skip to content

Commit 85ef102

Browse files
committed
Polygon Transfer Tracking
1 parent 00937b6 commit 85ef102

File tree

11 files changed

+178
-2
lines changed

11 files changed

+178
-2
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
const createTable = ` create table events_polygon.log_transfer_events
3+
(
4+
observed_timestamp bigint not null,
5+
contract_address text not null,
6+
transaction_hash text not null,
7+
transaction_index bigint not null,
8+
log_index bigint not null,
9+
block_hash text not null,
10+
block_number bigint not null,
11+
token text not null,
12+
"from" text not null,
13+
"to" text not null,
14+
amount numeric not null,
15+
input1 numeric not null,
16+
input2 numeric not null,
17+
output1 numeric not null,
18+
output2 numeric not null,
19+
primary key (transaction_hash, log_index)
20+
);`;
21+
const createIndexes = `
22+
create index log_transfer_events_transaction_block_number_index
23+
on events_polygon.log_transfer_events (block_number);
24+
`;
25+
26+
const dropTable = `DROP TABLE events_polygon.log_transfer_events;`;
27+
28+
export class PolygonCreateLogTransferEventTable1653498151000 implements MigrationInterface {
29+
public async up(queryRunner: QueryRunner): Promise<void> {
30+
await queryRunner.query(createTable);
31+
await queryRunner.query(createIndexes);
32+
}
33+
34+
public async down(queryRunner: QueryRunner): Promise<void> {
35+
await queryRunner.query(dropTable);
36+
}
37+
}

event-pipeline-evm/src/abis.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,3 +1046,19 @@ export const ERC1155_ORDER_PRESIGNED_ABI = {
10461046
name: 'ERC1155OrderPreSigned',
10471047
type: 'event',
10481048
};
1049+
1050+
export const LOG_TRANSFER_ABI = {
1051+
anonymous: false,
1052+
inputs: [
1053+
{ indexed: true, internalType: 'address', name: 'token', type: 'address' },
1054+
{ indexed: true, internalType: 'address', name: 'from', type: 'address' },
1055+
{ indexed: true, internalType: 'address', name: 'to', type: 'address' },
1056+
{ indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' },
1057+
{ indexed: false, internalType: 'uint256', name: 'input1', type: 'uint256' },
1058+
{ indexed: false, internalType: 'uint256', name: 'input2', type: 'uint256' },
1059+
{ indexed: false, internalType: 'uint256', name: 'output1', type: 'uint256' },
1060+
{ indexed: false, internalType: 'uint256', name: 'output2', type: 'uint256' },
1061+
],
1062+
name: 'LogTransfer',
1063+
type: 'event',
1064+
};

event-pipeline-evm/src/config.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
DEFAULT_FEAT_PARASWAP_SWAPPED_V4_EVENT,
1818
DEFAULT_FEAT_PARASWAP_SWAPPED_V5_EVENT,
1919
DEFAULT_FEAT_PLP_SWAP_EVENT,
20+
DEFAULT_FEAT_POLYGON_RFQM_PAYMENTS,
2021
DEFAULT_FEAT_RFQ_EVENT,
2122
DEFAULT_FEAT_SLINGSHOT_TRADE_EVENT,
2223
DEFAULT_FEAT_STAKING,
@@ -384,6 +385,26 @@ validateStartBlock(
384385

385386
export const FEAT_TX_BACKFILL = getBoolConfig('FEAT_TX_BACKFILL', DEFAULT_FEAT_TX_BACKFILL);
386387

388+
export const FEAT_POLYGON_RFQM_PAYMENTS = getBoolConfig(
389+
'FEAT_POLYGON_RFQM_PAYMENTS',
390+
DEFAULT_FEAT_POLYGON_RFQM_PAYMENTS,
391+
);
392+
393+
export const POLYGON_RFQM_PAYMENTS_START_BLOCK = getIntConfig('POLYGON_RFQM_PAYMENTS_START_BLOCK', -1);
394+
validateStartBlock(
395+
'POLYGON_RFQM_PAYMENTS_START_BLOCK',
396+
POLYGON_RFQM_PAYMENTS_START_BLOCK,
397+
'FEAT_POLYGON_RFQM_PAYMENTS',
398+
FEAT_POLYGON_RFQM_PAYMENTS,
399+
);
400+
401+
export const POLYGON_RFQM_PAYMENTS_ADDRESSES = process.env.POLYGON_RFQM_PAYMENTS_ADDRESSES
402+
? process.env.POLYGON_RFQM_PAYMENTS_ADDRESSES.split(',')
403+
: [];
404+
if (FEAT_POLYGON_RFQM_PAYMENTS && POLYGON_RFQM_PAYMENTS_ADDRESSES.length === 0) {
405+
throwError(`FEAT_POLYGON_RFQM_PAYMENTS is enabled, but no POLYGON_RFQM_PAYMENTS_ADDRESS was provided`);
406+
}
407+
387408
function getBoolConfig(env: string, defaultValue: boolean): boolean {
388409
if (Object.prototype.hasOwnProperty.call(process.env, env)) {
389410
return process.env[env] === 'true';

event-pipeline-evm/src/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const DEFAULT_FEAT_PARASWAP_SWAPPED2_V5_EVENT = false;
2525
export const DEFAULT_FEAT_PARASWAP_SWAPPED_V4_EVENT = false;
2626
export const DEFAULT_FEAT_PARASWAP_SWAPPED_V5_EVENT = false;
2727
export const DEFAULT_FEAT_PLP_SWAP_EVENT = false;
28+
export const DEFAULT_FEAT_POLYGON_RFQM_PAYMENTS = false;
2829
export const DEFAULT_FEAT_RFQ_EVENT = false;
2930
export const DEFAULT_FEAT_SLINGSHOT_TRADE_EVENT = false;
3031
export const DEFAULT_FEAT_STAKING = false;
@@ -95,3 +96,6 @@ export const ERC165_ERC721_INTERFACE = '80ac58cd';
9596
export const ERC165_ERC1155_INTERFACE = 'd9b67a26';
9697

9798
export * from './abis';
99+
100+
export const LOG_TRANSFER_EVENT_TOPIC_0 = '0xe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c4';
101+
export const POLYGON_MATIC_ADDRESS = '0x0000000000000000000000000000000000001010';

event-pipeline-evm/src/data_sources/events/web3.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface LogPullInfo {
1010
address: string;
1111
fromBlock: number;
1212
toBlock: number;
13-
topics: string[];
13+
topics: (string | null)[];
1414
}
1515
export interface ContractCallInfo {
1616
to: string;

event-pipeline-evm/src/entities/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export { Event } from './event';
1515
export { ExpiredRfqOrderEvent } from './expired_rfq_order_event';
1616
export { FillEvent } from './fill_event';
1717
export { LastBlockProcessed } from './last_block_processed';
18+
export { LogTransferEvent } from './log_transfer_event';
1819
export { MakerStakingPoolSetEvent } from './maker_staking_pool_set_event';
1920
export { MoveStakeEvent } from './move_stake_event';
2021
export { NativeFill } from './native_fill';
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { bigNumberTransformer } from '../transformers/big_number';
2+
import { BigNumber } from '@0x/utils';
3+
import { Column, Entity } from 'typeorm';
4+
5+
import { Event } from './event';
6+
7+
// These events come directly from the Exchange contract and are fired whenever
8+
// someone fills an order.
9+
@Entity({ name: 'log_transfer_events' })
10+
export class LogTransferEvent extends Event {
11+
@Column({ name: 'token' })
12+
public token!: string;
13+
@Column({ name: 'from' })
14+
public from!: string;
15+
@Column({ name: 'to' })
16+
public to!: string;
17+
@Column({ name: 'amount', type: 'numeric', transformer: bigNumberTransformer })
18+
public amount!: BigNumber;
19+
@Column({ name: 'input1', type: 'numeric', transformer: bigNumberTransformer })
20+
public input1!: BigNumber;
21+
@Column({ name: 'input2', type: 'numeric', transformer: bigNumberTransformer })
22+
public input2!: BigNumber;
23+
@Column({ name: 'output1', type: 'numeric', transformer: bigNumberTransformer })
24+
public output1!: BigNumber;
25+
@Column({ name: 'output2', type: 'numeric', transformer: bigNumberTransformer })
26+
public output2!: BigNumber;
27+
}

event-pipeline-evm/src/ormconfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
ExpiredRfqOrderEvent,
2020
FillEvent,
2121
LastBlockProcessed,
22+
LogTransferEvent,
2223
MakerStakingPoolSetEvent,
2324
MoveStakeEvent,
2425
NativeFill,
@@ -68,6 +69,7 @@ const entities = [
6869
ExpiredRfqOrderEvent,
6970
FillEvent,
7071
LastBlockProcessed,
72+
LogTransferEvent,
7173
MakerStakingPoolSetEvent,
7274
MoveStakeEvent,
7375
NativeFill,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const abiCoder = require('web3-eth-abi');
2+
import { RawLogEntry } from 'ethereum-types';
3+
import { LogTransferEvent } from '../../entities';
4+
5+
import { parseEvent } from './parse_event';
6+
import { LOG_TRANSFER_ABI } from '../../constants';
7+
import { BigNumber } from '@0x/utils';
8+
9+
export function parseLogTransferEvent(eventLog: RawLogEntry): LogTransferEvent {
10+
const logTransferEvent = new LogTransferEvent();
11+
parseEvent(eventLog, logTransferEvent);
12+
// decode the basic info directly into logTransferEvent
13+
const decodedLog = abiCoder.decodeLog(LOG_TRANSFER_ABI.inputs, eventLog.data, [
14+
eventLog.topics[1],
15+
eventLog.topics[2],
16+
eventLog.topics[3],
17+
]);
18+
19+
logTransferEvent.token = decodedLog.token;
20+
logTransferEvent.from = decodedLog.from;
21+
logTransferEvent.to = decodedLog.to;
22+
logTransferEvent.amount = new BigNumber(decodedLog.amount);
23+
logTransferEvent.input1 = new BigNumber(decodedLog.input1);
24+
logTransferEvent.input2 = new BigNumber(decodedLog.input2);
25+
logTransferEvent.output1 = new BigNumber(decodedLog.output1);
26+
logTransferEvent.output2 = new BigNumber(decodedLog.output2);
27+
28+
return logTransferEvent;
29+
}

event-pipeline-evm/src/scripts/pull_and_save_events_by_topic.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
Erc721OrderPresignedEvent,
1717
ExpiredRfqOrderEvent,
1818
FillEvent,
19+
LogTransferEvent,
1920
NativeFill,
2021
OneinchSwappedV3Event,
2122
OneinchSwappedV4Event,
@@ -47,6 +48,7 @@ import {
4748
FEAT_PARASWAP_SWAPPED_V4_EVENT,
4849
FEAT_PARASWAP_SWAPPED_V5_EVENT,
4950
FEAT_PLP_SWAP_EVENT,
51+
FEAT_POLYGON_RFQM_PAYMENTS,
5052
FEAT_RFQ_EVENT,
5153
FEAT_SLINGSHOT_TRADE_EVENT,
5254
FEAT_TIMECHAIN_SWAP_V1_EVENT,
@@ -69,6 +71,8 @@ import {
6971
PARASWAP_V5_CONTRACT_ADDRESS,
7072
PARASWAP_V5_DEPLOYMENT_BLOCK,
7173
PLP_VIP_START_BLOCK,
74+
POLYGON_RFQM_PAYMENTS_ADDRESSES,
75+
POLYGON_RFQM_PAYMENTS_START_BLOCK,
7276
SLINGSHOT_DEPLOYMENT_BLOCK,
7377
TIMECHAIN_V1_DEPLOYMENT_BLOCK,
7478
UNISWAP_V2_VIP_SWAP_SOURCES,
@@ -87,6 +91,7 @@ import {
8791
EXPIRED_RFQ_ORDER_EVENT_TOPIC,
8892
LIMITORDERFILLED_EVENT_TOPIC,
8993
LIQUIDITYPROVIDERSWAP_EVENT_TOPIC,
94+
LOG_TRANSFER_EVENT_TOPIC_0,
9095
ONEINCH_ROUTER_V3_CONTRACT_ADDRESS,
9196
ONEINCH_ROUTER_V4_CONTRACT_ADDRESS,
9297
ONEINCH_SWAPPED_EVENT_TOPIC,
@@ -96,6 +101,7 @@ import {
96101
PARASWAP_SWAPPED2_V5_EVENT_TOPIC,
97102
PARASWAP_SWAPPED_V4_EVENT_TOPIC,
98103
PARASWAP_SWAPPED_V5_EVENT_TOPIC,
104+
POLYGON_MATIC_ADDRESS,
99105
RFQORDERFILLED_EVENT_TOPIC,
100106
SLINGSHOT_CONTRACT_ADDRESS,
101107
SLINGSHOT_TRADE_EVENT_TOPIC,
@@ -148,6 +154,7 @@ import {
148154
} from '../parsers/events/nft_events';
149155

150156
import { parseBridgeFill } from '../parsers/events/bridge_transfer_events';
157+
import { parseLogTransferEvent } from '../parsers/events/log_transfer_events';
151158

152159
import { PullAndSaveEventsByTopic } from './utils/event_abi_utils';
153160
import { SCRIPT_RUN_DURATION } from '../utils/metrics';
@@ -673,6 +680,31 @@ export class EventsByTopicScraper {
673680
);
674681
}
675682

683+
if (FEAT_POLYGON_RFQM_PAYMENTS) {
684+
console.log('POLYGON_RFQM_PAYMENTS_ADDRESSES', POLYGON_RFQM_PAYMENTS_ADDRESSES);
685+
for (const payment_recipient of POLYGON_RFQM_PAYMENTS_ADDRESSES) {
686+
promises.push(
687+
pullAndSaveEventsByTopic.getParseSaveEventsByTopic<LogTransferEvent>(
688+
connection,
689+
web3Source,
690+
latestBlockWithOffset,
691+
'LogTransferEvent',
692+
LogTransferEvent,
693+
'log_transfer_events',
694+
[
695+
LOG_TRANSFER_EVENT_TOPIC_0,
696+
addressToTopic(POLYGON_MATIC_ADDRESS),
697+
null,
698+
addressToTopic(payment_recipient),
699+
],
700+
POLYGON_MATIC_ADDRESS,
701+
POLYGON_RFQM_PAYMENTS_START_BLOCK,
702+
parseLogTransferEvent,
703+
{},
704+
),
705+
);
706+
}
707+
}
676708
const txHashes = [
677709
...new Set((await Promise.all(promises)).reduce((accumulator, value) => accumulator.concat(value), [])),
678710
];
@@ -685,3 +717,10 @@ export class EventsByTopicScraper {
685717
logger.info(`Finished pulling events by topic in ${scriptDurationSeconds}`);
686718
}
687719
}
720+
721+
function addressToTopic(address: string): string {
722+
if (address.length === 42 && address.substring(0, 2) === '0x') {
723+
return `0x000000000000000000000000${address.substring(2)}`;
724+
}
725+
throw new Error(`Error while converting convert ${address} to topic`);
726+
}

0 commit comments

Comments
 (0)