Skip to main content

Common Event Topic Hashes

Pre-computed keccak256 hashes for common Ethereum events. Use these directly instead of computing at runtime.

ERC-20 Token Events

EventSignatureTopic Hash
TransferTransfer(address,address,uint256)0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
ApprovalApproval(address,address,uint256)0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925

ERC-721 NFT Events

EventSignatureTopic Hash
TransferTransfer(address,address,uint256)0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
ApprovalApproval(address,address,uint256)0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
ApprovalForAllApprovalForAll(address,address,bool)0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31

Uniswap V2 Events

EventSignatureTopic Hash
SwapSwap(address,uint256,uint256,uint256,uint256,address)0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822
SyncSync(uint112,uint112)0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1
MintMint(address,uint256,uint256)0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f
BurnBurn(address,uint256,uint256,address)0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496
PairCreatedPairCreated(address,address,address,uint256)0x0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9

Uniswap V3 Events

EventSignatureTopic Hash
SwapSwap(address,address,int256,int256,uint160,uint128,int24)0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67
MintMint(address,address,int24,int24,uint128,uint256,uint256)0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde
BurnBurn(address,int24,int24,uint128,uint256,uint256)0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c
PoolCreatedPoolCreated(address,address,uint24,int24,address)0x783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118

WETH Events

EventSignatureTopic Hash
DepositDeposit(address,uint256)0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c
WithdrawalWithdrawal(address,uint256)0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65

Usage Example

// Copy-paste the topic hash you need
const UNISWAP_V2_SWAP = "0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"

const logs = yield* getLogs({
  topics: [[UNISWAP_V2_SWAP]],
  fromBlock: "0x1000000",
  toBlock: "latest"
})

Contract Addresses (Mainnet)

Uniswap

ContractAddress
V2 Factory0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
V2 Router0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
V3 Factory0x1F98431c8aD98523631AE4a59f267346ea31F984
V3 Router0xE592427A0AEce92De3Edee1F18E0157C05861564
Universal Router0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD

Common Tokens

TokenAddressDecimals
WETH0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc218
USDC0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB486
USDT0xdAC17F958D2ee523a2206206994597C13D831ec76
DAI0x6B175474E89094C44Da98b954EeshdC1c9E18
WBTC0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C5998

Deploy Blocks

ContractBlock Number
Uniswap V2 Factory10000835
Uniswap V3 Factory12369621
USDC6082465

Public RPC Endpoints

Free, rate-limited RPCs for development:
ProviderURLRate Limit
LlamaRPChttps://eth.llamarpc.com~25 req/s
Ankrhttps://rpc.ankr.com/eth~30 req/s
PublicNodehttps://ethereum.publicnode.com~10 req/s
Cloudflarehttps://cloudflare-eth.com~10 req/s

Fallback Pattern

const RPC_URLS = [
  process.env.ALCHEMY_URL,           // Primary (if set)
  "https://eth.llamarpc.com",        // Fallback 1
  "https://rpc.ankr.com/eth",        // Fallback 2
  "https://ethereum.publicnode.com", // Fallback 3
].filter(Boolean) as string[]

ABI Decoding Cheatsheet

Decode Address from Topic (indexed param)

// Topics are 32 bytes, addresses are 20 bytes (right-aligned)
const address = "0x" + topic.slice(-40)

Decode uint256 from Data

// Each param is 32 bytes = 64 hex chars
const data = log.data.slice(2) // remove 0x
const param0 = BigInt("0x" + data.slice(0, 64))
const param1 = BigInt("0x" + data.slice(64, 128))
const param2 = BigInt("0x" + data.slice(128, 192))

Decode int256 from Data

const raw = BigInt("0x" + data.slice(0, 64))
// Check sign bit (most significant bit)
const int256 = raw >= 2n ** 255n ? raw - 2n ** 256n : raw

Decode bytes32

const bytes32 = "0x" + data.slice(0, 64)

Decode Dynamic String/Bytes

// First 32 bytes = offset to data
const offset = parseInt(data.slice(0, 64), 16) * 2
// Next 32 bytes at offset = length
const length = parseInt(data.slice(offset, offset + 64), 16) * 2
// Actual data follows
const stringHex = data.slice(offset + 64, offset + 64 + length)
const string = Buffer.from(stringHex, 'hex').toString('utf8')

Effect Patterns Quick Reference

Retry with Exponential Backoff

import { Schedule } from "effect"

const retrySchedule = Schedule.exponential("100 millis").pipe(
  Schedule.jittered,
  Schedule.compose(Schedule.recurs(3))
)

myEffect.pipe(Effect.retry(retrySchedule))

Timeout

myEffect.pipe(Effect.timeout("5 seconds"))

Try Multiple in Sequence (First Success)

const tryAll = <A, E>(effects: Effect.Effect<A, E>[]) =>
  effects.slice(1).reduce(
    (acc, eff) => acc.pipe(Effect.orElse(() => eff)),
    effects[0]!
  )

Parallel with Concurrency Limit

Effect.forEach(items, processItem, { concurrency: 10 })

Stream to Array

Stream.runCollect(myStream).pipe(Effect.map(Chunk.toArray))