From b15400c2410a97feef8d7d15393b4d4beb79c6a1 Mon Sep 17 00:00:00 2001 From: Artyom Veremeenko Date: Tue, 28 May 2024 15:16:20 +0300 Subject: [PATCH] fix(multiple bots): unify address format in event filtering to prevent possible incorrect logic if a hardcoded address is specified in checksum format --- l2-bridge-arbitrum/src/agent-bridge-watcher.ts | 12 +++--------- l2-bridge-arbitrum/src/agent-governance.ts | 12 +++--------- l2-bridge-arbitrum/src/agent-proxy-watcher.ts | 4 ++-- l2-bridge-arbitrum/src/agent-withdrawals.ts | 5 ++--- l2-bridge-balance/src/agent-balance.ts | 9 ++++++--- l2-bridge-balance/src/constants.ts | 4 +--- l2-bridge-base/src/services/event_watcher.ts | 5 +++-- l2-bridge-ethereum/src/agent-bridge-watcher.ts | 3 ++- l2-bridge-ethereum/src/agent-proxy-watcher.ts | 9 +++++---- l2-bridge-ethereum/src/agent.ts | 4 ++-- l2-bridge-linea/src/services/event_watcher.ts | 3 ++- l2-bridge-mantle/src/services/event_watcher.ts | 3 ++- l2-bridge-mantle/src/services/monitor_withdrawals.ts | 7 ++++--- l2-bridge-optimism/src/agent-bridge-watcher.ts | 12 +++--------- l2-bridge-optimism/src/agent-governance.ts | 12 +++--------- l2-bridge-optimism/src/agent-proxy-watcher.ts | 3 ++- l2-bridge-optimism/src/agent-withdrawals.ts | 4 ++-- l2-bridge-zksync/src/services/event_watcher.ts | 8 +++++--- 18 files changed, 52 insertions(+), 67 deletions(-) diff --git a/l2-bridge-arbitrum/src/agent-bridge-watcher.ts b/l2-bridge-arbitrum/src/agent-bridge-watcher.ts index 4a2bdcb3..5ff08013 100644 --- a/l2-bridge-arbitrum/src/agent-bridge-watcher.ts +++ b/l2-bridge-arbitrum/src/agent-bridge-watcher.ts @@ -1,11 +1,5 @@ -import { - ethers, - BlockEvent, - TransactionEvent, - Finding, - FindingType, - FindingSeverity, -} from "forta-agent"; +import { TransactionEvent, Finding } from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; import { L2_BRIDGE_EVENTS } from "./constants"; export const name = "BridgeWatcher"; @@ -27,7 +21,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { function handleL2BridgeEvents(txEvent: TransactionEvent, findings: Finding[]) { L2_BRIDGE_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-arbitrum/src/agent-governance.ts b/l2-bridge-arbitrum/src/agent-governance.ts index e0e18866..c73d2985 100644 --- a/l2-bridge-arbitrum/src/agent-governance.ts +++ b/l2-bridge-arbitrum/src/agent-governance.ts @@ -1,11 +1,5 @@ -import { - ethers, - BlockEvent, - TransactionEvent, - Finding, - FindingType, - FindingSeverity, -} from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; +import { TransactionEvent, Finding } from "forta-agent"; import { GOV_BRIDGE_EVENTS } from "./constants"; export const name = "GovBridgeBot"; @@ -27,7 +21,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { function handleGovBridgeEvents(txEvent: TransactionEvent, findings: Finding[]) { GOV_BRIDGE_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-arbitrum/src/agent-proxy-watcher.ts b/l2-bridge-arbitrum/src/agent-proxy-watcher.ts index 83303041..9adf9ad9 100644 --- a/l2-bridge-arbitrum/src/agent-proxy-watcher.ts +++ b/l2-bridge-arbitrum/src/agent-proxy-watcher.ts @@ -1,3 +1,4 @@ +import { formatAddress } from "forta-agent/dist/cli/utils"; import { ethers, BlockEvent, @@ -11,7 +12,6 @@ import { LIDO_PROXY_CONTRACTS, LidoProxy, } from "./constants"; -import { ethersProvider } from "./ethers"; // Block interval tp fetch proxy params const BLOCK_INTERVAL = 10; @@ -52,7 +52,7 @@ function handleProxyAdminEvents( findings: Finding[], ) { PROXY_ADMIN_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-arbitrum/src/agent-withdrawals.ts b/l2-bridge-arbitrum/src/agent-withdrawals.ts index 4b1f765e..68476073 100644 --- a/l2-bridge-arbitrum/src/agent-withdrawals.ts +++ b/l2-bridge-arbitrum/src/agent-withdrawals.ts @@ -1,5 +1,5 @@ import BigNumber from "bignumber.js"; - +import { formatAddress } from "forta-agent/dist/cli/utils"; import { ethers, BlockEvent, @@ -10,7 +10,6 @@ import { } from "forta-agent"; import { Event } from "ethers"; -import { ethersProvider } from "./ethers"; import L2_BRIDGE_ABI from "./abi/L2Bridge.json"; import { @@ -159,7 +158,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { } function handleWithdrawalEvent(txEvent: TransactionEvent, findings: Finding[]) { - if (L2_ERC20_TOKEN_GATEWAY in txEvent.addresses) { + if (formatAddress(L2_ERC20_TOKEN_GATEWAY) in txEvent.addresses) { const events = txEvent.filterLog( WITHDRAWAL_INITIATED_EVENT, L2_ERC20_TOKEN_GATEWAY, diff --git a/l2-bridge-balance/src/agent-balance.ts b/l2-bridge-balance/src/agent-balance.ts index 60ab28a7..6bb20891 100644 --- a/l2-bridge-balance/src/agent-balance.ts +++ b/l2-bridge-balance/src/agent-balance.ts @@ -12,7 +12,7 @@ import { BridgeParamLDO, BridgeParamWstETH, ETH_DECIMALS, - LDO_ADDRESS, + LDO_L1_ADDRESS, WSTETH_ADDRESS, } from "./constants"; import ERC20_SHORT_ABI from "./abi/ERC20Short.json"; @@ -41,7 +41,6 @@ export async function handleBlock(blockEvent: BlockEvent) { findings, BRIDGE_PARAMS_WSTETH.Optimism, ), - handleBridgeBalanceLDO(blockEvent, findings, BRIDGE_PARAMS_LDO.Arbitrum), handleBridgeBalanceLDO(blockEvent, findings, BRIDGE_PARAMS_LDO.Optimism), ]); @@ -101,7 +100,11 @@ async function handleBridgeBalanceLDO( findings: Finding[], networkParams: BridgeParamLDO, ) { - const LDO = new ethers.Contract(LDO_ADDRESS, ERC20_SHORT_ABI, ethersProvider); + const LDO = new ethers.Contract( + LDO_L1_ADDRESS, + ERC20_SHORT_ABI, + ethersProvider, + ); const l1Balance = new BigNumber( String(await LDO.functions.balanceOf(networkParams.l1Gateway)), ); diff --git a/l2-bridge-balance/src/constants.ts b/l2-bridge-balance/src/constants.ts index d5190cdf..66dea354 100644 --- a/l2-bridge-balance/src/constants.ts +++ b/l2-bridge-balance/src/constants.ts @@ -1,8 +1,6 @@ import BigNumber from "bignumber.js"; import config from "./config/bot-config.json"; -// COMMON CONSTS - // 1 ETH export const ETH_DECIMALS = new BigNumber(10).pow(18); @@ -37,7 +35,7 @@ export const BRIDGE_PARAMS_WSTETH: BridgeParamsWstETH = { }, }; -export const LDO_ADDRESS = "0x5a98fcbea516cf06857215779fd812ca3bef1b32"; +export const LDO_L1_ADDRESS = "0x5a98fcbea516cf06857215779fd812ca3bef1b32"; export interface BridgeParamLDO { name: string; diff --git a/l2-bridge-base/src/services/event_watcher.ts b/l2-bridge-base/src/services/event_watcher.ts index 24047d6a..97b36f51 100644 --- a/l2-bridge-base/src/services/event_watcher.ts +++ b/l2-bridge-base/src/services/event_watcher.ts @@ -4,6 +4,7 @@ import { filterLog, Finding } from 'forta-agent' import { Logger } from 'winston' import { elapsedTime } from '../utils/time' import { getUniqueKey } from '../utils/finding.helpers' +import { formatAddress } from 'forta-agent/dist/cli/utils' export class EventWatcher { private readonly name: string @@ -25,12 +26,12 @@ export class EventWatcher { const addresses: string[] = [] for (const l2log of l2logs) { - addresses.push(l2log.address) + addresses.push(formatAddress(l2log.address)) } const findings: Finding[] = [] for (const eventToFinding of this.eventsToFinding) { - const ind = addresses.indexOf(eventToFinding.address) + const ind = addresses.indexOf(formatAddress(eventToFinding.address)) if (ind >= 0) { const filteredEvents = filterLog(l2logs, eventToFinding.event, eventToFinding.address) diff --git a/l2-bridge-ethereum/src/agent-bridge-watcher.ts b/l2-bridge-ethereum/src/agent-bridge-watcher.ts index d28fbf5d..2e8a5deb 100644 --- a/l2-bridge-ethereum/src/agent-bridge-watcher.ts +++ b/l2-bridge-ethereum/src/agent-bridge-watcher.ts @@ -1,4 +1,5 @@ import { Finding, TransactionEvent } from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; import { L1_BRIDGE_EVENTS } from "./constants"; export const name = "BridgeWatcher"; @@ -20,7 +21,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { function handleL1BridgeEvents(txEvent: TransactionEvent, findings: Finding[]) { L1_BRIDGE_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-ethereum/src/agent-proxy-watcher.ts b/l2-bridge-ethereum/src/agent-proxy-watcher.ts index 5b072da2..3388140f 100644 --- a/l2-bridge-ethereum/src/agent-proxy-watcher.ts +++ b/l2-bridge-ethereum/src/agent-proxy-watcher.ts @@ -6,6 +6,7 @@ import { FindingType, TransactionEvent, } from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; import { ARBITRUM_GATEWAY_SET_EVENT, ARBITRUM_L1_GATEWAY_ROUTER, @@ -57,7 +58,7 @@ function handleProxyAdminEvents( findings: Finding[], ) { PROXY_ADMIN_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( @@ -80,7 +81,7 @@ function handleThirdPartyProxyAdminEvents( findings: Finding[], ) { THIRD_PARTY_PROXY_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( @@ -96,7 +97,7 @@ function handleThirdPartyProxyAdminEvents( }); } }); - if (ARBITRUM_L1_GATEWAY_ROUTER in txEvent.addresses) { + if (formatAddress(ARBITRUM_L1_GATEWAY_ROUTER) in txEvent.addresses) { const events = txEvent.filterLog( ARBITRUM_GATEWAY_SET_EVENT, ARBITRUM_L1_GATEWAY_ROUTER, @@ -117,7 +118,7 @@ function handleThirdPartyProxyAdminEvents( }); } - if (LINEA_L1_CROSS_DOMAIN_MESSENGER in txEvent.addresses) { + if (formatAddress(LINEA_L1_CROSS_DOMAIN_MESSENGER) in txEvent.addresses) { const events = txEvent.filterLog( LINEA_CUSTOM_CONTRACT_SET_EVENT, LINEA_L1_CROSS_DOMAIN_MESSENGER, diff --git a/l2-bridge-ethereum/src/agent.ts b/l2-bridge-ethereum/src/agent.ts index ef00d86c..6906bb6c 100644 --- a/l2-bridge-ethereum/src/agent.ts +++ b/l2-bridge-ethereum/src/agent.ts @@ -152,7 +152,7 @@ const handleBlock: HandleBlock = async ( }), ); - runs.forEach((r: PromiseSettledResult, index: number) => { + runs.forEach((r: PromiseSettledResult, index: number) => { if (r.status == "rejected") { blockFindings.push( errorToFinding(r.reason, subAgents[index], "handleBlock"), @@ -199,7 +199,7 @@ const handleTransaction: HandleTransaction = async ( }), ); - runs.forEach((r: PromiseSettledResult, index: number) => { + runs.forEach((r: PromiseSettledResult, index: number) => { if (r.status == "rejected") { txFindings.push( errorToFinding(r.reason, subAgents[index], "handleBlock"), diff --git a/l2-bridge-linea/src/services/event_watcher.ts b/l2-bridge-linea/src/services/event_watcher.ts index 19731090..bc197eea 100644 --- a/l2-bridge-linea/src/services/event_watcher.ts +++ b/l2-bridge-linea/src/services/event_watcher.ts @@ -4,6 +4,7 @@ import { filterLog, Finding } from 'forta-agent' import { Logger } from 'winston' import { elapsedTime } from '../utils/time' import { getUniqueKey } from '../utils/finding.helpers' +import { formatAddress } from 'forta-agent/dist/cli/utils' export class EventWatcher { private readonly name: string @@ -30,7 +31,7 @@ export class EventWatcher { const findings: Finding[] = [] for (const eventToFinding of this.eventsToFinding) { - const ind = addresses.indexOf(eventToFinding.address) + const ind = addresses.indexOf(formatAddress(eventToFinding.address)) if (ind >= 0) { const filteredEvents = filterLog(logs, eventToFinding.event, eventToFinding.address) diff --git a/l2-bridge-mantle/src/services/event_watcher.ts b/l2-bridge-mantle/src/services/event_watcher.ts index b3a8e403..6937037b 100644 --- a/l2-bridge-mantle/src/services/event_watcher.ts +++ b/l2-bridge-mantle/src/services/event_watcher.ts @@ -4,6 +4,7 @@ import { filterLog, Finding } from 'forta-agent' import { getUniqueKey } from '../utils/finding.helpers' import { elapsedTime } from '../utils/time' import { Logger } from 'winston' +import { formatAddress } from 'forta-agent/dist/cli/utils' export class EventWatcher { private readonly name: string @@ -30,7 +31,7 @@ export class EventWatcher { const findings: Finding[] = [] for (const eventToFinding of this.eventsToFinding) { - const ind = addresses.indexOf(eventToFinding.address) + const ind = addresses.indexOf(formatAddress(eventToFinding.address)) if (ind >= 0) { const filteredEvents = filterLog(l2logs, eventToFinding.event, eventToFinding.address) diff --git a/l2-bridge-mantle/src/services/monitor_withdrawals.ts b/l2-bridge-mantle/src/services/monitor_withdrawals.ts index c6171a1f..cb730677 100644 --- a/l2-bridge-mantle/src/services/monitor_withdrawals.ts +++ b/l2-bridge-mantle/src/services/monitor_withdrawals.ts @@ -8,6 +8,7 @@ import { NetworkError } from '../utils/error' import { elapsedTime } from '../utils/time' import { Logger } from 'winston' import { getUniqueKey } from '../utils/finding.helpers' +import { formatAddress } from 'forta-agent/dist/cli/utils' const ETH_DECIMALS = new BigNumber(10).pow(18) // 10k wstETH @@ -42,7 +43,7 @@ export class MonitorWithdrawals { } public async initialize(currentBlock: number): Promise> { - // 48 hours + // TODO: Fix actually on Mantle block time is not constant and the check logic must be updated const pastBlock = currentBlock - Math.ceil(HOURS_48 / AVG_BLOCK_TIME_2SECONDS) const withdrawalEvents = await this.withdrawalsClient.getWithdrawalEvents(pastBlock, currentBlock - 1) @@ -145,7 +146,7 @@ export class MonitorWithdrawals { for (const log of logs) { logIndexToLogs.set(log.logIndex, log) - addresses.push(log.address.toLowerCase()) + addresses.push(formatAddress(log.address)) } for (const blockDto of blocksDto) { @@ -154,7 +155,7 @@ export class MonitorWithdrawals { const out: WithdrawalRecord[] = [] if (this.l2Erc20TokenGatewayAddress in addresses) { - const events = filterLog(logs, this.withdrawalInitiatedEvent, this.l2Erc20TokenGatewayAddress.toLowerCase()) + const events = filterLog(logs, this.withdrawalInitiatedEvent, formatAddress(this.l2Erc20TokenGatewayAddress)) for (const event of events) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/l2-bridge-optimism/src/agent-bridge-watcher.ts b/l2-bridge-optimism/src/agent-bridge-watcher.ts index 4a2bdcb3..5ff08013 100644 --- a/l2-bridge-optimism/src/agent-bridge-watcher.ts +++ b/l2-bridge-optimism/src/agent-bridge-watcher.ts @@ -1,11 +1,5 @@ -import { - ethers, - BlockEvent, - TransactionEvent, - Finding, - FindingType, - FindingSeverity, -} from "forta-agent"; +import { TransactionEvent, Finding } from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; import { L2_BRIDGE_EVENTS } from "./constants"; export const name = "BridgeWatcher"; @@ -27,7 +21,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { function handleL2BridgeEvents(txEvent: TransactionEvent, findings: Finding[]) { L2_BRIDGE_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-optimism/src/agent-governance.ts b/l2-bridge-optimism/src/agent-governance.ts index e0e18866..d0edc2ae 100644 --- a/l2-bridge-optimism/src/agent-governance.ts +++ b/l2-bridge-optimism/src/agent-governance.ts @@ -1,11 +1,5 @@ -import { - ethers, - BlockEvent, - TransactionEvent, - Finding, - FindingType, - FindingSeverity, -} from "forta-agent"; +import { TransactionEvent, Finding } from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; import { GOV_BRIDGE_EVENTS } from "./constants"; export const name = "GovBridgeBot"; @@ -27,7 +21,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { function handleGovBridgeEvents(txEvent: TransactionEvent, findings: Finding[]) { GOV_BRIDGE_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-optimism/src/agent-proxy-watcher.ts b/l2-bridge-optimism/src/agent-proxy-watcher.ts index 29daedaf..4a19d61d 100644 --- a/l2-bridge-optimism/src/agent-proxy-watcher.ts +++ b/l2-bridge-optimism/src/agent-proxy-watcher.ts @@ -6,6 +6,7 @@ import { FindingType, FindingSeverity, } from "forta-agent"; +import { formatAddress } from "forta-agent/dist/cli/utils"; import { PROXY_ADMIN_EVENTS, LIDO_PROXY_CONTRACTS, @@ -52,7 +53,7 @@ function handleProxyAdminEvents( findings: Finding[], ) { PROXY_ADMIN_EVENTS.forEach((eventInfo) => { - if (eventInfo.address in txEvent.addresses) { + if (formatAddress(eventInfo.address) in txEvent.addresses) { const events = txEvent.filterLog(eventInfo.event, eventInfo.address); events.forEach((event) => { findings.push( diff --git a/l2-bridge-optimism/src/agent-withdrawals.ts b/l2-bridge-optimism/src/agent-withdrawals.ts index 76246fdd..ecc12e3c 100644 --- a/l2-bridge-optimism/src/agent-withdrawals.ts +++ b/l2-bridge-optimism/src/agent-withdrawals.ts @@ -1,5 +1,5 @@ import BigNumber from "bignumber.js"; - +import { formatAddress } from "forta-agent/dist/cli/utils"; import { ethers, BlockEvent, @@ -131,7 +131,7 @@ export async function handleTransaction(txEvent: TransactionEvent) { } function handleWithdrawalEvent(txEvent: TransactionEvent, findings: Finding[]) { - if (L2_ERC20_TOKEN_GATEWAY in txEvent.addresses) { + if (formatAddress(L2_ERC20_TOKEN_GATEWAY) in txEvent.addresses) { const events = txEvent.filterLog( WITHDRAWAL_INITIATED_EVENT, L2_ERC20_TOKEN_GATEWAY, diff --git a/l2-bridge-zksync/src/services/event_watcher.ts b/l2-bridge-zksync/src/services/event_watcher.ts index a415475c..50aa59b9 100644 --- a/l2-bridge-zksync/src/services/event_watcher.ts +++ b/l2-bridge-zksync/src/services/event_watcher.ts @@ -4,6 +4,7 @@ import { filterLog, Finding } from 'forta-agent' import { getUniqueKey } from '../utils/finding.helpers' import { elapsedTime } from '../utils/time' import { Logger } from 'winston' +import { formatAddress } from 'forta-agent/dist/cli/utils' import BigNumber from 'bignumber.js' export class EventWatcher { @@ -27,14 +28,15 @@ export class EventWatcher { const logIndexToLog = new Map() for (const l2Log of l2Logs) { - addresses.add(l2Log.address.toLowerCase()) + addresses.add(formatAddress(l2Log.address)) logIndexToLog.set(l2Log.logIndex, l2Log) } const findings: Finding[] = [] for (const eventToFinding of this.eventsToFinding) { - if (addresses.has(eventToFinding.address.toLowerCase())) { - const filteredEvents = filterLog(l2Logs, eventToFinding.event, eventToFinding.address.toLowerCase()) + const eventAddress = formatAddress(eventToFinding.address) + if (addresses.has(eventAddress)) { + const filteredEvents = filterLog(l2Logs, eventToFinding.event, eventAddress) for (const event of filteredEvents) { findings.push(