{ 跳至内容 }

abi.encodeCall 字面量错误

发布于 2022年3月16日,作者:Solidity 团队

安全警报

2022年3月10日,Solidity 团队发现 abi.encodeCall 的实现存在错误,当与固定长度字节字面量一起使用时会出现此问题。

该错误是在 Solidity 0.8.11 中引入的,并在 0.8.13 中修复。

我们将其严重性评级为“极低”。

哪些合约受影响?

如果您使用 abi.encodeCall(f, (...)),其中 f 接受一个 bytesNN 参数,并且您为该参数提供的值是十六进制字面量(0x1234hex"abcd")或字符串字面量("abcd"),则您可能会受到影响。

如果您仅将变量传递给 abi.encodeCall,则您的代码不受影响。

技术细节

编译器确实检查了所有值的数据类型是否都隐式可转换为函数参数的数据类型(这是 abi.encodeCall 相比于 abi.encode 的主要优势,也是添加此功能的原因),但它在为该函数调用生成代码时没有正确考虑数据类型。生成的代码与 abi.encode 的代码相同,后者只是根据参数的数据类型进行编码。

问题在于像 0x1234"abcd" 这样的字面量可以隐式转换为不同的数据类型:第一个可以转换为 bytes2uint16,第二个可以转换为 bytes4bytes memory

在第一种情况下,编译器选择将 0x1234 编码为 uint16。这意味着它右对齐而不是左对齐 bytes2。在第二种情况下,它被编码为 bytes memory,这是一个动态类型,因此在 bytes4 值的位置,存储了一个偏移指针,并在末尾添加了其他数据。

由于此错误仅存在于字面量中(实际变量具有适当的数据类型,并且隐式转换始终是无操作的),因此通过简单的测试很容易检测到。

上一篇

下一篇

参与进来

GitHub

Twitter

Mastodon

矩阵

了解更多

博客文档使用案例贡献关于论坛

2024Solidity 团队

安全策略

行为准则