From bfe074b2b1c886d648b9efa76ea421e8a3ec4aab Mon Sep 17 00:00:00 2001 From: mingchuan Date: Wed, 19 Jun 2019 10:46:05 +0800 Subject: [PATCH] Fix storage array abi encoding Fix incorrect abi encoding of storage array of data type that occupy multiple storage slots --- Changelog.md | 4 ++++ libsolidity/codegen/ABIFunctions.h | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 29 ++++++++++++++++-------- libsolidity/codegen/YulUtilFunctions.h | 2 +- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Changelog.md b/Changelog.md index 243284272..0474ad0d0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ ### 0.5.10 (unreleased) +Important Bugfixes: + * Fix incorrect abi encoding of storage array of data type that occupy multiple storage slots + + Language Features: diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index a54b403d9..eba01d765 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -154,7 +154,7 @@ private: EncodingOptions const& _options ); /// Part of @a abiEncodingFunction for array target type and given memory array or - /// a given storage array with one item per slot. + /// a given storage array with every item occupies one or multiple full slots. std::string abiEncodingFunctionSimpleArray( ArrayType const& _givenType, ArrayType const& _targetType, diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 65991f864..4f9c4a109 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -589,18 +589,29 @@ string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) } )"); templ("functionName", functionName); - if (_type.location() == DataLocation::Memory) + switch (_type.location()) + { + case DataLocation::Memory: templ("advance", "0x20"); - else if (_type.location() == DataLocation::Storage) - templ("advance", "1"); - else if (_type.location() == DataLocation::CallData) - templ("advance", toCompactHexWithPrefix( + break; + case DataLocation::Storage: + { + u256 size = _type.baseType()->storageSize(); + solAssert(size >= 1, ""); + templ("advance", toCompactHexWithPrefix(size)); + break; + } + case DataLocation::CallData: + { + u256 size = _type.baseType()->isDynamicallyEncoded() ? 32 : - _type.baseType()->calldataEncodedSize() - )); - else - solAssert(false, ""); + _type.baseType()->calldataEncodedSize(); + solAssert(size >= 32 && size % 32 == 0, ""); + templ("advance", toCompactHexWithPrefix(size)); + break; + } + } return templ.render(); }); } diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index b4e0dc727..c33a91ce1 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -113,7 +113,7 @@ public: /// for the data position of an array which is stored in that slot / memory area / calldata area. std::string arrayDataAreaFunction(ArrayType const& _type); /// @returns the name of a function that advances an array data pointer to the next element. - /// Only works for memory arrays, calldata arrays and storage arrays that store one item per slot. + /// Only works for memory arrays, calldata arrays and storage arrays that every item occupies one or multiple full slots. std::string nextArrayElementFunction(ArrayType const& _type); /// @returns the name of a function that performs index access for mappings.