RADIX WikiRADIX Wiki

On 31 August 2026, between 16:02 and 16:58 UTC, twenty-six transactions on Radix mainnet emptied every Hyperlane-bridged asset held on the network and sent the proceeds out over Hyperlane's own warp routes. The assets came out of user accounts and out of the liquidity pools of Radix dApps alike, in one pass, without a single owner signing anything. Six hours later the remaining supply of hUSDC on Radix was 1,092.79 tokens, and the other five wrapped assets stood at fractions of one unit.

The incident followed by less than a day the exploit of Weft Finance, whose attacker also left through a Hyperlane warp route. The two are different in kind, and that difference is most of what a reader needs: the Weft attacker manipulated the price of a listed collateral inside one application’s own contracts, which that application could change and has changed; this one needed no application, no oracle and no price feed, because the authorization it defeated belonged to the engine. Five hours later the cause was stated publicly as a flaw in the Radix Engine itself, placing every token and NFT on the network within reach of the same method rather than only the bridged six. At 21:19 UTC Radix mainnet was halted by its node runners, and it produced no round for the next ten days; the Eagle Ray protocol update enacted and transactions resumed at 11:39 UTC on 11 September 2026.

What the ledger shows

The largest of the twenty-six is txid_rdx19lzunu3…qd60u5v, committed at 16:33:28.554 UTC for a network fee of 8.39 XRD. It is a single manifest and it does three things in order.

First it publishes a package. The blueprint is named LiquidityTool and it exposes sixty-one functions called run_0 through run_60, which is the shape of code written for one transaction rather than for reuse.

Then it calls all sixty-one, and each call takes one argument: an internal_vault_ address. Sixty distinct vaults appear across the calls. An internal vault is the container an account or component holds a resource in, and its address is public. After the calls the worktop holds 442,985.632108 hUSDC drawn from fifty-nine separate accounts and components.

Last it takes that balance and 380.037752172 XRD into buckets and calls transfer_remote on the hUSDC warp route, passing destination domain 1 and a twenty-byte recipient address in EVM format. The change goes to account_rdx168lx…3973f29, which is the only account the manifest names anywhere.

Two absences in that manifest carry as much as the instructions do. There is no proof, no badge and no owner authorisation of any kind in front of the vault calls. And there is no LOCK_FEE instruction at all: the fee was locked from inside the published blueprint, against a vault the transaction passed to it by address. The XRD for fees came out of account_rdx1283x6…0ucx9j, which lost 500 XRD on each of the twenty-six and received nothing back. Whether that account belongs to the attacker or to a third party whose XRD vault was used the same way as the sixty others is not settled by the ledger.

What was taken

Summed across all twenty-six transactions, and set against what the same resources report on the ledger at epoch 339,871 (19:09:50 UTC, 31 August 2026):

AssetTakenSupply remaining on Radix
hUSDC458,914.8857411,092.793964
hUSDT72,420.3844760.036292
hETH61.0780060.010278
hWBTC6.3482430.005600
hSOL536.1598060.136338
hBNB32.9101050.002105
XRD13,000 (fees, 500 per transaction)

The two stablecoins alone carry a face value of 531,335.27 US dollars. The rest depends on market prices, and the wiki states no total for it. The supply column is the plainer measure of what happened: bridging an asset out of Radix burns it here, so the drain is visible in the supply of each resource, and what is left of five of the six is dust.

The hour

The sequence reads as a test followed by a sweep.

  • 16:02:20 to 16:22:37. Six transactions, one per asset, each moving a token amount: 0.005 hETH, 0.00035324 hSOL, 0.015 hBNB, 0.00084948 hWBTC, 482.99 hUSDT, 384.81 hUSDC. Each still paid the full 500 XRD bridge fee.
  • 16:30:08 to 16:57:41. Twenty transactions carrying the rest. The hUSDC sweep at 16:33 is the largest single one; hUSDT, hWBTC, hETH and hSOL follow in blocks.
  • 17:17 UTC. The first public report reaches the main Radix Telegram group, twenty minutes after the last transaction committed.
  • 18:18 UTC. A message in that group states that Hyperlane, the security firm Zellic and others have been contacted, and that parties on the receiving chain are being approached to contain the assets.

