Skip to content

Commit

Permalink
feat: erc20 contract no action (#908)
Browse files Browse the repository at this point in the history
* feat: erc20 contract no action

* refactor: review
  • Loading branch information
phamphong9981 authored Sep 24, 2024
1 parent 2a17c00 commit 9553e92
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
72 changes: 72 additions & 0 deletions migrations/evm/20240923064605_erc20_contract_no_action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Knex } from 'knex';
import { Erc20Activity } from '../../src/models';
import { ERC20_ACTION } from '../../src/services/evm/erc20_handler';
import _ from 'lodash';

export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable('erc20_contract', (table) => {
table.jsonb('total_actions').defaultTo('{}');
});
await knex.raw(`set statement_timeout to 0`);
const [totalTransfer, totalApproval, totalDeposit, totalWithdrawal] =
await Promise.all([
_.keyBy(
await Erc20Activity.query(knex)
.where('action', ERC20_ACTION.TRANSFER)
.groupBy('erc20_activity.erc20_contract_address')
.select('erc20_activity.erc20_contract_address')
.count('* as transfer'),
'erc20_contract_address'
),
_.keyBy(
await Erc20Activity.query(knex)
.where('action', ERC20_ACTION.APPROVAL)
.groupBy('erc20_activity.erc20_contract_address')
.select('erc20_activity.erc20_contract_address')
.count('* as approval'),
'erc20_contract_address'
),
_.keyBy(
await Erc20Activity.query(knex)
.where('action', ERC20_ACTION.DEPOSIT)
.groupBy('erc20_activity.erc20_contract_address')
.select('erc20_activity.erc20_contract_address')
.count('* as deposit'),
'erc20_contract_address'
),
_.keyBy(
await Erc20Activity.query(knex)
.where('action', ERC20_ACTION.WITHDRAWAL)
.groupBy('erc20_activity.erc20_contract_address')
.select('erc20_activity.erc20_contract_address')
.count('* as withdrawal'),
'erc20_contract_address'
),
]);
const totalAction = _.merge(
totalTransfer,
totalApproval,
totalDeposit,
totalWithdrawal
);
const erc20ContractsAddr = Object.keys(totalAction);
if (erc20ContractsAddr.length > 0) {
const stringListUpdates = erc20ContractsAddr
.map(
(addr) =>
`('${addr}', '${JSON.stringify(
_.omit(totalAction[addr], 'erc20_contract_address')
)}'::jsonb)`
)
.join(',');
await knex.raw(
`UPDATE erc20_contract SET total_actions = temp.total_actions from (VALUES ${stringListUpdates}) as temp(address, total_actions) where temp.address = erc20_contract.address`
);
}
}

export async function down(knex: Knex): Promise<void> {
await knex.schema.alterTable('erc20_contract', (table) => {
table.dropColumn('total_actions');
});
}
2 changes: 2 additions & 0 deletions src/models/erc20_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export class Erc20Contract extends BaseModel {

last_updated_height!: number;

total_actions!: any;

static get tableName() {
return 'erc20_contract';
}
Expand Down
5 changes: 5 additions & 0 deletions src/services/evm/erc20_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ export class Erc20Handler {
) {
this.handlerErc20Transfer(erc20Activity);
}
this.erc20Contracts[erc20Activity.erc20_contract_address].total_actions[
erc20Activity.action
] =
(this.erc20Contracts[erc20Activity.erc20_contract_address]
.total_actions[erc20Activity.action] || 0) + 1;
});
}

Expand Down
30 changes: 30 additions & 0 deletions test/unit/services/evm/erc20.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,20 @@ export class Erc20Test {
'0x21f905f14a26c5b35e43e1bfbcf8ff395e453d6497a0ce0a0c3cd7814ec0ba03',
evm_tx_id: this.evmTx.id,
},
{
id: 3,
evm_event_id: this.evmEvent.id,
sender: '0xDF587daaC47ae7B5586E34bCdb23d0b900b18a6C',
action: 'approval',
erc20_contract_address: this.evmSmartContract.address,
amount: '2211',
from: this.account2.evm_address,
to: this.account3.evm_address,
height: this.blockCheckpoints[0].height + 1,
tx_hash:
'0x21f905f14a26c5b35e43e1bfbcf8ff395e453d6497a0ce0a0c3cd7814ec0ba03',
evm_tx_id: this.evmTx.id,
},
];
await Erc20Activity.query().insert(erc20Activities);
await this.erc20Service.handleErc20Balance();
Expand All @@ -247,6 +261,14 @@ export class Erc20Test {
accountBalances[`${this.account3.id}_${this.evmSmartContract.address}`]
.amount
).toEqual(`${BigInt(erc20Activities[1].amount).toString()}`);
const erc20Contract = await Erc20Contract.query()
.where('address', this.evmSmartContract.address)
.first()
.throwIfNotFound();
expect(erc20Contract.total_actions).toEqual({
transfer: erc20Activities.length - 1,
approval: 1,
});
}

@Test('handle erc20 balance with missing account')
Expand Down Expand Up @@ -344,5 +366,13 @@ export class Erc20Test {
accountBalances[`${this.account3.id}_${this.evmSmartContract.address}`]
.amount
).toEqual(`${BigInt(erc20Activities[1].amount).toString()}`);
const erc20Contract = await Erc20Contract.query()
.where('address', this.evmSmartContract.address)
.first()
.throwIfNotFound();
expect(erc20Contract.total_actions).toEqual({
transfer: erc20Activities.length + 2,
approval: 1,
});
}
}

0 comments on commit 9553e92

Please sign in to comment.