Solidity Optimizer and ABIEncoderV2 error message
By means of the Ethereum bug bounty program, we obtained a report of a flaw inside the new experimental ABI encoder (referred to as ABIEncoderV2). Upon investigation, it was decided that the element suffered from a number of completely different variations of the identical kind. The primary a part of this announcement explains this error intimately. The brand new ABI encoder remains to be marked as experimental, however nonetheless we really feel it deserves a distinguished announcement as it’s already in use on the mainnet.
Moreover, two low-impact bugs within the optimizer have been recognized over the previous two weeks, one in all which was mounted with Solidity v0.5.6. Each have been launched with model 0.5.5. See the second a part of this publish for particulars.
The 0.5.7 launch accommodates fixes for all bugs defined on this weblog publish.
All of the bugs talked about right here needs to be simply seen in assessments that contact the related code paths, no less than when run with all mixtures of zero and non-zero values.
Credit score to the Melonport workforce (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!
Who needs to be anxious
You probably have deployed contracts that use the experimental ABI Encoder V2, they could be affected. Which means solely contracts that use the next directive inside the supply code could be affected:
pragma experimental ABIEncoderV2;
As well as, there are quite a few requests to run the bug. For extra data, see the technical particulars beneath.
So far as we will inform, there are about 2,500 contracts on the mainnet that use the experimental ABIEncoderV2. It’s not clear what number of include the error.
Tips on how to examine if a contract is weak
The error manifests itself solely when all the next situations are met:
- Storage knowledge that features arrays or constructions is shipped on to the exterior perform name, to abi. to code or to occasion knowledge with out prior project to a neighborhood (reminiscence) AND variable
- there may be an array that accommodates components lower than 32 bytes in measurement or a construction that has components that share a storage slot or kind members of bytesNN shorter than 32 bytes.
Moreover, your code is NOT affected within the following conditions:
- if all of your structs or arrays use solely uint256 or int256 species
- if you happen to solely use integer varieties (which could be shorter) and solely code at most one subject at a time
- if you happen to simply return such knowledge and don’t use it in abi. to codeexterior calls or occasion knowledge.
You probably have a contract that meets these situations and need to examine if the contract is certainly weak, you possibly can contact us through safety@ethereum.org.
Tips on how to forestall such defects sooner or later
To be conservative about modifications, the experimental ABI encoder was solely obtainable when explicitly enabled, to permit folks to work together with and check it with out an excessive amount of confidence earlier than it was thought of steady.
We do our greatest to make sure top quality and have just lately began engaged on ‘semantic’ fuzzing sure elements OSS-Fuzz (we beforehand crashed the compiler, however that did not check the correctness of the compiler).
For builders — bugs contained in the Solidity compiler are laborious to detect utilizing instruments like vulnerability detectors, since instruments that work on supply code or AST-representations do not detect flaws which are solely launched into the compiled bytecode.
The easiest way to guard in opposition to these kinds of flaws is to have a rigorous set of end-to-end assessments in your contracts (checking all code paths), since compiler errors are very probably not “silent” and as a substitute manifest as invalid knowledge.
Attainable penalties
After all, every error can have very completely different penalties relying on the management movement of this system, however we count on this to be extra prone to result in failure than exploitability.
The bug, when triggered, will ship corrupted parameters to methodology calls to different contracts below sure circumstances.
Timeline
2019-03-16:
- Report through bug bounty a crash brought on by studying from an array of boolean values immediately from storage to the ABI encoder.
2019-03-16 to 2019-03-21:
- Root trigger investigation, evaluation of affected contracts. An unexpectedly massive variety of contracts compiled with the experimental coder have been discovered deployed on the mainnet, many with out verified supply code.
- Analysis into the bug discovered a number of methods to set off the bug, eg utilizing constructions. Moreover, a subject overflow error was present in the identical routine.
- A handful of contracts discovered on Github have been checked and none have been affected.
- Fastened a bug within the ABI encoder.
2019-03-20:
- Resolution on public launch of knowledge.
- Rationale: It might not be possible to detect all weak contracts and attain all authors in time, and it could be good to forestall additional unfold of weak contracts on the principle community.
2019-03-26:
- New launch of translator, model 0.5.7.
- This publish printed.
Technical particulars
Background
Contract ABI is a specification of how knowledge could be exchanged with exterior contracts (Dapp) or when interacting between contracts. It helps quite a lot of knowledge varieties, together with easy values comparable to numbers, bytes, and strings, in addition to extra complicated knowledge varieties, together with strings and constructions.
When a contract receives enter knowledge, it should decode it (that is finished by the “ABI Decoder”) and earlier than returning the information or sending knowledge to a different contract, it should encode it (that is finished by the “ABI Decoder”). The Solidity compiler generates these two items of code for every perform outlined within the contract (and in addition for abi. to code and abi. to decode). Within the Solidity compiler, the subsystem that generates the encoder and decoder is named the “ABI encoder”.
In mid-2017, the Solidity workforce began engaged on a brand new implementation referred to as “ABI Coder V2” with the aim of making a extra versatile, safe, environment friendly, and auditable code generator. This experimental code generator, when explicitly enabled, has been supplied to customers since late 2017 with the 0.4.19 launch.
Flaw
The experimental ABI encoder doesn’t correctly deal with non-integer values shorter than 32 bytes. This refers to of bytesNN species, bool, enumeration and different varieties when they’re a part of an array or construction and encoded immediately from storage. Which means these storage references should be used immediately inside abi.encode(…), as arguments in exterior perform calls or in occasion knowledge with out prior project to a neighborhood variable. Use return doesn’t set off a bug. Sorts of bytesNN and bool will end in corrupted knowledge whereas enumeration could result in malfunction return.
Moreover, strings with components shorter than 32 bytes might not be dealt with appropriately even when the underlying kind is an integer kind. Encoding such strings within the method described above could result in different knowledge within the encoding being overwritten if the variety of encoded components just isn’t a a number of of the variety of components corresponding to 1 slot. If nothing follows the string within the encoding (be aware that dynamic-sized arrays are at all times encoded after static-sized arrays with static-sized content material), or if just one string is encoded, no different knowledge will probably be overwritten.
Other than the ABI encoder subject defined above, two errors have been discovered within the optimizer. Each have been launched with 0.5.5 (launched March 5). It’s unlikely to look in code generated by the compiler, until inline assembler is used.
These two bugs have been recognized with the latest addition of Solidity to the OSS-Fuzz – a safety software to seek out inconsistencies or issues in varied initiatives. For Solidity, we have included a lot of completely different fuzzers that check completely different elements of the compiler.
- The optimizer rotates opcode sequences as ((x << a) << b))the place And and b are compile-time constants, u (x << (a + b)) till it handles the overflow as well as appropriately.
- The optimizer is processing incorrectly byte opcode if the fixed 31 is used because the second argument. This may occur when performing an index entry on of bytesNN varieties with a compile-time fixed (not index) worth of 31 or when utilizing a byte opcode in inline assembler.
This publish was collectively written by @axic, @chriseth, @holiman