Via the Ethereum bug bounty program, we obtained a report a few flaw inside the new experimental ABI encoder (known as ABIEncoderV2). Upon investigation, it was discovered that the part suffers from just a few totally different variations of the identical kind. The primary a part of this announcement explains this bug intimately. The brand new ABI encoder remains to be marked as experimental, however we however assume that this deserves a distinguished announcement since it's already used on mainnet.
Moreover, two low-impact bugs within the optimizer have been recognized over the previous two weeks, one in all which was fastened with Solidity v0.5.6. Each have been launched with model 0.5.5. See the second a part of this announcement for particulars.
The 0.5.7 release comprises the fixes to all bugs defined on this weblog put up.
All of the bugs talked about right here ought to be simply seen in checks that contact the related code paths, at the least when run with all mixtures of zero and nonzero values.
Credit to Melonport crew (Travis Jacobs & Jenna Zenk) and the Melon Council (Nick Munoz-McDonald, Martin Lundfall, Matt di Ferrante & Adam Kolar), who reported this through the Ethereum bug bounty program!
When you've got deployed contracts which use the experimental ABI encoder V2, then these is likely to be affected. Because of this solely contracts which use the next directive inside the supply code will be affected:
pragma experimental ABIEncoderV2;
Moreover, there are a variety of necessities for the bug to set off. See technical particulars additional under for extra data.
So far as we are able to inform, there are about 2500 contracts dwell on mainnet that use the experimental ABIEncoderV2. It's not clear what number of of them include the bug.
The bug solely manifests itself when the entire following circumstances are met:
- Storage information involving arrays or structs is shipped on to an exterior operate name, to
abi.encodeor to occasion information with out prior task to a neighborhood (reminiscence) variable AND
- there may be an array that comprises parts with measurement lower than 32 bytes or a struct that has parts that share a storage slot or members of kind
bytesNNshorter than 32 bytes.
Along with that, within the following conditions, your code is NOT affected:
- if all of your structs or arrays solely use
- in case you solely use integer varieties (which may be shorter) and solely encode at most one array at a time
- in case you solely return such information and don't use it in
abi.encode, exterior calls or occasion information.
When you've got a contract that meets these circumstances, and need to confirm whether or not the contract is certainly weak, you'll be able to attain out to us through [email protected]
With a purpose to be conservative about adjustments, the experimental ABI encoder has been out there solely when explicitly enabled, to permit individuals to work together with it and take a look at it with out placing an excessive amount of belief in it earlier than it's thought of secure.
We do our greatest to make sure top quality, and have lately began engaged on ‘semantic’ fuzzing of sure elements on OSS-Fuzz (we now have beforehand crash-fuzzed the compiler, however that didn't take a look at compiler correctness).
For builders – bugs inside the Solidity compiler are troublesome to detect with instruments like vulnerability detectors, since instruments which function on supply code or AST-representations don't detect flaws which might be launched solely into the compiled bytecode.
One of the simplest ways to guard towards some of these flaws is to have a rigorous set of end-to-end checks on your contracts (verifying all code paths), since bugs in a compiler very probably aren't “silent” and as an alternative manifest in invalid information.
Naturally, any bug can have wildly various penalties relying on this system management movement, however we anticipate that that is extra more likely to result in malfunction than exploitability.
The bug, when triggered, will below sure circumstances ship corrupt parameters on technique invocations to different contracts.
- Report through bug bounty, about corruption prompted when studying from arrays of booleans instantly from storage into ABI encoder.
2019-03-16 to 2019-03-21:
- Investigation of root trigger, evaluation of affected contracts. An unexpectedly excessive depend of contracts compiled with the experimental encoder have been discovered deployed on mainnet, many with out verified source-code.
- Investigation of bug discovered extra methods to set off the bug, e.g. utilizing structs. Moreover, an array overflow bug was present in the identical routine.
- A handful of contracts discovered on Github have been checked, and none have been discovered to be affected.
- A bugfix to the ABI encoder was made.
- Choice to make data public.
- Reasoning: It could not be possible to detect all weak contracts and attain out to all authors in a well timed method, and it will be good to stop additional proliferation of weak contracts on mainnet.
- New compiler launch, model 0.5.7.
- This put up launched.
The Contract ABI is a specification how information will be exchanged with contracts from the surface (a Dapp) or when interacting between contracts. It helps a wide range of forms of information, together with easy values like numbers, bytes and strings, in addition to extra advanced information varieties, together with arrays and structs.
When a contract receives enter information, it should decode that (that is completed by the “ABI decoder”) and previous to returning information or sending information to a different contract, it should encode it (that is completed by the “ABI encoder”). The Solidity compiler generates these two items of code for every outlined operate in a contract (and likewise for
abi.decode). Within the Solidity compiler the subsystem producing the encoder and decoder known as the “ABI encoder”.
In mid-2017 the Solidity crew began to work on a contemporary implementation named “ABI encoder V2” with the purpose of getting a extra versatile, secure, performant and auditable code generator. This experimental code generator, when explicitly enabled, has been supplied to customers for the reason that finish of 2017 with the 0.4.19 launch.
The experimental ABI encoder doesn't deal with non-integer values shorter than 32 bytes correctly. This is applicable to
enum and different varieties when they're a part of an array or a struct and encoded instantly from storage. This implies these storage references have for use instantly inside
abi.encode(...), as arguments in exterior operate calls or in occasion information with out prior task to a neighborhood variable. Utilizing
return doesn't set off the bug. The kinds
bool will lead to corrupted information whereas
enum may result in an invalid
Moreover, arrays with parts shorter than 32 bytes will not be dealt with accurately even when the bottom kind is an integer kind. Encoding such arrays in the way in which described above can result in different information within the encoding being overwritten if the variety of parts encoded isn't a a number of of the variety of parts that match a single slot. If nothing follows the array within the encoding (notice that dynamically-sized arrays are at all times encoded after statically-sized arrays with statically-sized content material), or if solely a single array is encoded, no different information is overwritten.
Unrelated to the ABI encoder challenge defined above, two bugs have been discovered within the optimiser. Each have been launched with 0.5.5 (launched on fifth of March). They're unlikely to happen in code generated by the compiler, until inline meeting is used.
These two bugs have been recognized via the latest addition of Solidity to OSS-Fuzz – a safety toolkit for locating discrepancies or points in a wide range of initiatives. For Solidity we now have included a number of totally different fuzzers testing totally different elements of the compiler.
- The optimizer turns opcode sequences like
((x << a) << b)), the place
bare compile-time constants, into
(x << (a + b))whereas not dealing with overflow within the addition correctly.
- The optimizer incorrectly handles the
byteopcode if the fixed 31 is used as second argument. This will occur when performing index entry on
bytesNNvarieties with a compile-time fixed worth (not index) of 31 or when utilizing the byte opcode in inline meeting.
This put up was collectively composed by @axic, @chriseth, @holiman