diff --git a/README.md b/README.md
index 9986e20..dcb9ec9 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,9 @@
the RISC Zero proofs and Morpho Blue are real, and they ran live together on Base Sepolia on 27 October 2026,
every proof checked by RISC Zero's deployed router; the ZEC price, the loan token (MockUSDC) and the signers'
independence are not ([the full list](#what-is-real-and-what-is-a-mock)).
-5. **Read on:** [what ran, and how to reproduce it](docs/TESTING.md), [the judges' FAQ](docs/JURY_FAQ.md),
+5. **On the explorers:** every transaction of the live run, on Zcash and on Base, and every contract, verified on
+ Basescan ([the list](#the-live-run-on-the-explorers)).
+6. **Read on:** [what ran, and how to reproduce it](docs/TESTING.md), [the judges' FAQ](docs/JURY_FAQ.md),
[what is still open](docs/MAINNET.md#7-known-limitations-and-their-designs).
## What it does
@@ -133,7 +135,7 @@ last one, every proof of that run checked by RISC Zero's deployed router:
| The app in a browser | Gasless: open, deposit, borrow with pre-liquidation terms, deleverage and close from collateral (Safe signatures), repay and release, a claim paid from the bonds |
| Live on Base Sepolia (27 October) | The core flows on a public chain: a deposit minted on its Groth16 proof (made on a rented RTX 4090) through RISC Zero's router, a sponsored borrow from an account that never held ETH, a close from collateral paid in one 3-of-5 FROST Zcash transaction whose delivery was then proven on Base, and a swap settled on the proof of its Zcash payment ([docs/TESTING.md § 2c](docs/TESTING.md#2c-live-on-base-sepolia-2026-10-27)) |
-On 27 October 2026 the system ran live on Base Sepolia, its contracts verified on Basescan (all but our paymaster),
+On 27 October 2026 the system ran live on Base Sepolia, its contracts verified on Basescan ([the list](#the-live-run-on-the-explorers)),
every proof made on a rented GPU and checked by RISC Zero's deployed router. The earlier end-to-end runs used local forks of Base
Sepolia, against the real Morpho Blue deployment, and checked proofs with a MOCK verifier, since RISC Zero does not
run on our Windows machine; real Groth16 seals of every guest (deposit, F1, inclusion, swap payment) also pass RISC
@@ -142,6 +144,49 @@ test/fork/RealSealsV2.t.sol --isolate`. No deployment is kept running through ju
the live run's servers and GPU stopped after it, and the whole system runs on a local fork (below). Evidence (block
heights, txids, timings) and how to reproduce every run: [docs/TESTING.md](docs/TESTING.md).
+### The live run on the explorers
+
+Every step of the recorded run of 27 October, on ZecBlock (Zcash testnet) and Basescan (Base Sepolia); its
+timings and the rehearsal before it are in [docs/TESTING.md § 2c](docs/TESTING.md#2c-live-on-base-sepolia-2026-10-27).
+
+| Step | Chain | Transaction |
+|---|---|---|
+| The vault's address: shielded only (the explorer shows its Orchard receiver, never a balance or a history) | Zcash | [`utest1cj0ssr88…fzjc29hjgv`](https://testnet.zecblock.com/address/utest1cj0ssr88lec8yhxfvshutftg6283kye4c79mk9cugk8z0cpsmgwk4s5ueeeeskmu3z30pqhjjwmelpmz9nk3qtru70e686fzjc29hjgv) |
+| The deposit, 0.05 TAZ, Ironwood → Ironwood (block 4,548,243) | Zcash | [`e5eaf50d…75825c`](https://testnet.zecblock.com/tx/e5eaf50dc641b30f25c2cdc7785099979c66fa3d6ced5c7baaf5ad580d75825c) |
+| The deposit proven in zero knowledge, through RISC Zero's router | Base | [`0x92af7a0f…64384b`](https://sepolia.basescan.org/tx/0x92af7a0f3260c389799961c49a4971e76e5938b3eaac3e02c70bfa6b1464384b) |
+| zZEC minted into Morpho | Base | [`0xbfe27bc5…f9e219`](https://sepolia.basescan.org/tx/0xbfe27bc562805b8d29cd853cac428e63769a83aa64088502580a9f7e63f9e219) |
+| 10 MockUSDC borrowed by a brand-new account, gas sponsored | Base | [`0x0e17d8c2…469c9d`](https://sepolia.basescan.org/tx/0x0e17d8c2a2ee01206b9372998e43dc71bd6c59416d30ba6ff39479d7b9469c9d) |
+| Closed from collateral | Base | [`0xf9c5f4bc…2059e3`](https://sepolia.basescan.org/tx/0xf9c5f4bcfda141209063d1e7a6e03c4f991d4995d845d88bee80c2ad102059e3) |
+| Both payouts in one 3-of-5 FROST transaction (block 4,548,312) | Zcash | [`0e82a053…3e29fa`](https://testnet.zecblock.com/tx/0e82a05392014ada0859325e570666bb205553849c9ffc6e529b41cda93e29fa) |
+| The payouts' delivery proven on Base: the claims final | Base | [`0xee567c75…3edce9`](https://sepolia.basescan.org/tx/0xee567c750be2e9f60096590b5f9fcbbb7af5e2792e17b64fed636fcbee3edce9) |
+| Swap: the order opened from the buyer's own wallet, 5 MockUSDC locked | Base | [`0x27198f05…180e1a`](https://sepolia.basescan.org/tx/0x27198f0529e57f14b69d92ecaf0d828cf68c3b474c807ec936baf0ed6f180e1a) |
+| Swap: the maker paid 0.00391343 TAZ (block 4,548,320) | Zcash | [`fa6ce860…245ee0`](https://testnet.zecblock.com/tx/fa6ce860bce2a39b3be793d36d6e767b1e9cd738b0d716bc9185ea7797245ee0) |
+| Swap: the payment proven on Base | Base | [`0xac5ad94f…c318fa`](https://sepolia.basescan.org/tx/0xac5ad94fc62de4dbe76d9b17243f39713bffe6f8fc29a2e8167699c394c318fa) |
+| Swap: settled, the tokens released to the maker | Base | [`0xd1c1989d…038d69`](https://sepolia.basescan.org/tx/0xd1c1989d699bb55d0b78d04a61f7ca77996043c4d139769d48b307bed7038d69) |
+
+The contracts, all verified on Basescan (`contracts/deployments/base-sepolia{,.swap,.relay,.paymaster}.json`):
+
+| Contract | Address |
+|---|---|
+| ZecuredRegistry | [`0xDC9C7E6abeF85A7bE0C65e4208bC87D098b86479`](https://sepolia.basescan.org/address/0xDC9C7E6abeF85A7bE0C65e4208bC87D098b86479#code) |
+| ZecuredSpendLogic | [`0xaED9Fea923D8DD915f5A1367b9bc67DdC763e94a`](https://sepolia.basescan.org/address/0xaED9Fea923D8DD915f5A1367b9bc67DdC763e94a#code) |
+| ZecuredIntake | [`0x90e5F23645529e5009eD3179ae0D6D9F1D0FbF78`](https://sepolia.basescan.org/address/0x90e5F23645529e5009eD3179ae0D6D9F1D0FbF78#code) |
+| ZZEC (zZEC, the collateral receipt) | [`0xAa823B4A4339f371fd3BB3cd502e8D3feCEb2e83`](https://sepolia.basescan.org/address/0xAa823B4A4339f371fd3BB3cd502e8D3feCEb2e83#code) |
+| SettlementAdapter | [`0xCFa5c24718Cc87C4731D1969Fd6a6EC88f3a74cb`](https://sepolia.basescan.org/address/0xCFa5c24718Cc87C4731D1969Fd6a6EC88f3a74cb#code) |
+| SignerBondV2 (the signers' bonds) | [`0x58A1b34a9a641F03C62D5D3A7Fb3D3AD85269e1d`](https://sepolia.basescan.org/address/0x58A1b34a9a641F03C62D5D3A7Fb3D3AD85269e1d#code) |
+| ZecuredSlasher | [`0x3983F1e1C7929A2208296895F01cE0d422917594`](https://sepolia.basescan.org/address/0x3983F1e1C7929A2208296895F01cE0d422917594#code) |
+| ZecuredCompensator | [`0x8F5cBBa2264D62ca16228eDd10253e3284bEB174`](https://sepolia.basescan.org/address/0x8F5cBBa2264D62ca16228eDd10253e3284bEB174#code) |
+| ZecuredVersions | [`0xae56343593A54C93043e0997c509607736EBEEA9`](https://sepolia.basescan.org/address/0xae56343593A54C93043e0997c509607736EBEEA9#code) |
+| ZecuredSwap | [`0xb8Cc1E883FFF77c098802317cC98A966248948fC`](https://sepolia.basescan.org/address/0xb8Cc1E883FFF77c098802317cC98A966248948fC#code) |
+| ZcashHeaderRelay (Equihash on Base) | [`0xEc34aA21cDe1366b397a99A4d90fc6B2f02cFaEa`](https://sepolia.basescan.org/address/0xEc34aA21cDe1366b397a99A4d90fc6B2f02cFaEa#code) |
+| MockUSDC (MOCK: the loan token) | [`0x637BBA9C47190C7a1ab2412F72cF0A9c088dE58b`](https://sepolia.basescan.org/address/0x637BBA9C47190C7a1ab2412F72cF0A9c088dE58b#code) |
+| MockZecOracle (MOCK: the ZEC price) | [`0x5CF271B75eC511FB12C3667a1dfc69AD566A12a9`](https://sepolia.basescan.org/address/0x5CF271B75eC511FB12C3667a1dfc69AD566A12a9#code) |
+| DemoShockOracle (DEMO: the market's oracle) | [`0x53a3D268683Cd748b3B71B55a202dF48B7cE633A`](https://sepolia.basescan.org/address/0x53a3D268683Cd748b3B71B55a202dF48B7cE633A#code) |
+| DemoCapPrice (DEMO: the coverage cap's price) | [`0xeC45AeDa5f0013fd37c9767eC79892Dd55834111`](https://sepolia.basescan.org/address/0xeC45AeDa5f0013fd37c9767eC79892Dd55834111#code) |
+| SingletonPaymasterV7 (our paymaster, Pimlico's contract) | [`0x86c16062083a64aDb333404204346C9e4E03bb1e`](https://sepolia.basescan.org/address/0x86c16062083a64aDb333404204346C9e4E03bb1e#code) |
+
+Used, not ours: [Morpho Blue](https://sepolia.basescan.org/address/0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb#code), [RISC Zero's verifier router](https://sepolia.basescan.org/address/0x0b144E07A0826182B6b59788c34b32Bfa86Fb711#code), [ERC-4337 EntryPoint v0.7](https://sepolia.basescan.org/address/0x0000000071727De22E5E9d8BAf0edAc6f37da032#code).
+
## What is real and what is a mock
**Real**, as run on Zcash testnet and Base Sepolia (live on 27 October 2026), and on forks of Base Sepolia and
diff --git a/app/components/BorrowForm.tsx b/app/components/BorrowForm.tsx
index 9a7ed18..ec51203 100644
--- a/app/components/BorrowForm.tsx
+++ b/app/components/BorrowForm.tsx
@@ -20,6 +20,7 @@ import { HealthRunway, healthOf, TokenAmount, usd, usdc, usdcFloor } from "./loa
import { UsdcMark, ZzecMark } from "./marks";
import { Button, cx, Disclosure, Hint, Notice } from "./ui";
import { TxResult } from "./TxResult";
+import { ChainRef } from "./ChainRef";
/** The quick picks under the amount: shares of what can still be borrowed at the target LTV. */
const PICKS = [
@@ -148,12 +149,12 @@ export function BorrowForm({
>
{result.to.toLowerCase() === loan.account.toLowerCase() ? (
<>
- In your loan account {short(loan.account)}.{" "}
+ In your loan account {short(loan.account)}.{" "}
{first ? "One transaction deployed it, authorized Zecured on Morpho and borrowed; it has never held ETH." : null}
>
) : (
<>
- Sent to {short(result.to)}.
+ Sent to {short(result.to)}.
>
)}
@@ -286,7 +287,7 @@ export function BorrowForm({
) : (
To this loan's account
- {short(loan.account)}
+ {short(loan.account)}
diff --git a/app/components/ChainRef.tsx b/app/components/ChainRef.tsx
new file mode 100644
index 0000000..31bda55
--- /dev/null
+++ b/app/components/ChainRef.tsx
@@ -0,0 +1,60 @@
+/**
+ * A transaction, an address or a commit, in monospace like Mono, linked to its explorer where this build links one
+ * (lib/explorer.ts): Basescan for Base, ZecBlock for Zcash, GitHub for a commit, in a new tab with no referrer. Where
+ * the build links none (the mainnet beta, the replay's placeholder), it is plain text. Server-safe: no hooks.
+ */
+import type { ReactNode } from "react";
+import { IconExternal } from "./icons";
+import { cx } from "./ui";
+import { baseAddressUrl, baseTxUrl, commitUrl, zcashAddressUrl, zcashTxUrl } from "@/lib/explorer";
+
+export type ChainRefKind = "base-tx" | "base-address" | "zcash-tx" | "zcash-address" | "commit";
+
+const SITE: Record = {
+ "base-tx": "Basescan",
+ "base-address": "Basescan",
+ "zcash-tx": "ZecBlock",
+ "zcash-address": "ZecBlock",
+ commit: "GitHub",
+};
+
+export function chainRefUrl(kind: ChainRefKind, value: string): string | null {
+ switch (kind) {
+ case "base-tx":
+ return baseTxUrl(value);
+ case "base-address":
+ return baseAddressUrl(value);
+ case "zcash-tx":
+ return zcashTxUrl(value);
+ case "zcash-address":
+ return zcashAddressUrl(value);
+ case "commit":
+ return commitUrl(value);
+ }
+}
+
+/** `children` is what shows: the whole value by default, or its shortened form. */
+export function ChainRef({ kind, value, children, className }: { kind: ChainRefKind; value: string; children?: ReactNode; className?: string }) {
+ const shown = children ?? value;
+ const url = chainRefUrl(kind, value);
+ const text = cx(
+ "font-mono text-[0.85em] text-[color:var(--strong-color,var(--color-text))]",
+ typeof shown === "string" && shown.length > 24 ? "break-all" : "whitespace-nowrap",
+ className,
+ );
+ if (!url) return {shown};
+ return (
+
+ {shown}
+
+ (opens {SITE[kind]}, a third-party site, in a new tab)
+
+ );
+}
diff --git a/app/components/DemoPanel.tsx b/app/components/DemoPanel.tsx
index 21a3e53..20cc266 100644
--- a/app/components/DemoPanel.tsx
+++ b/app/components/DemoPanel.tsx
@@ -19,6 +19,7 @@ import {
TARGET_LTV_BPS,
} from "@/lib/morpho";
import { formatTaz, ZATS_PER_ZEC } from "@/lib/zcash";
+import { ChainRef } from "./ChainRef";
const TOKEN_KEY = "zecured:demo-token";
const MODES: { mode: NodeMode; label: string; help: string }[] = [
@@ -423,7 +424,7 @@ function OracleCard({ token }: { token: string }) {
) : null}
{loan.destinationCommitment ? (
diff --git a/app/components/borrow/BorrowWizard.tsx b/app/components/borrow/BorrowWizard.tsx
index c7ff88d..430914f 100644
--- a/app/components/borrow/BorrowWizard.tsx
+++ b/app/components/borrow/BorrowWizard.tsx
@@ -40,6 +40,7 @@ import { formatPeriod, openGate, openingFee } from "@/lib/v3";
import { awaitingDeposit, capWait, depositConfirmed, openingsNotice, openRefusal, refundProofRefusal } from "@/lib/v4";
import { blocksToDuration, formatTaz, formatZec } from "@/lib/zcash";
import { DemoPayment } from "./DemoPayment";
+import { ChainRef } from "@/components/ChainRef";
/** The flow in five chapters, as the site tells it; the π of "Prove" turns gold once the deposit is proven. */
const STEPS = ["Vault", "Key", "Deposit", "Prove", "Borrow"];
@@ -179,7 +180,7 @@ export function BorrowWizard() {
- account {short(l.account)}
+ account {short(l.account)}
{l.vaultId ? null : Vault not opened}
@@ -915,7 +916,7 @@ function DepositStep({
- {loan.vaultAddress}
+
diff --git a/app/components/position/Deleverage.tsx b/app/components/position/Deleverage.tsx
index a78bf2d..d5cac83 100644
--- a/app/components/position/Deleverage.tsx
+++ b/app/components/position/Deleverage.tsx
@@ -15,6 +15,7 @@ import type { StoredLoan } from "@/lib/keys";
import { loanTokenName } from "@/lib/labels";
import { formatBps, formatUsdc, formatUsdPrice, formatWad, ltvBps, parseUsdc } from "@/lib/morpho";
import { formatTaz } from "@/lib/zcash";
+import { ChainRef } from "@/components/ChainRef";
/**
* P-7, "Reduce debt with collateral" (S18): a market maker repays the amount asked for and takes
@@ -148,7 +149,7 @@ export function Deleverage({
],
["Health factor after", preview.healthAfter === null ? "∞ (no debt left)" : formatWad(preview.healthAfter)],
["Liquidation price after", preview.liquidationPriceAfter === null ? "—" : `${formatUsdPrice(preview.liquidationPriceAfter)} per ZEC`],
- ["Executor", {quote.executor}],
+ ["Executor", ],
["Quote valid until", new Date(quote.expiresAt * 1000).toLocaleTimeString()],
]}
/>
@@ -184,7 +185,7 @@ export function Deleverage({
{submit.result.tx ? (
<>
- The market maker's transaction: {submit.result.tx}
+ The market maker's transaction:
>
) : (
"Executed by the market maker."
diff --git a/app/components/position/Exits.tsx b/app/components/position/Exits.tsx
index 40a2ccf..fbe6267 100644
--- a/app/components/position/Exits.tsx
+++ b/app/components/position/Exits.tsx
@@ -20,6 +20,7 @@ import { loanStore, short, type StoredLoan } from "@/lib/keys";
import { loanTokenName } from "@/lib/labels";
import { formatUsdc, parseUsdc } from "@/lib/morpho";
import { formatTaz } from "@/lib/zcash";
+import { ChainRef } from "@/components/ChainRef";
/** The borrower accepts up to 1 % less ZEC than quoted (price moves between quote and execution). */
const CLOSE_SLIPPAGE_BPS = 100n;
@@ -213,7 +214,7 @@ function RepayFlow({ loan, vault, snapshot, commitment, onChanged }: FlowProps)
{!enough ? (
- Send at least {formatUsdc(needed - snapshot.usdcBalance)} more {loanTokenName()} to {loan.account}, then
+ Send at least {formatUsdc(needed - snapshot.usdcBalance)} more {loanTokenName()} to , then
refresh. That transfer is public: send it from an address with no link to you, or close from collateral
instead.
))}
diff --git a/app/components/public/StatusView.tsx b/app/components/public/StatusView.tsx
index 9bb40dc..01be757 100644
--- a/app/components/public/StatusView.tsx
+++ b/app/components/public/StatusView.tsx
@@ -15,6 +15,7 @@ import { formatBps, formatUsdc } from "@/lib/morpho";
import { formatWadPercent } from "@/lib/preliq";
import { anonymitySets, bondNumbers, capNumbers, relayLag, SIGNERS } from "@/lib/public";
import { formatTaz } from "@/lib/zcash";
+import { ChainRef } from "@/components/ChainRef";
const MODE_TONE: Record = {
normal: "ok",
@@ -297,7 +298,7 @@ export function StatusView() {
[
"Commit",
- {r.commit} {r.treeClean ? null : uncommitted changes}
+ {r.treeClean ? null : uncommitted changes}
,
],
["Started", r.startedAt ? formatUtc(r.startedAt) : "—"],
diff --git a/app/components/swap/BuyZec.tsx b/app/components/swap/BuyZec.tsx
index 4901de9..68d17da 100644
--- a/app/components/swap/BuyZec.tsx
+++ b/app/components/swap/BuyZec.tsx
@@ -30,6 +30,7 @@ import { SWAP_PRIVACY_SENTENCE } from "@/lib/v4";
import { connectWallet, ensureChain, injectedWallet, sendFromWallet, WalletError } from "@/lib/wallet";
import { formatTaz, formatZec, TICKER } from "@/lib/zcash";
import { QrScan } from "./QrScan";
+import { ChainRef } from "@/components/ChainRef";
const store = () => new SwapStore(browserStorage());
const nowSeconds = () => Math.floor(Date.now() / 1000);
@@ -350,7 +351,7 @@ export function BuyZec() {
{quote ? (
- The maker {short(quote.quote.maker)} has {Math.round(quote.quote.payWindow / 3600)} h to pay and prove, or you take your{" "}
+ The maker {short(quote.quote.maker)} has {Math.round(quote.quote.payWindow / 3600)} h to pay and prove, or you take your{" "}
{name} back.
- {short(wallet)}
+ {short(wallet)}· your wallet, visible on Base when you open the order
) : null}
@@ -637,7 +638,7 @@ function OrderCard({
Order {short(order.orderId, 10, 8)}
- · paid to {short(order.receiver, 12, 8)}
+ · paid to {short(order.receiver, 12, 8)}· destination {order.destinationSent ? "handed to the maker" : "not yet handed to the maker"}
diff --git a/app/lib/explorer.ts b/app/lib/explorer.ts
index 2095634..58608f1 100644
--- a/app/lib/explorer.ts
+++ b/app/lib/explorer.ts
@@ -1,27 +1,52 @@
/**
- * Where the app links a Base or a Zcash transaction. A live build follows its deployment profile (lib/deployment.ts
- * `baseExplorerTx`, `zcashExplorerTx`: the judge testnet links, the mainnet beta does not); a replay build (DEMO)
- * links its recording's real transactions, and nothing while its recording is the placeholder, whose hashes are dummies.
+ * Where the app links a Base or a Zcash transaction or address. A live build follows its deployment profile
+ * (lib/deployment.ts `baseExplorerTx`, `zcashExplorerTx`: the judge testnet links, the mainnet beta does not); a replay
+ * build (DEMO) links its recording's real transactions, and nothing while its recording is the placeholder, whose
+ * hashes are dummies. An explorer's address page sits beside its `/tx/` page.
*/
import { DEPLOYMENT } from "./deployment";
import { REPLAY } from "./replay/flag";
import { recording } from "./replay/recording";
-export function baseTxUrl(hash: string): string | null {
+/** The explorers' `/tx/` prefixes this build links to, or null where it links none. */
+function txPrefixes(): { base: string | null; zcash: string | null } {
if (REPLAY) {
const r = recording();
- return r.placeholder ? null : `${r.explorers.base}${hash}`;
+ return r.placeholder ? { base: null, zcash: null } : { base: r.explorers.base, zcash: r.explorers.zcash };
}
- return DEPLOYMENT.baseExplorerTx ? `${DEPLOYMENT.baseExplorerTx}${hash}` : null;
+ return { base: DEPLOYMENT.baseExplorerTx, zcash: DEPLOYMENT.zcashExplorerTx };
+}
+
+function addressPrefix(txPrefix: string | null): string | null {
+ return txPrefix && /\/tx\/$/.test(txPrefix) ? txPrefix.replace(/\/tx\/$/, "/address/") : null;
+}
+
+export function baseTxUrl(hash: string): string | null {
+ const p = txPrefixes().base;
+ return p ? `${p}${hash}` : null;
+}
+
+/** An account's or a contract's page on the Base explorer. */
+export function baseAddressUrl(address: string): string | null {
+ const p = addressPrefix(txPrefixes().base);
+ return p ? `${p}${address}` : null;
}
/** A Zcash transaction's link, its id in display order (as `zecured-wallet balance` prints it). */
export function zcashTxUrl(txid: string): string | null {
- if (REPLAY) {
- const r = recording();
- return r.placeholder || !r.explorers.zcash ? null : `${r.explorers.zcash}${txid}`;
- }
- return DEPLOYMENT.zcashExplorerTx ? `${DEPLOYMENT.zcashExplorerTx}${txid}` : null;
+ const p = txPrefixes().zcash;
+ return p ? `${p}${txid}` : null;
+}
+
+/** A unified address's page on the Zcash explorer: its receivers, never a shielded balance or history. */
+export function zcashAddressUrl(address: string): string | null {
+ const p = addressPrefix(txPrefixes().zcash);
+ return p ? `${p}${address}` : null;
+}
+
+/** A commit of this repository on GitHub. */
+export function commitUrl(sha: string): string | null {
+ return /^[0-9a-f]{7,40}$/i.test(sha) ? `https://github.com/Himess/zecured/commit/${sha}` : null;
}
/** DEMO: the replay plays sample data, whose hashes are dummies: the app names no transaction then. */
diff --git a/docs/SUBMISSION.md b/docs/SUBMISSION.md
index 63e4078..9c29126 100644
--- a/docs/SUBMISSION.md
+++ b/docs/SUBMISSION.md
@@ -5,7 +5,8 @@ and what is a mock. Every link is absolute, so it works from the form.
**Links.** The site: https://zecured.vercel.app/ (the details: https://zecured.vercel.app/docs/). The
app replaying our live run of 27 October in your browser (DEMO, no server needed): https://zecured.vercel.app/app/.
-The video of the live run: https://youtu.be/iyXiao54KWk. The code: https://github.com/Himess/zecured. The same pages on GitHub Pages: https://himess.github.io/zecured/.
+The video of the live run: https://youtu.be/iyXiao54KWk. Its transactions on ZecBlock and Basescan, and the contracts,
+verified on Basescan: https://github.com/Himess/zecured#the-live-run-on-the-explorers. The code: https://github.com/Himess/zecured. The same pages on GitHub Pages: https://himess.github.io/zecured/.
**Team.** Himess (https://github.com/Himess). Built from scratch for ZECATHON 2026, Cross-Chain track; first commit
10 October 2026.