Protected swaps
DexGuard, ThreatFeed V2 and CompositeGuard on a new EPKVault 2.3.0 — created through the public 2.3.0 factory like any integrator's vault — trading through the real PancakeSwap V2 testnet router with real Chainlink price feeds. A compromised operator key and an AI agent tried to steal or waste the vault's money; every attempt was sent on-chain and rejected, while fair trades went through. Press the button and your browser checks every claim below directly against BSC Testnet.
Live log
Rejected attacks
What a compromised operator key or AI agent would try. Each attempt was really sent to the vault and failed on-chain. STRICT = the reason is read from an execution trace of that exact transaction, saved in the repository. REPLAY = the transaction is replayed against the chain state right before its block, and no earlier transaction in that block touched the vault or the token (a replay is strong evidence, not a trace). Archived = none of the nodes asked still keeps that old state; the rejection itself is still checked on-chain, and its reason was replayed while nodes still had the state (reports archived in the repository).
| Step | Attempt | Vault's answer | Proof | Tx |
|---|
A real pool 38 % below the market (2026-11-08)
The real WBNB/BUSD pool on BSC Testnet pays far less than the Chainlink BNB price. In step C1 a plain
wallet with no EPK makes a 0.0001 BNB trade there and receives about 0.043 BUSD instead of about 0.070 — it loses
roughly 38 %. In step A3 the operator key asks the guarded vault for the same trade at that pool's own
quote; DexGuard compares it with Chainlink and the vault refuses with PriceTooLow. Fair trades on a
pool at the Chainlink price (steps S1, S2, S6) go through. Both transactions are checked in the tables on this
page.
A fix you can check: tokens parked at the router
The fifth internal review (2026-11-08) found that tokens sent to a router — an allowed destination — could be
swept by anyone, so DexGuard refuses any token transfer to a router. In step A11 the operator key tries
exactly that and the vault answers RecipientNotAllowed. The vault runs release 2.3.0, which includes the
review's two vault fixes.
Real transactions on BSC Testnet
Setup, allowed trades (operator policy and AI-agent session), the plain-wallet control trade, the ThreatFeed block, and every rejected attack.
| Step | What | From | Result | Tx |
|---|
Contracts
Each contract's bytecode hash is checked; the vault's 2.3.0 implementation must be the one pinned in the
registry of the public stack (5-minute release window on test networks), and the vault proxy must point to
it. On the command line, --build shows that the implementation, the factory, the vault proxy and the
three guards equal this repository's build byte for byte. tUSD and its fixed $1 feed are the demo's own test
contracts; PancakeSwap, BUSD and the Chainlink feeds are third-party contracts on BSC Testnet.
| Contract | Address | Code hash | Result |
|---|
Run it yourself, without this page
Everything on this page comes from one fixed public Git commit, –. A commit cannot be changed afterwards, so the claims you check here are exactly the claims that were published.
This page and the command line run the same checks: network, the document vs the evidence file, code
hashes and the registry pin, every transaction with its events or rejection reason, and the attack window. The
command line with --build also compiles the published contract source and compares it byte for byte
with the code on chain — a browser cannot compile Solidity. A detail whose history none of the nodes asked still
keeps is reported as archived instead of being checked, never as passed.
Evidence file: epk-guards-evidence.json · Runbook and tables: docs/TESTNET_GUARDS.md · Source: contracts/v2/guards
Choose the RPC nodes
Free public nodes forget old history, each in its own way, so this page asks several of them, in the order below (one URL per line): every request goes to the first node, and the next one is asked only when a node has no answer — a transaction it no longer returns, state it has pruned, a request it refuses, or no response. Event logs are used only from a node whose logs contain every event of the evidence transactions. What no node can answer is shown as archived, never as passed. Put your own node first, or keep a single line to use only that node.
The defaults, tested 2026-11-08: bsc-testnet.bnbchain.org — BNB Chain's own node: every
transaction, but only the latest state; 97.rpc.thirdweb.com — keeps old state and event logs, with a
strict rate limit, so it is asked second; bsc-testnet-rpc.publicnode.com — state of about the last
hour, transactions of about the last day.