On-chain investigationDominionSolanaMultisig compromise

Dominion SILV hack: $3 million of silver tokens sold for $238,000.

It began a little after midnight UTC on 11 September, with a wallet paying off its loans and moving the collateral to an address with no history. Six hours later the multisigs had new members. Four hours after that, one of the old keys was moving money again, and by the afternoon Dominion was freezing accounts. We traced each step on-chain, including the part that crossed to Ethereum.

At a glance
Dominion sells silver as a token on Solana. Each SILV is meant to stand for one troy ounce, and the company kept a large stock of them in a treasury that moved only when three of its five signers agreed. On 11 September an attacker held three of those keys. It emptied the treasury with a single proposal and pulled more SILV out of loans the stolen wallets had taken. Then it dumped 46,909 SILV, half of all the SILV in existence, into DEX pools far too thin to absorb it. Tokens worth about $3 million the evening before left the attacker with about $238,000. The team had replaced its signers by 06:19 UTC. At 10:51 the attacker was back, using wallets no rotation could fix. That afternoon Dominion froze 2,819 SILV accounts holding 33% of the supply, nearly all of them wallets that got SILV after the attack began, while the attacker pushed the last of its SOL through Chainflip.
46,909
SILV dumped, half of all the SILV in existence
$238K
Left with the attacker, from tokens worth about $3M
2,819
SILV accounts Dominion froze that afternoon
10:51
UTC, when the attacker came back after the rotation

01 · The loan that closed after midnight

A new wallet, and a price that would not hold

At 00:23 UTC on 11 September, a Solana wallet paid off a loan. It had borrowed dollars on Loopscale, a lending market, against a stack of SILV tokens. In one transaction it pulled the tokens back out, sold them and cleared the debt. People close loans like that every day.

Six minutes later the same wallet did it again. This time the freed tokens went to an address that had never made a transaction, and about 10 minutes after that the new address started selling. SILV had spent the evening at about $63. By 01:00 UTC it was changing hands for less than half of that.

SILV comes from Dominion, a company that sells silver as a crypto token and says each one is a troy ounce of physical silver in a vault. The wallet with the loan was one of the five signers on Dominion's treasury.

What followed was a multisig compromise. The treasury moved only when three of its five keys agreed, and whoever was behind this held three. Bitquery indexes every transfer and trade on Solana, so we rebuilt the night from the ledger, reading every approval, swap and bridge deposit and checking each figure a second way. The ledger shows how the treasury was emptied, what the tokens fetched, a fight over the keys, and a second visit hours after the team took them back. The stolen wallets were still exposed when we finished, so balances here are a snapshot taken at 15:36 UTC.

02 · What SILV is

A silver token with a treasury and two sets of keys

Dominion launched SILV on Solana in August, and most of the supply was minted between 13 and 16 August. The token's own metadata says it is "backed one to one by physical silver", with each token standing for one troy ounce "held in allocated, audited vault storage". On DEXes it traded close to the price Dominion's program charged for a new token, about $63 on the evening of 10 September.

Dominion's own program kept it there. It mints new SILV for anyone who pays USDC at the silver price plus a fee, and buys SILV back for USDC at close to the same price. When the DEX price drifts, traders mint or redeem and pocket the gap, and the price comes back into line.

The company also kept a large stock of SILV in a treasury vault. On the night of the hack that vault held 45% of all the SILV there was.

Two Squads multisigs sat on top of all this. A multisig is a wallet that moves only when enough of its keys sign. The first controlled the treasury and the switches that turn minting and redemptions on and off. The second held three powers over the token itself. Through a Token-2022 feature called a permanent delegate it could move SILV out of any holder's account. It could also freeze any account, and replace the code of Dominion's mint program. Both multisigs needed three signatures out of five, and both had the same five signers.

Power over SILVWho could use it
Move the treasury's tokensTreasury multisig, 3 of 5 signatures
Switch minting or redemptionsTreasury multisig, 3 of 5 signatures
Move SILV out of any accountAuthority multisig, 3 of 5 signatures
Freeze any SILV accountAuthority multisig, 3 of 5 signatures
Replace the mint programAuthority multisig, 3 of 5 signatures
Mint new SILVOnly the program, for USDC at the silver price

