From 1bdbc101100d9366f391527ce4e4aef06be076a4 Mon Sep 17 00:00:00 2001 From: Harikrishnan Mulackal Date: Thu, 1 Oct 2020 19:07:56 +0200 Subject: [PATCH 1/2] Properly cleanup after copying dynamic-array to storage for packed types --- Changelog.md | 3 ++ libsolidity/codegen/ArrayUtils.cpp | 6 ++- test/libsolidity/SolidityOptimizer.cpp | 4 +- .../array/array_copy_cleanup_uint128.sol | 23 +++++++++ .../array/array_copy_cleanup_uint40.sol | 48 +++++++++++++++++++ 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/array_copy_cleanup_uint128.sol create mode 100644 test/libsolidity/semanticTests/array/array_copy_cleanup_uint40.sol diff --git a/Changelog.md b/Changelog.md index eb5090c2c..2e8c32826 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ ### 0.7.3 (unreleased) +Important Bugfixes: + * Code Generator: Properly cleanup after copying dynamic-array to storage for packed types. + Compiler Features: * SMTChecker: Support ``addmod`` and ``mulmod``. * SMTChecker: Support array slices. diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index ef94b6bf2..1ae76bb45 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -290,7 +290,10 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // stack: target_ref target_data_end source_data_pos target_data_pos_updated source_data_end _context << Instruction::POP << Instruction::SWAP1 << Instruction::POP; // stack: target_ref target_data_end target_data_pos_updated - utils.clearStorageLoop(targetBaseType); + if (targetBaseType->storageBytes() < 32) + utils.clearStorageLoop(TypeProvider::uint256()); + else + utils.clearStorageLoop(targetBaseType); _context << Instruction::POP; } ); @@ -922,6 +925,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const void ArrayUtils::clearStorageLoop(TypePointer _type) const { + solAssert(_type->storageBytes() >= 32, ""); m_context.callLowLevelFunction( "$clearStorageLoop_" + _type->identifier(), 2, diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 24428c5ad..89960186d 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -633,8 +633,8 @@ BOOST_AUTO_TEST_CASE(optimise_multi_stores) )"; compileBothVersions(sourceCode); compareVersions("f()"); - BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 9); - BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 8); + BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 8); + BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 7); } BOOST_AUTO_TEST_CASE(optimise_constant_to_codecopy) diff --git a/test/libsolidity/semanticTests/array/array_copy_cleanup_uint128.sol b/test/libsolidity/semanticTests/array/array_copy_cleanup_uint128.sol new file mode 100644 index 000000000..a2405921d --- /dev/null +++ b/test/libsolidity/semanticTests/array/array_copy_cleanup_uint128.sol @@ -0,0 +1,23 @@ +// Test to see if cleanup is performed properly during array copying +contract C { + uint128[] x; + function f() public returns(bool) { + x.push(42); x.push(42); x.push(42); x.push(42); + uint128[] memory y = new uint128[](1); + y[0] = 23; + x = y; + assembly { sstore(x.slot, 4) } + + assert(x[0] == 23); + assert(x[1] == 0); + + assert(x[2] == 0); + // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of + // the slot dirty. + assert(x[3] == 0); + + return true; + } +} +// ---- +// f() -> true diff --git a/test/libsolidity/semanticTests/array/array_copy_cleanup_uint40.sol b/test/libsolidity/semanticTests/array/array_copy_cleanup_uint40.sol new file mode 100644 index 000000000..ae2de79ce --- /dev/null +++ b/test/libsolidity/semanticTests/array/array_copy_cleanup_uint40.sol @@ -0,0 +1,48 @@ +// Issue 9832: Test to see if cleanup is performed properly after array copying +contract C { + uint40[] x; + function f() public returns(bool) { + + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + + uint40[] memory y = new uint40[](1); + y[0] = 23; + x = y; + + assembly { sstore(x.slot, 20) } + + assert(x[0] == 23); + assert(x[1] == 0); + assert(x[2] == 0); + assert(x[3] == 0); + + assert(x[4] == 0); + assert(x[5] == 0); + assert(x[6] == 0); + assert(x[7] == 0); + + assert(x[8] == 0); + assert(x[9] == 0); + assert(x[10] == 0); + assert(x[11] == 0); + + assert(x[12] == 0); + assert(x[13] == 0); + assert(x[14] == 0); + assert(x[15] == 0); + + assert(x[16] == 0); + assert(x[17] == 0); + assert(x[18] == 0); + assert(x[19] == 0); + + return true; + + } +} +// ---- +// f() -> true From 24ba5aa3aa3499362361cd1b1a8da571c4e71d65 Mon Sep 17 00:00:00 2001 From: Harikrishnan Mulackal Date: Thu, 1 Oct 2020 20:05:25 +0200 Subject: [PATCH 2/2] Updating docs on DynamicArrayCleanup bug --- docs/bugs.json | 7 +++ docs/bugs_by_version.json | 97 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 6 deletions(-) diff --git a/docs/bugs.json b/docs/bugs.json index ec1d75670..2d48b44b2 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,11 @@ [ + { + "name": "DynamicArrayCleanup", + "summary": "When assigning a dynamically-sized array with types of size at most 16 bytes in storage causing the assigned array to shrink, some parts of deleted slots were not zeroed out.", + "description": "Consider a dynamically-sized array in storage whose base-type is small enough such that multiple values can be packed into a single slot, such as `uint128[]`. Let us define its length to be `l`. When this array gets assigned from another array with a smaller length, say `m`, the slots between elements `m` and `l` have to be cleaned by zeroing them out. However, this cleaning was not performed properly. Specifically, after the slot corresponding to `m`, only the first packed value was cleaned up. If this array gets resized to a length larger than `m`, the indices corresponding to the unclean parts of the slot contained the original value, instead of 0. The resizing here is performed by assigning to the array `length`, by a `push()` or via inline assembly. You are not affected if you are only using `.push()` or if you assign a value (even zero) to the new elements after increasing the length of the array.", + "fixed": "0.7.3", + "severity": "medium" + }, { "name": "FreeFunctionRedefinition", "summary": "The compiler does not flag an error when two or more free functions with the same name and parameter types are defined in a source unit or when an imported free function alias shadows another free function with a different name but identical parameter types.", diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 8ebe8b060..ec9d5652b 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1,6 +1,7 @@ { "0.1.0": { "bugs": [ + "DynamicArrayCleanup", "ExpExponentCleanup", "ZeroFunctionSelector", "ECRecoverMalformedInput", @@ -19,6 +20,7 @@ }, "0.1.1": { "bugs": [ + "DynamicArrayCleanup", "ExpExponentCleanup", "ZeroFunctionSelector", "ECRecoverMalformedInput", @@ -37,6 +39,7 @@ }, "0.1.2": { "bugs": [ + "DynamicArrayCleanup", "ExpExponentCleanup", "ZeroFunctionSelector", "ECRecoverMalformedInput", @@ -55,6 +58,7 @@ }, "0.1.3": { "bugs": [ + "DynamicArrayCleanup", "ExpExponentCleanup", "ZeroFunctionSelector", "ECRecoverMalformedInput", @@ -73,6 +77,7 @@ }, "0.1.4": { "bugs": [ + "DynamicArrayCleanup", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", @@ -92,6 +97,7 @@ }, "0.1.5": { "bugs": [ + "DynamicArrayCleanup", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", @@ -111,6 +117,7 @@ }, "0.1.6": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", @@ -132,6 +139,7 @@ }, "0.1.7": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", @@ -153,6 +161,7 @@ }, "0.2.0": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "ExpExponentCleanup", @@ -175,6 +184,7 @@ }, "0.2.1": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "ExpExponentCleanup", @@ -197,6 +207,7 @@ }, "0.2.2": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "ExpExponentCleanup", @@ -219,6 +230,7 @@ }, "0.3.0": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -243,6 +255,7 @@ }, "0.3.1": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -266,6 +279,7 @@ }, "0.3.2": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -289,6 +303,7 @@ }, "0.3.3": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -311,6 +326,7 @@ }, "0.3.4": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -333,6 +349,7 @@ }, "0.3.5": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -355,6 +372,7 @@ }, "0.3.6": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -375,6 +393,7 @@ }, "0.4.0": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -395,6 +414,7 @@ }, "0.4.1": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -415,6 +435,7 @@ }, "0.4.10": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -434,6 +455,7 @@ }, "0.4.11": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -452,6 +474,7 @@ }, "0.4.12": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -469,6 +492,7 @@ }, "0.4.13": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -486,6 +510,7 @@ }, "0.4.14": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -502,6 +527,7 @@ }, "0.4.15": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -517,6 +543,7 @@ }, "0.4.16": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -534,6 +561,7 @@ }, "0.4.17": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -552,6 +580,7 @@ }, "0.4.18": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -569,6 +598,7 @@ }, "0.4.19": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -587,6 +617,7 @@ }, "0.4.2": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -606,6 +637,7 @@ }, "0.4.20": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -624,6 +656,7 @@ }, "0.4.21": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -642,6 +675,7 @@ }, "0.4.22": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -660,6 +694,7 @@ }, "0.4.23": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -677,6 +712,7 @@ }, "0.4.24": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -694,6 +730,7 @@ }, "0.4.25": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -709,6 +746,7 @@ }, "0.4.26": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -721,6 +759,7 @@ }, "0.4.3": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -739,6 +778,7 @@ }, "0.4.4": { "bugs": [ + "DynamicArrayCleanup", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", @@ -756,6 +796,7 @@ }, "0.4.5": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -776,6 +817,7 @@ }, "0.4.6": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -795,6 +837,7 @@ }, "0.4.7": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -814,6 +857,7 @@ }, "0.4.8": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -833,6 +877,7 @@ }, "0.4.9": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -852,6 +897,7 @@ }, "0.5.0": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -867,6 +913,7 @@ }, "0.5.1": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -882,6 +929,7 @@ }, "0.5.10": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -893,6 +941,7 @@ }, "0.5.11": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -903,6 +952,7 @@ }, "0.5.12": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -913,6 +963,7 @@ }, "0.5.13": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -923,6 +974,7 @@ }, "0.5.14": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", @@ -935,6 +987,7 @@ }, "0.5.15": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", @@ -946,6 +999,7 @@ }, "0.5.16": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", @@ -956,6 +1010,7 @@ }, "0.5.17": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", @@ -965,6 +1020,7 @@ }, "0.5.2": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -980,6 +1036,7 @@ }, "0.5.3": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -995,6 +1052,7 @@ }, "0.5.4": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -1010,6 +1068,7 @@ }, "0.5.5": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -1027,6 +1086,7 @@ }, "0.5.6": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -1044,6 +1104,7 @@ }, "0.5.7": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -1059,6 +1120,7 @@ }, "0.5.8": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -1073,6 +1135,7 @@ }, "0.5.9": { "bugs": [ + "DynamicArrayCleanup", "ImplicitConstructorCallvalueCheck", "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", @@ -1086,6 +1149,7 @@ }, "0.6.0": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck", @@ -1097,6 +1161,7 @@ }, "0.6.1": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck", @@ -1106,19 +1171,26 @@ "released": "2020-01-02" }, "0.6.10": { - "bugs": [], + "bugs": [ + "DynamicArrayCleanup" + ], "released": "2020-06-11" }, "0.6.11": { - "bugs": [], + "bugs": [ + "DynamicArrayCleanup" + ], "released": "2020-07-07" }, "0.6.12": { - "bugs": [], + "bugs": [ + "DynamicArrayCleanup" + ], "released": "2020-07-22" }, "0.6.2": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck", @@ -1129,6 +1201,7 @@ }, "0.6.3": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck", @@ -1139,6 +1212,7 @@ }, "0.6.4": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck", @@ -1149,6 +1223,7 @@ }, "0.6.5": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck", @@ -1158,6 +1233,7 @@ }, "0.6.6": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck" @@ -1166,6 +1242,7 @@ }, "0.6.7": { "bugs": [ + "DynamicArrayCleanup", "MissingEscapingInFormatting", "ArraySliceDynamicallyEncodedBaseType", "ImplicitConstructorCallvalueCheck" @@ -1173,27 +1250,35 @@ "released": "2020-05-04" }, "0.6.8": { - "bugs": [], + "bugs": [ + "DynamicArrayCleanup" + ], "released": "2020-05-14" }, "0.6.9": { "bugs": [ + "DynamicArrayCleanup", "UsingForCalldata" ], "released": "2020-06-04" }, "0.7.0": { - "bugs": [], + "bugs": [ + "DynamicArrayCleanup" + ], "released": "2020-07-28" }, "0.7.1": { "bugs": [ + "DynamicArrayCleanup", "FreeFunctionRedefinition" ], "released": "2020-09-02" }, "0.7.2": { - "bugs": [], + "bugs": [ + "DynamicArrayCleanup" + ], "released": "2020-09-28" } } \ No newline at end of file