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
Constantinopledev tools. We released the
EthereumJSConstantinople VM 22 Nov 2018, it took Truffle some time to integrate and the first
Constantinople-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
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.
pragma experimental SStoreCheap); thus giving people time to develop using this instead, read about the changes and potential security risks, and implement their contracts with this knowledge in mind.