03 · Three keys that signed as one

What the signing record shows

A multisig with five signers and a threshold of three is built to survive the loss of two keys. That only works if the keys live in different places.

The signing record suggests three of these did not. From 26 August, every payment out of the treasury was started, approved and executed by the same three keys, each inside a minute. Four days earlier the rhythm was different. Another signer started two treasury transactions, and the approvals needed to pass them came 101 minutes and 25 minutes later.

Treasury transactionWho signed, and how long it took
22 August, 13:32 UTCStarted by 2Lp91FyJ in three separate steps, passed 1 hour 41 minutes later
22 August, 17:59 UTCStarted by 2Lp91FyJ in three separate steps, passed 25 minutes later
26 AugustThe three keys, start to finish in 56 seconds
31 AugustThe three keys, 33 seconds
3 SeptemberThe three keys, 38 seconds
8 SeptemberThe three keys, 33 seconds
10 SeptemberThe three keys, 35 seconds

The three keys also rolled the create, propose and approve steps into a single transaction, the way software wallets and scripts sign. One of the two signers the attacker never held signed each step on its own, seconds apart, which is how signing on a hardware wallet usually looks. Where the keys were stored is not on the chain. For two weeks before the hack, though, three of them acted as a unit, which fits keys kept together and within reach of a single break-in.

04 · Paying off the loans

The first hour, and 11 wallets

The attack began with debt. Several of the stolen wallets had borrowed USDC on Loopscale with SILV as collateral, and collateral stays locked until the loan is repaid. So the attacker repaid the loans, in the biggest case by selling part of the SILV inside the same transaction, and kept the rest.

Within an hour, SILV collateral had come out of loans in four wallets. Clearing the first wallet's loans alone meant handing more than $81,000 back to lenders.

Time (UTC)What happened
00:23:28A stolen signer wallet repays a Loopscale loan by selling its SILV collateral. Transaction
00:29:38The first stolen SILV reaches a new wallet, in its first transaction ever. Transaction
00:39:55That wallet starts selling
00:44:56SOL starts being swept out of the stolen wallets
01:08:35A second attacker wallet makes its first transaction
01:24:34The first SOL goes into Chainflip, bound for Ethereum. Transaction
01:50:24Proposal 45 empties the treasury. Transaction
02:02:56The lowest trade of the day, at $0.339. Transaction
02:20:32The first redemption at the silver price
03:43:48A new signer, almost certainly the attacker's, joins the authority multisig. Transaction
03:44:54The team's first move on-chain. Transaction
03:48:29Redemptions switched off. Transaction
03:56:23Minting switched off. Transaction
03:57:38The attacker's last sale of the night
05:24:58A vote to remove a clean signer reaches 2 of the 3 approvals it needs. Transaction
06:19:24The last stolen keys are removed from both multisigs. Transaction
10:51:39A stolen wallet repays its loan and the attacker takes 279.95 SILV. Transaction
13:37:27Dominion starts freezing SILV accounts. Transaction
13:50:20The attacker moves 1,923.50 SOL to a new wallet and starts feeding it into Chainflip. Transaction

SOL was being swept out at the same time. Ten wallets were emptied down to exactly 890,880 lamports each, about 9 cents, and every sweep went to the attacker's first wallet. The same odd leftover every time looks like one script working through a list of keys.

Leaving out its own two new wallets, the attacker signed for at least 11. The oldest first moved in February 2024 and the newest in June 2026. Four were created within 25 minutes of each other on 26 February 2026, and one of those four was sent 1,500 SILV straight from Dominion's treasury in August. Any of them can be traced the same way through the Bitquery MCP.

05 · One proposal

The treasury, in two minutes

The treasury was guarded by the same three keys, so nothing had to be broken to reach it. At 01:48 UTC one of them created proposal 45, a plain transfer of every SILV in the vault. A second key approved it about a minute later and a third 49 seconds after that. It executed 8 seconds later.

Proposal 45
Every SILV in the treasury, 45% of the supply, moved in 2 minutes and 5 seconds.
42,181.88
SILV sent to the attacker's second wallet, 42 minutes old
3
Stolen keys that proposed and approved it
01:50:24
UTC, when it executed

