BUG announcement from the Solidity storage matrix
This blog article concerns two storage berries that, otherwise, would not be linked. The two have been present in the compiler for a long time and have only been discovered now even if a contract containing them should most likely show dysfunctions in the tests.
Daenam Kim with the help of Nguyên Phamboth Curve grid Discovered a problem where non -valid data is stored in relation to signed whole tables.
This bug has been present since Solidey 0.4.7 and we consider it the most serious of the two. If these tables use negative integers in a certain situation, this will lead to corruption of data and the bug should therefore be easy to detect.
Thanks to the Ethereum Bug Bounty program, we received a report on a flaw in the new experimental encoder ABI (called Abiencoderv2). The new ABI encoder is still marked as an experimental, but we nevertheless think that it deserves an important announcement since it is already used on the main network. Credits to Ming Chuan Lin (from https://www.secondstate.io) For having discovered and corrected the bug!
THE version 0.5.10 Contains bug fixes. For the moment, we are not planning to publish a corrective for the old 0.4.x of Solidey series, but we could if the general request is felt.
The two bugs should be easily visible in tests that affect the relevant code paths.
Details on the two bugs can be found below.
Bug of signed whole table
Worried
If you have deployed contracts that use whole tables signed in storage and you attribute directly
- a literal table containing at least one negative value (X = (-1, -2, -3);) Or
- an existing table of a different Signed whole type
This would cause data corruption in the storage matrix.
Contracts that only attribute individual table elements (that is to say with x (2) = -1;) are not concerned.
How to check if the contract is vulnerable
If you use whole tables signed in storage, try to perform tests in which you use negative values. The effect should be that the real stored value is positive instead of negative.
If you have a contract that meets these conditions and want to check if the contract is actually vulnerable, you can contact us via safety@ethereum.org.
Technical details
Storage berries can be assigned from bays of different types. During this copy and assignment operation, a type conversion is carried out on each of the elements. In addition to the conversion, especially if the signed whole type is less than 256 bits, certain value bits must be zero for the storage of several values in the same storage location.
The bits to be zero have been poorly determined from the source and not of the target type. This leads to the zero of too many bits. In particular, the sign bit will be zero which makes the value positive.
Abiencoderv2 table bug
Worried
If you have deployed contracts that use the Abi V2 experimental encoder, they could be assigned. This means that only contracts that use the following directive in the source code can be affected:
pragma experimental ABIEncoderV2;
In addition, there are a number of conditions for the bug to be triggered. See the technical details below for more information.
How to check if the contract is vulnerable
The bug only manifests itself when all the following conditions are met:
- The storage data involving tables or structures are sent directly to an external function call, for Abi. Encoder or event data without prior assignment to a local variable (memory) and
- These data contain either a table of structures, or a table of static tables (that is to say at least two-dimensional).
In addition, in the following situation, your code is not affected:
- If you only return this data and do not use it Abi. EncoderExternal calls or event data.
Possible consequences
Naturally, any bug can have very variable consequences depending on the program control flow, but we expect it to be more likely to lead to dysfunction than to exploitability.
The bug, when triggered, will send in certain circumstances corrupt parameters during methods of methods towards other contracts.
Technical details
During the coding process, the experimental abi encoder does not properly advance towards the following element in a table in case the elements occupy more than one storage location.
This is only the case for elements which are structures or tables of static size. Tables of dynamic size tables or basic data types are not affected.
The specific effect you will see is that the data is “offset” in the coded table: if you have a table of type Uint (2) () And it contains the data
((1, 2), (3, 4), (5, 6))So he will be coded as ((1, 2), (2, 3), (3, 4)) Because the encoder advances only from a single location between the elements instead of two.
This post was written jointly by @Axic, @chriseth, @Holiman