Appearance
S2C5: Assembly Memory
1. 問題
コントラクトは Yul インラインアセンブリを使用してメモリ操作と数値計算を行っています。mintFlag の条件を満たすためには、これらの低レベル操作を理解し操作する必要があります。
2. 原因
コントラクトは Yul アセンブリ内で非標準的な数値処理方法(特殊なシフト操作、メモリレイアウト操作など)を使用しており、Solidity レベルでの安全性の前提が成立しません。
3. 解決策
Yul アセンブリコードを分析し、どのストレージスロットとメモリ領域が変更されているかを理解します。正確な呼び出しパラメータによって条件を満たします。
4. 遭遇した落とし穴
Yul アセンブリのセマンティクス: アセンブリ内の shl、shr、mstore などの操作のセマンティクスは、Solidity の高レベルコードとは異なります(例えば、bytes4 型はアセンブリ内では左詰めになります)。
5. 落とし穴の原因
Solidity では bytes4 は右詰め(下位 4 バイトを占有)ですが、Yul アセンブリでは bytes4 は 32 バイトのスタックスロット内で左詰め(上位 4 バイトを占有)になります。shl(224, bytes4) を使用すると、データが誤った位置に移動してしまいます。
6. 解決方法
Solidity レベルで bytes4 をまず uint256 に変換してから、シフト操作を行います。アセンブリ内で直接 bytes 型を操作することを避けます:
solidity
bytes4 selector = bytes4(keccak256("someFunction()"));
uint256 shifted = uint256(uint32(selector)) << 224; // 正しい
7. 技術的ポイント
| ポイント | 説明 |
|---|---|
| Yul アセンブリでの bytes4 のアライメント | bytes4 はアセンブリスタック内で左詰めであり、Solidity の右詰めとは異なります |
| データ型変換 | Solidity と Yul の間でデータ型のエンコード方法が異なる場合があります |
| メモリ操作 | Yul の mstore、mload は生のメモリを直接操作します |