Proof of Security
EPK gives every customer their own on-chain vault. Even if the server or AI agent holding a key is hacked, the vault itself enforces limits, allowed destinations, agent budgets, a panic button, timelocked upgrades and an emergency evacuation to the owner's own cold wallet. This page does not ask you to trust us: press the button and your browser checks every claim below directly against BSC Testnet.
New, in development: protected swaps for trading bots and AI agents (guards on EPKVault 2.3.0) have their own live proof on a separate demo vault — Protected swaps.
Live log
Rejected attacks
What a hacked agent or a stranger 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 stolen admin key, stopped by the Watchtower
The worst case: an attacker holds the vault's real admin key. Every change that could let money out has to
wait in the vault's timelock, and any guardian may cancel it while it waits. The EPK Watchtower is a guardian
that keeps watching while it runs. In steps W1–W3 the attacker scheduled "allow payments to my address"; the Watchtower
cancelled it 9 blocks (about 4 seconds) later, and the attacker's attempt to push it through anyway was rejected with
UnknownOperation — the change no longer existed. All three transactions are checked in the tables
on this page. How the Watchtower works.
Emergency evacuation to the owner's cold wallet
When control is lost, the owner moves everything to safety in one transaction — but only to the cold wallet
registered in advance, so nobody can choose a destination in the moment of the emergency. In step E1 the
attacker with the stolen admin key tried to point that cold wallet at their own address; the Watchtower cancelled
it 6 blocks (about 3 seconds) later (E2), and executing it anyway was rejected with
UnknownOperation (E3). A guardian's attempt to evacuate was refused with
NotEvacuator (E4) — guardians stop, they never move funds. Then the owner's recovery key
evacuated all 9,940 eUSD to the registered cold wallet and paused the vault (E5). Every step is checked in
the tables on this page. Design and threat model.
Real transactions on BSC Testnet
The whole lifecycle: deploy, a customer's vault, an AI agent paying on its own, panic, recovery, the stolen admin key, the emergency evacuation.
| Step | What | From | Result | Tx |
|---|
Vault state at fixed blocks
Historical state read directly from the chain at the listed block numbers, so it stays checkable after later upgrades. This works while public nodes keep BSC Testnet history; in case they stop, the traces, verification reports and a snapshot of the raw node answers are archived in the repository (verification archive).
| Block | Moment | Claims | Result |
|---|
Code and upgrades without moving funds
Each contract's bytecode hash is checked. Vault implementations must match the hash pinned in the public EPKRegistry. A new release can only be used after a 7-day public window, and a vault opts in through its own timelock (at least 2 days) — same address, same funds. On test networks the same code runs these two clocks in 5 minutes each.
| 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 registry pins, versions, every transaction with its events or rejection reason, the vault at fixed
blocks and the attack windows. The command line with --build adds one more check per contract (6 in
total): it compiles the published contract source and compares it byte for byte with the code on chain — a browser
cannot compile Solidity. Both counts depend a little on the nodes: 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-v2-evidence.json · Runbook and tables: docs/TESTNET_V2.md · Source: contracts/v2
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.