The collecting account has committed no further transaction since 16:57:41, read at ledger state version 557,804,842.

Why the usual controls did not apply

A Radix resource can carry authorities that let a named badge holder claw tokens back or halt movement in them. Neither existed here. Read live at 19:08 UTC on 31 August, hUSDC reports recaller and freezer both set to deny_all, with rules_locked true, so those settings cannot be changed by anyone. The token can be minted and burned only by the badge the bridge holds, which is what a warp route needs in order to work at all.

The consequence runs both ways. Nobody could have recalled these assets out of user accounts, which is the property holders were told they had. And nobody can recall them back, which is why containment moved to the receiving chain within the hour. The drain was not a recall and not a freeze; on the ledger it is an ordinary withdrawal that no owner authorised.

XRD itself was not swept by the twenty-six transactions. The 13,000 XRD that moved in them was fee payment, and it came from one vault rather than from the network at large. The scope of the drain is what the attacker could bridge, which is not the same statement as the scope of what the method could reach, and not the same statement as the scope of the loss either: the pools the drain emptied paid out the rest of their $XRD to whoever asked next.

Who the sweep took from

The 16:33 transaction is the one to read for this, because it is the largest and because its receipt lists every balance it changed. Sixty-two entities lost hUSDC in it, and they are not all people. Thirty-six are user accounts. Thirteen are native two-resource pools, the component type that holds a trading pair and issues a pool unit to whoever deposited into it. Thirteen are dApp components: the largest is XHSWAP, which exists to swap Radix-native assets into Hyperlane ones, and the second is an order book for the $XRD/hUSDC pair.

Held byEntitieshUSDC taken
User accounts36182,508.03
Native two-resource pools13155,391.82
dApp components13105,085.79

Two resources moved in the whole transaction, hUSDC and $XRD, and the only $XRD row is a 380.04 credit to one component plus the 8.39 fee. No non-fungible balance changed at all, and the collecting account holds no NFT at the last committed state version. That is the answer to the question the main Radix chat has been asking since the halt: staked $XRD, stake units and NFTs were not taken. A liquidity position was, if the pair had a bridged asset on one side, and its holder never touched a bridged asset directly.

What the empty pools paid out

An automated market maker prices one asset against the other by what it holds of each. Empty one side and the price of the remaining side collapses towards nothing, and the pool will still trade at it, because a pool has no way to know why its balance changed. Thirteen pools were left in that state at 16:33 UTC, and the first was arbitraged forty-one minutes later.

The largest of them, pool_rdx1chxzajmur7p67h0uvk7etgnm9m67ptzfv7ysfdvq35ck2zz6zuttqq, issues the pool unit named Defiplaza hUSDC Base and held 2,687,281.65 $XRD alongside its 105,038.34 hUSDC at the state version immediately before the sweep. At 17:14:40 UTC one account withdrew 0.000001 hUSDC from its own balance, swapped it through DefiPlaza, and took the entire $XRD side. It is a different account from the one that ran the drain, and it signed an ordinary transaction: no flaw was needed, only a price.

It kept going for an hour, through the $XRD/hSOL pools as well:

Time, 31 AugustInOut
17:14:400.000001 hUSDC106,076 ASTRL
17:16:01106,076 ASTRL2,420,151 $XRD
17:32:580.0001 hSOL1,700,015 $XRD
17:33:150.0001 hSOL1,574,116 $XRD
17:43:190.0000001 hSOL102,266 ASTRL
17:56:5910 $XRD10,181 ASTRL
18:13:460.01 hUSDC72,556 ASTRL

