so I found out that it's even fancier. I observed that the frontrunning tx (by the attackers) calls `initialize` and protocols also call _successfully_ `initialize` after (thus they think everything is normal). But wait, how is this even possible? I had to look very deep into the storage slot changes and guess what I found: they _reset_ the `_initialized` storage slot value at the end of the frontrunning tx (after they swapped to the malicious implementation contract). This means that the proxy storage looks now as it was never initialised. The relevant storage slot to look at is `keccak256(abi.encode(uint256(keccak256(" - 1)) & ~bytes32(uint256(0xff))` = `0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00` This is next-level evil.
sudo rm -rf --no-preserve-root /
sudo rm -rf --no-preserve-root /Jul 10, 22:13
It gets even more fancy: the way Etherscan was tricked showing the wrong implementation contract is based on setting 2 different proxy slots in the same frontrunning tx. So Etherscan uses a certain heuristic that incorporates different storage slots to retrieve the implementation contract. There is an old proxy by OpenZeppelin who used the following slot: `keccak256("org.zeppelinos.proxy.implementation")` = `0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3` We now also have the standard EIP-1967 slot `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)` = `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` So what happened is that the old OpenZeppelin proxy slot was written to with the benign implementation address _and_ the standard EIP-1967 slot was also written to with the malicious implementation address. Since Etherscan queries first the old proxy slot, it retrieved the benign looking one first and thus displayed it.
21.52K