fixed EIP-712 encoding type.

This commit is contained in:
Saw-mon & Natalie 2023-05-16 01:08:11 +01:00 committed by Anton Bukov
parent 78981fac52
commit 145dfcf6da
3 changed files with 65 additions and 9 deletions

View File

@ -395,12 +395,33 @@ void StructDefinition::insertEip712EncodedSubtypes(std::set<std::string>& subtyp
{
for (size_t i = 0; i < m_members.size(); i++)
{
if (m_members[i]->type()->category() == Type::Category::Struct)
{
Declaration const* declaration = m_members[i]->type()->typeDefinition();
StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration);
solAssert(structDef != nullptr);
Declaration const* declaration = nullptr;
switch (m_members[i]->type()->category())
{
case Type::Category::Struct:
declaration = m_members[i]->type()->typeDefinition();
break;
case Type::Category::Array:
{
auto const* arrayType = dynamic_cast<ArrayType const*>(m_members[i]->type());
solAssert(!!arrayType);
if (auto finalyBaseType = dynamic_cast<StructType const*>(arrayType->finalBaseType(false)))
{
declaration = finalyBaseType->typeDefinition();
}
}
break;
default:
continue;
}
if(!declaration) {
continue;
}
if (auto const* structDef = dynamic_cast<StructDefinition const*>(declaration))
{
subtypes.insert(structDef->eip712EncodeTypeWithoutSubtypes());
structDef->insertEip712EncodedSubtypes(subtypes);
}
@ -413,16 +434,13 @@ std::string StructDefinition::eip712EncodeTypeWithoutSubtypes() const
for (size_t i = 0; i < m_members.size(); i++)
{
str += i == 0 ? "" : ",";
str += m_members[i]->type()->canonicalName() + " " + m_members[i]->name();
str += m_members[i]->type()->eip712TypeName() + " " + m_members[i]->name();
}
return str + ")";
}
std::string StructDefinition::eip712EncodeType() const
{
// EIP-712 supports recurvie structs, but not containing nested mappings
solAssert(!annotation().containsNestedMapping.has_value() || !annotation().containsNestedMapping.value(), "Struct containing mapping cannot be used in EIP-712.");
// std::set enables duplicates elimination and ordered enumeration
std::set<std::string> subtypes;
insertEip712EncodedSubtypes(subtypes);

View File

@ -1887,6 +1887,23 @@ string ArrayType::canonicalName() const
return ret;
}
string ArrayType::eip712TypeName() const
{
string ret;
if (isString())
ret = "string";
else if (isByteArrayOrString())
ret = "bytes";
else
{
ret = baseType()->eip712TypeName() + "[";
if (!isDynamicallySized())
ret += length().str();
ret += "]";
}
return ret;
}
string ArrayType::signatureInExternalFunction(bool _structsByName) const
{
if (isByteArrayOrString())
@ -2511,6 +2528,11 @@ string StructType::canonicalName() const
return *m_struct.annotation().canonicalName;
}
string StructType::eip712TypeName() const
{
return this->typeDefinition()->name();
}
FunctionTypePointer StructType::constructorType() const
{
TypePointers paramTypes;

View File

@ -357,6 +357,7 @@ public:
/// @returns the canonical name of this type for use in library function signatures.
virtual std::string canonicalName() const { return toString(true); }
virtual std::string humanReadableName() const { return toString(); }
virtual std::string eip712TypeName() const { return encodingType()->toString(true); }
/// @returns the signature of this type in external functions, i.e. `uint256` for integers
/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
/// structs are given by canonical name like `ContractName.StructName[2]`.
@ -551,6 +552,7 @@ public:
bool nameable() const override { return true; }
std::string toString(bool _withoutDataLocation) const override;
std::string eip712TypeName() const override{ solAssert(false, "EIP-712 is not supported for struct members of fixed point type"); }
Type const* encodingType() const override { return this; }
TypeResult interfaceType(bool) const override { return this; }
@ -867,6 +869,7 @@ public:
std::string toString(bool _withoutDataLocation) const override;
std::string humanReadableName() const override;
std::string canonicalName() const override;
std::string eip712TypeName() const override;
std::string signatureInExternalFunction(bool _structsByName) const override;
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
Type const* encodingType() const override;
@ -924,6 +927,7 @@ public:
BoolResult isImplicitlyConvertibleTo(Type const& _other) const override;
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
std::string richIdentifier() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of array slice type"); }
bool operator==(Type const& _other) const override;
unsigned calldataEncodedSize(bool) const override { solAssert(false, ""); }
unsigned calldataEncodedTailSize() const override { return 32; }
@ -1052,6 +1056,7 @@ public:
std::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const override;
std::string canonicalName() const override;
std::string eip712TypeName() const override;
std::string signatureInExternalFunction(bool _structsByName) const override;
/// @returns a function that performs the type conversion between a list of struct members
@ -1100,6 +1105,7 @@ public:
bool leftAligned() const override { return false; }
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of Enum type"); }
bool isValueType() const override { return true; }
bool nameable() const override { return true; }
@ -1187,6 +1193,7 @@ public:
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of user defined value type"); }
std::string signatureInExternalFunction(bool) const override { solAssert(false, ""); }
protected:
@ -1218,6 +1225,8 @@ public:
bool hasSimpleZeroValueInMemory() const override { return false; }
Type const* mobileType() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of tuple type"); }
std::vector<Type const*> const& components() const { return m_components; }
protected:
@ -1415,6 +1424,7 @@ public:
TypeResult binaryOperatorResult(Token, Type const*) const override;
std::string canonicalName() const override;
std::string humanReadableName() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of function type"); }
std::string toString(bool _withoutDataLocation) const override;
unsigned calldataEncodedSize(bool _padded) const override;
bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
@ -1551,6 +1561,7 @@ public:
bool operator==(Type const& _other) const override;
std::string toString(bool _withoutDataLocation) const override;
std::string canonicalName() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of mapping type"); }
bool containsNestedMapping() const override { return true; }
TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
Type const* encodingType() const override;
@ -1595,6 +1606,7 @@ public:
bool operator==(Type const& _other) const override;
bool canBeStored() const override { return false; }
u256 storageSize() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of type type"); }
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
std::string toString(bool _withoutDataLocation) const override { return "type(" + m_actualType->toString(_withoutDataLocation) + ")"; }
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
@ -1622,6 +1634,7 @@ public:
u256 storageSize() const override;
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
std::string richIdentifier() const override;
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of modfier type"); }
bool operator==(Type const& _other) const override;
std::string toString(bool _withoutDataLocation) const override;
protected:
@ -1646,6 +1659,7 @@ public:
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;
bool canBeStored() const override { return false; }
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of module type"); }
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
@ -1685,6 +1699,7 @@ public:
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;
bool canBeStored() const override { return false; }
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of magic type"); }
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
@ -1718,6 +1733,7 @@ public:
unsigned calldataEncodedSize(bool) const override { return 32; }
bool canBeStored() const override { return false; }
bool isValueType() const override { return true; }
std::string eip712TypeName() const override { solAssert(false, "EIP-712 is not supported for struct members of inaccessible dynamic type"); }
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
std::string toString(bool) const override { return "inaccessible dynamic type"; }
Type const* decodingType() const override;