Half an hour later the attacker used the same three keys again, this time to take 5 SOL out of each multisig's vault. One of those vaults belonged to the multisig with power over the token itself.

06 · Silver sold for pennies

Half the supply, into pools built for a quiet market

Selling that much SILV at once was never going to fetch the silver price. The pools were sized for everyday trading, and each sale pushed the price down for the next.

The attacker sold anyway, in dozens of swaps a few seconds apart. Its second wallet got rid of about 43,100 SILV that night, the treasury's tokens among them, at an average of $3.34.

SILV's price through the night5-minute median, all Solana pools
Attacker's moveTeam's move5-minute median priceEvening before, $63.59$0$20$40$6023:0001:0003:0005:0007:0009:0011:0013:0015:0010 Sep11 Sep$0.339 lowest trade1234567100:23 attack starts201:50 treasury drained303:44 team's first move406:19 stolen keys removed510:51 attacker back613:37 freezing starts714:17 big pools frozen
5-minute medians of every SILV trade over $10 across Solana pools. Numbered markers sit on the price at the moment of each event. The two biggest pools stopped trading when their vaults were frozen. Source: Bitquery DEX trades and raw Solana transactions.

Six minutes after the treasury drain, a wallet with no transfers to or from any attacker wallet opened a new SILV pool. The attacker sold into it, and one trade there printed the lowest price of the day, 2,457 SILV for 8.39 SOL.

Dominion's program was still buying SILV back at the silver price, so traders bought cheap tokens on DEXes and redeemed each one for about $63 of USDC. The window stayed open until the team switched redemptions off, and it cost the reserve little.

The redemption windowValue
First and last redemption02:20:32 and 03:48:25 UTC
Redemptions105
Paid out of the reserve$5,178.13
Left in the reserve after$121,748.46
Median DEX price meanwhile$25.11

No new SILV was minted after 00:06 UTC, and neither the permanent delegate nor the freeze power was used that night. The chart shows 5-minute medians of every SILV trade over $10 on Solana, from Bitquery's Solana DEX data.

07 · The fight for the keys

Two sides, signing with the same keys

At 03:42 UTC one of the stolen keys proposed adding a sixth signer to the second multisig, the one with power over the token. The new key had never been used, and the three stolen keys passed the change a minute later. Nobody has ever signed with that key, and the team removed it less than two hours later, so it was almost certainly the attacker's.

About a minute after that change went through, the team made its first move on-chain. One of the clean signers started a proposal to switch off redemptions.

Within a minute, a stolen key filed a proposal to remove one clean signer and tried to remove the other. The second attempt failed because the key had run out of SOL to pay rent. Another stolen key sent it 0.02 SOL 36 seconds later, and the proposal went in on the next try. If both removals had passed, every signer left would have been a key the attacker held.

Less than a minute after filing that proposal, the same stolen key signed the team's proposal to switch off redemptions. It signed the one that switched off minting 8 minutes later. Only one clean key signed either of them, so the other two signatures came from stolen keys, and the simplest reading is that the team held copies of those keys too. Until the rotation was done, both sides could sign with the same keys.

Who held the keysSigners on Dominion's multisigs
Before the hackBoth multisigs, 10 September2Lp91FyJclean2ZqTm9ytclean8kTSi3vkstolenEkDhR65JstolenEHVcpEgDstolenNeeds 3 signatures.The attacker held 3.What the attacker triedAuthority multisig, 03:47 to 05:27 UTC2Lp91FyJvote to remove, 2 of 32ZqTm9ytvote to remove, 1 of 38kTSi3vkstolenEkDhR65JstolenEHVcpEgDstolenEHQZBu5yadded by attackerNeeds 3 of 6.Both votes voided at 05:27.After the rotationBoth multisigs, from 06:19 UTC2Lp91FyJclean2ZqTm9ytcleaniMxHnYidnew, first seen 10 Sep2FndD1W9new, used since Sep 20253 stolen keys removedNeeds 3 of 4.No stolen key left.
Signers, proposals and approvals read from the Squads multisig and proposal accounts. Red squares are keys the attacker held, teal circles keys it did not. Both removal votes were voided when the team added a new signer.

