EVM 局限性与汇编审计技巧
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 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
版权声明
本文仅代表作者观点,不代表区块链技术网立场。
本文系作者授权本站发表,未经许可,不得转载。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。