https://github.com/anders94/usdc-speedtest
Benchmark EVM network throughput by sending USDC transfers in parallel.
https://github.com/anders94/usdc-speedtest
Last synced: 30 days ago
JSON representation
Benchmark EVM network throughput by sending USDC transfers in parallel.
- Host: GitHub
- URL: https://github.com/anders94/usdc-speedtest
- Owner: anders94
- Created: 2026-02-19T18:58:47.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-03-05T16:42:28.000Z (5 months ago)
- Last Synced: 2026-03-05T19:31:59.273Z (5 months ago)
- Language: TypeScript
- Size: 91.8 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# usdc-speedtest
Benchmark EVM network throughput by sending USDC transfers in parallel.
Derives deterministic wallet pairs from a master key, funds them, runs back-and-forth USDC transfers across N parallel testers, and reports throughput and latency statistics.
## Quick Start
```bash
npm install
npm run build
# Set your master wallet private key
export PRIVATE_KEY=0x...
# Run with defaults (Base Sepolia, 5 testers, 60s)
npx usdc-speedtest
# Or link globally so `usdc-speedtest` works anywhere
npm link
usdc-speedtest
# Or run directly without installing
node dist/cli.js
```
## How It Works
1. **Derive wallets** — deterministically generates 2N wallets (N pairs) from the master key using BIP-44 HD derivation (`m/44'/60'/0'/0`)
2. **Fund wallets** — sends ETH (for gas) and USDC ($0.01 per sender) from the master wallet to each derived wallet
3. **Run test** — each tester ping-pongs $0.01 USDC between its wallet pair for the configured duration
4. **Report stats** — aggregates throughput (tx/s), latency percentiles (p50/p95/p99), and gas usage
5. **Cleanup** — optionally sweeps all funds back to the master wallet
## CLI Options
```
usdc-speedtest [options]
Options:
-n, --network Network name (default: "baseSepolia")
-p, --parallel Number of parallel testers (default: "5")
-d, --duration Test duration in seconds (default: 60, or 1800 with --traffic-shape)
--traffic-shape Vary load over time using a random traffic curve
--rpc Override RPC endpoint
--usdc-address Override USDC contract address
--chain-id Override chain ID
--cleanup Sweep funds from derived wallets back to master
--skip-funding Skip the wallet funding step
--seed-gas
Seed a target address with RUSD (Radius only)
--seed-rounds Number of seed-gas iterations (Radius only - default: 10)
-h, --help Display help
```
## Environment
| Variable | Required | Description |
|----------|----------|-------------|
| `PRIVATE_KEY` | Yes | Master wallet private key (hex, with or without `0x` prefix) |
Create a `.env` file in the project root or set it in your shell. The master wallet needs enough ETH for gas and enough USDC to fund sender wallets.
## Supported Networks
| Network | Flag | Chain ID | Block Time |
|---------|------|----------|------------|
| Ethereum Mainnet | `mainnet` | 1 | ~12s |
| Ethereum Sepolia | `sepolia` | 11155111 | ~12s |
| Base | `base` | 8453 | ~2s |
| **Base Sepolia** | `baseSepolia` | 84532 | ~2s |
| Radius | `radius` | 723 | ~0.5s |
| Radius Testnet | `radiusTestnet` | — | ~0.5s |
For networks without built-in configs (or custom chains), use `--rpc`, `--usdc-address`, and `--chain-id` overrides.
## Batch Funding via Disperse.app
When the [Disperse.app](https://disperse.app) contract is detected on the target chain, funding is batched into 3 transactions regardless of wallet count:
| Step | Transaction | Description |
|------|-------------|-------------|
| 1 | `disperseEther()` | Batch ETH to all wallets in one tx |
| 2 | `approve()` | Approve Disperse to spend USDC |
| 3 | `disperseToken()` | Batch USDC to all sender wallets in one tx |
If Disperse is unavailable (e.g. a new chain), the tool falls back to individual transactions with nonce pipelining.
## Examples
```bash
# Base Sepolia, 10 parallel testers, 2 minutes
usdc-speedtest -n baseSepolia -p 10 -d 120
# Ethereum mainnet, 3 testers, 30 seconds
usdc-speedtest -n mainnet -p 3 -d 30
# Custom RPC and USDC address
usdc-speedtest --rpc https://my-rpc.example.com --usdc-address 0x... --chain-id 12345
# Traffic shaping: ramp load up and down over 30 minutes
usdc-speedtest --traffic-shape -p 4
# Traffic shaping with custom duration
usdc-speedtest --traffic-shape -p 4 -d 120
# Sweep all funds back to master wallet
usdc-speedtest --cleanup
# Seed a Radius address with RUSD (5 rounds)
usdc-speedtest -n radius --seed-gas 0xTARGET --seed-rounds 5 --rpc https://rpc.radiustech.xyz/...
```
## Traffic Shaping
The `--traffic-shape` flag runs a longer test where throughput varies over time following a randomly generated curve. This is useful for testing how chains handle autoscaling under fluctuating load.
When enabled, a random sequence of waypoints is generated (e.g. 25% → 77% over 2min → 16% over 5min → 50% over 1min). Each tester uses probabilistic throttling to match the current target — at 50% target, testers proceed roughly half the time; at 10%, they mostly wait. The curve is logged before the test starts and the spinner shows the current target percentage in real time.
Without `-d`, duration defaults to 1800s (30 minutes) to give the curve enough time to exercise a range of load levels.
## RUSD Seeding (Radius)
On Radius, the native gas token (RUSD) is created by an automatic "turnstile" that converts SBC (an ERC-20) into RUSD ~$0.10 at a time, triggered whenever a transaction needs more RUSD than is available. The `--seed-gas` mode exploits this to accumulate RUSD on a target address.
Each round:
1. Queries the master wallet's actual RUSD balance via `rad_getBalanceRaw()`
2. Sends available RUSD to the target as a native transfer
3. Sends 1 wei of SBC to the target, which triggers the turnstile and refills ~$0.10 RUSD on master
4. Repeats
The loop stops early if SBC balance is too low or RUSD is dust. A summary table is printed at the end.
## Development
```bash
npm install
npm run dev # Run directly via tsx
npm run build # Build to dist/
```
## Project Structure
```
src/
cli.ts Entry point and argument parsing
config/networks.ts Network definitions
wallet/derive.ts HD wallet derivation and pairing
wallet/fund.ts Balance checks, funding plan, Disperse batching
test/runner.ts Parallel test orchestration, Ctrl+C handling
test/tester.ts Single tester: ping-pong USDC between wallet pair
test/traffic-curve.ts Random traffic curve generation and interpolation
test/stats.ts Statistics computation and display
radius/seed-gas.ts RUSD seeding loop for Radius
cleanup/sweep.ts Sweep USDC and ETH back to master
utils/usdc.ts ERC-20 ABI and USDC helpers
utils/disperse.ts Disperse.app contract detection and helpers
utils/prompt.ts Interactive confirmation prompts
utils/logger.ts Formatted console output
```
## License
MIT