Skip to content

Commit b2a3cf5

Browse files
authored
Merge pull request #97 from 0xProject/feat/scrape-otc-event
Feat/scrape otc event
2 parents 86d38fb + 0464c82 commit b2a3cf5

10 files changed

+198
-2
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
postgres/
2+
node_modules

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: '3'
22
services:
33
postgres:
4-
image: postgres:9.6
4+
image: postgres:10.14
55
environment:
66
- POSTGRES_USER=api
77
- POSTGRES_PASSWORD=api

event-pipeline/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RUN apk update && \
1010
apk upgrade && \
1111
apk add --no-cache --virtual build-dependencies bash git openssh python3 make g++ && \
1212
yarn --frozen-lockfile --no-cache
13-
13+
1414
RUN yarn build
1515

1616
# Stage 2
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { MigrationInterface, QueryRunner, Table } from 'typeorm';
2+
3+
const eventsOtcOrderFilledEvents = new Table({
4+
name: 'events.otc_order_filled_events',
5+
columns: [
6+
{ name: 'observed_timestamp', type: 'bigint' },
7+
{ name: 'contract_address', type: 'varchar' },
8+
{ name: 'transaction_hash', type: 'varchar', isPrimary: true },
9+
{ name: 'transaction_index', type: 'bigint' },
10+
{ name: 'log_index', type: 'bigint', isPrimary: true },
11+
{ name: 'block_hash', type: 'varchar' },
12+
{ name: 'block_number', type: 'bigint' },
13+
14+
{ name: 'order_hash', type: 'varchar' },
15+
{ name: 'maker_address', type: 'varchar' },
16+
{ name: 'taker_address', type: 'varchar' },
17+
{ name: 'maker_token_address', type: 'varchar' },
18+
{ name: 'taker_token_address', type: 'varchar' },
19+
{ name: 'maker_token_filled_amount', type: 'numeric' },
20+
{ name: 'taker_token_filled_amount', type: 'numeric' },
21+
],
22+
});
23+
24+
const indexQuery = `
25+
CREATE INDEX otc_order_filled_events_transaction_hash_index
26+
ON events.otc_order_filled_events (transaction_hash);
27+
CREATE INDEX otc_order_filled_events_block_number_index
28+
ON events.otc_order_filled_events (block_number);
29+
CREATE INDEX otc_order_filled_events_maker_address_index
30+
ON events.otc_order_filled_events (maker_address);
31+
CREATE INDEX otc_order_filled_events_order_hash_index
32+
ON events.otc_order_filled_events (order_hash);
33+
34+
`;
35+
36+
const dropIndexQuery = `
37+
DROP INDEX events.otc_order_filled_events_transaction_hash_index;
38+
DROP INDEX events.otc_order_filled_events_block_number_index;
39+
DROP INDEX events.otc_order_filled_events_maker_address_index;
40+
DROP INDEX events.otc_order_filled_events_order_hash_index;
41+
`;
42+
43+
export class AddOtcOrderFilledEvents1641418834000 implements MigrationInterface {
44+
public async up(queryRunner: QueryRunner): Promise<any> {
45+
await queryRunner.createTable(eventsOtcOrderFilledEvents);
46+
await queryRunner.query(indexQuery);
47+
}
48+
49+
public async down(queryRunner: QueryRunner): Promise<any> {
50+
await queryRunner.query(dropIndexQuery);
51+
await queryRunner.dropTable(eventsOtcOrderFilledEvents);
52+
}
53+
}

event-pipeline/src/constants.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export const SWAP_V3_EVENT_TOPIC = [
3838
'0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67',
3939
'0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff',
4040
];
41+
export const OTC_ORDER_FILLED_EVENT_TOPIC = ['0xac75f773e3a92f1a02b12134d65e1f47f8a14eabe4eaf1e24624918e6a8b269f'];
42+
export const OTC_ORDERS_FEATURE_START_BLOCK = 13143075;
4143

