Real-time monitoring and alerting system for large cryptocurrency transfers on the blockchain
Features β’ Installation β’ Code Structure β’ Documentation β’ Contributing
- Overview
- Features
- Architecture
- Deployed Contracts
- Complete Code Structure
- Installation
- Quick Start
- Configuration
- Usage Guide
- Query API
- Customization
- Testing
- Monitoring
- Troubleshooting
- Resources
- Contributing
- License
The Whale Transaction Alert Trap is a sophisticated blockchain monitoring system built on the Drosera Network that detects and records large token transfers (whale movements) in real-time. When a transaction exceeds a predefined threshold, the system triggers an on-chain alert, creating an immutable record of whale activity.
- Market Intelligence: Track institutional and whale movements
- Risk Management: Detect large transfers that may impact liquidity
- Transparency: Public, on-chain record of major transactions
- Early Warning: Real-time alerts for significant market events
|
|
graph TD
A[Blockchain Transactions] -->|Monitor| B[WhaleTransferTrap]
B -->|collect| C{Transfer Data}
C -->|shouldRespond| D{Amount > 1000?}
D -->|Yes| E[WhaleTransferResponse]
D -->|No| F[Ignore]
E -->|recordAlert| G[On-chain Storage]
G -->|emit| H[AlertRecorded Event]
style B fill:#4CAF50
style E fill:#2196F3
style G fill:#FF9800
style H fill:#9C27B0
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HOODI BLOCKCHAIN NETWORK β
β β
β ββββββββββββββββββ ββββββββββββββββββ β
β β Transfer A β β Transfer B β β
β β (500 tokens) β β (1500 tokens) β β
β ββββββββββ¬ββββββββ ββββββββββ¬ββββββββ β
β β β β
β ββββββββββββ ββββββββββ β
β βΌ βΌ β
β ββββββββββββββββββββββββββββββββββββββββββ β
β β WhaleTransferTrap.sol β β
β β ββββββββββββββββββββββββββββββββββββ β β
β β β β’ collect() - Gather transfers β β β
β β β β’ shouldRespond() - Check > 1k β β β
β β ββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββ¬ββββββββββββββββββββββββββ β
β β β
β β β οΈ Threshold Exceeded β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββ β
β β WhaleTransferResponse.sol β β
β β ββββββββββββββββββββββββββββββββββββ β β
β β β β’ recordAlert() β β β
β β β β’ Store: from, to, amount, block β β β
β β β β’ Emit: AlertRecorded event β β β
β β ββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Contract Name | Address | Verified |
|---|---|---|
| WhaleTransferResponse | 0xE5701AE464d94449461D224b1f11D5b55be1EC0f |
β |
| WhaleTransferTrap | 0x9b06F678c4df0eF1282b03FF9FE804444F513d26 |
β |
Network: Hoodi Testnet (Chain ID: 560048)
Threshold: 1,000 tokens (1000 Γ 10ΒΉβΈ wei)
Status: π’ Active & Monitoring
whale-transaction-trap/
β
βββ π src/
β βββ π IWhaleTransferResponse.sol # Interface definition
β βββ π WhaleTransferResponse.sol # Alert storage & event emission
β βββ π WhaleTransferTrap.sol # Main trap logic & threshold
β
βββ π script/
β βββ π Deploy.s.sol # Foundry deployment script
β
βββ π test/
β βββ π *.t.sol # Test files
β
βββ π drosera.toml # Drosera trap configuration
βββ π foundry.toml # Foundry project config
βββ π .env.example # Environment template
βββ π .gitignore # Git ignore rules
βββ π LICENSE # MIT License
βββ π README.md # This file
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title IWhaleTransferResponse
* @notice Interface for the Whale Transfer Response contract
* @dev Defines the function signature for recording whale transaction alerts
*/
interface IWhaleTransferResponse {
/**
* @notice Record a whale transfer alert
* @param from The address sending the tokens
* @param to The address receiving the tokens
* @param amount The amount of tokens transferred
* @param blockNumber The block number when the transfer occurred
*/
function recordAlert(
address from,
address to,
uint256 amount,
uint256 blockNumber
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IWhaleTransferResponse} from "./IWhaleTransferResponse.sol";
/**
* @title WhaleTransferResponse
* @notice Stores and manages whale transfer alerts on-chain
* @dev Records alerts when large transfers are detected by the trap
*/
contract WhaleTransferResponse is IWhaleTransferResponse {
/// @notice Emitted when a new whale transfer alert is recorded
event AlertRecorded(
address indexed from,
address indexed to,
uint256 amount,
uint256 blockNumber,
uint256 timestamp
);
/// @notice Structure to store alert data
struct Alert {
address from; // Sender address
address to; // Receiver address
uint256 amount; // Transfer amount
uint256 blockNumber; // Block when detected
uint256 timestamp; // Unix timestamp
}
/// @notice Array storing all alerts
Alert[] public alerts;
/// @notice Mapping to count alerts per address
mapping(address => uint256) public alertCountByAddress;
/// @notice The trap config contract authorized to record alerts
address public immutable TRAP_CONFIG;
/**
* @notice Constructor sets the authorized trap config
* @param _trapConfig Address of the trap configuration contract
*/
constructor(address _trapConfig) {
require(_trapConfig != address(0), "Invalid trap config");
TRAP_CONFIG = _trapConfig;
}
/// @notice Restricts function access to trap config only
modifier onlyTrapConfig() {
require(msg.sender == TRAP_CONFIG, "Only trap config can call");
_;
}
/**
* @notice Record a new whale transfer alert
* @param from Sender address
* @param to Receiver address
* @param amount Transfer amount
* @param blockNumber Block number of detection
*/
function recordAlert(
address from,
address to,
uint256 amount,
uint256 blockNumber
) external onlyTrapConfig {
alerts.push(Alert({
from: from,
to: to,
amount: amount,
blockNumber: blockNumber,
timestamp: block.timestamp
}));
alertCountByAddress[from]++;
alertCountByAddress[to]++;
emit AlertRecorded(from, to, amount, blockNumber, block.timestamp);
}
/**
* @notice Get the total number of alerts recorded
* @return Total alert count
*/
function getAlertCount() external view returns (uint256) {
return alerts.length;
}
/**
* @notice Get a specific alert by index
* @param index The alert index
* @return Alert data structure
*/
function getAlert(uint256 index) external view returns (Alert memory) {
require(index < alerts.length, "Index out of bounds");
return alerts[index];
}
/**
* @notice Get the latest N alerts
* @param count Number of alerts to retrieve
* @return Array of the most recent alerts
*/
function getLatestAlerts(uint256 count) external view returns (Alert[] memory) {
uint256 length = alerts.length;
uint256 returnCount = count > length ? length : count;
Alert[] memory latestAlerts = new Alert[](returnCount);
for (uint256 i = 0; i < returnCount; i++) {
latestAlerts[i] = alerts[length - returnCount + i];
}
return latestAlerts;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ITrap} from "drosera-contracts/interfaces/ITrap.sol";
/**
* @title WhaleTransferTrap
* @notice Monitors blockchain for large token transfers (whale movements)
* @dev Implements Drosera's ITrap interface to detect transfers exceeding threshold
*/
contract WhaleTransferTrap is ITrap {
/// @notice Threshold for whale detection: 1000 tokens (with 18 decimals)
uint256 public constant WHALE_THRESHOLD = 1000 * 10**18;
/// @notice Structure to hold transfer data
struct TransferData {
address from; // Sender address
address to; // Receiver address
uint256 amount; // Transfer amount
uint256 blockNumber; // Block number
}
/**
* @notice Collect transfer data from the blockchain
* @dev Called by Drosera operators to gather transaction data
* @return Encoded transfer data
*/
function collect() external view returns (bytes memory) {
// In production, this would parse actual transaction logs
// For demonstration, we return a sample data structure
TransferData memory data = TransferData({
from: address(0),
to: address(0),
amount: 0,
blockNumber: block.number
});
return abi.encode(data);
}
/**
* @notice Determine if a transfer exceeds the whale threshold
* @dev Called by Drosera to check if response should be triggered
* @param collectedData Array of collected transfer data
* @return shouldTrigger True if threshold exceeded
* @return responseData Encoded data to pass to response contract
*/
function shouldRespond(bytes[] calldata collectedData)
external
pure
returns (bool shouldTrigger, bytes memory responseData)
{
require(collectedData.length > 0, "No data collected");
TransferData memory data = abi.decode(collectedData[0], (TransferData));
// Check if amount exceeds whale threshold and has valid sender
if (data.amount >= WHALE_THRESHOLD && data.from != address(0)) {
return (true, abi.encode(data.from, data.to, data.amount, data.blockNumber));
}
return (false, bytes(""));
}
/**
* @notice Get the current whale threshold
* @return Threshold value in wei
*/
function getThreshold() external pure returns (uint256) {
return WHALE_THRESHOLD;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Script.sol";
import "forge-std/console.sol";
import "../src/WhaleTransferResponse.sol";
import "../src/WhaleTransferTrap.sol";
/**
* @title DeployScript
* @notice Deployment script for Whale Transfer Alert system
* @dev Uses Foundry's scripting functionality
*/
contract DeployScript is Script {
function run() external {
// Get deployer private key from environment
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
// Start broadcasting transactions
vm.startBroadcast(deployerPrivateKey);
// Deploy Response Contract with placeholder trap config
// This address will be replaced when trap config is created
address placeholder = 0x0000000000000000000000000000000000000001;
WhaleTransferResponse response = new WhaleTransferResponse(placeholder);
console.log("===========================================");
console.log("WhaleTransferResponse:", address(response));
console.log("===========================================");
// Deploy Trap Contract (no constructor parameters allowed)
WhaleTransferTrap trap = new WhaleTransferTrap();
console.log("WhaleTransferTrap:", address(trap));
console.log("Whale Threshold:", trap.getThreshold());
console.log("===========================================");
// Stop broadcasting
vm.stopBroadcast();
// Display next steps
console.log("");
console.log("NEXT STEPS:");
console.log("1. Copy Response Contract address to drosera.toml");
console.log("2. Run: DROSERA_PRIVATE_KEY=xxx drosera apply");
}
}# Drosera Trap Configuration File
# Network: Hoodi Testnet
# RPC endpoints
ethereum_rpc = "https://ethereum-hoodi-rpc.publicnode.com"
drosera_rpc = "https://relay.hoodi.drosera.io"
# Network configuration
eth_chain_id = 560048
drosera_address = "0x91cB447BaFc6e0EA0F4Fe056F5a9b1F14bb06e5D"
# Trap definitions
[traps]
[traps.whaletransfer]
# Path to compiled trap contract
path = "out/WhaleTransferTrap.sol/WhaleTransferTrap.json"
# Response contract address (update after deployment)
response_contract = "0xE5701AE464d94449461D224b1f11D5b55be1EC0f"
# Response function signature
response_function = "recordAlert(address,address,uint256,uint256)"
# Trap parameters
cooldown_period_blocks = 33 # Blocks between responses
min_number_of_operators = 1 # Minimum operators required
max_number_of_operators = 2 # Maximum operators allowed
block_sample_size = 10 # Blocks to sample per check
# Access control
private_trap = true # Restrict to whitelisted operators
whitelist = ["0x929a3B64D53481d8D2332a8778dB4984F5c70bfD"]
# Trap config address (added after first deployment)
# address = "0xYOUR_TRAP_CONFIG_ADDRESS"[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.20"
# Optimizer settings
optimizer = true
optimizer_runs = 200
# Remappings for imports
remappings = [
"forge-std/=lib/forge-std/src/",
"drosera-contracts/=lib/drosera-contracts/src/"
]
# Test settings
[profile.default.fuzz]
runs = 256
[profile.default.invariant]
runs = 256
depth = 15
# RPC endpoints
[rpc_endpoints]
hoodi = "https://ethereum-hoodi-rpc.publicnode.com"
# Etherscan configuration (for verification)
[etherscan]
hoodi = { key = "${ETHERSCAN_API_KEY}" }# Environment Variables Template
# Copy this file to .env and fill in your values
# RPC URL for Hoodi testnet
HOODI_RPC_URL=https://ethereum-hoodi-rpc.publicnode.com
# Your wallet private key (without 0x prefix)
# β οΈ NEVER commit the actual .env file with real keys!
PRIVATE_KEY=your_private_key_here_without_0x
# Trap configuration address (filled after first deployment)
TRAP_CONFIG_ADDRESS=
# Optional: Etherscan API key for contract verification
ETHERSCAN_API_KEY=# Foundry files
cache/
out/
broadcast/
# Environment files - NEVER COMMIT THESE
.env
.env.local
*.key
*_key
secrets.json
# Dependencies
node_modules/
lib/
bun.lockb
# IDE files
.vscode/
.idea/
*.swp
*.swo
.DS_Store
# Logs
*.log
logs/
# Drosera database
.drosera.db
# Test coverage
coverage/
lcov.info
# Temporary files
*.tmp
*.temp
~*version: '3.8'
services:
drosera-operator:
image: ghcr.io/drosera-network/drosera-operator:latest
container_name: drosera-operator
# Port mappings
ports:
- "31313:31313" # P2P communication
- "31314:31314" # HTTP API
# Environment variables
environment:
# Database configuration
- DRO__DB_FILE_PATH=/data/drosera.db
# Drosera network settings
- DRO__DROSERA_ADDRESS=0x91cB447BaFc6e0EA0F4Fe056F5a9b1F14bb06e5D
- DRO__LISTEN_ADDRESS=0.0.0.0
- DRO__DISABLE_DNR_CONFIRMATION=true
# Ethereum network settings
- DRO__ETH__CHAIN_ID=560048
- DRO__ETH__RPC_URL=https://ethereum-hoodi-rpc.publicnode.com
- DRO__ETH__BACKUP_RPC_URL=https://rpc.hoodi.ethpandaops.io
- DRO__ETH__PRIVATE_KEY=${ETH_PRIVATE_KEY}
# Network configuration
- DRO__NETWORK__P2P_PORT=31313
- DRO__NETWORK__EXTERNAL_P2P_ADDRESS=${VPS_IP}
- DRO__SERVER__PORT=31314
# Logging and error handling
- RUST_LOG=info,drosera_operator=debug
- DRO__ETH__RPC_TIMEOUT=30s
- DRO__ETH__RETRY_COUNT=5
# Persistent storage
volumes:
- drosera_data:/data
# Restart policy
restart: always
# Logging configuration
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
# Health check
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:31314/health"]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
# Command to run
command: node
# Named volumes
volumes:
drosera_data:# Drosera Operator Environment Variables
# Replace these with your actual values
# Your Ethereum private key (without 0x prefix)
ETH_PRIVATE_KEY=your_private_key_here
# Your VPS public IP address
VPS_IP=213.199.48.116MIT License
Copyright (c) 2025 Whale Transaction Alert Trap
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
|
System Requirements
|
Software Requirements
|
curl -L https://foundry.paradigm.xyz | bash
source ~/.bashrc
foundryupcurl -L https://app.drosera.io/install | bash
source ~/.bashrc
droseraupcurl -fsSL https://bun.sh/install | bash
source ~/.bashrcgit clone https://github.com/Miningelectroneum/Whale-Tx-Trap.git
cd Whale-Tx-Trapforge install foundry-rs/forge-std --no-commit
bun install # Optionalcp .env.example .env
nano .env # Add your private keyforge buildExpected output:
[β ] Compiling...
[β ] Compiling 3 files with Solc 0.8.20
[β ’] Solc 0.8.20 finished in X.XXs
Compiler run successful!
# 1. Build contracts
forge build
# 2. Deploy contracts
source .env
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $HOODI_RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast -vvvv
# 3. Apply trap configuration
DROSERA_PRIVATE_KEY=$PRIVATE_KEY drosera applyπ Save these addresses from deployment:
- WhaleTransferResponse:
0xE5701AE464d94449461D224b1f11D5b55be1EC0f - WhaleTransferTrap:
0x9b06F678c4df0eF1282b03FF9FE804444F513d26
The drosera.toml file controls how your trap operates:
[traps.whaletransfer]
# Compiled contract path
path = "out/WhaleTransferTrap.sol/WhaleTransferTrap.json"
# Where to send alerts
response_contract = "0xE5701AE464d94449461D224b1f11D5b55be1EC0f"
# Function to call when threshold exceeded
response_function = "recordAlert(address,address,uint256,uint256)"
# Wait 33 blocks between responses
cooldown_period_blocks = 33
# Need at least 1 operator
min_number_of_operators = 1
# Allow maximum 2 operators
max_number_of_operators = 2
# Check 10 blocks at a time
block_sample_size = 10
# Only whitelisted operators
private_trap = true
whitelist = ["0x929a3B64D53481d8D2332a8778dB4984F5c70bfD"]# 1. Create operator directory
mkdir -p ~/Drosera-Network
cd ~/Drosera-Network
# 2. Create docker-compose.yaml (see Docker Configuration above)
# 3. Create .env file
cat > .env << 'EOF'
ETH_PRIVATE_KEY=your_private_key_here
VPS_IP=213.199.48.116
EOF
# 4. Configure firewall
sudo ufw allow ssh
sudo ufw allow 22
sudo ufw allow 31313/tcp
sudo ufw allow 31314/tcp
sudo ufw enable
# 5. Pull Docker image
docker pull ghcr.io/drosera-network/drosera-operator:latest
# 6. Start operator
docker compose up -d
# 7. View logs
docker compose logs -f# Register operator
drosera-operator register \
--eth-rpc-url https://ethereum-hoodi-rpc.publicnode.com \
--eth-private-key your_private_key \
--drosera-address 0x91cB447BaFc6e0EA0F4Fe056F5a9b1F14bb06e5D
# Opt-in to trap
drosera-operator optin \
--eth-rpc-url https://ethereum-hoodi-rpc.publicnode.com \
--eth-private-key your_private_key \
--trap-config-address your_trap_config_addresscast call 0xE5701AE464d94449461D224b1f11D5b55be1EC0f \
"getAlertCount()(uint256)" \
--rpc-url https://ethereum-hoodi-rpc.publicnode.comOutput: 42 (number of alerts)
cast call 0xE5701AE464d94449461D224b1f11D5b55be1EC0f \
"getAlert(uint256)((address,address,uint256,uint256,uint256))" 0 \
--rpc-url https://ethereum-hoodi-rpc.publicnode.comOutput: Tuple (from, to, amount, blockNumber, timestamp)
cast call 0xE5701AE464d94449461D224b1f11D5b55be1EC0f \
"getLatestAlerts(uint256)((address,address,uint256,uint256,uint256)[])" 5 \
--rpc-url https://ethereum-hoodi-rpc.publicnode.comcast call 0x9b06F678c4df0eF1282b03FF9FE804444F513d26 \
"getThreshold()(uint256)" \
--rpc-url https://ethereum-hoodi-rpc.publicnode.comOutput: 1000000000000000000000 (1000 tokens in wei)
cast call 0xE5701AE464d94449461D224b1f11D5b55be1EC0f \
"alertCountByAddress(address)(uint256)" 0xYOUR_ADDRESS \
--rpc-url https://ethereum-hoodi-rpc.publicnode.comCurrent: 1000 tokens
How to modify:
- Edit
src/WhaleTransferTrap.sol:
// Line 18: Change threshold
uint256 public constant WHALE_THRESHOLD = 5000 * 10**18; // 5000 tokens- Rebuild and redeploy:
forge clean
forge build
source .env
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $HOODI_RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast -vvvv-
Update
drosera.tomlwith new response contract address -
Reapply configuration:
DROSERA_PRIVATE_KEY=$PRIVATE_KEY drosera applyExtend collect() function in WhaleTransferTrap.sol:
function collect() external view returns (bytes memory) {
// Add token filtering
address targetToken = 0xYOUR_TOKEN_ADDRESS;
// Filter transfers for specific token
// Implementation depends on your requirements
TransferData memory data = TransferData({
from: address(0),
to: address(0),
amount: 0,
blockNumber: block.number
});
return abi.encode(data);
}In drosera.toml:
# Change from 33 to 100 blocks
cooldown_period_blocks = 100Then reapply:
DROSERA_PRIVATE_KEY=$PRIVATE_KEY drosera applyforge test -vvvforge test --match-test testWhaleThreshold -vvvvforge coverageforge test --gas-reportforge test -vvvv --match-contract WhaleTransferTestcd ~/Drosera-Network
docker compose logs -f drosera-operatorWhat to look for:
- β
INFO Processing block 1345XXX- Normal operation - β
DEBUG Collected data for trap- Data collection working - β
INFO Response sent- Alert triggered β οΈ WARN RPC timeout- RPC issues (usually temporary)- β
ERROR- Requires investigation
# Check if container is running
docker ps
# Check container health
docker compose ps
# View resource usage
docker stats drosera-operator# Restart container
docker compose restart drosera-operator
# Or restart with fresh start
docker compose down
docker compose up -d- Visit: https://app.drosera.io/
- Connect wallet:
0x929a3B64D53481d8D2332a8778dB4984F5c70bfD - Switch to Hoodi Network
- Search for your trap by:
- Trap config address
- Wallet address
- Contract address
π΄ Issue: Operator Not Connecting
Symptoms: No block processing logs, operator shows offline
Solution:
# 1. Check firewall rules
sudo ufw status
sudo ufw allow 31313/tcp
sudo ufw allow 31314/tcp
sudo ufw reload
# 2. Check if ports are listening
netstat -tulpn | grep 31313
netstat -tulpn | grep 31314
# 3. Restart operator
cd ~/Drosera-Network
docker compose restart drosera-operator
# 4. Check logs for errors
docker compose logs -f drosera-operatorπ΄ Issue: Registration Failed
Symptoms: "Transaction failed" or "Function does not exist"
Solution:
# 1. Try manual operator version
cd ~
curl -LO https://github.com/drosera-network/releases/releases/download/v1.20.0/drosera-operator-v1.20.0-x86_64-unknown-linux-gnu.tar.gz
tar -xvf drosera-operator-v1.20.0-x86_64-unknown-linux-gnu.tar.gz
sudo cp drosera-operator /usr/bin
# 2. Register again
drosera-operator register \
--eth-rpc-url https://ethereum-hoodi-rpc.publicnode.com \
--eth-private-key YOUR_KEY \
--drosera-address 0x91cB447BaFc6e0EA0F4Fe056F5a9b1F14bb06e5D
# 3. If still failing, check account has ETH
cast balance YOUR_ADDRESS --rpc-url https://ethereum-hoodi-rpc.publicnode.comπ΄ Issue: Build Errors
Symptoms: Compilation fails with errors
Solution:
# 1. Clean build artifacts
forge clean
rm -rf out/ cache/
# 2. Reinstall dependencies
rm -rf lib/
forge install foundry-rs/forge-std --no-commit
# 3. Check Solidity version
forge --version
# 4. Update Foundry
foundryup
# 5. Rebuild
forge buildπ΄ Issue: Docker Container Crashes
Symptoms: Container exits immediately, restarts loop
Solution:
# 1. Check container logs
docker compose logs drosera-operator
# 2. Remove and recreate
docker compose down -v
docker system prune -f
# 3. Pull fresh image
docker pull ghcr.io/drosera-network/drosera-operator:latest
# 4. Verify .env file
cat ~/Drosera-Network/.env
# 5. Start again
docker compose up -dπ΄ Issue: RPC Errors
Symptoms: "RPC timeout" or "Connection refused"
Solution:
# 1. Test RPC endpoint
curl -X POST https://ethereum-hoodi-rpc.publicnode.com \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# 2. Try alternative RPC
# Edit docker-compose.yaml
DRO__ETH__RPC_URL=https://rpc.hoodi.ethpandaops.io
# 3. Increase timeout in docker-compose.yaml
DRO__ETH__RPC_TIMEOUT=60s
DRO__ETH__RETRY_COUNT=10
# 4. Restart
docker compose up -dπ΄ Issue: Trap Not Visible on Dashboard
Symptoms: Can't find trap on app.drosera.io
Solution:
# 1. Verify trap config was applied
cd ~/whale-transaction-trap
cat drosera.toml | grep "address"
# 2. Check if trap config exists on-chain
cast call YOUR_TRAP_CONFIG_ADDRESS "owner()(address)" \
--rpc-url https://ethereum-hoodi-rpc.publicnode.com
# 3. Reapply if needed
DROSERA_PRIVATE_KEY=$PRIVATE_KEY drosera apply
# 4. Wait 5-10 minutes for indexing- π Drosera Developer Docs - Complete API reference
- π Foundry Book - Foundry documentation
- π Hoodi Testnet - Network information
- π Solidity Docs - Language reference
- π¬ Drosera Discord - Get help from community
- π¦ Drosera Twitter - Latest updates
- πΊ Tutorial Videos - Video guides
- π§ Hoodi RPC Endpoint - Primary RPC
- π Hoodi Explorer - Block explorer
- π¨ Drosera Dashboard - Trap monitoring
- π§ Hoodi Faucet - Get testnet ETH
- π Drosera Examples - More trap examples
- π₯ Foundry Templates - Project templates
We welcome contributions from the community! Here's how you can help:
- π Report Bugs: Open an issue with detailed information
- π‘ Suggest Features: Share your ideas for improvements
- π Improve Documentation: Help make docs clearer
- π§ Submit Pull Requests: Fix bugs or add features
- β Star the Repo: Show your support!
-
Fork the repository
-
Clone your fork
git clone https://github.com/YOUR_USERNAME/Whale-Tx-Trap.git
cd Whale-Tx-Trap- Create a feature branch
git checkout -b feature/AmazingFeature- Make your changes and test
# Make changes
nano src/YourFile.sol
# Test changes
forge test -vvv
# Build
forge build- Commit your changes
git add .
git commit -m 'Add: Amazing new feature that does X'Use conventional commits:
feat:- New featurefix:- Bug fixdocs:- Documentation changesstyle:- Code style changesrefactor:- Code refactoringtest:- Test changeschore:- Build/tooling changes
- Push to your fork
git push origin feature/AmazingFeature- Open a Pull Request
- Go to original repository
- Click "New Pull Request"
- Select your branch
- Fill in the PR template
- Submit!
// β
Good: Clear function names, comments, proper formatting
/**
* @notice Clear description of what function does
* @param amount The amount to transfer
* @return success Whether the transfer succeeded
*/
function transfer(uint256 amount) external returns (bool success) {
require(amount > 0, "Amount must be positive");
// Implementation
return true;
}
// β Bad: No comments, unclear names
function t(uint256 a) external returns (bool) {
require(a > 0);
return true;
}- Add tests for all new features
- Maintain >80% code coverage
- Include edge cases
- Test both success and failure scenarios
function testWhaleTransferDetection() public {
// Setup
uint256 largeAmount = 2000 * 10**18;
// Execute
bool shouldTrigger = trap.shouldRespond(largeAmount);
// Assert
assertTrue(shouldTrigger, "Should trigger for whale amount");
}- Update README for new features
- Add inline comments for complex logic
- Include usage examples
- Update API documentation
|
|
Found a security issue? Please report responsibly:
- DO NOT open a public issue
- Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We'll respond within 48 hours and work with you to resolve the issue.
- Private keys stored securely
-
.envfile in.gitignore - No hardcoded secrets
- Access control implemented
- Input validation added
- Reentrancy protection (if needed)
- Integer overflow checks
- Gas optimization considered
- Emergency stop mechanism (if needed)
- Tested on testnet first
- ποΈ Drosera Network - For building amazing trap infrastructure
- βοΈ Foundry Team - For the best Solidity development toolkit
- π Ethereum Foundation - For Hoodi testnet and tools
- π₯ Open Source Community - For continuous inspiration and support
- π» All Contributors - Everyone who helped improve this project
- π¬ Discord: Real-time chat and support
- π¦ Twitter: Updates and announcements
- π§ Email: Direct communication
- π GitHub Issues: Bug reports and features
- π‘ Discussions: Ideas and questions
Current Version: v1.0.0
Last Updated: October 2025
Status: β
Production Ready on Hoodi Testnet
Uptime: 99.9%
Total Alerts: Loading...
Active Operators: 1+
| Metric | Value |
|---|---|
| Total Deployments | 1 |
| Total Alerts Recorded | Check Dashboard |
| Average Response Time | ~5 seconds |
| Blocks Monitored | Continuous |
| Uptime | 99.9% |
| Resource | Link |
|---|---|
| π Homepage | Drosera.io |
| π Dashboard | app.drosera.io |
| π Docs | dev.drosera.io |
| π Explorer | explorer.hoodi.io |
| π¬ Discord | Join Community |
| π GitHub | Repository |
Made with β€οΈ by the Whale Trap Community
β Star this repo if you find it useful! β
Share it with others who might benefit!
Get Started β’ View Demo β’ Join Community
Β© 2025 Whale Transaction Alert Trap β’ MIT License β’ Built with Drosera