That is 5,694,282 $XRD out of the pools between 17:16 and 17:33, and 185,003 ASTRL kept after the round trips. Two million of the $XRD left Radix at 17:18 and 17:26, in two calls to transfer_remote on the $XRD warp route, a million each, destination domain 8453, which is Base. The drain used domain 1, which is Ethereum, and a different recipient address, so this is a second party rather than the same one twice. The account still holds 3,920,351 $XRD and 185,003 ASTRL, frozen where the ledger stopped.

The loss lands on the liquidity providers, and it is still outstanding. The Defiplaza hUSDC Base pool unit had 91,710.25 tokens in supply before the sweep and the same 91,710.25 at the last committed state version, so nobody redeemed and nobody was diluted; the pool behind those 91,710.25 units reads zero $XRD and zero hUSDC. Every figure in this section is read from the Gateway pinned to state version 557,840,622, the position its status endpoint reported throughout the outage and five states short of 557,840,627, the last one the ledger reached; a pinned read was the only way to ask it anything while the network was halted.

The cause

At 22:02 UTC, five hours after the last transaction committed, the question this page had left open was answered in the main Radix Telegram group: "the issue was in the Radix Engine. Which means any assets, token or nft, could have been withdrawn and moved without permission." The Radix Accountability Council had said the same eight minutes earlier — an outstanding issue in the execution layer, "the root cause that allowed the more recent hack on hAssets", with several sources converging on it. Neither statement described the flaw. The code does.

Every reference a transaction names is checked before any WASM runs. In system_callback.rs::verify_boot_ref_value, a node that is not global is accepted as a StableReferenceType::DirectAccess reference — and injected into the caller's frame — when its blueprint is FungibleVault or NonFungibleVault from the resource package. That is the whole test. The function does not ask who owns the vault, and it has no way to: ownership is not one of its inputs. Direct access to a vault exists in the Engine so that recall can work, and the vault blueprint gates recall behind the resource's RECALLER_ROLE.

The second half is which other methods that reference reaches. In the same auth template, take, take_advanced and lock_fee are gated by the WITHDRAWER_ROLE of the resource — not by anything belonging to the account or component that holds the vault. On a freely transferable token that role is open, which is what makes the token transferable at all; what normally protects a balance is the account component's own access rules on its withdraw method, and a call made straight to the vault never passes through them. So the attacker did not need to defeat an authority. Holding a reference the Engine should never have granted, take was open to them on sixty vaults, and so was lock_fee — which is why the transactions carry no LOCK_FEE instruction and still paid their fees from a stranger's XRD vault. Both absences this page recorded before the cause was known follow from the same defect.

Two consequences of that reading. The recall and freeze authorities were never in play: nothing was recalled, so deny_all on those roles was irrelevant to the outcome. And the reach is the reach of the Engine, not of the bridge — the Foundation's own statement puts every token and NFT on the network inside it, and the limit the attacker actually hit was transaction size, one vault named per call. The version this was read at is v1.3.1, the Cuttlefish release of 20 January 2026; the same function on the repository's main branch is byte-identical to it.

The halt

Radix mainnet committed its last round before the stop at 21:19:48.939 UTC on 31 August 2026 – state version 557,840,627, epoch 339,897, round 4. The Gateway status endpoint reported a different ledger for the whole of the outage, state version 557,840,622 at epoch 339,896 round 102, timestamped 21:19:06.179 UTC: its aggregator stopped five state versions short of the tip, and the gap was invisible for as long as neither number moved. Every endpoint that reads state refused with NotSyncedUpError for the next ten days, a sync delay that grew by a second every second because the ledger no longer moved. That is why wallets, the dashboard and the explorers went dark within minutes of the halt: they were all reading the same stalled Gateway.

The stop was deliberate. Radix consensus requires more than two thirds of staked XRD to be validating; below that threshold the network cannot form rounds and simply stops, which is the liveness half of a BFT trade-off it makes in favour of safety. Node runners took enough stake offline to cross that line. The announcement at 21:17:30 UTC read: "Since epoch 339897, round 2, the Radix network has been halted by Radix's Node Runner Community. A fix for a security vulnerability is currently being developed and will be rolled out shortly, after which the network will resume." By 22:36 the StakeSafe validator dashboard had shipped a stake-up/stake-down view and put 48.32% of delegated stake offline.

