From f9a48b94d41d4838cefbc5daa5dcc1748810ea56 Mon Sep 17 00:00:00 2001 From: Anton Bukov Date: Thu, 4 May 2023 13:36:06 +0200 Subject: [PATCH] Handle nested structs encoding for EIP-712 --- libsolidity/ast/AST.cpp | 16 ++++++++++++++-- libsolidity/ast/AST.h | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index d75c0d63d..1166d8ffd 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -389,15 +389,27 @@ std::vector, std::optional>> UsingFo return ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to; } -util::h256 StructDefinition::typehash() const +std::string StructDefinition::encodeType() const { std::string str = name() + "("; + std::set nested; // std::set enables duplicates elimination and ordered enumeration for (size_t i = 0; i < m_members.size(); i++) { str += i == 0 ? "" : ","; str += m_members[i]->type()->canonicalName() + " " + m_members[i]->name(); + if (m_members[i]->type()->category() == Type::Category::Struct) { + Declaration const* declaration = m_members[i]->type()->typeDefinition(); + if (StructDefinition const* structDef = dynamic_cast(declaration)) { + nested.insert(structDef->encodeType()); + } + } } - return util::keccak256(str + ")"); + return std::accumulate(nested.begin(), nested.end(), str + ")"); +} + +util::h256 StructDefinition::typehash() const +{ + return util::keccak256(encodeType()); } Type const* StructDefinition::type() const diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 88171361d..2d5cce81c 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -741,6 +741,9 @@ public: std::vector> const& members() const { return m_members; } + /// @returns the EIP-712 compatible struct encoding. + std::string encodeType() const; + /// @returns the EIP-712 compatible typehash of this struct. util::h256 typehash() const;