The closest call came at 05:24 UTC. One stolen key gave the vote to remove a clean signer its second approval, one short of passing. The same key had created the team's rescue proposal 30 seconds earlier. The chain cannot tell us whether that was the attacker racing the team or a misclick in the Squads app. Less than 3 minutes later the rescue proposal passed, and under Squads rules a change of members voids every proposal filed before it.

By 06:19 UTC the stolen keys were gone from both multisigs. Two new keys took their place, and neither was made after the hack. One first appeared on the evening of 10 September. The other has been active since September 2025.

It could have gone further. For 5 hours after the attack began, the attacker held enough keys to pass anything on the multisig that can move any holder's SILV and rewrite the mint program. Beyond adding a signer and filing votes against the team, it used that power once, to take 5 SOL.

08 · Where the money went

Two trips through Chainflip

The attacker sold almost everything for SOL. The SILV sold to clear loans went for USDC, and nearly all of those dollars went to the lenders.

Where the SILV wentTokens out, SOL in, then Chainflip
Out of Dominion's control46,909.12 SILV42,181.88 from the treasury, 4,727.24 from loans and balances in 5 stolen walletssentsentsold where it satAttacker's second wallet43,377.93 SILVGe2GYH…AH7gAttacker's first wallet1,940.27 SILVBmgpLv…rrkZInside the stolen wallets1,590.93 SILV8kTSi3vk and 8Ysc7csold for SOLsold for SOLSOL and USDCUSDCWhat the attacker ended up with2,402.32 SOLabout $238,000 at $99.20 a SOLPaid to Loopscale lenders81,370.49 USDCto free the collateralbridged overnightmoved from 13:45Through Chainflip, 01:24 and 02:07229.72 SOLpaid out 9.25 ETHThrough Chainflip, afternoon2,172.38 SOL5 deposit addresses, 1 direct swapFees and dust0.22 SOLchecked at 15:36 UTCto one walletdirect swap paidEthereum wallet, unmoved9.25 ETH0x8b34…daafSecond Ethereum address9.83 ETH0xd137…eeffDeposit-address payouts arerecorded on Chainflip's chain.Dollar value at $99.20 a SOL.
Token amounts from raw Solana transactions, including every token account the wallets own. Chainflip hops count only where Chainflip's agent key swept them or the swap instruction decodes. The attacker's total also includes a few thousand dollars of SOL and USDC taken straight from wallets and vaults.

Twice before 02:10 UTC, the first attacker wallet sent SOL to a hop wallet, which passed it into Chainflip, a network that swaps coins across chains, with a request for ether in return. We decoded both swap instructions. They name the same Ethereum address, and Chainflip's vault paid it 9.25 ETH.

That wallet has received and sent ether since May 2026, and it took two Chainflip payouts on its first day, 16 May. Its last outgoing transaction was on the evening of 10 September, under two hours before the attack began, and the 9.25 ETH has not moved. For anyone chasing the money, that older history is the best lead in the case. The attacker behind the Aquifer hack also left its haul sitting on Ethereum.

The rest of the SOL sat still until 13:45 UTC. Then the attacker moved all of it. The first wallet sent about 1,900 SOL to a new address, which passed it into Chainflip in 5 chunks, most of about 400 SOL. Each chunk went to a one-time deposit address that Chainflip's own agent key emptied within minutes, the same key that collected the first overnight deposit. The second wallet sent 249 SOL through a hop wallet in a direct swap to a different Ethereum address.

Chainflip paid that address 9.83 ETH. The address already held about 214 ETH and has taken ether from several sources since August. Whether it belongs to the attacker or to a service the attacker paid, the chain alone does not say. Where the deposit-address swaps paid out lives on Chainflip's own chain. By 15:36 UTC all but a fraction of one SOL of the attacker's haul had gone through Chainflip. The whole trail can be followed with the Bitquery MCP.

Look-alike addresses sent the attacker's wallets dust within a minute of several of these moves, the setup for address poisoning.

