Solidity Optimizer and ABIEncoderV2 bug announcement
Via the Ethereum bug bounty program, we acquired a report a few flaw throughout the new experimental ABI Encoder (referred to as ABIEncoderV2). On investigation, it was discovered that the part suffers from a number of variations of the identical sort. The primary a part of this announcement describes this bug intimately. The brand new ABI encoder continues to be marked as experimental, however we nonetheless suppose it deserves a significant announcement because it’s already in use on the mainnet.
Moreover, two low-impact bugs have been recognized within the optimizer over the previous two weeks, considered one of which was mounted with Solidity v0.5.6. Each have been launched with model 0.5.5. See Half II of this announcement for particulars.
0.5.7 launch This weblog publish consists of fixes for all of the bugs talked about.
All the bugs talked about right here must be readily seen in checks that contact the related code paths, at the very least when run with all combos of null and non-null values.
Credit to the Maloneport staff (Travis Jacobs and Jenna Zenk) and the Malone Council (Nick Munoz-McDonald, Martin Lundfall, Matt Di Ferrante and Adam Kolar) who reported this by way of the Ethereum bug bounty program!
who ought to care
You probably have deployed contracts that use the experimental ABI Encoder V2, they could be affected. Because of this the one contracts which may be affected are those who use the next directive throughout the supply code:
pragma experimental ABIEncoderV2;
Moreover, there are a number of necessities for triggering a bug. See technical description under for extra particulars.
So far as we will inform, there are about 2500 contracts reside on the mainnet that use the experimental ABIEncoderV2. It isn’t clear what number of of them have the bug.
Learn how to verify if contract is unsafe
The bug seems solely when all the following circumstances are met:
- storing knowledge consisting of arrays or buildings handed on to an exterior perform name abi.encode or to occasion knowledge with out prior project to an area (reminiscence) variable and
- is an array containing components with a dimension of lower than 32 bytes or a construction containing components that share storage slots or members of the sort bytesNN Smaller than 32 bytes.
Moreover, within the following circumstances, your code just isn’t affected:
- If all of your buildings or arrays are simply use uint256 Or int256 Kind
- in the event you solely use integer sorts (which could be trivial) and solely encode at most one array at a time
- In the event you solely return such knowledge and don’t use abi.encodeExterior name or occasion knowledge.
You probably have a contract that meets these circumstances, and wish to confirm whether or not the contract is certainly susceptible, you possibly can contact us firstname.lastname@example.org,
Learn how to stop these sort of lapses in future
To be conservative about modifications, the experimental ABI encoder is simply accessible when explicitly enabled, to permit individuals to work together with it and check it with out relying too closely on it earlier than it’s thought of steady .
We do our greatest to make sure prime quality, and have lately began engaged on ‘semantic’ fuzzing of some components oss-fuzz (We crash-fuzzed the compiler earlier than, however that did not check the correctness of the compiler).
For builders – Bugs throughout the Solidity compiler are tough to detect with instruments resembling vulnerability detectors, as a result of instruments that function on the supply code or AST-representation don’t detect flaws which might be launched solely within the compiled bytecode.
One of the simplest ways to guard towards all these flaws is to have a rigorous set of end-to-end checks (verifying all code paths) on your contracts, as a result of bugs in a compiler usually are not “silenced” and as a substitute can be utilized to detect invalid knowledge. seem in
Naturally, any given bug can have vastly completely different penalties relying on program management circulate, however we anticipate this to be extra of a bug than an exploit.
The bug, when triggered, will underneath sure circumstances ship corrupted parameters on methodology invocations to different contracts.
- Report by way of bug bounty, about corruption when studying arrays of booleans instantly from storage within the ABI encoder.
2019-03-16 to 2019-03-21:
- Root trigger investigation, evaluation of affected contracts. An unexpectedly excessive variety of contracts compiled with the experimental encoder have been discovered deployed on the mainnet, many with out verified source-code.
- Investigating the bug discovered different methods to set off the bug, for instance utilizing buildings. 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 bug was mounted within the ABI encoder.
- Determination to make info public.
- Rationale: It won’t be attainable to detect all weak contracts and attain all authors in time, and it will be good to forestall additional propagation of weak contracts on the mainnet.
- New compiler launch, model 0.5.7.
- This publish has been launched.
The Contracts ABI is a specification of how knowledge could be exchanged when interacting with contracts (a Dapp) from the skin, or between contracts. It helps a wide range of knowledge sorts, together with easy values resembling numbers, bytes, and strings, in addition to extra advanced knowledge sorts together with arrays and buildings.
When a contract receives enter knowledge, it should decode it (that is accomplished by the “ABI decoder”) and encode it (that is accomplished by the “ABI encoder”) earlier than returning the information or sending the information to a different contract. The Solidity compiler generates these two items of code for (and in addition for) every outlined perform in a contract. abi.encode And abi.decode, The subsystem that generates the encoders and decoders within the Solidity compiler is named the “ABI Encoder”.
In mid-2017 the Solidity staff began engaged on a brand new implementation referred to as “ABI Encoder v2”, with the purpose of a extra versatile, safe, executable 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.
The experimental ABI encoder doesn’t correctly deal with non-integer values smaller than 32 bytes. this is applicable to bytesNN Kind, bool, enum and different sorts when they’re a part of an array or construction and are encoded instantly from storage. Because of this these storage references are for use instantly inside abi.encode(…), as arguments in exterior perform calls or in occasion knowledge with out prior project to native variables. utilizing the return Does not set off the bug. Kind bytesNN And bool whereas the end result will likely be corrupted knowledge enum could also be invalid come again once more,
Moreover, arrays with components smaller than 32 bytes might not be dealt with accurately, even when the bottom sort is an integer sort. Encoding such arrays within the method described above might overwrite different knowledge within the encoding if the variety of components encoded just isn’t a a number of of the variety of components that slot in a single slot. If nothing follows the array within the encoding (be aware that dynamic-sized arrays are at all times encoded after fixed-sized arrays with static-sized contents), or if just one array is encoded, then no Different knowledge just isn’t overwritten.
Two bugs have been discovered within the optimizer, unrelated to the ABI encoder problem talked about above. Each have been launched with 0.5.5 (launched March fifth). They’re unlikely to happen in compiler-generated code except inline meeting is used.
These two bugs have been recognized lately via including Solidity oss-fuzz – A safety toolkit for detecting anomalies or points in numerous initiatives. For Solidity we have included a lot of completely different fuzzers that check completely different facets of the compiler.
- The optimizer transforms the opcode sequences into ((x << a) << b))The place? A And b are compile-time constants (x << (a + b)) Whereas the overflow as well as just isn’t being dealt with correctly.
- Optimizer handles incorrectly byte Opcode if the fixed 31 is used because the second argument. This may occur if you activate index entry bytesNN Sorts with a compile-time fixed worth (not an index) of 31 or when utilizing byte opcodes in inline meeting.
This publish was collectively created by @axic, @chriseth, @holiman