Als sicherheitsbewusster Solidity-Entwickler ist dies dein Zeichen, sehr vorsichtig mit unkontrollierten Blöcken und Inline-Assembly umzugehen. Seit Version 0.8.0 und später behandelt der Compiler automatisch Über- und Unterläufe. Aber was passiert, wenn eine Variable, die einen Überlauf zulässt, dann in Yul verwendet wird? Die EVM hat tatsächlich kein Konzept für schmale Typen, sodass der Low-Level-Yul-Code auf der vollen 256-Bit-Wortgröße arbeitet. Siehst du, wohin das führt? In diesem stark vereinfachten Szenario, auf das ich in meinem aktuellen @CyfrinAudits-Engagement gestoßen bin, überläuft die Längenvariable stillschweigend uint8 innerhalb des unkontrollierten Blocks und wickelt sich wie erwartet auf 254 zurück. Wenn sie jedoch verwendet wird, um das Array im nachfolgenden Inline-Assembly-Block zu ändern, bleiben die schmutzigen oberen Bits bestehen, als ob der Überlauf nie aufgetreten wäre! Dies führt dazu, dass die Länge des Arrays erheblich größer ist als erwartet, obwohl wir erwarten könnten, dass sie modulo dem maximal darstellbaren Wert der Längenvariable begrenzt ist. Mit dem Foundry-Debugger und dem Befehl cast --to-base <0xfe|0x01fe> dec können wir bestätigen, dass unsere Annahmen falsch waren und die oberen Bits tatsächlich schmutzig bleiben, wenn die Länge im Speicher geschrieben wird. Obwohl dieses Beispiel noch weiter vereinfacht werden kann, ist die wichtigste Erkenntnis, immer sehr misstrauisch gegenüber unkontrollierten/Assembly-Blöcken zu sein und zu berücksichtigen, wie die oberen Bits schmaler Typen schmutzig werden können, selbst bei etwas so Einfachem in Yul wie einer Zuweisung. Das kann manchmal wie ein esoterischer Fehler erscheinen, der ohne tiefes Wissen über die EVM und die internen Abläufe des Solidity-Compilers unmöglich zu erkennen ist. Als ich jedoch erkannte, was los war, fand ich dieses konkrete Beispiel sehr hilfreich. Hinterlasse mir einen Kommentar, wenn du Fragen hast, aber hoffentlich fandest du es auch hilfreich!
7,76K