Where the 46,909 SILV came from
Treasury vault42,181.88
8kTSi3vk, loans2,654.28
8Ysc7c, loans and pools970.35
EHVcpEgD, loan589.36
BZsVSQUe, loan at 10:51279.95
Dt8op, loan233.31
Their value, and where the money went
Worth the evening before$2.98M
Left with the attacker$238K
Paid to lenders$81K

09 · Back at 10:51

Rotating the signers left the wallets exposed

Dominion's update on X said the team had full control again. For the multisigs, that was true. The stolen wallets were a different matter, because a wallet with one key cannot be rotated and anyone holding a copy of the key keeps it.

At 10:34 UTC, one of the keys the team had removed from the multisigs that morning sent 0.03 SOL to another stolen wallet, enough to pay fees. That wallet repaid its Loopscale loan 17 minutes later, withdrew 279.95 SILV of collateral and sent it to the attacker's second wallet. About a minute and a half after that, the SILV was sold for 74.61 SOL.

Any position still held by one of the 11 wallets is exposed the same way. The safe assumption is that all of them are burned.

10 · The freeze

Dominion uses the token's own powers

At 13:37 UTC Dominion's authority multisig began freezing SILV accounts, using the power that sat idle through the attack. The three keys that approved it are the new and clean signers the team now holds. A first wave froze about 1,800 accounts in under three minutes. A second wave, about half an hour later, froze about 1,000 more. Among them were the SILV vaults of the two biggest pools, and trading in both stopped within a second.

A third of all SILV now sits in frozen accounts, and all but a handful of them belong to wallets that received SILV after the attack began. The freeze did not reach every such wallet. About 490 others that also got SILV after the attack began still held about 29,900 SILV, and 60 more transactions sat in batches the team had already approved. The frozen accounts can be listed with token holder data.

The freezeValue
First and last freeze13:37:27 and 14:22:33 UTC
Accounts frozen2,823, with 2,819 still frozen at 15:36 UTC
In each wave1,805 from 13:37:27, 1,018 from 14:15
Got SILV after 00:23The owners of all but 4 frozen accounts
SILV in frozen accounts31,078.51, or 33% of the supply
Pools frozenMeteora SILV/SOL and Orca SILV/USDC, both last traded at 14:17
Approved byiMxHnYid, 2FndD1W9 and 2Lp91FyJ
Permanent delegate0.000001 SILV moved to the treasury at 14:58:48. Transaction

At 14:58 the multisig used the permanent delegate for the first time. It thawed one frozen account and moved one millionth of a SILV out of it into Dominion's treasury, the smallest amount the token can move, then left the account unfrozen. The same power reaches every frozen account. What Dominion plans to do with it is not on the chain.

11 · What the team said, and what the chain shows

Dominion's update, line by line

Dominion posted an update on X, signed by its founder, after the attack. Most of it is about next steps. The lines that describe what happened and when can be checked against the chain.

Line in the updateWhat the chain shows
When it started"At approximately 01:00 UTC today, a number of Dominion wallets were compromised"
Doesn't match the chain. The first hostile transaction ran at 00:23:28 UTC, and the first stolen tokens reached an attacker wallet at 00:29:38.
When the team acted"We identified the issue at 04:00 UTC and acted immediately"
Partly. The team's first transaction ran at 03:44:54, 3 hours 21 minutes after the first hostile one. Redemptions were off at 03:48:29 and minting at 03:56:23.
Liquidity"Pulled liquidity"
Can't be checked on-chain. We cannot identify every team wallet. None of the wallets we can identify removed liquidity from the two biggest SILV pools.
The affected wallets"Secured the affected wallets"
Partly. Both multisigs had new signers by 06:19:24. Two stolen wallets with a single key each were used again at 10:34 and 10:51.
The new keys"Replaced every compromised wallet with fresh devices and new hardware wallets"
Partly. Neither new signer key was created after the hack. Devices do not show up on a chain.
Control"We now have full control again"
Doesn't match the chain. True of both multisigs. At 10:51 the attacker withdrew collateral from a Loopscale loan held by one of the stolen wallets.
SEAL 911"We're working with SEAL 911 on the investigation"
Can't be checked on-chain. Nothing on a chain records this.
The repeg"Begin the repeg within the next few hours"
Not yet. Between 14:35 and 15:35 UTC SILV traded around $22, against $63.59 the evening before.

