I've created a github issue, designed to capture questions and comments which cannot be addressed right now, but which would be valuable to discuss during a post-mortem.
ethereum-cat-herders/hard-fork-checklist#1
Thank you for your contributions and patience.
@Souptacular since all the updated versions are released, we should update the blog post to reflect that. I recommend changing:
"Miners, Exchanges, Node Operators:
to
"Miners, Exchanges, Node Operators:
Ok, so we found a contract in the wild that can be exploited. An old unused one, but shows the pattern in the wild. 0x693399AAe96A88B966B05394774cFb7b880355B4 - reentrancy between agreeToTrade and offerTrade to trigger balance underflow.
More details on EthSecurity telegram group, since here it's offtopic if I understand correctly (or I can copy the details here as well, @holiman )
@MicahZoltu I think one part of the story might be the not-so-long-yet availability of
Constantinople
dev tools. We released theEthereumJS
Constantinople VM 22 Nov 2018, it took Truffle some time to integrate and the firstConstantinople
-ready Ganache version came out just 6 days ago. Since ChainSecure uses this first beta to test the vulnerability my assumption is that these releases might have triggered experimentation, will investigate this further.One outcome of this might be to take dev tool readyness stronger into account when planning a hardfork date, and make release of the 2-3 most used tools (and not just the VM as some base layer) a precondition for some date settlement.
I share the concern (I'm a member of the Truffle team and oversee the development of ganache-core
and ganache-cli
).
Who should I be coordinating with to make sure we're supporting things appropriately here?
Quoting Hubert from ChainSecurity who double-checked my findings:
Here is how it works for contract 0x693399AAe96A88B966B05394774cFb7b880355B4. This is a contract that can be used to exchange ether and tokens. The attacker acts as follows within one transaction:
We assume that the balance of the attacker is one token.
The problem is this sequence.
if (balanceOf[_from]<tokensOfferedOf[_from]) throw;
if (!_from.send((msg.value*(100-ethTaxRate))/100)) throw;
balanceOf[_from] -= tokensOfferedOf[_from];
It is expected to be executed atomically, but this is not true due to the reentrancy.