June 10, 2026
Tenderly + Etherscan Debugging & Recon
Series: Web3 Security Zero se Advance π‘οΈ | Article #14 By HackerMD | 25 min read
Hacker MD
13 min read
Aaj Kya Seekhenge?
- Etherscan contract reading, recon techniques
- Etherscan API programmatic data fetch
- Transaction trace reading exploit analyze karna
- Storage slot reading hidden state nikalna
- Tenderly transaction simulation
- Tenderly trace analysis depth mein
- Tenderly fork + debug workflow
- Real hack transaction analyze karna!
Hacker Note: Jab bhi koi protocol hack hota hai top researchers pehle Etherscan pe jaate hain, hack transaction dhundhte hain, Tenderly mein simulate karte hain, aur 1-2 ghante mein root cause samajh jaate hain! Yeh skill = Competitive edge! π―
PART 1: Etherscan Web3 Ka Google!
Etherscan kya hai?
β Ethereum blockchain explorer
β Transactions, contracts, addresses β sab!
β Contract source code verify + read
β ABI available hota hai
β Events, logs, traces dekh sakte hain
Security research mein use:
β Target contract ka code padho
β Deployment history samjho
β Admin/owner kaun hai dhundho
β Kaunse functions exposed hain
β Recent suspicious transactions dekho
β Hack transaction analyze karo!
Related explorers:
β Arbiscan.io (Arbitrum)
β Bscscan.com (BNB Chain)
β Polygonscan.com(Polygon)
β Optimistic.etherscan.io (Optimism)
β Snowtrace.io (Avalanche)
Sab similar interface!Etherscan kya hai?
β Ethereum blockchain explorer
β Transactions, contracts, addresses β sab!
β Contract source code verify + read
β ABI available hota hai
β Events, logs, traces dekh sakte hain
Security research mein use:
β Target contract ka code padho
β Deployment history samjho
β Admin/owner kaun hai dhundho
β Kaunse functions exposed hain
β Recent suspicious transactions dekho
β Hack transaction analyze karo!
Related explorers:
β Arbiscan.io (Arbitrum)
β Bscscan.com (BNB Chain)
β Polygonscan.com(Polygon)
β Optimistic.etherscan.io (Optimism)
β Snowtrace.io (Avalanche)
Sab similar interface!PART 2: Etherscan Recon Step by Step!
Target: Koi bhi DeFi protocol
Goal: Security researcher ban ke recon karo
URL format:
https://etherscan.io/address/0xCONTRACTTarget: Koi bhi DeFi protocol
Goal: Security researcher ban ke recon karo
URL format:
https://etherscan.io/address/0xCONTRACTContract Page Breakdown:
Etherscan Contract Page:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Contract: 0xABC...123 β
β Balance: 50,000 ETH β
β Txn Count: 1,234,567 β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β [Transactions] [Internal Txns] [Erc20 Txns]β
β [Contract] [Events] [Analytics] β
βββββββββββββββββββββββββββββββββββββββββββββββ
Security Research Focus:
1. [Contract] Tab:
β Code tab: Source code!
β Read Contract: Public variables
β Write Contract: Execute functions
β Read as Proxy: Proxy state!
β Write as Proxy: Proxy functions!
2. [Transactions] Tab:
β Latest transactions
β Large ETH movements = Suspicious!
β Failed transactions = Interesting!
3. [Internal Txns] Tab:
β Contract-to-contract calls!
β Flash loans yahan dikhte hain!
β ETH flows trace karo!
4. [Events] Tab:
β All emitted events
β Admin events filter karo!
β "OwnershipTransferred" = Owner change!
5. [Analytics] Tab:
β TVL graph
β Sudden drop = Hack?Etherscan Contract Page:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Contract: 0xABC...123 β
β Balance: 50,000 ETH β
β Txn Count: 1,234,567 β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β [Transactions] [Internal Txns] [Erc20 Txns]β
β [Contract] [Events] [Analytics] β
βββββββββββββββββββββββββββββββββββββββββββββββ
Security Research Focus:
1. [Contract] Tab:
β Code tab: Source code!
β Read Contract: Public variables
β Write Contract: Execute functions
β Read as Proxy: Proxy state!
β Write as Proxy: Proxy functions!
2. [Transactions] Tab:
β Latest transactions
β Large ETH movements = Suspicious!
β Failed transactions = Interesting!
3. [Internal Txns] Tab:
β Contract-to-contract calls!
β Flash loans yahan dikhte hain!
β ETH flows trace karo!
4. [Events] Tab:
β All emitted events
β Admin events filter karo!
β "OwnershipTransferred" = Owner change!
5. [Analytics] Tab:
β TVL graph
β Sudden drop = Hack?Contract Tab Deep Dive:
READ CONTRACT β Security Research Ke Liye:
ββββββββββββββββββββββββββββββββββββββββββββ
β 1. owner() β 0xOwnerAddress β
β β Kaun control karta hai? β
β β
β 2. paused() β false β
β β Emergency switch available? β
β β
β 3. totalSupply() β 1,000,000 TOKENS β
β β
β 4. implementation() β 0xImplAddress β
β β Proxy! Actual code yahan hai! β
β β
β 5. timelock() β 0xTimelockAddr β
β β Governance kitna protected? β
ββββββββββββββββββββββββββββββββββββββββββββ
Important: "Read as Proxy" tab!
β Proxy contracts ka actual state!
β "Read Contract" sirf proxy ka state!
β Implementation ka state alag!
WRITE CONTRACT β Testing Ke Liye:
β MetaMask connect karo
β Functions call karo
β Parameters try karo
β (Test wallet use karo! Real wallet NEVER!)READ CONTRACT β Security Research Ke Liye:
ββββββββββββββββββββββββββββββββββββββββββββ
β 1. owner() β 0xOwnerAddress β
β β Kaun control karta hai? β
β β
β 2. paused() β false β
β β Emergency switch available? β
β β
β 3. totalSupply() β 1,000,000 TOKENS β
β β
β 4. implementation() β 0xImplAddress β
β β Proxy! Actual code yahan hai! β
β β
β 5. timelock() β 0xTimelockAddr β
β β Governance kitna protected? β
ββββββββββββββββββββββββββββββββββββββββββββ
Important: "Read as Proxy" tab!
β Proxy contracts ka actual state!
β "Read Contract" sirf proxy ka state!
β Implementation ka state alag!
WRITE CONTRACT β Testing Ke Liye:
β MetaMask connect karo
β Functions call karo
β Parameters try karo
β (Test wallet use karo! Real wallet NEVER!)PART 3: Etherscan API Programmatic Recon!
# βββ API Key Setup ββββββββββββββββββββββββ
# 1. etherscan.io pe register karo (free!)
# 2. API Keys β Add
# 3. Copy key
export ETHERSCAN_API_KEY=YOUR_API_KEY_HERE
# Base URL:
BASE="https://api.etherscan.io/api"
# βββ Account APIs βββββββββββββββββββββββββ
# ETH Balance:
curl "$BASE?\
module=account\
&action=balance\
&address=0xVitalikAddress\
&tag=latest\
&apikey=$ETHERSCAN_API_KEY"
# Output:
# {"status":"1","message":"OK",
# "result":"1234567890000000000000"}
# Token Balance (ERC-20):
curl "$BASE?\
module=account\
&action=tokenbalance\
&contractaddress=$USDC_ADDRESS\
&address=0xWhaleAddress\
&tag=latest\
&apikey=$ETHERSCAN_API_KEY"
# Transaction list:
curl "$BASE?\
module=account\
&action=txlist\
&address=0xContractAddress\
&startblock=0\
&endblock=99999999\
&sort=desc\
&apikey=$ETHERSCAN_API_KEY"
# Internal transactions:
curl "$BASE?\
module=account\
&action=txlistinternal\
&address=0xContractAddress\
&startblock=18000000\
&endblock=19000000\
&sort=desc\
&apikey=$ETHERSCAN_API_KEY"
# βββ Contract APIs ββββββββββββββββββββββββ
# ABI fetch karo:
curl "$BASE?\
module=contract\
&action=getabi\
&address=0xContractAddress\
&apikey=$ETHERSCAN_API_KEY" \
| python3 -m json.tool
# Source code:
curl "$BASE?\
module=contract\
&action=getsourcecode\
&address=0xUSDC_ADDRESS\
&apikey=$ETHERSCAN_API_KEY" \
| python3 -c "
import json, sys
d = json.load(sys.stdin)
result = d['result'][0]
print('Contract:', result['ContractName'])
print('Compiler:', result['CompilerVersion'])
print('Proxy:', result['Proxy'])
if result['Proxy'] == '1':
print('Implementation:', result['Implementation'])
"
# Contract creation TX:
curl "$BASE?\
module=contract\
&action=getcontractcreation\
&contractaddresses=0xContractAddress\
&apikey=$ETHERSCAN_API_KEY"
# βββ Transaction APIs βββββββββββββββββββββ
# TX Receipt + Logs:
curl "$BASE?\
module=proxy\
&action=eth_getTransactionReceipt\
&txhash=0xTXHASH\
&apikey=$ETHERSCAN_API_KEY"
# TX by hash:
curl "$BASE?\
module=proxy\
&action=eth_getTransactionByHash\
&txhash=0xTXHASH\
&apikey=$ETHERSCAN_API_KEY"
# βββ Logs/Events API ββββββββββββββββββββββ
# Specific events filter karo!
# Transfer events in last 1000 blocks:
LATEST_BLOCK=$(cast block latest --field number \
--rpc-url $MAINNET_RPC)
FROM_BLOCK=$((LATEST_BLOCK - 1000))
# Transfer event topic:
TRANSFER_TOPIC="0xddf252ad1be2c89b69c2b068fc378\
daa952ba7f163c4a11628f55a4df523b3ef"
curl "$BASE?\
module=logs\
&action=getLogs\
&fromBlock=$FROM_BLOCK\
&toBlock=latest\
&address=$TOKEN_ADDRESS\
&topic0=$TRANSFER_TOPIC\
&apikey=$ETHERSCAN_API_KEY"# βββ API Key Setup ββββββββββββββββββββββββ
# 1. etherscan.io pe register karo (free!)
# 2. API Keys β Add
# 3. Copy key
export ETHERSCAN_API_KEY=YOUR_API_KEY_HERE
# Base URL:
BASE="https://api.etherscan.io/api"
# βββ Account APIs βββββββββββββββββββββββββ
# ETH Balance:
curl "$BASE?\
module=account\
&action=balance\
&address=0xVitalikAddress\
&tag=latest\
&apikey=$ETHERSCAN_API_KEY"
# Output:
# {"status":"1","message":"OK",
# "result":"1234567890000000000000"}
# Token Balance (ERC-20):
curl "$BASE?\
module=account\
&action=tokenbalance\
&contractaddress=$USDC_ADDRESS\
&address=0xWhaleAddress\
&tag=latest\
&apikey=$ETHERSCAN_API_KEY"
# Transaction list:
curl "$BASE?\
module=account\
&action=txlist\
&address=0xContractAddress\
&startblock=0\
&endblock=99999999\
&sort=desc\
&apikey=$ETHERSCAN_API_KEY"
# Internal transactions:
curl "$BASE?\
module=account\
&action=txlistinternal\
&address=0xContractAddress\
&startblock=18000000\
&endblock=19000000\
&sort=desc\
&apikey=$ETHERSCAN_API_KEY"
# βββ Contract APIs ββββββββββββββββββββββββ
# ABI fetch karo:
curl "$BASE?\
module=contract\
&action=getabi\
&address=0xContractAddress\
&apikey=$ETHERSCAN_API_KEY" \
| python3 -m json.tool
# Source code:
curl "$BASE?\
module=contract\
&action=getsourcecode\
&address=0xUSDC_ADDRESS\
&apikey=$ETHERSCAN_API_KEY" \
| python3 -c "
import json, sys
d = json.load(sys.stdin)
result = d['result'][0]
print('Contract:', result['ContractName'])
print('Compiler:', result['CompilerVersion'])
print('Proxy:', result['Proxy'])
if result['Proxy'] == '1':
print('Implementation:', result['Implementation'])
"
# Contract creation TX:
curl "$BASE?\
module=contract\
&action=getcontractcreation\
&contractaddresses=0xContractAddress\
&apikey=$ETHERSCAN_API_KEY"
# βββ Transaction APIs βββββββββββββββββββββ
# TX Receipt + Logs:
curl "$BASE?\
module=proxy\
&action=eth_getTransactionReceipt\
&txhash=0xTXHASH\
&apikey=$ETHERSCAN_API_KEY"
# TX by hash:
curl "$BASE?\
module=proxy\
&action=eth_getTransactionByHash\
&txhash=0xTXHASH\
&apikey=$ETHERSCAN_API_KEY"
# βββ Logs/Events API ββββββββββββββββββββββ
# Specific events filter karo!
# Transfer events in last 1000 blocks:
LATEST_BLOCK=$(cast block latest --field number \
--rpc-url $MAINNET_RPC)
FROM_BLOCK=$((LATEST_BLOCK - 1000))
# Transfer event topic:
TRANSFER_TOPIC="0xddf252ad1be2c89b69c2b068fc378\
daa952ba7f163c4a11628f55a4df523b3ef"
curl "$BASE?\
module=logs\
&action=getLogs\
&fromBlock=$FROM_BLOCK\
&toBlock=latest\
&address=$TOKEN_ADDRESS\
&topic0=$TRANSFER_TOPIC\
&apikey=$ETHERSCAN_API_KEY"Python Script Automated Recon:
#!/usr/bin/env python3
# etherscan_recon.py
# Target protocol ka automated recon!
import requests
import json
import os
from datetime import datetime
API_KEY = os.environ.get("ETHERSCAN_API_KEY")
BASE = "https://api.etherscan.io/api"
def api_call(params):
params["apikey"] = API_KEY
r = requests.get(BASE, params=params)
return r.json()
def recon_contract(address):
print(f"\n{'='*50}")
print(f"RECON: {address}")
print(f"{'='*50}")
# 1. Source code check:
code = api_call({
"module": "contract",
"action": "getsourcecode",
"address": address
})
if code["status"] == "1":
r = code["result"][0]
print(f"\nπ Contract Info:")
print(f" Name: {r['ContractName']}")
print(f" Compiler: {r['CompilerVersion']}")
print(f" Verified: {'Yes β
' if r['ABI'] != 'Contract source code not verified' else 'No β'}")
print(f" Proxy: {'Yes β οΈ' if r['Proxy'] == '1' else 'No'}")
if r["Proxy"] == "1":
print(f" Impl: {r['Implementation']}")
# 2. ETH Balance:
bal = api_call({
"module": "account",
"action": "balance",
"address": address,
"tag": "latest"
})
if bal["status"] == "1":
eth_bal = int(bal["result"]) / 1e18
print(f"\nπ° ETH Balance: {eth_bal:.4f} ETH")
# 3. Recent transactions:
txns = api_call({
"module": "account",
"action": "txlist",
"address": address,
"startblock":"0",
"endblock": "99999999",
"sort": "desc",
"offset": "10",
"page": "1"
})
if txns["status"] == "1":
print(f"\nπ Recent Transactions (last 10):")
for tx in txns["result"][:5]:
ts = datetime.fromtimestamp(
int(tx["timeStamp"])
).strftime("%Y-%m-%d %H:%M")
value = int(tx["value"]) / 1e18
status = "β
" if tx["txreceipt_status"] == "1" else "β"
print(f" {status} {ts} | "
f"{value:.4f} ETH | "
f"{tx['hash'][:20]}...")
# 4. Failed transactions check:
failed = [
tx for tx in txns.get("result", [])
if tx.get("txreceipt_status") == "0"
]
if failed:
print(f"\nβ οΈ Failed TXs: {len(failed)}")
print(" Investigate these!")
print(f"\n{'='*50}\n")
# Usage:
if __name__ == "__main__":
# USDC contract:
recon_contract(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
)#!/usr/bin/env python3
# etherscan_recon.py
# Target protocol ka automated recon!
import requests
import json
import os
from datetime import datetime
API_KEY = os.environ.get("ETHERSCAN_API_KEY")
BASE = "https://api.etherscan.io/api"
def api_call(params):
params["apikey"] = API_KEY
r = requests.get(BASE, params=params)
return r.json()
def recon_contract(address):
print(f"\n{'='*50}")
print(f"RECON: {address}")
print(f"{'='*50}")
# 1. Source code check:
code = api_call({
"module": "contract",
"action": "getsourcecode",
"address": address
})
if code["status"] == "1":
r = code["result"][0]
print(f"\nπ Contract Info:")
print(f" Name: {r['ContractName']}")
print(f" Compiler: {r['CompilerVersion']}")
print(f" Verified: {'Yes β
' if r['ABI'] != 'Contract source code not verified' else 'No β'}")
print(f" Proxy: {'Yes β οΈ' if r['Proxy'] == '1' else 'No'}")
if r["Proxy"] == "1":
print(f" Impl: {r['Implementation']}")
# 2. ETH Balance:
bal = api_call({
"module": "account",
"action": "balance",
"address": address,
"tag": "latest"
})
if bal["status"] == "1":
eth_bal = int(bal["result"]) / 1e18
print(f"\nπ° ETH Balance: {eth_bal:.4f} ETH")
# 3. Recent transactions:
txns = api_call({
"module": "account",
"action": "txlist",
"address": address,
"startblock":"0",
"endblock": "99999999",
"sort": "desc",
"offset": "10",
"page": "1"
})
if txns["status"] == "1":
print(f"\nπ Recent Transactions (last 10):")
for tx in txns["result"][:5]:
ts = datetime.fromtimestamp(
int(tx["timeStamp"])
).strftime("%Y-%m-%d %H:%M")
value = int(tx["value"]) / 1e18
status = "β
" if tx["txreceipt_status"] == "1" else "β"
print(f" {status} {ts} | "
f"{value:.4f} ETH | "
f"{tx['hash'][:20]}...")
# 4. Failed transactions check:
failed = [
tx for tx in txns.get("result", [])
if tx.get("txreceipt_status") == "0"
]
if failed:
print(f"\nβ οΈ Failed TXs: {len(failed)}")
print(" Investigate these!")
print(f"\n{'='*50}\n")
# Usage:
if __name__ == "__main__":
# USDC contract:
recon_contract(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
)PART 4: Transaction Trace Reading!
Hack transaction analyze karna =
Most important skill!
Steps:
1. Hack TX hash dhundho
2. Etherscan pe dekho
3. Internal transactions trace karo
4. Tenderly mein full trace dekho
5. Root cause samjho
6. PoC likho!
Example: Reentrancy hack TX
https://etherscan.io/tx/0xHACK_HASH
Transaction Page Layout:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Transaction Hash: 0xABC... β
β Status: β
Success β
β Block: 19,500,000 β
β From: 0xAttacker β
β To: 0xVictimContract β
β Value: 0 ETH β
β Gas Used: 234,567 β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β [Input Data] β
β Function: attack() β
β MethodID: 0x9e5faafc β
βββββββββββββββββββββββββββββββββββββββββββββββ
"Click to see more" β Internal Transactions:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Internal Transactions (reentrancy example): β
β β
β CALL Attacker β Vault : withdraw(1 ETH) β
β CALL Vault β Attacker: 1 ETH transfer β
β ββ CALL Attacker β Vault: withdraw(1 ETH) β
β CALL Vault β Attacker: 1 ETH β
β ββ CALL Attacker β Vault: withdraw β
β CALL Vault β Attacker: 1 ETH β
β ββ ... (5 times!) β
β β
β Pattern = REENTRANCY! π¨ β
βββββββββββββββββββββββββββββββββββββββββββββββHack transaction analyze karna =
Most important skill!
Steps:
1. Hack TX hash dhundho
2. Etherscan pe dekho
3. Internal transactions trace karo
4. Tenderly mein full trace dekho
5. Root cause samjho
6. PoC likho!
Example: Reentrancy hack TX
https://etherscan.io/tx/0xHACK_HASH
Transaction Page Layout:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Transaction Hash: 0xABC... β
β Status: β
Success β
β Block: 19,500,000 β
β From: 0xAttacker β
β To: 0xVictimContract β
β Value: 0 ETH β
β Gas Used: 234,567 β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β [Input Data] β
β Function: attack() β
β MethodID: 0x9e5faafc β
βββββββββββββββββββββββββββββββββββββββββββββββ
"Click to see more" β Internal Transactions:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Internal Transactions (reentrancy example): β
β β
β CALL Attacker β Vault : withdraw(1 ETH) β
β CALL Vault β Attacker: 1 ETH transfer β
β ββ CALL Attacker β Vault: withdraw(1 ETH) β
β CALL Vault β Attacker: 1 ETH β
β ββ CALL Attacker β Vault: withdraw β
β CALL Vault β Attacker: 1 ETH β
β ββ ... (5 times!) β
β β
β Pattern = REENTRANCY! π¨ β
βββββββββββββββββββββββββββββββββββββββββββββββPART 5: Storage Slot Reading Hidden State!
# Contract ka storage directly read karo!
# Private variables bhi!
# βββ Basic Slot Reading βββββββββββββββββββ
TARGET="0xContractAddress"
RPC=$MAINNET_RPC_URL
# Slot 0 (usually: owner ya first variable):
cast storage $TARGET 0 --rpc-url $RPC
# 0x000000000000000000000000OWNER_ADDRESS
# Address extract karo:
cast storage $TARGET 0 --rpc-url $RPC \
| xargs -I{} cast parse-bytes32-address {}
# 0xOwnerAddress
# βββ Mapping Slots ββββββββββββββββββββββββ
# mapping(address => uint256) at slot N
# User ka value = keccak256(user_address ++ N)
# User ka balance (mapping at slot 1):
USER="0xUserAddress"
SLOT=$(cast index address $USER 1)
echo "Mapping slot: $SLOT"
cast storage $TARGET $SLOT --rpc-url $RPC
# User ka balance!
# βββ Proxy Implementation βββββββββββββββββ
# EIP-1967 implementation slot:
IMPL_SLOT="0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
cast storage $TARGET $IMPL_SLOT \
--rpc-url $RPC
# Implementation contract address!
# Admin slot:
ADMIN_SLOT="0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"
cast storage $TARGET $ADMIN_SLOT \
--rpc-url $RPC
# Proxy admin address!
# βββ Packed Storage βββββββββββββββββββββββ
# Multiple variables ek slot mein!
# Example: slot 0 = address(20 bytes) + bool(1 byte)
# address = bytes 0-19
# bool = byte 20
RAW=$(cast storage $TARGET 0 --rpc-url $RPC)
echo "Raw slot: $RAW"
# 0x000000000000000000000001ADDRESS_HERE
# Last byte = bool value:
echo ${RAW: -2} # Last 2 hex chars
# 01 = true, 00 = false
# βββ Brute Force Important Slots ββββββββββ
for i in {0..10}; do
VAL=$(cast storage $TARGET $i \
--rpc-url $RPC 2>/dev/null)
echo "Slot $i: $VAL"
done
# Output:
# Slot 0: 0x0000...owner_address
# Slot 1: 0x0000...total_supply
# Slot 2: 0x0000...paused_flag
# ...
# Pattern recognize karo!# Contract ka storage directly read karo!
# Private variables bhi!
# βββ Basic Slot Reading βββββββββββββββββββ
TARGET="0xContractAddress"
RPC=$MAINNET_RPC_URL
# Slot 0 (usually: owner ya first variable):
cast storage $TARGET 0 --rpc-url $RPC
# 0x000000000000000000000000OWNER_ADDRESS
# Address extract karo:
cast storage $TARGET 0 --rpc-url $RPC \
| xargs -I{} cast parse-bytes32-address {}
# 0xOwnerAddress
# βββ Mapping Slots ββββββββββββββββββββββββ
# mapping(address => uint256) at slot N
# User ka value = keccak256(user_address ++ N)
# User ka balance (mapping at slot 1):
USER="0xUserAddress"
SLOT=$(cast index address $USER 1)
echo "Mapping slot: $SLOT"
cast storage $TARGET $SLOT --rpc-url $RPC
# User ka balance!
# βββ Proxy Implementation βββββββββββββββββ
# EIP-1967 implementation slot:
IMPL_SLOT="0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
cast storage $TARGET $IMPL_SLOT \
--rpc-url $RPC
# Implementation contract address!
# Admin slot:
ADMIN_SLOT="0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"
cast storage $TARGET $ADMIN_SLOT \
--rpc-url $RPC
# Proxy admin address!
# βββ Packed Storage βββββββββββββββββββββββ
# Multiple variables ek slot mein!
# Example: slot 0 = address(20 bytes) + bool(1 byte)
# address = bytes 0-19
# bool = byte 20
RAW=$(cast storage $TARGET 0 --rpc-url $RPC)
echo "Raw slot: $RAW"
# 0x000000000000000000000001ADDRESS_HERE
# Last byte = bool value:
echo ${RAW: -2} # Last 2 hex chars
# 01 = true, 00 = false
# βββ Brute Force Important Slots ββββββββββ
for i in {0..10}; do
VAL=$(cast storage $TARGET $i \
--rpc-url $RPC 2>/dev/null)
echo "Slot $i: $VAL"
done
# Output:
# Slot 0: 0x0000...owner_address
# Slot 1: 0x0000...total_supply
# Slot 2: 0x0000...paused_flag
# ...
# Pattern recognize karo!PART 6: Tenderly Introduction!
Tenderly kya hai?
β Web3 development + debugging platform
β Transaction simulation
β Full execution traces
β Smart contract monitoring
β Alerts + webhooks
β Fork environment
URL: https://tenderly.co
Free tier: Available!
Kyun Tenderly?
β Etherscan sirf basic info deta hai
β Tenderly FULL trace deta hai!
β Har opcode level detail!
β Storage changes deta hai!
β Gas profiling!
β Simulation! (Mainnet state pe test!)
Security Research Mein:
β Hack TX simulate karo
β Storage changes step by step
β Exact bug point identify karo
β Fix verify karo simulation se!
β Fork pe exploit test karo!Tenderly kya hai?
β Web3 development + debugging platform
β Transaction simulation
β Full execution traces
β Smart contract monitoring
β Alerts + webhooks
β Fork environment
URL: https://tenderly.co
Free tier: Available!
Kyun Tenderly?
β Etherscan sirf basic info deta hai
β Tenderly FULL trace deta hai!
β Har opcode level detail!
β Storage changes deta hai!
β Gas profiling!
β Simulation! (Mainnet state pe test!)
Security Research Mein:
β Hack TX simulate karo
β Storage changes step by step
β Exact bug point identify karo
β Fix verify karo simulation se!
β Fork pe exploit test karo!PART 7: Tenderly Setup!
Account Create:
1. https://tenderly.co β Sign Up (free!)
2. Dashboard β New Project
3. Project name: "web3-security-research"
4. Create Project
Free Tier Limits:
β 25 simulations/day
β 5 alert rules
β Community support
β Public networks
Paid (Pro):
β Unlimited simulations
β Private forks
β Team features
β Priority support
For learning: Free tier enough hai! β
Account Create:
1. https://tenderly.co β Sign Up (free!)
2. Dashboard β New Project
3. Project name: "web3-security-research"
4. Create Project
Free Tier Limits:
β 25 simulations/day
β 5 alert rules
β Community support
β Public networks
Paid (Pro):
β Unlimited simulations
β Private forks
β Team features
β Priority support
For learning: Free tier enough hai! β
Tenderly CLI Setup:
# βββ CLI Install ββββββββββββββββββββββββββ
# npm se:
npm install -g @tenderly/cli
# Verify:
tenderly version
# tenderly version v1.x.x
# βββ Login ββββββββββββββββββββββββββββββββ
tenderly login
# Browser mein open hoga
# Authorize karo!
# βββ Project Init βββββββββββββββββββββββββ
cd my-foundry-project
tenderly init
# prompts:
# Project slug: web3-security-research
# β
tenderly.yaml created!
# tenderly.yaml:
# tenderly.yaml
account_id: "your-username"
project_slug: "web3-security-research"
push:
networks:
- mainnet
- sepolia
devnets: {}
# βββ Contract Push ββββββββββββββββββββββββ
# Contracts Tenderly pe push karo
# Better debugging ke liye!
tenderly push
# Contracts verified on Tenderly!
# Now traces mein source code dikhega!
# βββ Verify Specific Contract βββββββββββββ
tenderly verify \
--network mainnet \
--address 0xContractAddress# βββ CLI Install ββββββββββββββββββββββββββ
# npm se:
npm install -g @tenderly/cli
# Verify:
tenderly version
# tenderly version v1.x.x
# βββ Login ββββββββββββββββββββββββββββββββ
tenderly login
# Browser mein open hoga
# Authorize karo!
# βββ Project Init βββββββββββββββββββββββββ
cd my-foundry-project
tenderly init
# prompts:
# Project slug: web3-security-research
# β
tenderly.yaml created!
# tenderly.yaml:
# tenderly.yaml
account_id: "your-username"
project_slug: "web3-security-research"
push:
networks:
- mainnet
- sepolia
devnets: {}
# βββ Contract Push ββββββββββββββββββββββββ
# Contracts Tenderly pe push karo
# Better debugging ke liye!
tenderly push
# Contracts verified on Tenderly!
# Now traces mein source code dikhega!
# βββ Verify Specific Contract βββββββββββββ
tenderly verify \
--network mainnet \
--address 0xContractAddressPART 8: Tenderly Transaction Debugger!
Transaction Debug Karna:
Method 1: Website se
ββββββββββββββββββββ
1. https://dashboard.tenderly.co
2. Left sidebar β "Transactions"
3. TX hash paste karo
4. "Debug" button click karo!
Method 2: Direct URL
ββββββββββββββββββββ
https://dashboard.tenderly.co/tx/mainnet/0xTXHASH
Method 3: CLI
βββββββββββββ
tenderly export 0xTXHASH
Tenderly Debugger Interface:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Transaction: 0xABC... β
β Status: Reverted β / Success β
β
β Gas Used: 234,567 / 300,000 β
βββββββββββββββ¬ββββββββββββββββββββββββββββββββ€
β CALL TRACE β SOURCE CODE β
β β β
β βΆ attack() β function attack() { β
β βΆ deposit β vault.deposit{value: 1}(); β
β βΆ withdrawβ vault.withdraw(1 ether); β
β βΆ CALL β } β
β βΆ CALL β β
β βΆ CALL β // β Reentrancy here! β
βββββββββββββββ΄ββββββββββββββββββββββββββββββββ€
β STATE CHANGES β
β balances[attacker]: 0 β 1 ETH β 2 ETH β
β balances[victim]: 10 ETH β 9 β 8 β 7... β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β GAS PROFILER β
β withdraw(): 45,123 gas (67%) β
β deposit(): 23,456 gas (33%) β
βββββββββββββββββββββββββββββββββββββββββββββββ
Security Research Focus:
β State Changes tab = What changed when!
β Call Trace = Exact execution path!
β Revert reason = Why failed!Transaction Debug Karna:
Method 1: Website se
ββββββββββββββββββββ
1. https://dashboard.tenderly.co
2. Left sidebar β "Transactions"
3. TX hash paste karo
4. "Debug" button click karo!
Method 2: Direct URL
ββββββββββββββββββββ
https://dashboard.tenderly.co/tx/mainnet/0xTXHASH
Method 3: CLI
βββββββββββββ
tenderly export 0xTXHASH
Tenderly Debugger Interface:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Transaction: 0xABC... β
β Status: Reverted β / Success β
β
β Gas Used: 234,567 / 300,000 β
βββββββββββββββ¬ββββββββββββββββββββββββββββββββ€
β CALL TRACE β SOURCE CODE β
β β β
β βΆ attack() β function attack() { β
β βΆ deposit β vault.deposit{value: 1}(); β
β βΆ withdrawβ vault.withdraw(1 ether); β
β βΆ CALL β } β
β βΆ CALL β β
β βΆ CALL β // β Reentrancy here! β
βββββββββββββββ΄ββββββββββββββββββββββββββββββββ€
β STATE CHANGES β
β balances[attacker]: 0 β 1 ETH β 2 ETH β
β balances[victim]: 10 ETH β 9 β 8 β 7... β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β GAS PROFILER β
β withdraw(): 45,123 gas (67%) β
β deposit(): 23,456 gas (33%) β
βββββββββββββββββββββββββββββββββββββββββββββββ
Security Research Focus:
β State Changes tab = What changed when!
β Call Trace = Exact execution path!
β Revert reason = Why failed!PART 9: Tenderly Simulation Powerful Feature!
Simulation kya hai?
β Mainnet state use karo
β Apni custom transaction run karo
β Broadcast kiye bina!
β "Kya hoga agar..." test karo!
Security Research Use Cases:
β Exploit simulate karo pehle!
β Patch verify karo (kya fix kaam kiya?)
β Edge cases test karo
β Different block pe test karoSimulation kya hai?
β Mainnet state use karo
β Apni custom transaction run karo
β Broadcast kiye bina!
β "Kya hoga agar..." test karo!
Security Research Use Cases:
β Exploit simulate karo pehle!
β Patch verify karo (kya fix kaam kiya?)
β Edge cases test karo
β Different block pe test karoWeb Dashboard Simulation:
Tenderly Dashboard Simulation:
1. Dashboard β "Simulator" β "New Simulation"
2. Fill form:
ββββββββββββββββββββββββββββββββββββββββββ
β Network: Ethereum Mainnet β
β Block: 19500000 (ya Latest) β
β From: 0xYourAddress β
β To: 0xContractAddress β
β Value: 0.1 ETH (ya 0) β
β Function: deposit() β
β Params: (koi nahi) β
ββββββββββββββββββββββββββββββββββββββββββ
3. "Simulate" click karo!
4. Full trace milega:
β Execution steps
β State changes
β Events emitted
β Gas used
5. Bug mila? β "Fork" button!
β Fork create hoga
β Is state pe experiments karo!Tenderly Dashboard Simulation:
1. Dashboard β "Simulator" β "New Simulation"
2. Fill form:
ββββββββββββββββββββββββββββββββββββββββββ
β Network: Ethereum Mainnet β
β Block: 19500000 (ya Latest) β
β From: 0xYourAddress β
β To: 0xContractAddress β
β Value: 0.1 ETH (ya 0) β
β Function: deposit() β
β Params: (koi nahi) β
ββββββββββββββββββββββββββββββββββββββββββ
3. "Simulate" click karo!
4. Full trace milega:
β Execution steps
β State changes
β Events emitted
β Gas used
5. Bug mila? β "Fork" button!
β Fork create hoga
β Is state pe experiments karo!Tenderly API Programmatic Simulation:
#!/usr/bin/env python3
# tenderly_simulate.py
import requests
import json
import os
TENDERLY_KEY = os.environ.get("TENDERLY_API_KEY")
TENDERLY_ACCOUNT = os.environ.get("TENDERLY_ACCOUNT")
TENDERLY_PROJECT = os.environ.get("TENDERLY_PROJECT")
BASE_URL = (
f"https://api.tenderly.co/api/v1/account/"
f"{TENDERLY_ACCOUNT}/project/"
f"{TENDERLY_PROJECT}"
)
HEADERS = {
"X-Access-Key": TENDERLY_KEY,
"Content-Type": "application/json"
}
def simulate_transaction(
from_addr,
to_addr,
data,
value=0,
block_number=None
):
"""
Transaction simulate karo Tenderly se!
"""
payload = {
"network_id": "1", # Mainnet
"from": from_addr,
"to": to_addr,
"input": data,
"value": str(value),
"save": True, # Save karo!
"save_if_fails": True, # Even if fails!
"simulation_type": "full", # Full trace!
}
if block_number:
payload["block_number"] = block_number
response = requests.post(
f"{BASE_URL}/simulate",
headers=HEADERS,
json=payload
)
return response.json()
def analyze_simulation(result):
"""
Simulation result analyze karo!
"""
sim = result.get("simulation", {})
print("\n=== SIMULATION RESULT ===")
print(f"Status: {'β
Success' if sim.get('status') else 'β Reverted'}")
print(f"Gas Used: {sim.get('gas_used', 'N/A')}")
if not sim.get("status"):
print(f"Revert Reason: {sim.get('error_message', 'Unknown')}")
# State changes:
changes = result.get("transaction", {}).get(
"state_diff", {}
)
if changes:
print("\nπ State Changes:")
for addr, diff in changes.items():
print(f"\n Contract: {addr}")
for slot, change in diff.items():
print(f" Slot {slot}:")
print(f" Before: {change.get('original')}")
print(f" After: {change.get('dirty')}")
# Events:
logs = result.get("transaction", {}).get(
"logs", []
)
if logs:
print(f"\nπ’ Events Emitted: {len(logs)}")
for log in logs:
print(f" - {log.get('name', 'Unknown')}")
# Simulation URL:
sim_id = sim.get("id")
if sim_id:
print(f"\nπ View: https://dashboard.tenderly.co/"
f"{TENDERLY_ACCOUNT}/{TENDERLY_PROJECT}/"
f"simulator/{sim_id}")
# βββ Example Usage ββββββββββββββββββββββββ
if __name__ == "__main__":
# USDC transfer simulate karo:
from web3 import Web3
# Encode function call:
w3 = Web3()
abi_fragment = [{
"name": "transfer",
"type": "function",
"inputs": [
{"name": "to", "type": "address"},
{"name": "value", "type": "uint256"}
]
}]
contract = w3.eth.contract(abi=abi_fragment)
data = contract.encodeABI(
fn_name="transfer",
args=[
"0xRecipientAddress",
1000 * 10**6 # 1000 USDC
]
)
result = simulate_transaction(
from_addr="0xUSDC_WHALE",
to_addr="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
data=data,
block_number=19500000
)
analyze_simulation(result)#!/usr/bin/env python3
# tenderly_simulate.py
import requests
import json
import os
TENDERLY_KEY = os.environ.get("TENDERLY_API_KEY")
TENDERLY_ACCOUNT = os.environ.get("TENDERLY_ACCOUNT")
TENDERLY_PROJECT = os.environ.get("TENDERLY_PROJECT")
BASE_URL = (
f"https://api.tenderly.co/api/v1/account/"
f"{TENDERLY_ACCOUNT}/project/"
f"{TENDERLY_PROJECT}"
)
HEADERS = {
"X-Access-Key": TENDERLY_KEY,
"Content-Type": "application/json"
}
def simulate_transaction(
from_addr,
to_addr,
data,
value=0,
block_number=None
):
"""
Transaction simulate karo Tenderly se!
"""
payload = {
"network_id": "1", # Mainnet
"from": from_addr,
"to": to_addr,
"input": data,
"value": str(value),
"save": True, # Save karo!
"save_if_fails": True, # Even if fails!
"simulation_type": "full", # Full trace!
}
if block_number:
payload["block_number"] = block_number
response = requests.post(
f"{BASE_URL}/simulate",
headers=HEADERS,
json=payload
)
return response.json()
def analyze_simulation(result):
"""
Simulation result analyze karo!
"""
sim = result.get("simulation", {})
print("\n=== SIMULATION RESULT ===")
print(f"Status: {'β
Success' if sim.get('status') else 'β Reverted'}")
print(f"Gas Used: {sim.get('gas_used', 'N/A')}")
if not sim.get("status"):
print(f"Revert Reason: {sim.get('error_message', 'Unknown')}")
# State changes:
changes = result.get("transaction", {}).get(
"state_diff", {}
)
if changes:
print("\nπ State Changes:")
for addr, diff in changes.items():
print(f"\n Contract: {addr}")
for slot, change in diff.items():
print(f" Slot {slot}:")
print(f" Before: {change.get('original')}")
print(f" After: {change.get('dirty')}")
# Events:
logs = result.get("transaction", {}).get(
"logs", []
)
if logs:
print(f"\nπ’ Events Emitted: {len(logs)}")
for log in logs:
print(f" - {log.get('name', 'Unknown')}")
# Simulation URL:
sim_id = sim.get("id")
if sim_id:
print(f"\nπ View: https://dashboard.tenderly.co/"
f"{TENDERLY_ACCOUNT}/{TENDERLY_PROJECT}/"
f"simulator/{sim_id}")
# βββ Example Usage ββββββββββββββββββββββββ
if __name__ == "__main__":
# USDC transfer simulate karo:
from web3 import Web3
# Encode function call:
w3 = Web3()
abi_fragment = [{
"name": "transfer",
"type": "function",
"inputs": [
{"name": "to", "type": "address"},
{"name": "value", "type": "uint256"}
]
}]
contract = w3.eth.contract(abi=abi_fragment)
data = contract.encodeABI(
fn_name="transfer",
args=[
"0xRecipientAddress",
1000 * 10**6 # 1000 USDC
]
)
result = simulate_transaction(
from_addr="0xUSDC_WHALE",
to_addr="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
data=data,
block_number=19500000
)
analyze_simulation(result)PART 10: Tenderly Fork Testing Environment!
Tenderly Fork kya hai?
β Mainnet ka snapshot
β Apna private fork!
β Real state + apni transactions
β Broadcast nahi hoti real chain pe!
β Experiments ke liye perfect!
Foundry ke vm.createFork() jaisa!
Lekin:
β Persistent (restart ke baad bhi)
β Shareable (team ke saath)
β Web dashboard available
β No RPC needed for basic use!
# βββ Tenderly Fork Create βββββββββββββββββ
# Dashboard se:
# 1. Tenderly Dashboard β "Forks"
# 2. "Create Fork"
# 3. Network: Mainnet
# 4. Block: 19500000
# 5. Create!
# 6. Fork RPC URL copy karo!
# CLI se:
tenderly devnet spawn-rpc \
--project web3-security-research \
--template mainnet
# Output:
# DevNet RPC: https://rpc.tenderly.co/fork/YOUR_FORK_ID
# βββ Fork Ke Saath Foundry Use Karo βββββββ
# foundry.toml mein add karo:
[rpc_endpoints]
tenderly_fork = "https://rpc.tenderly.co/fork/YOUR_ID"
# Tests run karo Tenderly fork pe:
forge test \
--fork-url $TENDERLY_FORK_URL \
-vvvv
# Ya script:
forge script script/Exploit.s.sol \
--rpc-url $TENDERLY_FORK_URL \
--broadcast
# Tenderly dashboard mein:
# β Sari transactions visible!
# β Full traces available!
# β State changes color coded!Tenderly Fork kya hai?
β Mainnet ka snapshot
β Apna private fork!
β Real state + apni transactions
β Broadcast nahi hoti real chain pe!
β Experiments ke liye perfect!
Foundry ke vm.createFork() jaisa!
Lekin:
β Persistent (restart ke baad bhi)
β Shareable (team ke saath)
β Web dashboard available
β No RPC needed for basic use!
# βββ Tenderly Fork Create βββββββββββββββββ
# Dashboard se:
# 1. Tenderly Dashboard β "Forks"
# 2. "Create Fork"
# 3. Network: Mainnet
# 4. Block: 19500000
# 5. Create!
# 6. Fork RPC URL copy karo!
# CLI se:
tenderly devnet spawn-rpc \
--project web3-security-research \
--template mainnet
# Output:
# DevNet RPC: https://rpc.tenderly.co/fork/YOUR_FORK_ID
# βββ Fork Ke Saath Foundry Use Karo βββββββ
# foundry.toml mein add karo:
[rpc_endpoints]
tenderly_fork = "https://rpc.tenderly.co/fork/YOUR_ID"
# Tests run karo Tenderly fork pe:
forge test \
--fork-url $TENDERLY_FORK_URL \
-vvvv
# Ya script:
forge script script/Exploit.s.sol \
--rpc-url $TENDERLY_FORK_URL \
--broadcast
# Tenderly dashboard mein:
# β Sari transactions visible!
# β Full traces available!
# β State changes color coded!PART 11: Real Hack Analyze Euler Finance!
# Euler Finance Hack β $197M (March 2023)
# Hack TX analyze karte hain!
HACK_TX="0xc310a0affe2169d1f6feec1c63dbc7f7c62a887521"
# (Simplified hash β real hash longer)
# βββ Step 1: Etherscan pe dekho βββββββββββ
# https://etherscan.io/tx/0xHACK_TX
# Internal transactions tab:
# Flash loan β Donate β Liquidate β Profit!
# βββ Step 2: cast se analyze ββββββββββββββ
cast tx $HACK_TX \
--rpc-url $MAINNET_RPC
# Output:
# from: 0xb66cd966670d962C227B3EABA30a872DbFb995db
# to: 0xb66cd9... (Euler exploit contract)
# value: 0
# input: 0x... (complex calldata)
# βββ Step 3: Trace decode βββββββββββββββββ
cast run $HACK_TX \
--rpc-url $MAINNET_RPC \
--trace
# Full execution trace!
# Each CALL, SSTORE, SLOAD visible!
# βββ Step 4: Tenderly mein open karo ββββββ
# https://dashboard.tenderly.co/tx/mainnet/0xHACK_TX
# Tenderly trace mein dikhega:
# 1. EulerExploit.attack() called
# 2. DToken.donateToReserves() β Bug here!
# 3. Violator position created
# 4. Liquidation executed
# 5. Massive profit extracted!
# Root cause:
# donateToReserves() ne
# health factor check nahi kiya!
# Attacker apna loan donate kiya
# β Underwater position bana
# β Self-liquidate kiya
# β Liquidation bonus steal kiya!
# βββ Step 5: Foundry mein PoC βββββββββββββ
forge test \
--match-test "test_eulerExploit" \
--fork-url $MAINNET_RPC \
--fork-block-number 16817995 \
-vvvv
# Block number = 1 block before hack!# Euler Finance Hack β $197M (March 2023)
# Hack TX analyze karte hain!
HACK_TX="0xc310a0affe2169d1f6feec1c63dbc7f7c62a887521"
# (Simplified hash β real hash longer)
# βββ Step 1: Etherscan pe dekho βββββββββββ
# https://etherscan.io/tx/0xHACK_TX
# Internal transactions tab:
# Flash loan β Donate β Liquidate β Profit!
# βββ Step 2: cast se analyze ββββββββββββββ
cast tx $HACK_TX \
--rpc-url $MAINNET_RPC
# Output:
# from: 0xb66cd966670d962C227B3EABA30a872DbFb995db
# to: 0xb66cd9... (Euler exploit contract)
# value: 0
# input: 0x... (complex calldata)
# βββ Step 3: Trace decode βββββββββββββββββ
cast run $HACK_TX \
--rpc-url $MAINNET_RPC \
--trace
# Full execution trace!
# Each CALL, SSTORE, SLOAD visible!
# βββ Step 4: Tenderly mein open karo ββββββ
# https://dashboard.tenderly.co/tx/mainnet/0xHACK_TX
# Tenderly trace mein dikhega:
# 1. EulerExploit.attack() called
# 2. DToken.donateToReserves() β Bug here!
# 3. Violator position created
# 4. Liquidation executed
# 5. Massive profit extracted!
# Root cause:
# donateToReserves() ne
# health factor check nahi kiya!
# Attacker apna loan donate kiya
# β Underwater position bana
# β Self-liquidate kiya
# β Liquidation bonus steal kiya!
# βββ Step 5: Foundry mein PoC βββββββββββββ
forge test \
--match-test "test_eulerExploit" \
--fork-url $MAINNET_RPC \
--fork-block-number 16817995 \
-vvvv
# Block number = 1 block before hack!PART 12: Complete Recon Workflow!
#!/bin/bash
# recon.sh
# Complete target recon script!
TARGET=$1
# Usage: ./recon.sh 0xContractAddress
echo "ββββββββββββββββββββββββββββββββββββ"
echo "β Web3 Security Recon Tool β"
echo "ββββββββββββββββββββββββββββββββββββ"
echo "Target: $TARGET"
echo ""
RPC=$MAINNET_RPC_URL
# βββ 1. Basic Info ββββββββββββββββββββββββ
echo "π [1/6] Basic Information"
# Code exists?
CODE=$(cast code $TARGET --rpc-url $RPC)
if [ "$CODE" = "0x" ]; then
echo " β οΈ EOA β Not a contract!"
exit 1
fi
# Code size:
SIZE=$(cast codesize $TARGET --rpc-url $RPC)
echo " Code size: $SIZE bytes"
# ETH balance:
BAL=$(cast balance $TARGET \
--ether --rpc-url $RPC)
echo " ETH balance: $BAL ETH"
# βββ 2. Contract Metadata βββββββββββββββββ
echo ""
echo "π [2/6] Contract Metadata"
# Try owner():
OWNER=$(cast call $TARGET \
"owner()(address)" \
--rpc-url $RPC 2>/dev/null)
if [ ! -z "$OWNER" ]; then
echo " Owner: $OWNER"
fi
# Try paused():
PAUSED=$(cast call $TARGET \
"paused()(bool)" \
--rpc-url $RPC 2>/dev/null)
if [ ! -z "$PAUSED" ]; then
echo " Paused: $PAUSED"
fi
# Proxy check (EIP-1967):
IMPL_SLOT="0x360894a13ba1a3210667c828492db98\
dca3e2076cc3735a920a3ca505d382bbc"
IMPL=$(cast storage $TARGET $IMPL_SLOT \
--rpc-url $RPC 2>/dev/null)
if [ "$IMPL" != "0x0000000000000000000000000000000000000000000000000000000000000000" ]; then
echo " β οΈ PROXY DETECTED!"
echo " Implementation: $IMPL"
fi
# βββ 3. Storage Slots βββββββββββββββββββββ
echo ""
echo "ποΈ [3/6] Storage Slots (0-5)"
for i in {0..5}; do
VAL=$(cast storage $TARGET $i \
--rpc-url $RPC 2>/dev/null)
echo " Slot $i: $VAL"
done
# βββ 4. Slither Quick Scan ββββββββββββββββ
echo ""
echo "π [4/6] Slither Quick Scan"
# Download source from Etherscan:
slither $TARGET \
--etherscan-apikey $ETHERSCAN_API_KEY \
--exclude-informational \
--exclude-low \
2>&1 | tail -20
# βββ 5. Recent Activity βββββββββββββββββββ
echo ""
echo "π [5/6] Recent Transactions"
curl -s "https://api.etherscan.io/api?\
module=account&action=txlist\
&address=$TARGET\
&sort=desc&offset=5&page=1\
&apikey=$ETHERSCAN_API_KEY" \
| python3 -c "
import json, sys
from datetime import datetime
d = json.load(sys.stdin)
txs = d.get('result', [])
for tx in txs[:5]:
ts = datetime.fromtimestamp(
int(tx['timeStamp'])
).strftime('%Y-%m-%d %H:%M')
val = int(tx['value'])/1e18
st = 'β
' if tx['txreceipt_status']=='1' else 'β'
print(f' {st} {ts} {val:.3f}ETH {tx[\"hash\"][:16]}...')
"
# βββ 6. Summary βββββββββββββββββββββββββββ
echo ""
echo "ββββββββββββββββββββββββββββββββββββ"
echo "β RECON SUMMARY β"
echo "β βββββββββββββββββββββββββββββββββββ£"
echo "β Target: $TARGET β"
echo "β Balance: $BAL ETH β"
echo "ββββββββββββββββββββββββββββββββββββ"
echo ""
echo "Next Steps:"
echo " 1. Tenderly mein TX traces dekho"
echo " 2. Mythril deep scan karo"
echo " 3. Manual code review karo"
echo " 4. Foundry mein PoC likho!"#!/bin/bash
# recon.sh
# Complete target recon script!
TARGET=$1
# Usage: ./recon.sh 0xContractAddress
echo "ββββββββββββββββββββββββββββββββββββ"
echo "β Web3 Security Recon Tool β"
echo "ββββββββββββββββββββββββββββββββββββ"
echo "Target: $TARGET"
echo ""
RPC=$MAINNET_RPC_URL
# βββ 1. Basic Info ββββββββββββββββββββββββ
echo "π [1/6] Basic Information"
# Code exists?
CODE=$(cast code $TARGET --rpc-url $RPC)
if [ "$CODE" = "0x" ]; then
echo " β οΈ EOA β Not a contract!"
exit 1
fi
# Code size:
SIZE=$(cast codesize $TARGET --rpc-url $RPC)
echo " Code size: $SIZE bytes"
# ETH balance:
BAL=$(cast balance $TARGET \
--ether --rpc-url $RPC)
echo " ETH balance: $BAL ETH"
# βββ 2. Contract Metadata βββββββββββββββββ
echo ""
echo "π [2/6] Contract Metadata"
# Try owner():
OWNER=$(cast call $TARGET \
"owner()(address)" \
--rpc-url $RPC 2>/dev/null)
if [ ! -z "$OWNER" ]; then
echo " Owner: $OWNER"
fi
# Try paused():
PAUSED=$(cast call $TARGET \
"paused()(bool)" \
--rpc-url $RPC 2>/dev/null)
if [ ! -z "$PAUSED" ]; then
echo " Paused: $PAUSED"
fi
# Proxy check (EIP-1967):
IMPL_SLOT="0x360894a13ba1a3210667c828492db98\
dca3e2076cc3735a920a3ca505d382bbc"
IMPL=$(cast storage $TARGET $IMPL_SLOT \
--rpc-url $RPC 2>/dev/null)
if [ "$IMPL" != "0x0000000000000000000000000000000000000000000000000000000000000000" ]; then
echo " β οΈ PROXY DETECTED!"
echo " Implementation: $IMPL"
fi
# βββ 3. Storage Slots βββββββββββββββββββββ
echo ""
echo "ποΈ [3/6] Storage Slots (0-5)"
for i in {0..5}; do
VAL=$(cast storage $TARGET $i \
--rpc-url $RPC 2>/dev/null)
echo " Slot $i: $VAL"
done
# βββ 4. Slither Quick Scan ββββββββββββββββ
echo ""
echo "π [4/6] Slither Quick Scan"
# Download source from Etherscan:
slither $TARGET \
--etherscan-apikey $ETHERSCAN_API_KEY \
--exclude-informational \
--exclude-low \
2>&1 | tail -20
# βββ 5. Recent Activity βββββββββββββββββββ
echo ""
echo "π [5/6] Recent Transactions"
curl -s "https://api.etherscan.io/api?\
module=account&action=txlist\
&address=$TARGET\
&sort=desc&offset=5&page=1\
&apikey=$ETHERSCAN_API_KEY" \
| python3 -c "
import json, sys
from datetime import datetime
d = json.load(sys.stdin)
txs = d.get('result', [])
for tx in txs[:5]:
ts = datetime.fromtimestamp(
int(tx['timeStamp'])
).strftime('%Y-%m-%d %H:%M')
val = int(tx['value'])/1e18
st = 'β
' if tx['txreceipt_status']=='1' else 'β'
print(f' {st} {ts} {val:.3f}ETH {tx[\"hash\"][:16]}...')
"
# βββ 6. Summary βββββββββββββββββββββββββββ
echo ""
echo "ββββββββββββββββββββββββββββββββββββ"
echo "β RECON SUMMARY β"
echo "β βββββββββββββββββββββββββββββββββββ£"
echo "β Target: $TARGET β"
echo "β Balance: $BAL ETH β"
echo "ββββββββββββββββββββββββββββββββββββ"
echo ""
echo "Next Steps:"
echo " 1. Tenderly mein TX traces dekho"
echo " 2. Mythril deep scan karo"
echo " 3. Manual code review karo"
echo " 4. Foundry mein PoC likho!"Quick Revision
π Etherscan:
Contract tab β Source code!
Read Contract β State variables
Read as Proxy β Proxy state!
Internal Txns β Contract calls!
Events tab β Admin actions!
API endpoints:
getsourcecode β ABI + Code
txlist β TX history
getLogs β Events filter
getabi β ABI only
π Storage Reading:
cast storage ADDR SLOT β Raw value
cast index address USER SLOT β Mapping!
EIP-1967 impl slot β Proxy detection
π Tenderly:
Transaction Debugger β Full traces!
Simulator β Test without broadcasting!
Fork β Private test environment!
CLI β tenderly push/export
Key features:
β Step-by-step execution
β State changes visualization
β Gas profiling
β Revert reason
β Source code mapping
π Complete Workflow:
1. Etherscan β Basic recon
2. Storage slots β Hidden state
3. Tenderly Simulator β Test
4. Tenderly Fork β Exploit test
5. Slither scan β Static analysis
6. Foundry PoC β Confirm bug
π― Hack Analysis Workflow:
1. Hack TX on Etherscan
2. Internal txns trace
3. Tenderly full trace
4. Root cause identify
5. Foundry fork reproduce
6. Write report!π Etherscan:
Contract tab β Source code!
Read Contract β State variables
Read as Proxy β Proxy state!
Internal Txns β Contract calls!
Events tab β Admin actions!
API endpoints:
getsourcecode β ABI + Code
txlist β TX history
getLogs β Events filter
getabi β ABI only
π Storage Reading:
cast storage ADDR SLOT β Raw value
cast index address USER SLOT β Mapping!
EIP-1967 impl slot β Proxy detection
π Tenderly:
Transaction Debugger β Full traces!
Simulator β Test without broadcasting!
Fork β Private test environment!
CLI β tenderly push/export
Key features:
β Step-by-step execution
β State changes visualization
β Gas profiling
β Revert reason
β Source code mapping
π Complete Workflow:
1. Etherscan β Basic recon
2. Storage slots β Hidden state
3. Tenderly Simulator β Test
4. Tenderly Fork β Exploit test
5. Slither scan β Static analysis
6. Foundry PoC β Confirm bug
π― Hack Analysis Workflow:
1. Hack TX on Etherscan
2. Internal txns trace
3. Tenderly full trace
4. Root cause identify
5. Foundry fork reproduce
6. Write report!Meri Baatβ¦
Ek story:
2022 mein Wormhole hack hua β $320M!
Hack ke 2 ghante baad:
Researcher A ne kya kiya:
β Etherscan pe hack TX dhundha
β Internal transactions dekha
β Tenderly mein simulate kiya
β Root cause: Signature bypass!
β Detailed thread Twitter pe
β 50,000 followers overnight!
Researcher B ne kya kiya:
β News padhi
β "Bahut bura hua" bola
β Soy gaya
Difference:
Researcher A ke paas tools tha!
Etherscan + Tenderly = Complete picture!
Aaj tum ne seekha:
β Etherscan recon
β API automation
β Storage slots read karna
β Tenderly simulation
β Tenderly fork
β Hack TX analyze karna
Yeh skills = Hack ke baad
sabse pehle samajhne waale
researchers mein se ek!
Phase 2 (Tools) COMPLETE!
Agle phase mein:
RECON & METHODOLOGY!
Web3 targets kaise dhundhte aur
analyze karte hain β professional way!Ek story:
2022 mein Wormhole hack hua β $320M!
Hack ke 2 ghante baad:
Researcher A ne kya kiya:
β Etherscan pe hack TX dhundha
β Internal transactions dekha
β Tenderly mein simulate kiya
β Root cause: Signature bypass!
β Detailed thread Twitter pe
β 50,000 followers overnight!
Researcher B ne kya kiya:
β News padhi
β "Bahut bura hua" bola
β Soy gaya
Difference:
Researcher A ke paas tools tha!
Etherscan + Tenderly = Complete picture!
Aaj tum ne seekha:
β Etherscan recon
β API automation
β Storage slots read karna
β Tenderly simulation
β Tenderly fork
β Hack TX analyze karna
Yeh skills = Hack ke baad
sabse pehle samajhne waale
researchers mein se ek!
Phase 2 (Tools) COMPLETE!
Agle phase mein:
RECON & METHODOLOGY!
Web3 targets kaise dhundhte aur
analyze karte hain β professional way!Article #15 mein: Web3 Recon Target Research Kaise Karo Etherscan, DeFiLlama, Dune Analytics, GitHub! β‘
HackerMD_ Web3 Security Researcher_ GitHub: BotGJ16 | Medium: @HackerMD
Previous: Article #13 Mythril + Echidna Next: Article #15 Web3 Recon
#Tenderly #Etherscan #Web3Security #Debugging #TransactionTrace #BugBounty #Hinglish #HackerMD