The order of the evening matters, because the exploit was public knowledge before the network was stopped and the fix was not yet written. The Foundation said it had held the diagnosis back until the halt was in place, and separately that it was in contact with bridges, exchanges and security partners, reaching out to authorities, and might be limited in what it could say next. No resumption time was given that night, or for the ten days after it. The Council's notice put it plainly: the network's inoperative status "does not have a predictable comeback time as of yet".

16:02:20 – 16:57:41The twenty-six transactions
17:17First public report in the main Telegram group
21:17:30Halt announced by the node-runner community
21:19:48.939Last round on the ledger — epoch 339,897, round 4, state version 557,840,627
21:54:11Radix Accountability Council notice: execution-layer issue, no comeback time
22:02:14Cause stated publicly as the Radix Engine, any token or NFT in scope

The outage

The network did not come back overnight. Re-read at 03:09 UTC on 1 September 2026, the Gateway status endpoint returns the identical ledger it returned at the halt — state version 557,840,622, epoch 339,896, round 102, proposer round timestamp 21:19:06.179 UTC — which puts Radix mainnet close to six hours without a committed transaction. The Gateway itself is answering normally; network-configuration returns 200. It simply has nothing new to report, which is the distinction between an outage of the infrastructure and an outage of the ledger underneath it.

The fix is not public. babylon-node, the node implementation every validator runs, has published nothing since v1.3.0.5 on 1 June 2026, and the default branch of radixdlt-scrypto, which carries the Engine itself, last moved on 27 March 2026. No post has appeared on the Foundation's blog, and the DAO's notice feed carries nothing after 29 August. Six hours in, the only public account of the path forward is a Telegram message: Timan — the DeFiPlaza contributor and Astrolescent founder the Foundation appointed Interim Hyperscale Lead on 10 November 2025 — wrote at 22:14 UTC that he had been "in emergency mode with a few others for the past 6 hours", that the group was "talking to (former) core node devs", and that "we'll get back online". A restart therefore depends on people who no longer work on the codebase, which is a consequence of the Foundation having moved to maintenance mode and is the first operational cost of that decision to be visible from outside.

Two questions were raised in the main group and answered there. Rolling the ledger back to before 16:02 was proposed by a validator at 20:12 UTC and refused within eight minutes on a point of arithmetic rather than of policy: the wrapped tokens were burned on Radix and the assets backing them released on Ethereum, so as one reply put it, "roll back not possible. it's already on ethereum". Restoring the Radix balances would restore the claims without restoring what backs them. And the exploit's payload drew a forensic note from 0xOmarA — the fifth-largest contributor to radixdlt-scrypto with 1,318 commits, and the author of most of the Radix Engine Toolkit — who observed at 00:54 UTC that the attacker's WebAssembly carries no build-host string and no panic paths, the two artefacts Rust compilation leaves behind by default, and read that as code hand-written in WAT rather than compiled. That is an inference about method, not identity, and nothing in the ledger names anyone.

The clearest measure of how the halt was read from inside the ecosystem came from Hyperscale. At 18:55 UTC, before the cause was public and before the network stopped, flightofthefox, who leads the Rust Hyperscale effort, told his own channel he had begun liquidating all exposure to the Radix blockchain, saying he could not risk Hyperscale's runway "to this many unknowns" and that he was stating it publicly only because of the circumstances. The two Hyperscale efforts are separate — the Foundation’s programme, which Timan leads, and the independent Rust reimplementation, which flightofthefox leads — and on the night of 31 August the people running them took opposite positions: one coordinating the restart, the other selling out of the asset it would restart.

What the halt does off the chain

