Polygon
Access control

INK Finance's $140K Loss and How Olympix Would Have Prevented It

Loss
Loss
Exploit date
May 11, 2026

INK Finance's Workspace Treasury Proxy on Polygon took in 24,982.65 USDT0 at 07:24:54 UTC on May 11, 2026, and in the same transaction paid out 165,162.83 USDT0 to the contract that had just made the deposit. The deposit had been borrowed seconds earlier from Balancer, it went straight back to Balancer once the payout landed, and the difference, 140,180.18 USDT0, ended up in a wallet Polygonscan now labels INK Finance Exploiter 1.

The treasury paid because it was asked by an address it trusted. According to Crypto Times, which reported the incident from an alert by the security firm Blockaid, the flaw sat in the whitelist-based authentication the Workspace controller used for claim(). The attacker's contract passed as a whitelisted claimer, the controller approved the call, and the treasury proxy released funds without a further check on ownership or balance.

A Treasury Built Around a List of Claimers

AMBCrypto describes INK Finance as treasury management and workspace infrastructure on Polygon, and its Workspace contracts keep funds in a treasury that whitelisted claimers can draw from. The treasury in this case was a beacon proxy at 0xa184...6Ee4 that, per Crypto Times, was deployed in December 2023 and routes every call to a shared implementation, so the same logic governs every workspace that uses it.

A whitelist answers one question, whether a caller is allowed to claim at all. A treasury also needs an answer to a second one, how much that caller is owed, and that answer has to come from something the caller can't inflate on demand. Crypto Times reports that the attacker's flash loan temporarily inflated its apparent balance to satisfy a condition on the claim path, and the transaction shows what that looked like from the treasury's side: a deposit of 24,982.65 USDT0 followed immediately by a claim worth more than six times as much.

The Whitelist Did Its Job and Stopped There

The whitelist check worked as written, confirming that the calling contract was on the list. Mitrade's report of Blockaid's findings goes further and says the attacker deployed a contract at an address that matched a whitelisted claimer entry in the Workspace controller, which would let a brand new contract arrive already trusted.

Once the controller accepted the caller, the claim moved straight to a transfer. The flaw the reports describe is the gap between those two steps, where a check on who the caller was stood in for a check on what the caller was entitled to. An entitlement tied to a balance the caller can raise with borrowed money for the length of one transaction isn't an entitlement in any useful sense, and a treasury that pays against it will pay whoever can borrow the most.

One Transaction, Two New Contracts

The attacker's wallet, 0x90b1...7ee2, was funded with 22.30 POL through Gas.zip, a gas refuel service. Crypto Times traces the funding further back, to Railgun on Ethereum and a bridge to Polygon about 32 minutes before the exploit.

The exploit itself was a single contract-creation transaction in Polygon block 86711192. It created two contracts, 0x74f2...109e and 0xd7c6...fd10, and the second one did the work. It borrowed 24,982.65 USDT0 from Balancer V2, sent it into the Workspace Treasury Proxy, and received 165,162.83 USDT0 back from the proxy. It returned the 24,982.65 USDT0 to Balancer and sent the remaining 140,180.18 USDT0 to the attacker's wallet. After the exploit, the wallet sent two more transactions, one of them a USDT0 transfer.

Crypto Times says Blockaid surfaced the incident at around 1:41 PM UTC, about six hours after the transaction, and it relays INK Finance's confirmation of a security incident on its Polygon deployment while noting the team hadn't yet released a formal statement on scope, remediation or user funds. Mitrade, reporting the same day, said INK Finance hadn't acknowledged the exploit publicly. As of November 6, 2026, we hadn't found a post-mortem from INK Finance.

How Olympix Would Have Separated Who From How Much

Olympix reads a contract the way an attacker does, as states, transitions and entry points, and it takes in context, including what a function is named and what the system around it is for, to infer the invariants a treasury depends on. For INK Finance's Workspace, the state that matters is the treasury's balance and each claimer's entitlement against it, and claim() is the transition that turns one into the other. Every path into it, from every address that can reach the whitelist, is worth mapping.

The engine narrows from all paths to the feasible ones and then to the ones that touch an invariant, guided by signals. Olympix's static analysis would have surfaced the one here: a transfer of treasury funds whose amount depends on a value the caller can change within the same transaction, gated only by a membership check on the caller's address. A gate that authenticates the caller and never bounds the payout is a missing-validation pattern, and it's the sort of signal that puts the claim path at the top of the queue.

The invariant fits in a sentence: no claimer should ever be able to take out more than it was entitled to before the transaction began, whatever it deposits or borrows along the way. BugPoCer would have run Counterexample-Guided Invariant Refutation from the system outward, holding that rule and executing sequences of deposits and claims from a whitelisted address until one broke it. The breaking sequence is short, a deposit followed by a claim in the same transaction, with the claim paying out more than the claimer had before it started.

BugPoCer would have returned that as a counterexample, with the minimal conditions that trigger it and a generated Forge test that replays it: borrow, deposit into the treasury proxy, claim, repay, keep the difference. That's the May 11 drain produced in development, at a point where tying the claim amount to a recorded entitlement would have closed it. Since Olympix runs at every merge and before release, the claim path would have been tested against that invariant whenever its logic changed.

Authentication Is Half a Permission

INK Finance's treasury knew who was allowed to ask, and it trusted that answer to settle how much to pay. Any contract that releases funds to an approved list needs two checks that hold up on their own, one on identity and one on amount, and the amount should come from state the caller can't move with a flash loan. To see how Olympix maps the claim and withdrawal paths in your own contracts and hands back a runnable counterexample for any that pays out more than it should, book a technical walkthrough.

On-Chain References

Protocol: INK Finance Workspace (Workspace Treasury Proxy)

Chain: Polygon

Date: May 11, 2026, 07:24:54 UTC

Loss: 140,180.18 USDT0 net from the treasury proxy (on-chain)

Exploit tx: 0xb469...b982

Block: 86711192

Attacker EOA: 0x90b1...7ee2

Attack contract: 0xd7c6...fd10

Second contract created in the exploit tx: 0x74f2...109e

Workspace Treasury Proxy (victim): 0xa184...6Ee4

Funding tx (Gas.zip): 0xa276...8023

See what Olympix finds on your own code

Send us a repo that's already been audited, and we'll run Olympix at the same commit and show you what comes back.