In Brief
SIR lost $355K due to a transient storage slot manipulation vulnerability.
Cardex suffered a $400K loss due to a compromised private key.
Hegic Options was targeted in a $80K logic vulnerability attack.
Hacks Analysis
SIR | Amount Lost: $355K
On March 30, the SIR exploit on the Ethereum mainnet resulted in a $355K loss. The root cause of the exploit was a logic vulnerability in the uniswapV3SwapCallback() function (in Vault.sol), which used transient storage slot to hold the Uniswap pool address, loaded with tload(1) for verifying msg.sender. The function also stored the minted token amount in the same slot using tstore(1, amount). The attacker exploited this by calling the function twice in one transaction. In the first call, they overwrote slot with the malicious contract address. In the second call, load (1) returned this malicious contract address, bypassing the caller verification. This allowed the attacker to mint tokens without authorization.
Exploited Contract: 0xb91ae2c8365fd45030aba84a4666c4db074e53e7
Transaction: 0xa05f047ddfdad9126624c4496b5d4a59f961ee7c091e7b4e38cee86f1335736f
Cardex | Amount Lost: $400K
On February 19, the Cardex exploit on the Abstract mainnet resulted in a $400K loss. The root cause was exposed private keys on Cardex’s frontend. Cardex used a single session signer wallet for all users. The attacker used the compromised signer to call buyShares() to purchase shares and transferShares() to move shares to their wallet. The attacker then sold the shares on Cardex’s bonding curve.
One of Multiple Transactions (on Abstract Mainnet): 0x07940b17a9f3f1a103a3b10bce6090cf7dbe5115c3cfad325004e0423f75e6cc
Hegic Options | Amount Lost: $80K
On February 23, the Hegic Options exploit on the Ethereum Mainnet resulted in a $80K loss. The root cause was a logic vulnerability in the withdrawWithoutHedge() function. The attacker exploited the commented-out code in the _withdraw() internal function that should have verified tranches were in an "Open" state (available for withdrawal) and updated them to a "Closed" state after withdrawal. Although the code included a line to set t.state = TrancheState.Closed after withdrawal, without the initial state check, the attacker was able to repeatedly call withdrawWithoutHedge() on the same tranche ID, draining funds multiple times without ‘closing’ the TrancheState status.
Exploited Contract (HegicPool): 0x7094E706E75E13D1E0ea237f71A7C4511e9d270B
Transaction: 0x260d5eb9151c565efda80466de2e7eee9c6bd4973d54ff68c8e045a26f62ea73