Re-read at 07:02:30 UTC on 1 September 2026, the Gateway status endpoint still returns the ledger it returned at the halt — state version 557,840,622, epoch 339,896, round 102, proposer round timestamp 21:19:06.179 UTC — nine hours and forty-three minutes after the last committed round. Four minutes later a read of /state/entity/details for XRD itself answered HTTP 500, and the error names the threshold: current_sync_delay_seconds 35,084 against max_allowed_sync_delay_seconds 720. The Gateway refuses to serve state it believes is more than twelve minutes stale, and it is nine hours and forty-four minutes behind, so every application that asks it a question about the present gets an error rather than an old answer. That is a deliberate design choice showing its value on the one day it matters.

The exchanges

The clearest external measure is at the venues, where the halt has been translated into a switch. Read at 07:09 UTC on 1 September from each exchange's own public API, native XRD cannot move on or off the chain at the three live venues that answer without a key:

VenueEndpoint readNative XRD chain
Gate.iospot/currencies/XRDdeposit_disabled: true, withdraw_disabled: true
KuCoinv3/currencies/XRDisDepositEnabled: false, isWithdrawEnabled: false
CoinExdeposit-withdraw-configdeposit_enabled: false, withdraw_enabled: false

The markets themselves stay open. Gate.io reports trade_disabled: false at the currency level and its XRD/USDT ticker was quoting 0.0006697 USDT on 98,929,511 XRD of 24-hour volume, down 17.3% over the day; KuCoin's XRD-USDT book was live at 0.000666. So XRD keeps a price, and a falling one, at venues from which it cannot be withdrawn to a wallet or deposited from one. What a holder can still do is sell the balance an exchange already custodies; what nobody can do is move the token itself, because the ledger that records the move has stopped. CoinEx makes the shape explicit in one field, leaving inter_transfer_enabled: true while both external legs are off: transfers inside the exchange, nothing across its edge.

One row is worth reading carefully. Gate.io lists XRD on two chains, and the second is eXRD, the ERC-20 that carried Radix on Ethereum before the Babylon network existed. Its withdrawals read withdraw_disabled: false while the native chain's are off — the predecessor still moves, because it settles on a chain that has not stopped. No exchange has published a dated notice that this page can cite tying any of these switches to the halt; the values above are the exchanges' own APIs, recorded with the hour they were read.

The applications

On Radix itself the outage divides applications by where their content comes from rather than by who runs them. Front ends built as static bundles keep serving: Ociswap, Astrolescent, Weft, RSwap, Surge, RadQuest and the Radix Dashboard all answered 200 on the same pass. Pages that have to resolve current state do not: Astrolescent's per-token page returned HTTP 500 through its own error boundary, and stats.defiplaza.net returned a bare Application Error. In between sit the cached read APIs, which answer normally and answer with the pre-halt ledger — Ociswap's token endpoint and Astrolescent's price feed both served full payloads. Neither payload says how old the ledger under it is, so a reader cannot tell from either that nothing has settled since 21:19 the previous evening. The Gateway, which does carry that information, is the only one of the three that declines to answer.

The fix, and the restart

Radix mainnet was down for 254 hours, 15 minutes and 40 seconds, and for most of them the only public account of the repair was a Telegram channel. What follows is the summary. The day-by-day record, with the ledger and repository readings each statement was checked against at the hour it was made, is on a separate page.

The four steps

At 12:16 UTC on 1 September the Radix Accountability Council published the shape of the repair, and it did not change: code fixes to the Radix Engine; updates to the node software carrying a protocol upgrade; a coordinated deployment of those across nodes; and a coordinated return to liveness. It attached no dates, and none of the four acquired one until the third. The Foundation's announcement channel spoke twice in the whole outage, on 31 August and at 08:58 UTC on 2 September, and the second post pointed readers to the council for anything further. Its blog carried nothing at all.

The first two steps were written by one contributor and were readable in public before anyone said so. The last two needed the few dozen node operators who had agreed the halt among themselves, and they are what the ten days were spent on.

Eagle Ray: the Engine half

