diff --git a/ethereum-steth/package.json b/ethereum-steth/package.json index 4d6883d8c..7e24abeab 100644 --- a/ethereum-steth/package.json +++ b/ethereum-steth/package.json @@ -39,10 +39,10 @@ "stake": "forta-agent stake", "test": "jest", "generate-types": "typechain --target=ethers-v5 --out-dir=./src/generated ./src/abi/*", - "eslint:lint": "eslint ./src ./tests", - "eslint:format": "eslint ./src ./tests --fix", - "prettier:check": "prettier --check ./src ./tests", - "prettier:format": "prettier --write ./src ./tests README.md", + "eslint:lint": "eslint ./src", + "eslint:format": "eslint ./src --fix", + "prettier:check": "prettier --check ./src", + "prettier:format": "prettier --write ./src README.md", "lint": "yarn run prettier:check && yarn run eslint:lint", "format": "yarn run eslint:format && yarn run prettier:format", "postinstall": "yarn generate-types" diff --git a/ethereum-steth/src/agent.ts b/ethereum-steth/src/agent.ts index 21c28941b..a4b5881b2 100644 --- a/ethereum-steth/src/agent.ts +++ b/ethereum-steth/src/agent.ts @@ -19,6 +19,7 @@ import { TransactionEvent } from 'forta-agent/dist/sdk/transaction.event' import { Metadata } from './entity/metadata' import Version from './utils/version' import { ETH_DECIMALS } from './utils/constants' +import { BlockDto } from './entity/events' export function initialize(): Initialize { const metadata: Metadata = { @@ -138,11 +139,17 @@ export const handleBlock = (): HandleBlock => { out.push(...findingsAsync) } + const blockDto: BlockDto = { + number: blockEvent.block.number, + timestamp: blockEvent.block.timestamp, + parentHash: blockEvent.block.parentHash, + } + const [bufferedEthFindings, withdrawalsFindings, gateSealFindings, vaultFindings] = await Promise.all([ - app.StethOperationSrv.handleBlock(blockEvent), - app.WithdrawalsSrv.handleBlock(blockEvent), - app.GateSealSrv.handleBlock(blockEvent), - app.VaultSrv.handleBlock(blockEvent), + app.StethOperationSrv.handleBlock(blockDto), + app.WithdrawalsSrv.handleBlock(blockDto), + app.GateSealSrv.handleBlock(blockDto), + app.VaultSrv.handleBlock(blockDto), ]) out.push(...bufferedEthFindings, ...withdrawalsFindings, ...gateSealFindings, ...vaultFindings) diff --git a/ethereum-steth/src/app.ts b/ethereum-steth/src/app.ts index 892df036c..dcd6010c7 100644 --- a/ethereum-steth/src/app.ts +++ b/ethereum-steth/src/app.ts @@ -82,12 +82,19 @@ export class App { return knex(config) } - public static async getInstance(): Promise { + public static async getInstance(rpcUrl?: string): Promise { if (!App.instance) { const db = App.getConnection() + const drpcProvider = `https://eth.drpc.org` + const mainnet = 1 + const drcpClient = new ethers.providers.JsonRpcProvider(drpcProvider, mainnet) + const etherscanKey = Buffer.from('SVZCSjZUSVBXWUpZSllXSVM0SVJBSlcyNjRITkFUUjZHVQ==', 'base64').toString('utf-8') - const ethersProvider = getEthersProvider() + let ethersProvider = getEthersProvider() + if (rpcUrl !== undefined) { + ethersProvider = drcpClient + } ethersProvider.formatter = new FormatterWithEIP1898() const etherscanProvider = new ethers.providers.EtherscanProvider(ethersProvider.network, etherscanKey) @@ -96,10 +103,6 @@ export class App { const lidoContact = Lido__factory.connect(address.LIDO_STETH_ADDRESS, ethersProvider) - const drpcProvider = `https://eth.drpc.org` - - const mainnet = 1 - const drcpClient = new ethers.providers.JsonRpcProvider(drpcProvider, mainnet) const wdQueueContact = WithdrawalQueueERC721__factory.connect(address.WITHDRAWALS_QUEUE_ADDRESS, drcpClient) const gateSealContact = GateSeal__factory.connect(address.GATE_SEAL_DEFAULT_ADDRESS, ethersProvider) diff --git a/ethereum-steth/src/clients/eth_provider.spec.ts b/ethereum-steth/src/clients/eth_provider.spec.ts index bc916a79d..16cc40aa3 100644 --- a/ethereum-steth/src/clients/eth_provider.spec.ts +++ b/ethereum-steth/src/clients/eth_provider.spec.ts @@ -1,9 +1,19 @@ import { App } from '../app' import * as E from 'fp-ts/Either' -import { Address } from '../utils/constants' +import { Address, ETH_DECIMALS } from '../utils/constants' import { GateSeal } from '../entity/gate_seal' +import { JsonRpcProvider } from '@ethersproject/providers' +import { ethers } from 'forta-agent' describe('eth provider tests', () => { + let ethProvider: JsonRpcProvider + const mainnet = 1 + const drpcProvider = 'https://eth.drpc.org/' + + beforeAll(async () => { + ethProvider = new ethers.providers.JsonRpcProvider(drpcProvider, mainnet) + }) + test('getWithdrawalStatuses should return 1750 withdrawal statuses', async () => { const app = await App.getInstance() @@ -40,4 +50,18 @@ describe('eth provider tests', () => { expect(resp.right).toEqual(expected) }, 120_000) + + test('getBalanceByBlockHash is ok', async () => { + const app = await App.getInstance(drpcProvider) + + const blockNumber = 19_140_476 + const block = await ethProvider.getBlock(blockNumber) + + const resp = await app.ethClient.getBalanceByBlockHash(Address.WITHDRAWALS_QUEUE_ADDRESS, block.parentHash) + if (E.isLeft(resp)) { + throw resp.left.message + } + + expect(resp.right.dividedBy(ETH_DECIMALS).toNumber()).toEqual(16_619.29059680177) + }, 120_000) }) diff --git a/ethereum-steth/src/clients/eth_provider.ts b/ethereum-steth/src/clients/eth_provider.ts index 7ade9f5df..a16cc1e77 100644 --- a/ethereum-steth/src/clients/eth_provider.ts +++ b/ethereum-steth/src/clients/eth_provider.ts @@ -182,9 +182,7 @@ export class ETHProvider implements IGateSealClient, IStethClient, IVaultClient, try { const out = await retryAsync( async (): Promise => { - return await this.jsonRpcProvider.getBalance(address, { - blockHash: blockHash, - } as never) + return await this.jsonRpcProvider.getBalance(address, blockHash) }, { delay: DELAY_IN_500MS, maxTry: ATTEMPTS_5 }, ) diff --git a/ethereum-steth/src/entity/events.ts b/ethereum-steth/src/entity/events.ts index d7816035c..142d80418 100644 --- a/ethereum-steth/src/entity/events.ts +++ b/ethereum-steth/src/entity/events.ts @@ -9,3 +9,9 @@ export type EventOfNotice = { severity: FindingSeverity type: FindingType } + +export type BlockDto = { + number: number + timestamp: number + parentHash: string +} diff --git a/ethereum-steth/src/generated/.gitignore b/ethereum-steth/src/generated/.gitignore new file mode 100644 index 000000000..f59ec20aa --- /dev/null +++ b/ethereum-steth/src/generated/.gitignore @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/ethereum-steth/src/services/gate-seal/GateSeal.srv.ts b/ethereum-steth/src/services/gate-seal/GateSeal.srv.ts index 17df25bae..ebe88e813 100644 --- a/ethereum-steth/src/services/gate-seal/GateSeal.srv.ts +++ b/ethereum-steth/src/services/gate-seal/GateSeal.srv.ts @@ -8,7 +8,8 @@ import { etherscanAddress } from '../../utils/string' import { Logger } from 'winston' import { networkAlert } from '../../utils/errors' import { IGateSealClient } from './contract' -import { BlockEvent, filterLog, Finding, FindingSeverity, FindingType } from 'forta-agent' +import { filterLog, Finding, FindingSeverity, FindingType } from 'forta-agent' +import { BlockDto } from '../../entity/events' const ONE_HOUR = 60 * 60 const ONE_DAY = 24 * ONE_HOUR @@ -102,13 +103,13 @@ export class GateSealSrv { return this.name } - public async handleBlock(blockEvent: BlockEvent): Promise { + public async handleBlock(blockDto: BlockDto): Promise { const start = new Date().getTime() const findings: Finding[] = [] const [pauseRoleFindings, expiryGateSealFindings] = await Promise.all([ - this.handlePauseRole(blockEvent), - this.handleExpiryGateSeal(blockEvent), + this.handlePauseRole(blockDto), + this.handleExpiryGateSeal(blockDto), ]) findings.push(...pauseRoleFindings, ...expiryGateSealFindings) @@ -117,14 +118,14 @@ export class GateSealSrv { return findings } - public async handlePauseRole(blockEvent: BlockEvent): Promise { + public async handlePauseRole(blockDto: BlockDto): Promise { const out: Finding[] = [] if (this.gateSealAddress === undefined) { return [] } - const currentBlockTimestamp = blockEvent.block.timestamp - const status = await this.ethProvider.checkGateSeal(blockEvent.block.number, this.gateSealAddress) + const currentBlockTimestamp = blockDto.timestamp + const status = await this.ethProvider.checkGateSeal(blockDto.number, this.gateSealAddress) if (E.isLeft(status)) { if (status.left === GateSealExpiredErr) { const f = Finding.fromObject({ @@ -182,13 +183,13 @@ export class GateSealSrv { return out } - public async handleExpiryGateSeal(blockEvent: BlockEvent): Promise { + public async handleExpiryGateSeal(blockDto: BlockDto): Promise { if (this.gateSealAddress === undefined) { return [] } - const currentBlockTimestamp = blockEvent.block.timestamp - const expiryTimestamp = await this.ethProvider.getExpiryTimestamp(blockEvent.block.number) + const currentBlockTimestamp = blockDto.timestamp + const expiryTimestamp = await this.ethProvider.getExpiryTimestamp(blockDto.number) if (E.isLeft(expiryTimestamp)) { return [ diff --git a/ethereum-steth/src/services/gate-seal/gate-seal.spec.ts b/ethereum-steth/src/services/gate-seal/gate-seal.spec.ts index 5cb722268..1b191c045 100644 --- a/ethereum-steth/src/services/gate-seal/gate-seal.spec.ts +++ b/ethereum-steth/src/services/gate-seal/gate-seal.spec.ts @@ -1,12 +1,12 @@ import { Finding, FindingSeverity, FindingType, getEthersProvider } from 'forta-agent' -import { etherBlockToFortaBlockEvent } from '../../../tests/e2e/utils' import { App } from '../../app' import { Address } from '../../utils/constants' import * as E from 'fp-ts/Either' import { GateSeal } from '../../entity/gate_seal' import { expect } from '@jest/globals' +import { BlockDto } from '../../entity/events' -describe('GateSeal srv e2e tests', () => { +describe('GateSeal srv functional tests', () => { const ethProvider = getEthersProvider() test('handle pause role true', async () => { @@ -14,6 +14,11 @@ describe('GateSeal srv e2e tests', () => { const blockNumber = 19113580 const block = await ethProvider.getBlock(blockNumber) + const blockDto: BlockDto = { + number: block.number, + timestamp: block.timestamp, + parentHash: block.parentHash, + } const initErr = await app.GateSealSrv.initialize(blockNumber) if (initErr instanceof Error) { @@ -33,8 +38,7 @@ describe('GateSeal srv e2e tests', () => { } expect(status.right).toEqual(expected) - const blockEvent = etherBlockToFortaBlockEvent(block) - const result = await app.GateSealSrv.handlePauseRole(blockEvent) + const result = await app.GateSealSrv.handlePauseRole(blockDto) expect(result.length).toEqual(0) }, 120_000) @@ -51,8 +55,12 @@ describe('GateSeal srv e2e tests', () => { const neededBlock = 19_172_615 const block = await ethProvider.getBlock(neededBlock) - const blockEvent = etherBlockToFortaBlockEvent(block) - const result = await app.GateSealSrv.handleExpiryGateSeal(blockEvent) + const blockDto: BlockDto = { + number: block.number, + timestamp: block.timestamp, + parentHash: block.parentHash, + } + const result = await app.GateSealSrv.handleExpiryGateSeal(blockDto) const expected = Finding.fromObject({ alertId: 'GATE-SEAL-IS-ABOUT-TO-BE-EXPIRED', diff --git a/ethereum-steth/tests/e2e/agent-steth-ops.spec.ts b/ethereum-steth/src/services/steth_operation/StethOperation.functional.spec.ts similarity index 92% rename from ethereum-steth/tests/e2e/agent-steth-ops.spec.ts rename to ethereum-steth/src/services/steth_operation/StethOperation.functional.spec.ts index ab30b8e00..89cd2b5d5 100644 --- a/ethereum-steth/tests/e2e/agent-steth-ops.spec.ts +++ b/ethereum-steth/src/services/steth_operation/StethOperation.functional.spec.ts @@ -1,12 +1,13 @@ import { ethers, Finding, FindingSeverity, FindingType, getEthersProvider, Network, Transaction } from 'forta-agent' -import { App } from '../../src/app' +import { App } from '../../app' import { JsonRpcProvider } from '@ethersproject/providers' -import { createTransactionEvent, etherBlockToFortaBlockEvent } from './utils' +import { createTransactionEvent } from '../../utils/forta' import BigNumber from 'bignumber.js' +import { BlockDto } from '../../entity/events' const TEST_TIMEOUT = 60_000 // ms -describe('agent-steth-ops e2e tests', () => { +describe('Steth.srv functional tests', () => { let ethProvider: JsonRpcProvider beforeAll(async () => { @@ -14,15 +15,19 @@ describe('agent-steth-ops e2e tests', () => { }) test( - 'should process block with low staking limit (10%)', + 'LOW-STAKING-LIMIT', async () => { const app = await App.getInstance() - const blockNumber = 16704075 + const blockNumber = 16_704_075 const block = await ethProvider.getBlock(blockNumber) - const blockEvent = etherBlockToFortaBlockEvent(block) + const blockDto: BlockDto = { + number: block.number, + timestamp: block.timestamp, + parentHash: block.parentHash, + } - const result = await app.StethOperationSrv.handleBlock(blockEvent) + const result = await app.StethOperationSrv.handleBlock(blockDto) const expected = Finding.fromObject({ alertId: 'LOW-STAKING-LIMIT', @@ -43,15 +48,19 @@ describe('agent-steth-ops e2e tests', () => { ) test( - 'should process block with huge buffered ETH amount and low deposit executor balance', + 'LOW-DEPOSIT-EXECUTOR-BALANCE', async () => { const app = await App.getInstance() const blockNumber = 17241600 const block = await ethProvider.getBlock(blockNumber) - const blockEvent = etherBlockToFortaBlockEvent(block) + const blockDto: BlockDto = { + number: block.number, + timestamp: block.timestamp, + parentHash: block.parentHash, + } - const result = await app.StethOperationSrv.handleDepositExecutorBalance(blockEvent.block.number, block.timestamp) + const result = await app.StethOperationSrv.handleDepositExecutorBalance(blockDto.number, blockDto.timestamp) const expected = Finding.fromObject({ alertId: 'LOW-DEPOSIT-EXECUTOR-BALANCE', @@ -127,7 +136,7 @@ describe('agent-steth-ops e2e tests', () => { ) test( - 'should process tx with transferred ownership of Insurance fund', + 'Insurance fund', async () => { const app = await App.getInstance() const txHash = '0x91c7c2f33faf3b5fb097138c1d49c1d4e83f99e1c3b346b3cad35a5928c03b3a' diff --git a/ethereum-steth/src/services/steth_operation/StethOperation.srv.ts b/ethereum-steth/src/services/steth_operation/StethOperation.srv.ts index d100dfab6..651d3a2bd 100644 --- a/ethereum-steth/src/services/steth_operation/StethOperation.srv.ts +++ b/ethereum-steth/src/services/steth_operation/StethOperation.srv.ts @@ -1,13 +1,14 @@ import { StethOperationCache } from './StethOperation.cache' import { ETH_DECIMALS } from '../../utils/constants' import * as E from 'fp-ts/Either' -import { BlockEvent, Finding, FindingSeverity, FindingType } from 'forta-agent' +import { Finding, FindingSeverity, FindingType } from 'forta-agent' import { EventOfNotice } from '../../entity/events' import { elapsedTime } from '../../utils/time' import { IStethClient, TransactionEventContract } from './contracts' import { Logger } from 'winston' import { alertId_token_rebased } from '../../utils/events/lido_events' import { networkAlert } from '../../utils/errors' +import { BlockDto } from '../../entity/events' // Formula: (60 * 60 * 72) / 13 = 19_938 const HISTORY_BLOCK_OFFSET: number = Math.floor((60 * 60 * 72) / 13) @@ -101,15 +102,15 @@ export class StethOperationSrv { return this.name } - public async handleBlock(blockEvent: BlockEvent) { + public async handleBlock(blockDto: BlockDto) { const start = new Date().getTime() const findings: Finding[] = [] const [bufferedEthFindings, depositorBalanceFindings, stakingLimitFindings] = await Promise.all([ - this.handleBufferedEth(blockEvent.block.number, blockEvent.block.timestamp), - this.handleDepositExecutorBalance(blockEvent.block.number, blockEvent.block.timestamp), - this.handleStakingLimit(blockEvent.block.number, blockEvent.block.timestamp), - this.handleShareRateChange(blockEvent.block.number), + this.handleBufferedEth(blockDto.number, blockDto.timestamp), + this.handleDepositExecutorBalance(blockDto.number, blockDto.timestamp), + this.handleStakingLimit(blockDto.number, blockDto.timestamp), + this.handleShareRateChange(blockDto.number), ]) findings.push(...bufferedEthFindings, ...depositorBalanceFindings, ...stakingLimitFindings) diff --git a/ethereum-steth/src/services/steth_operation/StethOperation.spec.ts b/ethereum-steth/src/services/steth_operation/StethOperation.unit.spec.ts similarity index 100% rename from ethereum-steth/src/services/steth_operation/StethOperation.spec.ts rename to ethereum-steth/src/services/steth_operation/StethOperation.unit.spec.ts diff --git a/ethereum-steth/src/services/vault/Vault.srv.ts b/ethereum-steth/src/services/vault/Vault.srv.ts index f3efa0583..5ba6454c2 100644 --- a/ethereum-steth/src/services/vault/Vault.srv.ts +++ b/ethereum-steth/src/services/vault/Vault.srv.ts @@ -1,7 +1,7 @@ import BigNumber from 'bignumber.js' import { ETH_DECIMALS } from '../../utils/constants' import * as E from 'fp-ts/Either' -import { BlockEvent, Finding, FindingSeverity, FindingType } from 'forta-agent' +import { Finding, FindingSeverity, FindingType } from 'forta-agent' import { elapsedTime } from '../../utils/time' import { toEthString } from '../../utils/string' import { ETHDistributedEvent } from '../../generated/Lido' @@ -10,6 +10,7 @@ import { TRANSFER_SHARES_EVENT } from '../../utils/events/vault_events' import { Logger } from 'winston' import { networkAlert } from '../../utils/errors' import { IVaultClient } from './contract' +import { BlockDto } from '../../entity/events' const WITHDRAWAL_VAULT_BALANCE_BLOCK_INTERVAL = 100 const WITHDRAWAL_VAULT_BALANCE_DIFF_INFO = ETH_DECIMALS.times(1000) @@ -52,14 +53,14 @@ export class VaultSrv { return this.name } - public async handleBlock(blockEvent: BlockEvent) { + public async handleBlock(blockDto: BlockDto) { const start = new Date().getTime() const findings: Finding[] = [] - const currentBlock = blockEvent.block.number + const currentBlock = blockDto.number const prevBlockWithdrawalVaultBalance = await this.ethProvider.getBalanceByBlockHash( this.withdrawalsVaultAddress, - blockEvent.block.parentHash, + blockDto.parentHash, ) if (E.isLeft(prevBlockWithdrawalVaultBalance)) { return [ @@ -72,7 +73,7 @@ export class VaultSrv { } const prevBlockElVaultBalance = await this.ethProvider.getBalanceByBlockHash( this.elRewardsVaultAddress, - blockEvent.block.parentHash, + blockDto.parentHash, ) if (E.isLeft(prevBlockElVaultBalance)) { return [ diff --git a/ethereum-steth/tests/e2e/agent-vaults.spec.ts b/ethereum-steth/src/services/vault/Vaults.functional.spec.ts similarity index 68% rename from ethereum-steth/tests/e2e/agent-vaults.spec.ts rename to ethereum-steth/src/services/vault/Vaults.functional.spec.ts index c9d6e8af4..13b5e2e20 100644 --- a/ethereum-steth/tests/e2e/agent-vaults.spec.ts +++ b/ethereum-steth/src/services/vault/Vaults.functional.spec.ts @@ -1,18 +1,24 @@ -import { App } from '../../src/app' +import { App } from '../../app' import { Finding, FindingSeverity, FindingType, getEthersProvider } from 'forta-agent' -import { etherBlockToFortaBlockEvent } from './utils' +import { BlockDto } from '../../entity/events' -describe('agent-vaults e2e tests', () => { +describe('Vaults.srv functional tests', () => { const ethProvider = getEthersProvider() - test('should process block with high EL vault balance difference', async () => { + test('EL-VAULT-BALANCE-CHANGE', async () => { const app = await App.getInstance() - const blockNumber = 17007842 - const block = await ethProvider.getBlock(17007842) + const blockNumber = 17_007_842 + const block = await ethProvider.getBlock(blockNumber) app.VaultSrv.initialize(blockNumber) - const blockEvent = etherBlockToFortaBlockEvent(block) + + const blockEvent: BlockDto = { + number: block.number, + timestamp: block.timestamp, + parentHash: block.parentHash, + } + const result = await app.VaultSrv.handleBlock(blockEvent) const expected = Finding.fromObject({ diff --git a/ethereum-steth/tests/e2e/withdrawals.spec.ts b/ethereum-steth/src/services/withdrawals/Withdrawals.functional.spec.ts similarity index 86% rename from ethereum-steth/tests/e2e/withdrawals.spec.ts rename to ethereum-steth/src/services/withdrawals/Withdrawals.functional.spec.ts index 3d4a1bb58..a9746f280 100644 --- a/ethereum-steth/tests/e2e/withdrawals.spec.ts +++ b/ethereum-steth/src/services/withdrawals/Withdrawals.functional.spec.ts @@ -1,15 +1,15 @@ import { ethers, filterLog, getEthersProvider, Network, Transaction } from 'forta-agent' -import { App, Container } from '../../src/app' -import { createTransactionEvent } from './utils' -import { WITHDRAWAL_QUEUE_WITHDRAWAL_CLAIMED_EVENT } from '../../src/utils/events/withdrawals_events' -import { Address } from '../../src/utils/constants' +import { App, Container } from '../../app' +import { createTransactionEvent } from '../../utils/forta' +import { WITHDRAWAL_QUEUE_WITHDRAWAL_CLAIMED_EVENT } from '../../utils/events/withdrawals_events' +import { Address } from '../../utils/constants' import BigNumber from 'bignumber.js' -import { WithdrawalsRepo } from '../../src/services/withdrawals/Withdrawals.repo' +import { WithdrawalsRepo } from './Withdrawals.repo' import * as E from 'fp-ts/Either' const timeout = 120_000 -describe('Withdrawals srv e2e tests', () => { +describe('Withdrawals.srv functional tests', () => { const ethProvider = getEthersProvider() let app: Container let repo: WithdrawalsRepo diff --git a/ethereum-steth/src/services/withdrawals/Withdrawals.srv.ts b/ethereum-steth/src/services/withdrawals/Withdrawals.srv.ts index e010ffcdb..a4eb77c1b 100644 --- a/ethereum-steth/src/services/withdrawals/Withdrawals.srv.ts +++ b/ethereum-steth/src/services/withdrawals/Withdrawals.srv.ts @@ -1,6 +1,6 @@ import BigNumber from 'bignumber.js' import { WithdrawalsCache } from './Withdrawals.cache' -import { BlockEvent, filterLog, Finding, FindingSeverity, FindingType } from 'forta-agent' +import { filterLog, Finding, FindingSeverity, FindingType } from 'forta-agent' import * as E from 'fp-ts/Either' import { ETH_DECIMALS } from '../../utils/constants' import { elapsedTime, formatDelay } from '../../utils/time' @@ -20,6 +20,7 @@ import { WithdrawalRequest } from '../../entity/withdrawal_request' import { WithdrawalsRepo } from './Withdrawals.repo' import { dbAlert, networkAlert } from '../../utils/errors' import { IWithdrawalsClient } from './contract' +import { BlockDto } from '../../entity/events' const ONE_HOUR = 60 * 60 const ONE_DAY = ONE_HOUR * 24 @@ -131,11 +132,11 @@ export class WithdrawalsSrv { return this.name } - async handleBlock(blockEvent: BlockEvent): Promise { + async handleBlock(blockDto: BlockDto): Promise { const start = new Date().getTime() const findings: Finding[] = [] - const chainLastRequestId = await this.ethProvider.getWithdrawalLastRequestId(blockEvent.block.number) + const chainLastRequestId = await this.ethProvider.getWithdrawalLastRequestId(blockDto.number) if (E.isLeft(chainLastRequestId)) { return [ networkAlert( @@ -165,7 +166,7 @@ export class WithdrawalsSrv { requestIds.push(i) } - const requests = await this.ethProvider.getWithdrawalStatuses(requestIds, blockEvent.block.number) + const requests = await this.ethProvider.getWithdrawalStatuses(requestIds, blockDto.number) if (E.isLeft(requests)) { return [ networkAlert( @@ -188,12 +189,12 @@ export class WithdrawalsSrv { } } - if (blockEvent.block.number % BLOCK_CHECK_INTERVAL === 0) { + if (blockDto.number % BLOCK_CHECK_INTERVAL === 0) { const [queueOnParWithStakeLimitFindings, unfinalizedRequestNumberFindings, unclaimedRequestsFindings] = await Promise.all([ - this.handleQueueOnParWithStakeLimit(blockEvent), - this.handleUnfinalizedRequestNumber(blockEvent), - this.handleUnclaimedRequests(blockEvent), + this.handleQueueOnParWithStakeLimit(blockDto), + this.handleUnfinalizedRequestNumber(blockDto), + this.handleUnclaimedRequests(blockDto), ]) findings.push( @@ -230,8 +231,8 @@ export class WithdrawalsSrv { return out } - public async handleQueueOnParWithStakeLimit(blockEvent: BlockEvent): Promise { - const blockTimestamp = blockEvent.block.timestamp + public async handleQueueOnParWithStakeLimit(blockDto: BlockDto): Promise { + const blockTimestamp = blockDto.timestamp if ( blockTimestamp - this.cache.getLastQueueOnParStakeLimitAlertTimestamp() <= @@ -240,7 +241,7 @@ export class WithdrawalsSrv { return [] } - const stakeLimitFullInfo = await this.ethProvider.getStakingLimitInfo(blockEvent.block.number) + const stakeLimitFullInfo = await this.ethProvider.getStakingLimitInfo(blockDto.number) if (E.isLeft(stakeLimitFullInfo)) { return [ networkAlert( @@ -251,7 +252,7 @@ export class WithdrawalsSrv { ] } - const unfinalizedStETH = await this.ethProvider.getUnfinalizedStETH(blockEvent.block.number) + const unfinalizedStETH = await this.ethProvider.getUnfinalizedStETH(blockDto.number) if (E.isLeft(unfinalizedStETH)) { return [ networkAlert( @@ -290,8 +291,8 @@ export class WithdrawalsSrv { return findings } - public async handleUnfinalizedRequestNumber(blockEvent: BlockEvent): Promise { - const currentBlockTimestamp = blockEvent.block.timestamp + public async handleUnfinalizedRequestNumber(blockDto: BlockDto): Promise { + const currentBlockTimestamp = blockDto.timestamp let unfinalizedStETH = new BigNumber(0) @@ -319,7 +320,7 @@ export class WithdrawalsSrv { } if (currentBlockTimestamp >= lastFinalizedRequest.right.timestamp) { - const unfinalizedStETHraw = await this.ethProvider.getUnfinalizedStETH(blockEvent.block.number) + const unfinalizedStETHraw = await this.ethProvider.getUnfinalizedStETH(blockDto.number) if (E.isLeft(unfinalizedStETHraw)) { return [ networkAlert( @@ -380,9 +381,9 @@ export class WithdrawalsSrv { return out } - public async handleUnclaimedRequests(blockEvent: BlockEvent): Promise { + public async handleUnclaimedRequests(blockDto: BlockDto): Promise { const out: Finding[] = [] - const currentBlockTimestamp = blockEvent.block.timestamp + const currentBlockTimestamp = blockDto.timestamp const outdatedClaimedReqIds: number[] = [] let unclaimedStETH = new BigNumber(0) @@ -400,7 +401,7 @@ export class WithdrawalsSrv { } const unclaimedRequestsStatuses = await this.ethProvider.getWithdrawalStatuses( unclaimedReqIds.right, - blockEvent.block.number, + blockDto.number, ) if (E.isLeft(unclaimedRequestsStatuses)) { return [ @@ -484,10 +485,7 @@ export class WithdrawalsSrv { currentBlockTimestamp - this.cache.getLastUnclaimedMoreThanBalanceAlertTimestamp() > UNCLAIMED_REQUESTS_MORE_THAN_BALANCE_TRIGGER_EVERY ) { - const withdrawalQueueBalance = await this.ethProvider.getBalance( - this.withdrawalsQueueAddress, - blockEvent.block.number, - ) + const withdrawalQueueBalance = await this.ethProvider.getBalance(this.withdrawalsQueueAddress, blockDto.number) if (E.isLeft(withdrawalQueueBalance)) { return [ networkAlert( diff --git a/ethereum-steth/src/services/withdrawals/withdrawals.repo.spec.ts b/ethereum-steth/src/services/withdrawals/withdrawals.repo.spec.ts index 10fb96adb..b620fc5af 100644 --- a/ethereum-steth/src/services/withdrawals/withdrawals.repo.spec.ts +++ b/ethereum-steth/src/services/withdrawals/withdrawals.repo.spec.ts @@ -7,7 +7,7 @@ import * as E from 'fp-ts/Either' const timeout = 120_000 -describe('Withdrawals repo e2e tests', () => { +describe('Withdrawals repo tests', () => { let app: Container let repo: WithdrawalsRepo diff --git a/ethereum-steth/tests/e2e/utils.ts b/ethereum-steth/src/utils/forta.ts similarity index 78% rename from ethereum-steth/tests/e2e/utils.ts rename to ethereum-steth/src/utils/forta.ts index 1fccfdb19..297ba4acb 100644 --- a/ethereum-steth/tests/e2e/utils.ts +++ b/ethereum-steth/src/utils/forta.ts @@ -1,38 +1,10 @@ -import { Block as EtherBlock } from '@ethersproject/abstract-provider' -import { Block, BlockEvent, EventType, Network, Trace } from 'forta-agent' +import { EventType, Trace } from 'forta-agent' import { formatAddress, isZeroAddress } from 'forta-agent/dist/cli/utils' import { TransactionEvent } from 'forta-agent/dist/sdk/transaction.event' import { getContractAddress } from 'ethers/lib/utils' import { JsonRpcBlock, JsonRpcTransaction } from 'forta-agent/dist/cli/utils/get.block.with.transactions' import { JsonRpcLog } from 'forta-agent/dist/cli/utils/get.transaction.receipt' -export function etherBlockToFortaBlockEvent(block: EtherBlock): BlockEvent { - const blok: Block = { - difficulty: block.difficulty.toString(), - extraData: block.extraData, - gasLimit: block.gasLimit.toString(), - gasUsed: block.gasUsed.toString(), - hash: block.hash, - logsBloom: '', - miner: formatAddress(block.miner), - mixHash: '', - nonce: block.nonce, - number: block.number, - parentHash: block.parentHash, - receiptsRoot: '', - sha3Uncles: '', - size: '', - stateRoot: '', - timestamp: block.timestamp, - totalDifficulty: block.difficulty.toString(), - transactions: block.transactions, - transactionsRoot: '', - uncles: [], - } - - return new BlockEvent(EventType.BLOCK, Network.MAINNET, blok) -} - export function createTransactionEvent( transaction: JsonRpcTransaction, block: JsonRpcBlock, diff --git a/ethereum-steth/tests/.gitignore b/ethereum-steth/tests/.gitignore deleted file mode 100644 index d7d2a035e..000000000 --- a/ethereum-steth/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -custom_test.spec.ts