作为一个注重安全的Solidity开发者,这是你在使用unchecked块和内联汇编时要非常小心的信号。 从0.8.0及之后的版本开始,编译器会自动处理下溢/上溢。但如果一个允许上溢的变量随后在yul中使用,会发生什么呢? EVM实际上没有狭窄类型的概念,因此低级yul代码在完整的256位字大小上操作。你能看出这将如何发展吗? 在我目前的@CyfrinAudits项目中遇到的这个高度简化的场景中,长度变量在unchecked块中悄悄地上溢到uint8,并如预期那样回绕到254。 然而,当用于在随后的内联汇编块中调整数组大小时,肮脏的高位位仍然存在,仿佛上溢从未发生过! 这导致数组的长度远大于预期,即使我们可能期望它被限制在长度变量可表示的最大值的模数内。 使用foundry调试器和cast --to-base <0xfe|0x01fe> dec,我们可以确认我们的假设是错误的,确实在将长度写入内存时高位位仍然保持肮脏。 虽然这个例子可以进一步简化,但关键的收获是要始终对unchecked/assembly块保持高度怀疑,并考虑狭窄类型的高位位如何可能变得肮脏,即使在yul中像赋值这样简单的操作也是如此。 这有时可能感觉像是一个难以发现的深奥错误,除非对EVM和Solidity编译器内部有深入的了解,因此一旦意识到发生了什么,我发现这个具体的例子非常有帮助。 如果你有任何问题,请在下面留言,但希望你也觉得这很有帮助!
7.75K