The fix was written on the night of the drain. Pull request #2093 against radixdlt-scrypto was opened at 12:26 UTC on 2 September by 0xOmarA, the contributor whose forensic notes this page records from the first night, and its earliest commit is dated 22:41 UTC on 31 August – one hour and twenty-two minutes after the last round. The commit that adds the receiver check is dated 00:12 UTC on 1 September, hours before the first official update said anything in public.

Its content is a flash protocol update named Eagle Ray, which advances the system logic from SystemVersion::V4 to V5, and V5 turns on a single check. Before an invocation runs, the system asks whether the calling frame can actually see the node whose method it is calling – direct methods, the type used for recall and other direct vault access, requiring direct visibility of the receiver – and rejects the call otherwise with a new SystemError::InvalidInvokeAccess. That is the handle nobody tried, given a lock. The test it rewrites is test_recall_on_internal_vault, which used to fail obscurely inside the kernel's frame construction and now fails cleanly at the system layer.

It then sat unreviewed for five days. A seventh commit landed at 16:50 UTC on 7 September and the branch merged forty-three minutes later, at 17:33:31; ninety seconds after that Scrypto v1.4.0 was published, the first Scrypto release since January 2026, with the repository's licence text as its release notes and no description of the flaw, the fix or the update. The merge touches 587 files, but 538 of those are transaction-scenario receipts regenerated under the new protocol version; the engine change is 80 lines, plus 43 in the system callback that runs the check.

The node half, and the epoch it named

Pull request #1076 against babylon-node, the software every validator runs, opened at 06:00 UTC on 8 September from the same author with no description, and it carried the first public answer to what a restart would look like. EAGLE_RAY_ENACTMENT_EPOCH is set to 339,898 with the trigger EnactAtStartOfEpochUnconditionally, which makes it the only protocol update in Radix's mainnet history that does not wait for the validator set to signal readiness. Anemone, Bottlenose and Cuttlefish each required validators holding 75% of stake to signal over days or weeks; this one enacts on an epoch number alone.

The same pull request added a subsystem the node did not have, a user transaction moratorium: a range of epochs in which consensus continues and user transactions are refused. Mainnet got exactly one range, epoch 339,897 inclusive to 339,898 exclusive, commented for the incident. Three places enforce it – the mempool, the consensus pacemaker's vote, and a verifier on proposals arriving from other nodes – so a node that skipped the update could still propose a user transaction and the rest would decline to vote for it.

It merged at 15:28 UTC on 8 September, with no reviews and no comments, after being force-pushed and retargeted from develop, whose tip had not moved since March 2025, onto main, the line the releases actually come from. A release candidate followed seven minutes later.

The final release, v1.4.0.0 at 03:59 UTC on 10 September, resolves to the same commit as that candidate: byte for byte identical, with the pre-release flag as the only difference. The flag is not cosmetic. GitHub reports as latest the newest release that is neither a draft nor a pre-release, so from 8 to 10 September the answer was v1.3.0.5-test.1 – a rebuild of the exact version mainnet halted on – and that is what the babylonnode installer fetched. An operator running a standard install on 10 September got the fix. The day before, they got the flaw.

Deployment, and then liveness

The update was rehearsed before it was run. The council reported at 18:43 UTC on 9 September that Stokenet, the public test network, had taken the new software and protocol end to end, and Stokenet's own ledger corroborates it in the way that matters to someone waiting on mainnet: sampled hourly it never dropped a beat, committing exactly twelve epochs in each of the twenty-eight hours around the deployment. That is what a protocol update is meant to look like from outside, which is also why an unbroken ledger is not by itself proof that one enacted.

Operators were told to wait three times: on 7 September because a library release is not a node build, on 8 September because a candidate is not a release, and again at 09:13 UTC on 10 September when a final build existed and the coordination did not. The instruction changed at 16:15 UTC that day – upgrade now, from official sources, and leave a healthy node online – and nothing published after it named a time. That was deliberate. Asked on the morning of 11 September whether an announcement would precede the fork, Daffy answered that there would be none, because the moment could not be predicted, and gave the order plainly as secure liveness first, announce after.

