DEV Community

rim dinov
rim dinov

Posted on

Why I Rejected a "Free" Institutional API and Built My Own MEV-Protected WebSocket Scanner


How a spam integration proposal taught me more about Web3 security than any tutorial — and led to a better architecture.*


The Hook: A Suspicious Offer

Last week, after publishing my open-source arbitrage bot on Base (base-bot), I received an Issue from a GitHub user named @DIABLOX23:

"We recently launched the NetSwap Oracle API on Base Mainnet: a low-latency REST gateway streaming institutional Base telemetry directly from the sequencer... I would like to give your bot project a free Tier 3 Server Whitelist (1M collateral tier)."

Sounds impressive, doesn't it? "Institutional telemetry," "sub-millisecond latency," "zero subscription fees." Any arbitrage bot developer would be interested.

But something made me wary.


🚩 Red Flag #1: The Timeout Test

Before giving them my wallet address (as they had requested), I decided to test their API:
curl -X GET 'https://netswap.vercel.app/api/whales' \
-H 'X-Wallet-Address: 0xMyEmptyTestWallet'

The result: a three-minute wait and no response.
For an arbitrage bot, where milliseconds count, this spells the death of the strategy. A proper API should respond either instantly or with an error—but never hang.
🚩 Red Flag #2: The Excuse
Their response was classic:
"The timeout occurred because our free preview cluster had spun down into an idle sleep state during your test."
Translation: Their "institutional API" runs on Vercel's free hosting, which "goes to sleep" after a few minutes of inactivity. This is unacceptable for arbitrage—you need guaranteed 24/7 availability with sub-second latency.
🚩 Red Flag #3: The Local Python Script
Then they proposed:
"You can run the pre-simulation server directly inside your environment: git clone https://github.com/DIABLOX23/netswap-bot.git && python main.py"
Hold on. Running someone else's Python script—which requires network access—in the same folder as my crypto bot? That’s a direct path to:
The theft of the PRIVATE_KEY from .env
Mining on my CPU
The opening of a backdoor
I checked their GitHub profile:
Account created in October 2026 (less than a week ago)
A total of 3 repositories
15 contributions за год
9 identical issues across different arbitrage bots in a single day
Verdict: This is mass spam aimed at collecting wallet addresses or promoting the $NETSWAP token.
🛡️ What I Built Instead: A Real MEV-Protected Scanner
Instead of relying on unreliable external APIs, I created atomic-arbitrage-executor—a fully independent scanner with direct integration into the Base network.
Architecture

┌─────────────────┐ WebSocket ┌──────────────────┐
│ Base Network │ ──────────────────▶ │ Scanner │
│ (Swap Events) │ │ (This Project) │
└─────────────────┘ ────────┬─────────┘
│
│ HTTP (Flashbots)
▼
┌──────────────────┐
│ ArbitrageExecutor│
│ Smart Contract │
└──────────────────┘

Key components:

  1. WebSocket for instant event reading Instead of a REST API with latency, I use a WebSocket connection to Alchemy/QuickNode: typescript

this.publicClient = createPublicClient({
chain: base,
transport: webSocket(config.wsRpcUrl)
});

// Real-time subscription to Swap events
this.publicClient.watchEvent({
address: config.uniswapPool,
event: SWAP_EVENT_ABI,
onLogs: async (logs) => {
for (const log of logs) {
await this.handleSwap(log.args);
}
}
});

Advantage: Events arrive in milliseconds, without polling or delays.

  1. Flashbots Protect for MEV protection When a bot finds a profitable spread, it sends the transaction via the private Flashbots RPC: typescript

this.walletClient = createWalletClient({
chain: base,
transport: http('https://rpc.flashbots.net'), // NOT a public mempool!
account
});

const hash = await this.walletClient.writeContract({
address: config.contractAddress,
abi: ARBITRAGE_EXECUTOR_ABI,
functionName: 'executeArbitrage',
args: [tokenBorrow, amount, tokenIn, tokenOut, fee1, fee2]
});

Why this matters:
✅ Your transaction is invisible in the public mempool
✅ Protection against sandwich attacks (MEV bots cannot intercept it)
✅ Direct submission to block builders
✅ If the trade is unprofitable, it simply reverts (you lose only the gas, not your principal funds)

  1. Atomic execution via smart contract The smart contract (ArbitrageExecutor) uses flash loans for capital-free execution: solidity

function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external override returns (bytes32) {
// 1. Swap on Uniswap (cheaper to buy)
ISwapRouter(uniswapRouter).exactInputSingle(...);

// 2. Swap on Aerodrome (selling at a higher price)
ISwapRouter(aerodromeRouter).exactInputSingle(...);

// 3. Profit verification
uint256 profit = balanceAfter - (amount + fee);
require(profit >= minProfit, "Insufficient profit");

// 4. Flash loan refund
IERC20(token).safeTransfer(flashLoanPool, amount + fee);

return keccak256("ERC3156FlashBorrower.onFlashLoan");
Enter fullscreen mode Exit fullscreen mode

}

Key point: If any step fails, the entire transaction reverts. Zero risk.
📊 Real Results
During testing on the Base mainnet (via a local fork using Anvil):
0.57% spread between Uniswap V3 and Aerodrome for WETH/USDC
Sub-millisecond detection via WebSocket
Zero failed transactions — flash loan atomicity ensures safety

195 clones on GitHub in the first two weeks.
🧪 Community Testing Invitation
Due to network restrictions in some regions (my ISP blocks direct WebSocket connections), I invite the community to help test this scanner!
How to test:
Clone the repository:
bash

git clone https://github.com/rdin777/atomic-arbitrage-executor.git
cd atomic-arbitrage-executor
npm install

Configure .env:
env

WS_RPC_URL=wss://base-mainnet.g.alchemy.com/v2/YOUR_KEY
PRIVATE_RPC_URL=https://rpc.flashbots.net
PRIVATE_KEY=0xYourTestWalletKey
CONTRACT_ADDRESS=0xYourContractAddress
UNISWAP_POOL=0x...
AERODROME_POOL=0x...

Launch:
bash

npm run dev

⚠️ Important: Use a test wallet with a small amount of ETH (0.01 ETH). Never use your main wallet!

🎯 Lessons Learned

  1. If it sounds too good to be true, it usually is A "free institutional API" with sub-millisecond latency on free Vercel hosting? That doesn't exist.
  2. Always test before integrating A 3-minute timeout told me everything I needed to know.
  3. Never run third-party code in a production environment Especially if it requires access to the network and environment variables.
  4. Direct connection > intermediaries WebSocket + Flashbots gives you full control and minimal latency. No third-party dependencies.
  5. Open source is about community If you can't test it yourself, ask the community for help. They often find bugs and improvements that you might have missed. Links atomic-arbitrage-executor: github.com/rdin777/atomic-arbitrage-executor base-arbitrage-project (smart contract): github.com/rdin777/base-arbitrage-project Flashbots Protect Docs: docs.flashbots.net First article: Building an Atomic Arbitrage Bot on Base 🤝 Contributing Found a bug? Have a better pool pair? Want to improve the spread calculation? Open an Issue or submit a PR! All constructive feedback is welcome. Found this useful? Follow me for more Web3 development content. Questions? Drop them in the comments below. Tags: #arbitrage #mev #flashbots #base-chain #websocket #typescript #viem #defi #web3-security #open-source

Top comments (0)