{"id":4030,"date":"2026-06-24T13:16:25","date_gmt":"2026-06-24T13:16:25","guid":{"rendered":"https:\/\/tokenmetrics.com\/blog\/secondfi-traces-cardano-wallet-exploit-address-level\/"},"modified":"2026-06-24T13:16:25","modified_gmt":"2026-06-24T13:16:25","slug":"secondfi-traces-cardano-wallet-exploit-address-level","status":"publish","type":"post","link":"https:\/\/tokenmetrics.com\/ada\/news\/secondfi-traces-cardano-wallet-exploit-address-level\/","title":{"rendered":"SecondFi Traces Cardano Wallet Exploit to Address-Level Issue"},"content":{"rendered":"<h2>Signal Snapshot<\/h2>\n<ul>\n<li>Token Metrics sees a bearish trend for ADA.<\/li>\n<li>SecondFi found a wallet flaw that exposed private keys when users signed transactions.<\/li>\n<li>Attackers stole about 16 million ADA worth $2.4 million from 374 addresses.<\/li>\n<li>The platform saved about 129 million ADA by moving it to a safe place.<\/li>\n<li>Cardano founder Charles Hoskinson said his company has no ties to SecondFi.<\/li>\n<li>A new testnet upgrade for Cardano launches soon.<\/li>\n<\/ul>\n<h2>Key Takeaways<\/h2>\n<ul>\n<li>A flaw in SecondFi&#8217;s wallet showed private keys. This let attackers take user funds.<\/li>\n<li>The attack hit 374 addresses. Users lost about $2.4 million. But the team saved 129 million ADA.<\/li>\n<li>Hackers now target wallet systems more than blockchains. This shows we need better checks on wallet code.<\/li>\n<\/ul>\n<h2>What Happened<\/h2>\n<p>SecondFi confirmed the cause of the breach. It was an issue at the address level. This happens when users sign transactions. Attackers used this flaw to steal funds. The company traced the exploit to this specific weakness in its Cardano web wallet generation software.<\/p>\n<p>The team said attackers took about 16 million ADA. This equals about $2.4 million. It happened across 374 addresses. The platform acted fast. They started emergency steps. These steps saved about 129 million ADA. A third party now holds this money. It waits for users to verify their claims.<\/p>\n<p>Charles Hoskinson leads Cardano. He stated SecondFi is not an Input Output Global product. He said there is no link between the wallet and IOG.<\/p>\n<h2>Why It Matters<\/h2>\n<p>This exploit shows a risk in wallet systems. The blockchain itself worked fine. The problem was the wallet software. Mitchell Amador leads Immunefi, a security firm. He said SecondFi&#8217;s software showed private keys. The blockchain is safe, but key code often lacks checks.<\/p>\n<p>He said that attackers have increasingly shifted focus toward infrastructure that creates or stores crypto keys rather than blockchain protocols. This shift matters for investors. It shows that self-custody has risks if the tool is flawed. Investors must check wallet security, not just blockchain security.<\/p>\n<p>For portfolio managers, this incident shows why checking wallet security is vital. Even well-known wallet providers can have big problems. Exposing private keys is one of the worst security fails in crypto. It lets attackers control assets directly. This type of flaw skips all blockchain security measures. Even the safest networks become vulnerable if users use bad wallet software.<\/p>\n<p>The market impact goes beyond money lost. Such breaches can make users distrust self-custody options. This might push users toward big exchanges. That creates bigger targets for hackers. The incident also shows that wallet tools lag behind blockchain tech in safety.<\/p>\n<p>Retail investors should remember to use good key habits. Do not keep all assets in one wallet. This rule applies to different addresses. It also applies to separate wallets from different teams.<\/p>\n\t\t<style id=\"tm-token-card-styles\">\n\t\t.tm-token-card {\n\t\t\tposition: relative;\n\t\t\tmargin: 1.75em 0;\n\t\t\tpadding: 1.25em 1.4em 1.4em;\n\t\t\tbackground: #17171D;\n\t\t\tborder: 1px solid rgba(255, 214, 10, 0.18);\n\t\t\tborder-radius: 16px;\n\t\t\tcolor: #e8eaf2;\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n\t\t\toverflow: hidden;\n\t\t}\n\t\t.tm-token-card::before {\n\t\t\tcontent: \"\";\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tleft: 0;\n\t\t\twidth: 4px;\n\t\t\theight: 100%;\n\t\t\tbackground: #FFD60A;\n\t\t}\n\t\t.tm-token-card__header {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tgap: 0.4em;\n\t\t\tmargin-bottom: 1em;\n\t\t}\n\t\t.tm-token-card__eyebrow {\n\t\t\tmargin: 0;\n\t\t\tfont-size: 0.72em;\n\t\t\tfont-weight: 700;\n\t\t\tletter-spacing: 0.12em;\n\t\t\ttext-transform: uppercase;\n\t\t\tcolor: #FFD60A;\n\t\t}\n\t\t.tm-token-card__title {\n\t\t\tmargin: 0;\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: baseline;\n\t\t\tgap: 0.55em;\n\t\t\tflex-wrap: wrap;\n\t\t\tfont-size: 1.5em;\n\t\t\tfont-weight: 700;\n\t\t\tline-height: 1.15;\n\t\t\tcolor: #ffffff;\n\t\t\tletter-spacing: -0.01em;\n\t\t}\n\t\t.tm-token-card__name {\n\t\t\tcolor: #ffffff;\n\t\t}\n\t\t.tm-token-card__ticker {\n\t\t\tpadding: 0.2em 0.6em;\n\t\t\tbackground: rgba(255, 214, 10, 0.14);\n\t\t\tcolor: #FFD60A;\n\t\t\tfont-size: 0.55em;\n\t\t\tfont-weight: 700;\n\t\t\tletter-spacing: 0.08em;\n\t\t\tborder-radius: 999px;\n\t\t\ttext-transform: uppercase;\n\t\t\tline-height: 1;\n\t\t}\n\t\t\/* Recap theme forces `list-style-type: disc` on .entry-content ul\n\t\t * and `padding-left: 0` on every <li> via a high-specificity\n\t\t * selector chain (style.css:1872+). We need !important on these\n\t\t * specific properties to (a) suppress the native bullet so it\n\t\t * doesn't double up with our check icon, and (b) keep enough\n\t\t * left padding on the <li> to make room for the absolutely\n\t\t * positioned check icon without text overlap. *\/\n\t\t.tm-token-card__benefits {\n\t\t\tlist-style: none !important;\n\t\t\tmargin: 0 0 1.25em;\n\t\t\tpadding: 0 !important;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tgap: 0.55em;\n\t\t}\n\t\t.tm-token-card__benefit {\n\t\t\tposition: relative;\n\t\t\tpadding-left: 2.25em !important;\n\t\t\tpadding-right: 0;\n\t\t\tmargin: 0;\n\t\t\tfont-size: 0.95em;\n\t\t\tline-height: 1.5;\n\t\t\tcolor: rgba(232, 234, 242, 0.9);\n\t\t}\n\t\t.tm-token-card__benefit::marker {\n\t\t\tcontent: \"\" !important;\n\t\t}\n\t\t.tm-token-card__benefit::before {\n\t\t\tcontent: \"\";\n\t\t\tposition: absolute;\n\t\t\tleft: 0;\n\t\t\ttop: 0.32em;\n\t\t\twidth: 1.2em;\n\t\t\theight: 1.2em;\n\t\t\tbackground-image: url(\"data:image\/svg+xml;utf8,<svg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 16 16' fill='none'><circle cx='8' cy='8' r='7.5' fill='%23FFD60A'\/><path d='M4.5 8.2l2.3 2.3L11.5 5.8' stroke='%2317171D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'\/><\/svg>\");\n\t\t\tbackground-repeat: no-repeat;\n\t\t\tbackground-size: contain;\n\t\t\tbackground-position: center;\n\t\t}\n\t\t.tm-token-card__footer {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tgap: 1em;\n\t\t\tflex-wrap: wrap;\n\t\t}\n\t\t.tm-token-card__cta {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tpadding: 0.85em 1.4em;\n\t\t\tbackground: #FFD60A;\n\t\t\tcolor: #0a0e14;\n\t\t\tfont-weight: 800;\n\t\t\tfont-size: 0.95em;\n\t\t\tline-height: 1;\n\t\t\ttext-decoration: none;\n\t\t\tborder-radius: 999px;\n\t\t\twhite-space: nowrap;\n\t\t\ttransition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;\n\t\t}\n\t\t.tm-token-card__cta:visited {\n\t\t\tcolor: #0a0e14;\n\t\t}\n\t\t.tm-token-card__cta:hover,\n\t\t.tm-token-card__cta:focus {\n\t\t\tbackground: #ffe04b;\n\t\t\tcolor: #0a0e14;\n\t\t\ttransform: translateY(-1px);\n\t\t\ttext-decoration: none;\n\t\t\tbox-shadow: 0 6px 20px rgba(255, 214, 10, 0.28);\n\t\t}\n\t\t.tm-token-card__meta {\n\t\t\tfont-size: 0.8em;\n\t\t\tcolor: rgba(232, 234, 242, 0.55);\n\t\t\tletter-spacing: 0.01em;\n\t\t}\n\t\t\/* Lightweight Charts price chart \u2014 TM yellow on core dark, CoinGecko OHLC *\/\n\t\t.tm-tv-chart {\n\t\t\tmargin: 1.5em 0;\n\t\t\tpadding: 1em 1em 0.75em;\n\t\t\tbackground: #17171D;\n\t\t\tborder: 1px solid rgba(255, 214, 10, 0.18);\n\t\t\tborder-radius: 16px;\n\t\t\tcolor: #e8eaf2;\n\t\t\tfont-family: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tline-height: 1.5;\n\t\t}\n\t\t.tm-tv-chart__header {\n\t\t\tdisplay: flex;\n\t\t\talign-items: baseline;\n\t\t\tjustify-content: space-between;\n\t\t\tgap: 0.75em;\n\t\t\tmargin: 0 0.25em 0.6em;\n\t\t\tflex-wrap: wrap;\n\t\t}\n\t\t.tm-tv-chart__title {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: baseline;\n\t\t\tgap: 0.5em;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.tm-tv-chart__name {\n\t\t\tfont-size: 1.125em;\n\t\t\tfont-weight: 700;\n\t\t\tcolor: #e8eaf2;\n\t\t\tletter-spacing: 0.01em;\n\t\t}\n\t\t.tm-tv-chart__ticker {\n\t\t\tpadding: 0.15em 0.55em;\n\t\t\tbackground: rgba(255, 214, 10, 0.14);\n\t\t\tcolor: #FFD60A;\n\t\t\tfont-size: 0.7em;\n\t\t\tfont-weight: 700;\n\t\t\tletter-spacing: 0.06em;\n\t\t\tborder-radius: 999px;\n\t\t\ttext-transform: uppercase;\n\t\t}\n\t\t.tm-tv-chart__quote {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: baseline;\n\t\t\tgap: 0.5em;\n\t\t}\n\t\t.tm-tv-chart__price {\n\t\t\tfont-size: 1.25em;\n\t\t\tfont-weight: 700;\n\t\t\tcolor: #e8eaf2;\n\t\t\tfont-variant-numeric: tabular-nums;\n\t\t}\n\t\t.tm-tv-chart__change {\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: rgba(232, 234, 242, 0.55);\n\t\t\tfont-variant-numeric: tabular-nums;\n\t\t}\n\t\t.tm-tv-chart__change--up   { color: #4ade80; }\n\t\t.tm-tv-chart__change--down { color: #f87171; }\n\t\t.tm-tv-chart__canvas {\n\t\t\twidth: 100%;\n\t\t\tmin-height: 120px;\n\t\t}\n\t\t.tm-tv-chart__caption {\n\t\t\tmargin: 0.4em 0.25em 0;\n\t\t\tfont-size: 0.8em;\n\t\t\tcolor: rgba(232, 234, 242, 0.45);\n\t\t\ttext-align: right;\n\t\t}\n\n\t\t\/* Token stats panel \u2014 chart + stats + CTA stack on news posts *\/\n\t\t.tm-token-stats {\n\t\t\tmargin: 1.5em 0;\n\t\t\tpadding: 1em 1.1em 0.85em;\n\t\t\tbackground: #17171D;\n\t\t\tborder: 1px solid rgba(255, 214, 10, 0.18);\n\t\t\tborder-radius: 16px;\n\t\t\tcolor: #e8eaf2;\n\t\t\tfont-family: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tline-height: 1.5;\n\t\t}\n\t\t.tm-token-stats__header {\n\t\t\tdisplay: flex; align-items: baseline; justify-content: space-between;\n\t\t\tgap: 0.75em; margin-bottom: 0.6em;\n\t\t}\n\t\t.tm-token-stats__title {\n\t\t\tmargin: 0; font-size: 0.9em; font-weight: 700; color: #FFD60A;\n\t\t\tletter-spacing: 0.04em; text-transform: uppercase;\n\t\t}\n\t\t.tm-token-stats__lookback {\n\t\t\tfont-size: 0.7em; color: rgba(232, 234, 242, 0.5);\n\t\t\ttext-transform: uppercase; letter-spacing: 0.06em;\n\t\t}\n\t\t.tm-token-stats__section { margin-bottom: 0.6em; }\n\t\t.tm-token-stats__section:last-child { margin-bottom: 0; }\n\t\t.tm-token-stats__section-label {\n\t\t\tmargin: 0 0 0.25em; font-size: 0.7em; font-weight: 700;\n\t\t\tletter-spacing: 0.12em; text-transform: uppercase;\n\t\t\tcolor: rgba(255, 214, 10, 0.65);\n\t\t}\n\t\t.tm-token-stats__grid {\n\t\t\tdisplay: grid; grid-template-columns: repeat(3, minmax(0, 1fr));\n\t\t\tgap: 0.25em 0.75em; margin: 0; padding-top: 0.25em;\n\t\t\tborder-top: 1px solid rgba(232, 234, 242, 0.06);\n\t\t}\n\t\t.tm-token-stats__cell {\n\t\t\tdisplay: flex; flex-direction: column; gap: 0.15em; min-width: 0; padding: 0.3em 0;\n\t\t}\n\t\t.tm-token-stats__cell dt {\n\t\t\tmargin: 0; font-size: 0.8em; color: rgba(232, 234, 242, 0.55);\n\t\t\tfont-weight: 500; letter-spacing: 0.02em;\n\t\t}\n\t\t.tm-token-stats__cell dd {\n\t\t\tmargin: 0; font-size: 1em; font-weight: 700; color: #e8eaf2;\n\t\t\tfont-variant-numeric: tabular-nums; line-height: 1.3;\n\t\t}\n\t\t.tm-token-stats__cell dd[data-trend=\"up\"]   { color: #4ade80; }\n\t\t.tm-token-stats__cell dd[data-trend=\"down\"] { color: #f87171; }\n\t\t.tm-token-stats__range {\n\t\t\tdisplay: flex; flex-direction: column; gap: 3px; width: 100%; min-width: 0;\n\t\t}\n\t\t.tm-token-stats__range-track {\n\t\t\tposition: relative; width: 100%; height: 0.2em; margin-top: 0.35em;\n\t\t\tbackground: rgba(232, 234, 242, 0.12); border-radius: 999px;\n\t\t}\n\t\t.tm-token-stats__range-dot {\n\t\t\tposition: absolute; top: 50%; width: 0.6em; height: 0.6em;\n\t\t\tmargin-top: -0.3em; margin-left: -0.3em;\n\t\t\tbackground: #FFD60A; border-radius: 50%;\n\t\t\tbox-shadow: 0 0 0 0.15em rgba(23, 23, 29, 1);\n\t\t}\n\t\t.tm-token-stats__range-bounds {\n\t\t\tdisplay: flex; justify-content: space-between; width: 100%;\n\t\t\tfont-size: 0.75em; font-weight: 500; line-height: 1.2;\n\t\t\tcolor: rgba(232, 234, 242, 0.55); font-variant-numeric: tabular-nums;\n\t\t}\n\t\t.tm-token-stats__source {\n\t\t\tmargin: 0.75em 0 0; font-size: 0.75em; color: rgba(232, 234, 242, 0.45); text-align: right;\n\t\t}\n\t\t@media (max-width: 560px) {\n\t\t\t.tm-token-stats__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n\t\t}\n\t\t@media (max-width: 640px) {\n\t\t\t.tm-token-card {\n\t\t\t\tgrid-template-columns: auto 1fr;\n\t\t\t\tgrid-template-rows: auto auto;\n\t\t\t\tgap: 8px 14px;\n\t\t\t}\n\t\t\t.tm-token-card__cta {\n\t\t\t\tgrid-column: 1 \/ -1;\n\t\t\t\tjustify-content: center;\n\t\t\t}\n\t\t}\n\t<\/style>\n\t\t<figure\n\t\tclass=\"tm-tv-chart\"\n\t\tdata-tm-chart\n\t\tdata-tm-chart-id=\"cardano\"\n\t\tdata-tm-chart-days=\"14\"\n\t\tdata-tm-chart-height=\"220\"\n\t>\n\t\t<header class=\"tm-tv-chart__header\">\n\t\t\t<div class=\"tm-tv-chart__title\">\n\t\t\t\t<span class=\"tm-tv-chart__name\">Cardano<\/span>\n\t\t\t\t<span class=\"tm-tv-chart__ticker\">ADA<\/span>\n\t\t\t<\/div>\n\t\t\t<div class=\"tm-tv-chart__quote\">\n\t\t\t\t<span class=\"tm-tv-chart__price\" data-tm-chart-price>\u2014<\/span>\n\t\t\t\t<span class=\"tm-tv-chart__change\" data-tm-chart-change><\/span>\n\t\t\t<\/div>\n\t\t<\/header>\n\t\t<div\n\t\t\tclass=\"tm-tv-chart__canvas\"\n\t\t\trole=\"img\"\n\t\t\taria-label=\"Price chart for Cardano\"\n\t\t\tstyle=\"height: 220px;\"\n\t\t><\/div>\n\t\t<figcaption class=\"tm-tv-chart__caption\">Live price for Cardano \u2014 data via CoinGecko.<\/figcaption>\n\t<\/figure>\n\t\t<script id=\"tm-tv-chart-hydrator\">\n\t(function () {\n\t\tvar TM_BRAND = {\n\t\t\tbg:      '#17171D',\n\t\t\tline:    '#FFD60A',\n\t\t\tfillTop: 'rgba(255, 214, 10, 0.40)',\n\t\t\tfillBot: 'rgba(255, 214, 10, 0.00)',\n\t\t\ttext:    '#e8eaf2',\n\t\t\tgrid:    'rgba(232, 234, 242, 0.06)',\n\t\t\tborder:  'rgba(255, 214, 10, 0.18)'\n\t\t};\n\t\tfunction loadLibrary(cb) {\n\t\t\tif (window.LightweightCharts) { cb(); return; }\n\t\t\tvar s = document.createElement('script');\n\t\t\ts.src = 'https:\/\/unpkg.com\/lightweight-charts@4.2.3\/dist\/lightweight-charts.standalone.production.js';\n\t\t\t\/\/ Subresource Integrity hash for the pinned 4.2.3 build.\n\t\t\t\/\/ Greptile P1 (PR #1470): without SRI, a compromised npm\n\t\t\t\/\/ package or a CDN MITM at this version would execute\n\t\t\t\/\/ arbitrary JS in every visitor's browser. Recompute via\n\t\t\t\/\/ `curl -sS <src> | openssl dgst -sha384 -binary | base64`\n\t\t\t\/\/ when bumping the version.\n\t\t\ts.integrity = 'sha384-stKllnUqA9AD0gsKCuUtf5XlqAW7PwIgDagoNsTWkjkBmJ\/GZ\/uHTgEBxdLV2VSK';\n\t\t\ts.async = true;\n\t\t\ts.crossOrigin = 'anonymous';\n\t\t\ts.onload = cb;\n\t\t\ts.onerror = function () { console.warn('[tm-tv-chart] failed to load lightweight-charts'); };\n\t\t\tdocument.head.appendChild(s);\n\t\t}\n\n\t\tfunction priceFormat(value) {\n\t\t\tvar abs = Math.abs(value);\n\t\t\tif (abs >= 0.01)    { return { precision: 2, minMove: 0.01 }; }\n\t\t\tif (abs >= 0.0001)  { return { precision: 6, minMove: 0.000001 }; }\n\t\t\treturn { precision: 8, minMove: 0.00000001 };\n\t\t}\n\t\tfunction formatPrice(value) {\n\t\t\tvar fmt = priceFormat(value);\n\t\t\treturn '$' + value.toLocaleString('en-US', { minimumFractionDigits: fmt.precision, maximumFractionDigits: fmt.precision });\n\t\t}\n\t\tfunction formatChangeAbs(value) {\n\t\t\tvar sign = value >= 0 ? '+' : '\u2212';\n\t\t\tvar abs  = Math.abs(value);\n\t\t\tvar fmt  = priceFormat(abs);\n\t\t\treturn sign + '$' + abs.toLocaleString('en-US', { minimumFractionDigits: fmt.precision, maximumFractionDigits: fmt.precision });\n\t\t}\n\t\tfunction updateQuote(figure, data) {\n\t\t\tvar priceEl  = figure.querySelector('[data-tm-chart-price]');\n\t\t\tvar changeEl = figure.querySelector('[data-tm-chart-change]');\n\t\t\tif (!priceEl || !changeEl || data.length === 0) { return; }\n\t\t\tvar last = data[data.length - 1];\n\t\t\tvar dayAgoTs = last.time - 86400;\n\t\t\tvar baseline = data[0];\n\t\t\tfor (var i = data.length - 1; i >= 0; i--) {\n\t\t\t\tif (data[i].time <= dayAgoTs) { baseline = data[i]; break; }\n\t\t\t}\n\t\t\tvar changeAbs = last.value - baseline.value;\n\t\t\tvar changePct = baseline.value !== 0 ? (changeAbs \/ baseline.value) * 100 : 0;\n\t\t\tpriceEl.textContent  = formatPrice(last.value);\n\t\t\tchangeEl.textContent = formatChangeAbs(changeAbs) + ' (' + (changePct >= 0 ? '+' : '\u2212') + Math.abs(changePct).toFixed(2) + '%)';\n\t\t\tchangeEl.classList.remove('tm-tv-chart__change--up', 'tm-tv-chart__change--down');\n\t\t\tif (changeAbs > 0) { changeEl.classList.add('tm-tv-chart__change--up'); }\n\t\t\telse if (changeAbs < 0) { changeEl.classList.add('tm-tv-chart__change--down'); }\n\t\t}\n\n\t\tfunction fetchOhlc(coinId, days) {\n\t\t\tvar url = 'https:\/\/api.coingecko.com\/api\/v3\/coins\/' + encodeURIComponent(coinId)\n\t\t\t\t+ '\/ohlc?vs_currency=usd&days=' + encodeURIComponent(days);\n\t\t\treturn fetch(url, { credentials: 'omit' }).then(function (r) {\n\t\t\t\tif (!r.ok) { throw new Error('coingecko ' + r.status); }\n\t\t\t\treturn r.json();\n\t\t\t}).then(function (rows) {\n\t\t\t\tif (!Array.isArray(rows)) { return []; }\n\t\t\t\treturn rows.map(function (k) {\n\t\t\t\t\treturn { time: Math.floor(k[0] \/ 1000), value: parseFloat(k[4]) };\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tfunction renderOne(figure) {\n\t\t\tif (figure.dataset.tmChartReady) { return; }\n\t\t\tif (figure.dataset.tmChartFetching) { return; }\n\t\t\tvar coinId = figure.getAttribute('data-tm-chart-id');\n\t\t\tvar days   = figure.getAttribute('data-tm-chart-days') || '14';\n\t\t\tvar height = parseInt(figure.getAttribute('data-tm-chart-height') || '220', 10);\n\t\t\tvar canvas = figure.querySelector('.tm-tv-chart__canvas');\n\t\t\tif (!coinId || !canvas) { return; }\n\t\t\t\/\/ Greptile P1 (PR #1470): only mark the figure ready AFTER\n\t\t\t\/\/ the OHLC fetch resolves successfully. The earlier flow set\n\t\t\t\/\/ the flag before the await, so a single 429 from CoinGecko\n\t\t\t\/\/ permanently disabled retry for that page-load \u2014 every\n\t\t\t\/\/ subsequent renderAll() call (e.g. on resize \/ hashchange)\n\t\t\t\/\/ would short-circuit on the stale flag and the chart would\n\t\t\t\/\/ stay blank forever. The intermediate `tmChartFetching`\n\t\t\t\/\/ flag still prevents in-flight double-fetches.\n\t\t\tfigure.dataset.tmChartFetching = '1';\n\n\t\t\tfetchOhlc(coinId, days).then(function (data) {\n\t\t\t\tif (!data || data.length === 0) {\n\t\t\t\t\tdelete figure.dataset.tmChartFetching;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfigure.dataset.tmChartReady = '1';\n\t\t\t\tdelete figure.dataset.tmChartFetching;\n\t\t\t\tvar precision = priceFormat(data[data.length - 1].value);\n\t\t\t\t\/\/ Greptile P2 (PR #1470): canvas.clientWidth is 0 when\n\t\t\t\t\/\/ the .tm-tv-chart__canvas isn't laid out yet (lazy-load\n\t\t\t\t\/\/ container, hidden tab, accordion). lightweight-charts\n\t\t\t\t\/\/ silently accepts 0 and creates an invisible chart.\n\t\t\t\t\/\/ Fall back to offsetWidth, then a sane default.\n\t\t\t\tvar initialWidth = canvas.clientWidth || canvas.offsetWidth || 600;\n\t\t\t\tvar chart = window.LightweightCharts.createChart(canvas, {\n\t\t\t\t\twidth: initialWidth,\n\t\t\t\t\theight: height,\n\t\t\t\t\tlayout: { background: { color: TM_BRAND.bg }, textColor: TM_BRAND.text, fontFamily: '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif', attributionLogo: false },\n\t\t\t\t\tgrid: { vertLines: { visible: false }, horzLines: { color: TM_BRAND.grid } },\n\t\t\t\t\trightPriceScale: { borderColor: TM_BRAND.border },\n\t\t\t\t\ttimeScale: {\n\t\t\t\t\t\tborderColor: TM_BRAND.border,\n\t\t\t\t\t\ttimeVisible: true,\n\t\t\t\t\t\tsecondsVisible: false,\n\t\t\t\t\t\t\/\/ End-user feedback: the default DayOfMonth formatter\n\t\t\t\t\t\t\/\/ shows bare numbers (\"4 7 10 13 16\") with no month\n\t\t\t\t\t\t\/\/ context, leaving readers to guess what month\n\t\t\t\t\t\t\/\/ they're looking at. Force a Month-Day format for\n\t\t\t\t\t\t\/\/ DayOfMonth ticks and full Month-Day-Year for\n\t\t\t\t\t\t\/\/ Month\/Year ticks. lightweight-charts passes a\n\t\t\t\t\t\t\/\/ numeric tickMarkType from its TickMarkType enum:\n\t\t\t\t\t\t\/\/ 0=Year, 1=Month, 2=DayOfMonth, 3=Time, 4=TimeWithSeconds.\n\t\t\t\t\t\ttickMarkFormatter: function (time, tickMarkType, locale) {\n\t\t\t\t\t\t\tvar d = new Date(time * 1000);\n\t\t\t\t\t\t\tif (tickMarkType === 0) {\n\t\t\t\t\t\t\t\treturn d.getUTCFullYear().toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (tickMarkType === 1) {\n\t\t\t\t\t\t\t\treturn d.toLocaleDateString(locale, { month: 'short', year: 'numeric', timeZone: 'UTC' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\/\/ DayOfMonth (2) and any time-level ticks fall\n\t\t\t\t\t\t\t\/\/ through to month-day, which is the format users\n\t\t\t\t\t\t\t\/\/ actually wanted on the 14-day chart.\n\t\t\t\t\t\t\treturn d.toLocaleDateString(locale, { month: 'short', day: 'numeric', timeZone: 'UTC' });\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tcrosshair: { mode: 0 },\n\t\t\t\t\thandleScroll: false,\n\t\t\t\t\thandleScale: false\n\t\t\t\t});\n\t\t\t\tvar series = chart.addAreaSeries({\n\t\t\t\t\tlineColor: TM_BRAND.line,\n\t\t\t\t\ttopColor: TM_BRAND.fillTop,\n\t\t\t\t\tbottomColor: TM_BRAND.fillBot,\n\t\t\t\t\tlineWidth: 2,\n\t\t\t\t\tpriceFormat: { type: 'price', precision: precision.precision, minMove: precision.minMove }\n\t\t\t\t});\n\t\t\t\tseries.setData(data);\n\t\t\t\tchart.timeScale().fitContent();\n\t\t\t\tupdateQuote(figure, data);\n\t\t\t\tif (window.ResizeObserver) {\n\t\t\t\t\tvar ro = new ResizeObserver(function () { chart.applyOptions({ width: canvas.clientWidth }); });\n\t\t\t\t\tro.observe(canvas);\n\t\t\t\t}\n\t\t\t}).catch(function (err) {\n\t\t\t\t\/\/ Greptile P1 (PR #1470): clear the in-flight flag on\n\t\t\t\t\/\/ failure so a future renderAll() can retry. Without\n\t\t\t\t\/\/ this, a 429 from CoinGecko leaves the figure\n\t\t\t\t\/\/ permanently in a half-loaded state.\n\t\t\t\tdelete figure.dataset.tmChartFetching;\n\t\t\t\tconsole.warn('[tm-tv-chart] data fetch failed for ' + coinId, err);\n\t\t\t});\n\t\t}\n\n\t\tfunction renderAll() {\n\t\t\tvar figures = document.querySelectorAll('[data-tm-chart]');\n\t\t\tif (figures.length === 0) { return; }\n\t\t\tloadLibrary(function () { figures.forEach(renderOne); });\n\t\t}\n\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', renderAll);\n\t\t} else {\n\t\t\trenderAll();\n\t\t}\n\t})();\n\t<\/script>\n\t\t\n<h2>Token Metrics View<\/h2>\n<p>Token Metrics data shows a bearish view for ADA. The trend is down. Momentum is weak. The token trades near the bottom of its recent range. We see negative smart-money netflow. This suggests big players are selling.<\/p>\n<p>The technical indicators paint a concerning picture. The momentum indicator shows the trend just flipped bearish. The price is nearing oversold levels but has not hit the typical reversal zone. The trend strength shows a strong downward move is in place. The overall bias confirms the negative sentiment.<\/p>\n<p>Price action reveals ADA trading in the lower portion of its range. This indicates continued selling pressure. The price is moving sideways rather than making new highs or lows. This suggests a pause before the next big move. Volatility is elevated, which often comes before trend changes.<\/p>\n<p>The token-market signal is red. ADA fell about 2% in the last day. It dropped about 13% over the last week. Key levels to watch are support near $0.11 and resistance around $0.21.<\/p>\n<p>Our Daily Pulse coverage notes a key event. Cardano will launch its Ouroboros Leios testnet in four days. This upgrade aims to boost speed. Polymarket consensus on the outcome remains mixed. Investors should watch this event closely.<\/p>\n\t\t<aside\n\t\tclass=\"tm-token-stats\"\n\t\tdata-tm-token-stats\n\t\tdata-tm-stats-id=\"cardano\"\n\t\tdata-tm-stats-lookback=\"365\"\n\t\taria-label=\"Cardano key statistics\"\n\t>\n\t\t<header class=\"tm-token-stats__header\">\n\t\t\t<h3 class=\"tm-token-stats__title\">Cardano \u00b7 Key Stats<\/h3>\n\t\t\t<span class=\"tm-token-stats__lookback\">365d lookback<\/span>\n\t\t<\/header>\n\t\t<section class=\"tm-token-stats__section\">\n\t\t\t<h4 class=\"tm-token-stats__section-label\">Market<\/h4>\n\t\t\t<dl class=\"tm-token-stats__grid\">\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>Market Cap<\/dt><dd data-tm-stats-value=\"market-cap\">\u2014<\/dd><\/div>\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>Vol \/ Cap<\/dt><dd data-tm-stats-value=\"turnover\">\u2014<\/dd><\/div>\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>52-Week Range<\/dt><dd data-tm-stats-value=\"range-52w\">\u2014<\/dd><\/div>\n\t\t\t<\/dl>\n\t\t<\/section>\n\t\t<section class=\"tm-token-stats__section\">\n\t\t\t<h4 class=\"tm-token-stats__section-label\">Performance<\/h4>\n\t\t\t<dl class=\"tm-token-stats__grid\">\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>30d<\/dt><dd data-tm-stats-value=\"change-30d\">\u2014<\/dd><\/div>\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>1y<\/dt><dd data-tm-stats-value=\"change-1y\">\u2014<\/dd><\/div>\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>vs BTC<\/dt><dd data-tm-stats-value=\"vs-btc\">\u2014<\/dd><\/div>\n\t\t\t<\/dl>\n\t\t<\/section>\n\t\t<section class=\"tm-token-stats__section\">\n\t\t\t<h4 class=\"tm-token-stats__section-label\">Risk (1y)<\/h4>\n\t\t\t<dl class=\"tm-token-stats__grid\">\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>Volatility<\/dt><dd data-tm-stats-value=\"volatility\">\u2014<\/dd><\/div>\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>Max Drawdown<\/dt><dd data-tm-stats-value=\"max-drawdown\">\u2014<\/dd><\/div>\n\t\t\t\t<div class=\"tm-token-stats__cell\"><dt>Sharpe<\/dt><dd data-tm-stats-value=\"sharpe\">\u2014<\/dd><\/div>\n\t\t\t<\/dl>\n\t\t<\/section>\n\t\t<p class=\"tm-token-stats__source\">Data via CoinGecko. Risk metrics from the trailing daily closes.<\/p>\n\t<\/aside>\n\t\t<script id=\"tm-token-stats-hydrator\">\n\t(function () {\n\t\t\/\/ Routed through the tm-coingecko-proxy Worker (5-min KV cache,\n\t\t\/\/ paid Pro key) instead of api.coingecko.com directly. Base URL is\n\t\t\/\/ resolved server-side from the `tm_token_card_coingecko_proxy_base`\n\t\t\/\/ filter \/ TM_COINGECKO_PROXY_BASE constant so staging can point\n\t\t\/\/ at a separate Worker.\n\t\tvar PROXY_BASE = \"https:\\\/\\\/tokenmetrics.com\\\/api\\\/cg\";\n\t\tvar DAYS_PER_YEAR = 365;\n\t\tvar coinCache = {};\n\t\tfunction fetchJson(url) {\n\t\t\treturn fetch(url, { credentials: 'omit' }).then(function (r) {\n\t\t\t\tif (!r.ok) { throw new Error('coingecko ' + r.status); }\n\t\t\t\treturn r.json();\n\t\t\t});\n\t\t}\n\t\tfunction fetchSnapshot(id) {\n\t\t\tif (coinCache['snap_' + id]) { return coinCache['snap_' + id]; }\n\t\t\tvar url = PROXY_BASE + '\/coins\/' + encodeURIComponent(id)\n\t\t\t\t+ '?localization=false&tickers=false&community_data=false&developer_data=false&sparkline=false';\n\t\t\tcoinCache['snap_' + id] = fetchJson(url);\n\t\t\treturn coinCache['snap_' + id];\n\t\t}\n\t\tfunction fetchSeries(id, days) {\n\t\t\tvar key = 'series_' + id + '_' + days;\n\t\t\tif (coinCache[key]) { return coinCache[key]; }\n\t\t\tvar url = PROXY_BASE + '\/coins\/' + encodeURIComponent(id)\n\t\t\t\t+ '\/market_chart?vs_currency=usd&days=' + encodeURIComponent(days);\n\t\t\tcoinCache[key] = fetchJson(url).then(function (d) {\n\t\t\t\treturn Array.isArray(d.prices) ? d.prices : [];\n\t\t\t});\n\t\t\treturn coinCache[key];\n\t\t}\n\t\tfunction fmtUsd(value) {\n\t\t\tvar abs = Math.abs(value);\n\t\t\tvar precision = abs >= 0.01 ? 2 : (abs >= 0.0001 ? 6 : 8);\n\t\t\treturn '$' + value.toLocaleString('en-US', { minimumFractionDigits: precision, maximumFractionDigits: precision });\n\t\t}\n\t\tfunction fmtCompactUsd(value) {\n\t\t\tif (value === null || value === undefined || isNaN(value)) { return '\u2014'; }\n\t\t\tvar abs = Math.abs(value);\n\t\t\tif (abs >= 1e12) { return '$' + (value \/ 1e12).toFixed(2) + 'T'; }\n\t\t\tif (abs >= 1e9)  { return '$' + (value \/ 1e9).toFixed(2)  + 'B'; }\n\t\t\tif (abs >= 1e6)  { return '$' + (value \/ 1e6).toFixed(2)  + 'M'; }\n\t\t\tif (abs >= 1e3)  { return '$' + (value \/ 1e3).toFixed(2)  + 'K'; }\n\t\t\treturn fmtUsd(value);\n\t\t}\n\t\tfunction fmtPct(value) {\n\t\t\tif (value === null || value === undefined || isNaN(value)) { return '\u2014'; }\n\t\t\tvar sign = value >= 0 ? '+' : '\u2212';\n\t\t\treturn sign + Math.abs(value).toFixed(2) + '%';\n\t\t}\n\t\tfunction trendOf(value) {\n\t\t\tif (value === null || value === undefined || isNaN(value)) { return null; }\n\t\t\tif (value > 0) { return 'up'; }\n\t\t\tif (value < 0) { return 'down'; }\n\t\t\treturn null;\n\t\t}\n\t\tfunction setCell(root, key, text, trend) {\n\t\t\tvar el = root.querySelector('[data-tm-stats-value=\"' + key + '\"]');\n\t\t\tif (!el) { return; }\n\t\t\tel.textContent = text;\n\t\t\tif (trend === 'up' || trend === 'down') { el.setAttribute('data-trend', trend); }\n\t\t\telse { el.removeAttribute('data-trend'); }\n\t\t}\n\t\tfunction dailyReturns(prices) {\n\t\t\tvar rets = [];\n\t\t\tfor (var i = 1; i < prices.length; i++) {\n\t\t\t\tvar prev = prices[i - 1][1], cur = prices[i][1];\n\t\t\t\tif (prev > 0 && isFinite(prev) && isFinite(cur)) { rets.push(cur \/ prev - 1); }\n\t\t\t}\n\t\t\treturn rets;\n\t\t}\n\t\tfunction mean(arr) {\n\t\t\tif (arr.length === 0) { return 0; }\n\t\t\tvar s = 0; for (var i = 0; i < arr.length; i++) { s += arr[i]; }\n\t\t\treturn s \/ arr.length;\n\t\t}\n\t\tfunction stddev(arr, mu) {\n\t\t\tif (arr.length < 2) { return 0; }\n\t\t\tvar s = 0;\n\t\t\tfor (var i = 0; i < arr.length; i++) { var d = arr[i] - mu; s += d * d; }\n\t\t\treturn Math.sqrt(s \/ (arr.length - 1));\n\t\t}\n\t\tfunction maxDrawdown(prices) {\n\t\t\tif (prices.length < 2) { return { value: 0, duration: 0 }; }\n\t\t\tvar peak = prices[0][1], peakIdx = 0;\n\t\t\tvar maxDd = 0, troughIdx = 0, troughPeakIdx = 0;\n\t\t\tfor (var i = 1; i < prices.length; i++) {\n\t\t\t\tvar p = prices[i][1];\n\t\t\t\tif (p > peak) { peak = p; peakIdx = i; }\n\t\t\t\tif (peak > 0) {\n\t\t\t\t\tvar dd = (p - peak) \/ peak;\n\t\t\t\t\tif (dd < maxDd) { maxDd = dd; troughIdx = i; troughPeakIdx = peakIdx; }\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar duration = 0;\n\t\t\tif (prices[troughIdx] && prices[troughPeakIdx]) {\n\t\t\t\tvar ms = prices[troughIdx][0] - prices[troughPeakIdx][0];\n\t\t\t\tduration = Math.max(0, Math.round(ms \/ 86400000));\n\t\t\t}\n\t\t\treturn { value: maxDd, duration: duration };\n\t\t}\n\t\tfunction quantStats(prices) {\n\t\t\tif (!prices || prices.length < 30) { return null; }\n\t\t\tvar rets = dailyReturns(prices);\n\t\t\tif (rets.length === 0) { return null; }\n\t\t\tvar mu = mean(rets);\n\t\t\tvar sd = stddev(rets, mu);\n\t\t\tvar ann_mu = mu * DAYS_PER_YEAR;\n\t\t\tvar ann_sd = sd * Math.sqrt(DAYS_PER_YEAR);\n\t\t\tvar dd = maxDrawdown(prices);\n\t\t\treturn {\n\t\t\t\tvolatility:      ann_sd,\n\t\t\t\tmaxDrawdown:     dd.value,\n\t\t\t\tmaxDrawdownDays: dd.duration,\n\t\t\t\tsharpe:          ann_sd > 0 ? ann_mu \/ ann_sd : 0\n\t\t\t};\n\t\t}\n\t\tfunction totalReturn(prices) {\n\t\t\tif (!prices || prices.length < 2) { return null; }\n\t\t\tvar first = prices[0][1], last = prices[prices.length - 1][1];\n\t\t\tif (!isFinite(first) || !isFinite(last) || first <= 0) { return null; }\n\t\t\treturn last \/ first - 1;\n\t\t}\n\t\tfunction setRangeCell(root, key, low, current, high) {\n\t\t\tvar el = root.querySelector('[data-tm-stats-value=\"' + key + '\"]');\n\t\t\tif (!el) { return; }\n\t\t\tel.removeAttribute('data-trend');\n\t\t\tif (!isFinite(low) || !isFinite(high) || !isFinite(current) || high <= low) {\n\t\t\t\tel.textContent = '\u2014'; return;\n\t\t\t}\n\t\t\tvar pct = ((current - low) \/ (high - low)) * 100;\n\t\t\tpct = Math.max(0, Math.min(100, pct));\n\t\t\tel.innerHTML = '';\n\t\t\tvar wrap = document.createElement('div'); wrap.className = 'tm-token-stats__range';\n\t\t\tvar track = document.createElement('div'); track.className = 'tm-token-stats__range-track';\n\t\t\tvar dot = document.createElement('div'); dot.className = 'tm-token-stats__range-dot';\n\t\t\tdot.style.left = pct.toFixed(1) + '%';\n\t\t\ttrack.appendChild(dot);\n\t\t\tvar bounds = document.createElement('div'); bounds.className = 'tm-token-stats__range-bounds';\n\t\t\tvar loSpan = document.createElement('span'); loSpan.textContent = fmtUsd(low);\n\t\t\tvar hiSpan = document.createElement('span'); hiSpan.textContent = fmtUsd(high);\n\t\t\tbounds.appendChild(loSpan); bounds.appendChild(hiSpan);\n\t\t\twrap.appendChild(track); wrap.appendChild(bounds); el.appendChild(wrap);\n\t\t}\n\t\tfunction renderOne(root) {\n\t\t\tif (root.dataset.tmStatsReady) { return; }\n\t\t\tvar coinId = root.getAttribute('data-tm-stats-id');\n\t\t\tvar lookback = root.getAttribute('data-tm-stats-lookback') || '365';\n\t\t\tif (!coinId) { return; }\n\t\t\troot.dataset.tmStatsReady = '1';\n\t\t\tPromise.all([\n\t\t\t\tfetchSnapshot(coinId),\n\t\t\t\tfetchSeries(coinId, lookback),\n\t\t\t\tfetchSeries('bitcoin', lookback)\n\t\t\t]).then(function (results) {\n\t\t\t\tvar snap = results[0]; var prices = results[1]; var btcPrices = results[2];\n\t\t\t\tvar md = (snap && snap.market_data) || {};\n\t\t\t\tsetCell(root, 'market-cap', fmtCompactUsd(md.market_cap && md.market_cap.usd));\n\t\t\t\tvar vol = md.total_volume && md.total_volume.usd;\n\t\t\t\tvar mcap = md.market_cap && md.market_cap.usd;\n\t\t\t\tvar turnoverText = '\u2014';\n\t\t\t\tif (vol && mcap && mcap > 0) {\n\t\t\t\t\tturnoverText = fmtCompactUsd(vol) + ' (' + ((vol \/ mcap) * 100).toFixed(2) + '%)';\n\t\t\t\t} else if (vol) { turnoverText = fmtCompactUsd(vol); }\n\t\t\t\tsetCell(root, 'turnover', turnoverText);\n\t\t\t\tif (prices && prices.length > 1) {\n\t\t\t\t\tvar lo = Infinity, hi = -Infinity;\n\t\t\t\t\tfor (var i = 0; i < prices.length; i++) {\n\t\t\t\t\t\tvar p = prices[i][1];\n\t\t\t\t\t\tif (p < lo) { lo = p; } if (p > hi) { hi = p; }\n\t\t\t\t\t}\n\t\t\t\t\tvar cur = (md.current_price && md.current_price.usd) || prices[prices.length - 1][1];\n\t\t\t\t\tsetRangeCell(root, 'range-52w', lo, cur, hi);\n\t\t\t\t}\n\t\t\t\tsetCell(root, 'change-30d', fmtPct(md.price_change_percentage_30d), trendOf(md.price_change_percentage_30d));\n\t\t\t\tsetCell(root, 'change-1y',  fmtPct(md.price_change_percentage_1y),  trendOf(md.price_change_percentage_1y));\n\t\t\t\tvar tokenRet = totalReturn(prices), btcRet = totalReturn(btcPrices);\n\t\t\t\tif (tokenRet !== null && btcRet !== null) {\n\t\t\t\t\tvar vsBtc = (tokenRet - btcRet) * 100;\n\t\t\t\t\tsetCell(root, 'vs-btc', fmtPct(vsBtc), trendOf(vsBtc));\n\t\t\t\t}\n\t\t\t\tvar qs = quantStats(prices);\n\t\t\t\tvar btcQs = quantStats(btcPrices);\n\t\t\t\tif (qs) {\n\t\t\t\t\tsetCell(root, 'volatility', (qs.volatility * 100).toFixed(1) + '%');\n\t\t\t\t\tvar ddText = fmtPct(qs.maxDrawdown * 100);\n\t\t\t\t\tif (qs.maxDrawdownDays > 0) { ddText += ' (' + qs.maxDrawdownDays + 'd)'; }\n\t\t\t\t\tsetCell(root, 'max-drawdown', ddText, 'down');\n\t\t\t\t\tvar sharpeText = qs.sharpe.toFixed(2);\n\t\t\t\t\tif (btcQs && btcQs.sharpe !== 0) { sharpeText += ' \u00b7 BTC ' + btcQs.sharpe.toFixed(2); }\n\t\t\t\t\tsetCell(root, 'sharpe', sharpeText, trendOf(qs.sharpe));\n\t\t\t\t}\n\t\t\t}).catch(function (err) { console.warn('[tm-token-stats] fetch failed for ' + coinId, err); });\n\t\t}\n\t\tfunction renderAll() {\n\t\t\tvar roots = document.querySelectorAll('[data-tm-token-stats]');\n\t\t\troots.forEach(renderOne);\n\t\t}\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', renderAll);\n\t\t} else {\n\t\t\trenderAll();\n\t\t}\n\t})();\n\t<\/script>\n\t\t\n\t\t<aside\n\t\tclass=\"tm-token-card\"\n\t\trole=\"complementary\"\n\t\taria-label=\"Track Cardano (ADA) with Token Metrics\"\n\t\tdata-tm-token-card=\"ada\"\n\t>\n\t\t<header class=\"tm-token-card__header\">\n\t\t\t<p class=\"tm-token-card__eyebrow\">Track this token with Token Metrics<\/p>\n\t\t\t<h3 class=\"tm-token-card__title\">\n\t\t\t\t<span class=\"tm-token-card__name\">Cardano<\/span>\n\t\t\t\t<span class=\"tm-token-card__ticker\">ADA<\/span>\n\t\t\t<\/h3>\n\t\t<\/header>\n\t\t<ul class=\"tm-token-card__benefits\">\n\t\t\t\t\t\t\t<li class=\"tm-token-card__benefit\">7-day free trial of Signal<\/li>\n\t\t\t\t\t\t\t<li class=\"tm-token-card__benefit\">Smart-money wallet flows across the top tokens<\/li>\n\t\t\t\t\t\t\t<li class=\"tm-token-card__benefit\">Daily technical setup labels \u2014 Bullish to Bearish, both directions<\/li>\n\t\t\t\t\t\t\t<li class=\"tm-token-card__benefit\">Polymarket consensus on near-term catalysts<\/li>\n\t\t\t\t\t<\/ul>\n\t\t<div class=\"tm-token-card__footer\">\n\t\t\t<a\n\t\t\t\tclass=\"tm-token-card__cta\"\n\t\t\t\thref=\"https:\/\/tokenmetrics.com\/?utm_source=tm_blog&#038;utm_medium=token_card&#038;utm_campaign=signal_ada#premium\"\n\t\t\t\trel=\"noopener\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t>See the setup, risk, and invalidation before you act \u2192<\/a>\n\t\t\t<span class=\"tm-token-card__meta\">Signal alerts include the setup, risk, and what would change the trade.<\/span>\n\t\t<\/div>\n\t<\/aside>\n\t\n<h2>Market Context<\/h2>\n<p>This story fits the security and market structure sector. It shows flaws in wallet tools. It does not show a flaw in the blockchain. Such events can hurt trust in a specific wallet. Yet, the main network stays safe.<\/p>\n<p>SecondFi used to be the Yoroi wallet. It changed its name in April 2026. Emurgo built Yoroi. Emurgo calls itself the &#8220;for-profit arm of Cardano.&#8221; It launched Yoroi as the first light wallet for Cardano. This history shows the wallet has deep roots. However, the incident highlights risks. Even wallets tied to big projects can have bugs.<\/p>\n<p>This incident follows a pattern of wallet vulnerabilities across major blockchain networks. Similar exploits have happened before with different wallet types. The common issue is not the blockchain but how wallet software is made. These incidents often happen when many new users join and wallet providers rush to grow.<\/p>\n<p>The category framing places this in the broader crypto security topic. Wallet exploits are a major cause of user losses. The address-level vulnerability type is especially worrying. It bypasses most standard security measures.<\/p>\n<p>From a market view, this incident shows how Cardano&#8217;s wallet world is less unified than some others. Many wallet providers can be good, but it also means security standards vary. Users get different levels of safety. The market has historically favored networks with dominant, well-checked wallets that have fewer security problems.<\/p>\n<h2>Risks to Watch<\/h2>\n<ul>\n<li>Watch for news of bugs in other Cardano wallet apps, especially from providers using similar code generation libraries.<\/li>\n<li>Check if users report additional losses after migrating funds to supposedly safe wallets, indicating the vulnerability may be more widespread.<\/li>\n<li>See if other Cardano wallet firms announce emergency security audits in response to this incident.<\/li>\n<li>Look for any new regulatory guidance from financial authorities regarding wallet security standards.<\/li>\n<li>Monitor whether institutional custodians revise their due diligence processes for wallet software following this breach.<\/li>\n<li>Track if insurance providers adjust their coverage terms for self-custody solutions.<\/li>\n<\/ul>\n<h2>What to Watch Next<\/h2>\n<ul>\n<li>Wait for SecondFi to release a full technical post-mortem detailing the exact vulnerability and remediation steps.<\/li>\n<li>Track the results of the independent security audit and whether other similar vulnerabilities are discovered.<\/li>\n<li>Monitor if other wallet providers announce they have found and fixed related vulnerabilities in their own codebases.<\/li>\n<li>Watch the ADA price reaction during the Leios testnet launch in four days to gauge market sentiment.<\/li>\n<li>See whether wallet providers implement new multi-party computation or hardware-based key generation solutions in response.<\/li>\n<li>Monitor if affected users receive full compensation or partial recovery from the secured 129 million ADA fund.<\/li>\n<li>Track whether this incident accelerates adoption of hardware wallet solutions among Cardano users.<\/li>\n<\/ul>\n<p>This article is for informational purposes only and does not constitute investment advice.<\/p>\n<h2>Sources \/ Data Used<\/h2>\n<ul>\n<li>SecondFi confirmed the root cause of the issue.<\/li>\n<li>SecondFi estimated the value of the affected funds.<\/li>\n<li>Charles Hoskinson stated the relationship with IOG.<\/li>\n<li>SecondFi explained the address-level problem.<\/li>\n<li>Token Metrics provided technical data on ADA.<\/li>\n<li>Token Metrics listed the upcoming scaling upgrade.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"SecondFi secured 129 million ADA after attackers drained funds from 374 addresses due to a wallet generation vulnerability affecting private keys.","protected":false},"author":1,"featured_media":4029,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_tm_paid_cta_tier":"","_tm_paid_cta_heading":"","_tm_paid_cta_body":"","csco_display_header_overlay":false,"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_reading_time":"","csco_page_toc_navigation":"","csco_post_video_location":[],"csco_post_video_location_hash":"","csco_post_video_url":"","csco_post_video_bg_start_time":0,"csco_post_video_bg_end_time":0,"csco_post_video_bg_volume":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[741,158],"tags":[744,743,295,745,283,417],"sections":[183],"entities":[742],"class_list":["post-4030","post","type-post","status-publish","format-standard","has-post-thumbnail","category-ada","category-news","tag-ada","tag-cardano","tag-exploit","tag-secondfi","tag-security","tag-wallet","section-news","entity-ada","cs-entry","cs-video-wrap"],"jetpack_featured_media_url":"https:\/\/tokenmetrics.com\/blog\/wp-content\/uploads\/2026\/06\/secondfi-traces-cardano-wallet-exploit-address-level-featured.webp","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/posts\/4030","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/comments?post=4030"}],"version-history":[{"count":0,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/posts\/4030\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/media\/4029"}],"wp:attachment":[{"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/media?parent=4030"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/categories?post=4030"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/tags?post=4030"},{"taxonomy":"section","embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/sections?post=4030"},{"taxonomy":"entity","embeddable":true,"href":"https:\/\/tokenmetrics.com\/blog\/wp-json\/wp\/v2\/entities?post=4030"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}