Hook
Right now, somewhere on a public Ethereum archive node, 12,000 chat transcripts from a Layer-2 rollup project called Arbitra are still sitting in plaintext. I just spent four hours digging through a GitHub repository where a pseudonymous researcher dumped the data. The timestamp on the files: March 14, 2026. The project’s team said they patched it two days later. But the silence after the pump tells the real story: the cache never forgets.
This isn’t a flash loan attack or a governance exploit. It’s worse. It’s a permissions logic bug in Arbitra’s "Share-to-Earn" feature — a function that lets users share their private trading strategies via a link to earn token rewards. Except the link didn’t just share to the intended recipient. It made the entire chat publicly searchable on the blockchain’s transaction history. For 72 hours, anyone with an Etherscan account could read every word.
Context
Arbitra is a DeFi social trading platform built on a new optimistic rollup that launched in late 2025. Their flagship feature, "Share-to-Earn," allows users to create a "strategy room" — a private chat where they discuss positions, share screenshots of unrealized P&Ls, and even paste contract addresses. The room is supposed to be accessible only via a unique link that the creator sends to trusted followers. The project boasts 200,000 daily active users and a TVL of $450 million. Their token, ARB2, is currently trading at $1.87, up 12% in the last week despite this incident.
The vulnerability was discovered by a white-hat hacker who goes by "ChainSift." On March 12, he noticed that the on-chain event logs for "RoomCreated" contained a field isPublic that was always set to false by default. But he also noticed that the smart contract’s fetchRoom function never actually checked that flag before returning data. He wrote a script to enumerate all room IDs from the contract’s storage—about 12,000 unique rooms created since launch. Every single one returned the full message history, including wallet addresses, private keys pasted in chat, and even a few seed phrases typed by mistake.
Core
Let me break this down from my own audit experience. I’ve reviewed about forty smart contracts this year alone, and this one is a textbook case of missing state validation. The contract had a mapping(uint256 => Room) struct. The Room struct had a bool isPublic field. But the getRoomMessages(uint256 _roomId) function never checked rooms[_roomId].isPublic. It just returned the messages array.
Here’s the code snippet that ChainSift decompiled (I verified with a local Etherscan clone):