At 07:12 UTC on 11 September StakeSafe's adoption dashboard read 31.22% of active validator-set stake on v1.4.0.0, and the twelve largest validators all read a v1.3 version and all read offline. That was not a stalled upgrade. Faraz said so in the main Radix group at 10:11 UTC: the largest nodes were upgraded and waiting to boot together, so that the network would come back well clear of two thirds rather than marginally above it. The dashboard reports the version a node last advertised, so an offline validator shows whatever it was running when it stopped.

11 September

Radix mainnet committed a round at 11:35:28.96 UTC on 11 September 2026, its first in ten days, at epoch 339,897 round 5. That epoch then ran to round 106 under the moratorium and every ledger entry in the window is a system transaction, which is the moratorium working: consensus certifying rounds and refusing user payloads. At the start of epoch 339,898 the fork enacted and the moratorium lifted together, and at 11:39:25.129 UTC round 2 of that epoch committed 17 user transactions at once, five of them failing, as a queue ten days old cleared. Just under four minutes of empty blocks separate the network coming back from the network being usable. Read at 13:10 UTC, 80.85% of a 4,873,528,908 XRD active set was on the release.

The first published test of the fix is on the ledger, and it is the exploit. At 12:35:05.915 UTC a transaction published a package to mainnet whose blueprint is named VaultDrainer, with methods drain and drain_victim_pays. It committed successfully for a fee of 14.14 XRD, which is a package publish succeeding rather than a drain succeeding. The operator who submitted it said so in the developer group at 13:03 UTC: it is the drainer that had been run against the unpatched network throughout testing, put on mainnet to verify the fix is operative against live vaults.

The drain itself was refused. The transaction that calls the blueprint is permanently rejected on mainnet, and the reason the Gateway gives for it is SystemError::InvalidInvokeAccess, the check Eagle Ray turned on that morning, firing on a live attempt. It failed before repaying its fee loan, so it was rejected rather than committed as a failure and left no entry on the ledger. The operator reported the result in the developer group at 14:12 UTC.

The council announced the restart at 14:37 UTC, three hours after it happened, in a message that credits the node runners and says the restart arrived earlier than it had expected. It adds that the council had itself attempted the exploit against mainnet, and that every attempt failed. It asks for a few days before it publishes a report, says the Foundation is working with the exchanges and market makers but that when deposits and withdrawals return is each exchange's own decision, and says the Governance Framework ratification stays in its discussion phase, which the incident had pushed aside. The Foundation's own blog still carries nothing about any of it, and the documentation page for Eagle Ray still answered HTTP 404 at 15:24 UTC.

Where the assets went

Bridging out of Radix burns the wrapped token here and releases the real asset on the destination chain, so the second half of this incident is on Ethereum and is still readable there. The recipient named in the warp-route calls is 0x626d…7cD2, an ordinary externally-owned account. Its inbound transfers come from three Hyperlane collateral contracts, one per asset, and they line up with the Radix side to the last digit: the three probe amounts this page records — 0.00084948 hWBTC at 16:17, 482.994855 hUSDT at 16:21, 384.810629 hUSDC at 16:22 — arrive as WBTC, USDT and USDC within the same minute of each other. The USDT total received, 72,420.384476, is exactly the hUSDT burned on Radix, and the WBTC received sums to the 6.348 hWBTC burned.

The USDC does not match, and the gap is informative rather than mysterious: 15,929.25 USDC reached this address against 458,914.89 hUSDC burned on Radix, so the largest sweep of the afternoon was directed at a different recipient. From 16:44 the balances were forwarded to a contract at 0x225a…DC17 and converted; read at 23:15 UTC on 31 August the account holds 330.207 ETH and 53.93 USDT. Radix cannot reverse any of that — the ledger it would have to do it on is not the one the assets are sitting on, and by that evening it had halted as well.

The Foundation's report (17 September 2026)

