First, using msg.value in complex systems is hard. It’s a global variable that you can’t change and persists across delegate calls. If you use msg.value to check that payment was received, you absolutely cannot place that logic in a loop. As a codebase grows in complexity, it’s easy to lose track of where that happens and accidentally loop something in the wrong place. Although wrapping and unwrapping of ETH is annoying and introduces extra steps, the unified interface between WETH and other ERC20 tokens might be well worth the cost if it means avoiding something like this. Second, safe components can come together to make something unsafe. I’ve preached this before in the context of composability and DeFi protocols, but this incident shows that even safe contract-level components can be mixed in a way that produces unsafe contract-level behavior. There’s no catch-all advice to apply here like “check-effect-interaction,” so you just need to be cognizant of what additional interactions new components are introducing.
msg.valueto know the amount of ETH commited by the user. If the user commits more ETH than the contract’s capacity, the contract refunds the extra ETH. This function is fine on its own but becomes a vulnerability when combined with the
[batch](<https://github.com/sushiswap/miso/blob/44b51769b614826c50d8f5c55cb60094fa1c7bad/contracts/Utils/BoringBatchable.sol#L35>)function from BoringBatachable.
batchfunction works by making multiple
DELEGATECALLs to itself (the Auction contract). An interesting aspect about
DELEGATECALLis that they use the same global context as the parent call so every
DELEGATECALLhas the same
msg.valuethat the parent call had.
batchfunction and call the
commitEthfunction a hundred times with 1 ETH as
msg.value, every time.
msg.valueto know the amount committed, it will get tricked into thinking that the user committed 100 ETH (1*100) instead of the actual amount (1 ETH). If the contract had only 1 ETH of capacity left, it will refund the remaining 99 ETH to the user.
This time, the MPC wallet (used for warehousing / delivery management of cryptographic assets) used by our Singapore subsidiary QUOINE PTE was damaged by hacking. The impact on us is currently being confirmed.
The cold wallet used for segregation management is safe, and no impact on the assets entrusted to us by our customers has been confirmed.
Under these circumstances, we will suspend the warehousing and withdrawal of cryptographic assets until the security of all wallets is confirmed.
We are still investigating the details, so we will contact you by email or Twitter if there is a resumption of warehousing / delivery of crypto assets and progress in the situation.
MPC is an advanced cryptographic technique in which the private key controlling funds is generated collectively by a set of parties, none of whom can see the fragments calculated by the others. Liquid Global's blog post did not explain how this security arrangement was circumvented.