4244
export {
4345
EXPIRED_RFQ_ORDER_ABI,
@@ -309,3 +311,53 @@ export const V3_FILL_ABI = {
309311
name: 'Fill',
310312
type: 'event',
311313
};
314+
315+
export const OTC_ORDER_FILLED_ABI = {
316+
anonymous: false,
317+
inputs: [
318+
{
319+
indexed: false,
320+
internalType: 'bytes32',
321+
name: 'orderHash',
322+
type: 'bytes32',
323+
},
324+
{
325+
indexed: false,
326+
internalType: 'address',
327+
name: 'maker',
328+
type: 'address',
329+
},
330+
{
331+
indexed: false,
332+
internalType: 'address',
333+
name: 'taker',
334+
type: 'address',
335+
},
336+
{
337+
indexed: false,
338+
internalType: 'address',
339+
name: 'makerToken',
340+
type: 'address',
341+
},
342+
{
343+
indexed: false,
344+
internalType: 'address',
345+
name: 'takerToken',
346+
type: 'address',
347+
},
348+
{
349+
indexed: false,
350+
internalType: 'uint128',
351+
name: 'makerTokenFilledAmount',
352+
type: 'uint128',
353+
},
354+
{
355+
indexed: false,
356+
internalType: 'uint128',
357+
name: 'takerTokenFilledAmount',
358+
type: 'uint128',
359+
},
360+
],
361+
name: 'OtcOrderFilled',
362+
type: 'event',
363+
};

event-pipeline/src/entities/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export { EpochFinalizedEvent } from './epoch_finalized_event';
3232
export { RewardsPaidEvent } from './rewards_paid_event';
3333
export { StakingProxyDeployment } from './staking_proxy_deployment';
3434
export { TransactionExecutionEvent } from './transaction_execution_event';
35+
export { OtcOrderFilledEvent } from './otc_order_filled_event';
3536

3637
@Entity({ name: 'blocks', schema: 'events' })
3738
export class Block extends BlockTemplate {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { bigNumberTransformer } from '@0x/pipeline-utils';
2+
import { BigNumber } from '@0x/utils';
3+
import { Column, Entity } from 'typeorm';
4+
5+
import { Event } from '@0x/pipeline-utils';
6+
7+
import { ProxyType } from '../utils';
8+
9+
// These events come directly from the Exchange contract and are fired whenever
10+
// someone fills an order.
11+
@Entity({ name: 'otc_order_filled_events', schema: 'events' })
12+
export class OtcOrderFilledEvent extends Event {
13+
// The order hash.
14+
@Column({ name: 'order_hash' })
15+
public orderHash!: string;
16+
// The address of the maker.
17+
@Column({ name: 'maker_address' })
18+
public makerAddress!: string;
19+
// The address of the taker (may be null).
20+
@Column({ name: 'taker_address' })
21+
public takerAddress!: string;
22+
// The address of the maker token.
23+
@Column({ name: 'maker_token_address', type: 'varchar', nullable: true })
24+
public makerTokenAddress!: string | null;
25+
// The address of the taker token.
26+
@Column({ name: 'taker_token_address', type: 'varchar', nullable: true })
27+
public takerTokenAddress!: string | null;
28+
// The amount of the maker asset which was filled.
29+
@Column({ name: 'maker_token_filled_amount', type: 'numeric', transformer: bigNumberTransformer })
30+
public makerTokenFilledAmount!: BigNumber;
31+
// The amount of the taker asset which was filled.
32+
@Column({ name: 'taker_token_filled_amount', type: 'numeric', transformer: bigNumberTransformer })
33+
public takerTokenFilledAmount!: BigNumber;
34+
}

event-pipeline/src/ormconfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
EpochFinalizedEvent,
2626
RewardsPaidEvent,
2727
StakingProxyDeployment,
28+
OtcOrderFilledEvent,
2829
ERC20BridgeTransferEvent,
2930
TransformedERC20Event,
3031
TransactionExecutionEvent,
@@ -58,6 +59,7 @@ const entities = [
5859
EpochFinalizedEvent,
5960
RewardsPaidEvent,
6061
StakingProxyDeployment,
62+
OtcOrderFilledEvent,
6163
ERC20BridgeTransferEvent,
6264
TransformedERC20Event,
6365
TransactionExecutionEvent,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { assetDataUtils } from '@0x/order-utils';
2+
import { AssetProxyId } from '@0x/types';
3+
import { RawLogEntry } from 'ethereum-types';
4+
5+
import { OtcOrderFilledEvent } from '../../entities';
6+
import { convertAssetProxyIdToType } from '../../utils';
7+
import { parseEvent } from './parse_event';
8+
import { OTC_ORDER_FILLED_ABI } from '../../constants';
9+
10+
const abiCoder = require('web3-eth-abi');
11+
12+
/**
13+
* Parses raw event logs for a OTC Fill Event and returns an array of
14+
* OtcOrderFilledEvent entities.
15+
* @param eventLog Raw event log (e.g. returned from contract-wrappers).
16+
*/
17+
18+
export function parseOtcOrderFilledEvent(eventLog: RawLogEntry): OtcOrderFilledEvent {
19+
const otcOrderFillEvent = new OtcOrderFilledEvent();
20+
parseEvent(eventLog, otcOrderFillEvent);
21+
22+
const decodedLog = abiCoder.decodeLog(
23+
OTC_ORDER_FILLED_ABI.inputs,
24+
eventLog.data,
25+
eventLog.topics.slice(1, eventLog.topics.length),
26+
);
27+
28+
otcOrderFillEvent.orderHash = decodedLog.orderHash.toLowerCase();
29+
otcOrderFillEvent.makerAddress = decodedLog.maker.toLowerCase();
30+
otcOrderFillEvent.takerAddress = decodedLog.taker.toLowerCase();
31+
otcOrderFillEvent.makerTokenAddress = decodedLog.makerToken.toLowerCase();
32+
otcOrderFillEvent.takerTokenAddress = decodedLog.takerToken.toLowerCase();
33+
otcOrderFillEvent.makerTokenFilledAmount = decodedLog.makerTokenFilledAmount;
34+
otcOrderFillEvent.takerTokenFilledAmount = decodedLog.takerTokenFilledAmount;
35+
36+
return otcOrderFillEvent;
37+
}

event-pipeline/src/scripts/pull_and_save_events_by_topic.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
FillEvent,
1515
V4CancelEvent,
1616
ExpiredRfqOrderEvent,
17+
OtcOrderFilledEvent,
1718
} from '../entities';
1819

1920
import { ETHEREUM_RPC_URL, FIRST_SEARCH_BLOCK } from '../config';
@@ -36,6 +37,8 @@ import {
3637
NEW_BRIDGEFILL_BLOCK,
3738
FLASHWALLET_ADDRESS,
3839
SWAP_V3_EVENT_TOPIC,
40+
OTC_ORDER_FILLED_EVENT_TOPIC,
41+
OTC_ORDERS_FEATURE_START_BLOCK,
3942
} from '../constants';
4043

4144
import { parseTransformedERC20Event } from '../parsers/events/transformed_erc20_events';
@@ -54,6 +57,7 @@ import { parseFillEvent } from '../parsers/events/fill_events';
5457
import { parseNativeFillFromFillEvent } from '../parsers/events/fill_events';
5558
import { parseV4CancelEvent } from '../parsers/events/v4_cancel_events';
5659
import { parseExpiredRfqOrderEvent } from '../parsers/events/expired_rfq_order_events';
60+
import { parseOtcOrderFilledEvent } from '../parsers/events/otc_order_filled_events';
5761

5862
import { PullAndSaveEventsByTopic } from './utils/event_abi_utils';
5963

@@ -216,6 +220,18 @@ export class EventsByTopicScraper {
216220
parseExpiredRfqOrderEvent,
217221
{},
218222
),
223+
pullAndSaveEventsByTopic.getParseSaveEventsByTopic<OtcOrderFilledEvent>(
224+
connection,
225+
web3Source,
226+
latestBlockWithOffset,
227+
'OtcOrderFilledEvent',
228+
'otc_order_filled_events',
229+
OTC_ORDER_FILLED_EVENT_TOPIC,
230+
EXCHANGE_PROXY_ADDRESS,
231+
OTC_ORDERS_FEATURE_START_BLOCK,
232+
parseOtcOrderFilledEvent,
233+
{},
234+
),
219235
]);
220236

221237
const endTime = new Date().getTime();

0 commit comments

Comments
 (0)