EVM 局限性与汇编审计技巧

本文作者分享了以太坊虚拟机(EVM)的局限性以及在进行智能合约安全审计时的一些技巧,内容涵盖合约bytecode大小限制、gas优化、setter检查、循环检查、时间戳/区块依赖以及汇编检查等方面,旨在帮助开发者编写更安全、更高效的智能合约,并避免潜在的安全漏洞。

Image

EVM 限制 & 汇编审计技巧

本文将只关注那些在保持代码安全方面可能非常有价值的领域。

  • 合约字节码大小限制 - 24kb;

  • 自定义错误 比 revert(“error text”) 占用更少的字节码空间;

  • 包括旧的编码器 pragma abicoder v1; 如果合约中有数组的数组或结构的数组,则需要 Abicoder V2。但即使对于简单的参数,它也会产生更复杂的字节码 - 请记住这一点;

  • 总的来说:public->external, memory->calldata;

  • 可以删除或合并 Getters (包括 public 变量)以减少合约的大小;

  • 你也可以拒绝短类型(只保留在存储中,在局部变量、计算和参数中使用完整类型);

  • 可以不经常使用修饰器来减少合约大小;

  • 为了减少字节码,你可以使 Optimizer runs=1。 但是,不幸的是,它会使调用更昂贵;

  • {} - 用于限制局部变量可见性的块;

Setter 检查

  • 通常有访问控制;

  • 通常必须发出事件;

  • 必须更新存储:函数参数被写入存储(见过所有三种不正确的变体 - 它们很受欢迎🙂);

  • 在复杂的项目中,我们会考虑更改其中一个系统组件的地址将如何影响整个协议;

循环检查

  • 检查它们不是无限的,也不会变成无限的(或者可以使用有限的变体);

  • 从末尾开始的循环进行有效的检查,而不是 uint i = N; i >= 0(因为 uint 类型总是返回一个正值);

  • 在 Solidity 0.5.0 之前,do-while 内部的 continue 无法正常工作:continue 将执行切换到 do 而不检查 while 中的条件 - 这使得 do while 循环无限;

时间戳/块依赖

  • 不要以块为单位测量时间(除非我们谈论的是硬分叉 - 它们与块号相关)。有时,由于 TimeBomb,块的速度会减慢,而切换到 PoS 会将块之间的时间固定为 12 秒,而不是目前 PoW 的平均 13 秒;

  • 有时,合约依赖于非常小的时间间隔。一般来说,如果合约需要的精度高于 15 分钟,则可能存在危险;

  • 有些合约检查某些事情发生的频率不超过每个块一次。作为一种优化(例如,收取利息)这是可以的,但作为防止任何重入\闪电贷\其他攻击的保护措施则不可行。它还会破坏集成 - 很多用户将通过一个合约进入。

汇编检查

  • 代码本身不应破坏内存:

a) “搞乱”第三个或第四个插槽; b) “损坏”已分配的内存 - 从第四个 slot 一直到空闲内存指针(第三个 slot 中的值); c) 经常因为将 returndata 复制到内存的开头而损坏,returndatacopy(0, 0, returndatasize()) —

请参阅该部分的第二个代码块

  • 如果汇编块是内存安全的应该被标记为“memory-safe”(如果它不遵循内存约定,则不标记);

  • 汇编中没有溢出/下溢检查;

  • 当从确切的存储槽写入/读取时,请在继承时考虑存储结构。 如果 B 继承自 A,则在使用 B 内部的 sstore() 时,必须小心不要意外覆盖 A 的基本合约的槽;

  • 不同 Solidity 版本的设计变更:自 0.5.0 版本起使用 selfdestruct 代替 suicide,自 0.5.0 版本起使用 keccak256 代替 sha3。

最初发布在这里

  • 原文链接: x.com/officer_cia/status...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
officer_cia
officer_cia
江湖只有他的大名,没有他的介绍。