The Cosmos SDK is a blockchain development framework for application specific blockchains. Built into its core is blockchain interoperability by IBC (interblockchain communication).
Within the Cosmos SDK and most other blockchains, there are events. This makes it easy for off-chain applications to monitor the blockchain and query its state then act on these messages. So, keeping these events valid is important for the security of the system.
When communicating via IBC with two blockchains, a relayer sends over the data with a MsgRecvPacket message. If an error occurs within this handling, the blockchain cannot revert. This is because the other chain communicating needs to revert the state changes that were supposed to happen (but failed) from chain A to chain B.
So, instead, it uses an IBC acknowledgement message. Successful ack means the call succeeded and a failure indicates that the call to IBC failed for whatever reason. The relayer would then send the result from the target chain back to the original chain to revert the changes.
When handling an IBC packet with a failure, the event is still emitted due to poorly written code. Why is this bad? The events are emitted, even though the state changes were never made. As a result, any off-chain program listening would believe this went through when it really didn't.
The author calls with a "hallucination", which is a really good name for this. To trigger this, we must force a bad ack event. With CosmWasm, this is trivial through the built in IBC support. Then, to exploit this, an attacker can trigger arbitrary actions through CosmWasm, such as a bridge request. From there, this will have bad events emitted, tricking whatever off-chain applications. For non CosmWasm chains, other methods may be possible to trigger this.
What else is vulnerable? A decentralized exchange that requires transfer from one chain to another that is looking for events could be vulnerable. Additionally, various bridges could have been exploited in this way as well.
Overall, a really simple issue that was overlooked by the developers that caused a very serious problem. This was a really good find by Felix on the Cosmos SDK side.