A team fighting an attacker in the middle of the night can get a time wrong, and nothing here says anything about intent.

12 · What the chain cannot tell us

The limits of the record

How the keys were taken is not on any chain, and neither is whether the person using them sat inside the company or outside it. We say attacker for whoever held the stolen keys. As with the LootBot drain, the ledger shows keys being used and says nothing about where they leaked from.

We cannot say who clicked the approval at 05:24 UTC. Nor can we prove who owns every side wallet. One was funded straight from Dominion's treasury, and three more were created within 25 minutes of it, which links them without proving who controls them.

Nor can it tell us what Dominion will do with the frozen tokens. The permanent delegate has moved one millionth of a SILV so far. If it moves more, the chain will show where it goes.

13 · Method

How we checked it

We rebuilt the attack from raw Solana transactions and checked every figure a second way before using it.

What could go wrongHow we handled it
Missed token transfersA wallet's own history misses tokens sent to its token accounts, so We also pulled every token account the wallets own. That is how the 10:51 transfer surfaced.
Repeated or missing fillsTrade data can repeat or skip fills. Prices are 5-minute medians of trades over $10. Token amounts come only from transfers and balance changes.
Misread approvalsEvery proposal, approval, rejection and change of members was read from the Squads accounts themselves.
One data sourceSolana data came from two RPC providers and Bitquery's transfer index. The Ethereum payouts were confirmed in Bitquery's Ethereum data, Blockscout and a public node.
The wrong walletsA wallet counts only where the attacker's own transactions show control: signing for it, sweeping it, or receiving stolen tokens and selling them.
A live attackBalances, freezes and flows were checked at 15:36 UTC. Prices run to 15:35 UTC.
Who was frozenEvery freeze was read from the authority vault's transactions, then each account's owner, balance and state from the chain. Wallets that got SILV after 00:23 come from Bitquery's Solana transfers index.
Chainflip hopsA hop counts as a Chainflip deposit only where Chainflip's agent key swept it or its swap instruction decodes.
The SOL priceDollar figures use $99.20 per SOL, inside Kraken's hourly range for the night.

14 · The record

Addresses and transactions behind the story

Every address below can be followed onward with the Bitquery MCP.

RoleAddress or transaction
Attacker's first walletBmgpLv…rrkZ
Attacker's second walletGe2GYH…AH7g
Hop wallet into ChainflipGfvdsA…Cn1Y
Ethereum wallet paid 9.25 ETH0x8b34…daaf
New wallet, 13:506QAoKp…qvtF
Second Ethereum address0xd137…eeff
Signer the attacker addedEHQZBu…mSfY
Stolen multisig signers8kTSi3…WmpM, EkDhR6…7V56, EHVcpE…KGux
Other stolen wallets8Ysc7c…ksqY, Dt8opL…LNws, BZsVSQ…Nxw1
Treasury multisig, vault9BwMVm…5VtU, 65g5nN…qPPS
Authority multisig, vaultBjbtdE…XLAi, FqFNXC…vzZ3
SILV tokenSiLVFM…B35L
Treasury drain, proposal 4565EeDk…iJWE
Chainflip deposits5c4PpE…WxLu, 5ki24E…d7wn
Ethereum payouts0x9118…1da8, 0x4e28…9d64
The return visit5yH72U…tvz7, AZKYWe…oqJ6
Direct swap, and its payout2vDGBp…SjmM, 0x110f…9903
Freeze and delegate transfer2hEWue…r5Sk, 2RhaQF…KJco
Run it yourself

Ask these questions in plain English

Every figure above came from queries anyone can run. The Bitquery MCP server puts the same Solana and Ethereum data behind an AI assistant, so you can ask which keys approved a multisig proposal, where a wallet's SOL went, which accounts a token froze, or what it traded at minute by minute, without writing the query yourself.

Read the signers and instructions of any Solana transactionFollow SOL from a wallet into a bridge and out the other sidePull 5-minute prices for any Solana tokenList which holders of a token are frozen
Explore Bitquery MCP Figures measured 11 September 2026 against Bitquery's Solana and Ethereum data, with balances checked at 15:36 UTC.