The Radix Foundation published its account of the incident on 17 September as a public incident report on the Radix blog, reference RDX-INC-2026-0831. On the mechanism it agrees with the reading above: a vault address named in a transaction manifest is classed as a direct-access reference, meant for operations such as recall, and the Engine let the attacker's own package call the vault's ordinary take method through it. The report states that the Hyperlane package played no part in the exploit and served only as the way out, and that no private key, admin badge or recall badge was used.

What the report adds is where the flaw came from. By the Foundation's account it entered the code in June 2023, in a tidy-up of the Radix Engine by RDX Works, the company then contracted to develop the protocol. Hacken had audited the Engine before that change. Zellic audited the protocol in August 2024, including the part of the Engine that held the defect, and did not find it. The Foundation and the forensic team it worked with believe the attacker found the flaw in the public source code with AI-assisted analysis tools; the report gives this as their assessment rather than as evidence. It records that RDX Works was told the root cause and has not responded.

Its timeline covers the response between the last exploit transaction and the halt: validators and Radix team members escalated to Foundation leadership at 17:37 UTC; Hyperlane took its Radix validator, relayer and scraper operations offline between 17:53 and 18:09; the security response group SEAL 911, Zellic and Hacken were engaged between 18:09 and 18:52; at 18:46 the Foundation stopped its market making on centralised exchanges and asked exchanges to pause $XRD deposits, withdrawals and trading; and between 19:10 and 19:45 the Foundation signed a multi-signature transaction pausing the Ethereum route at the bridge contract, a second barrier that did not depend on the operators staying offline. At 20:30 a call between the Foundation, board members and key validators decided to stop the network, because the flaw exposed every vault on Radix and not only the bridged ones. The report places the loss of liveness between 20:30 and 23:30, and the ledger's last committed round, at 21:19:48 UTC, falls inside that window. On 2 September the Foundation reported the theft to the States of Jersey Police and to UK police through Action Fraud.

On the repair, the report says a third-party developer started work at 21:11 on 31 August and presented a candidate fix at 11:00 the next day. Audit firms and other security parties reviewed the fix and the node software, some on test networks of their own running the patched code, and found no critical issue.

The report publishes no dollar figure for the loss, no per-asset amounts and no attacker addresses; the amounts on this page are read from the ledger. Its status line, "Network restoration in progress", and its statement that no transaction has been committed since liveness was lost both describe the network before 11 September, although the report is dated 17 September as version 1.4.

What is unresolved

The cause is no longer one of them, and since 11 September neither is the restart. Three questions stand, and the ledger can be asked about them again.

The first is whether the fix holds, and what the twelve days cost. The Engine half was published on 2 September as pull request #2093, which introduces the Eagle Ray protocol update and the receiver check it exists to carry; it merged on 7 September and released the same evening as Scrypto v1.4.0. The node half was published on 8 September as pull request #1076, which sets the enactment epoch at 339,898 and refuses user transactions for the epoch before it, and it shipped final as babylon-node v1.4.0.0 at 03:59 UTC on 10 September. Both halves are now running: the fork enacted at 11:39 UTC on 11 September with 80.85% of active stake on the release, and the first exploit aimed at them was rejected the same afternoon. The account of the flaw the council promised at the restart arrived on 17 September as the Foundation's incident report. Nor has the validator set finished arriving, with 19.15% of active stake still on a version that predates the fork.

The second is recovery. The assets left the network within the hour, and what is left of them sits on Ethereum in an account nobody on Radix can reach. Containment moved to the receiving chain and to the exchanges, which is where it stays.

The third is who responds. The incident landed in the week the Radix DAO was taking over from the Foundation, with the Governance Framework in its ratification discussion period and no permanent council elected. Radix governance describes the bodies that exist and what each of them can decide. What actually stopped the network on 31 August was none of them: it was the node runners, acting together, using the only lever a validator set has.

HydrateLast updated 2d agov3.3.040 revisionsVerified Sep 18, 2026