argotorg / argotorg/solidity

[optimiser] msize may not be used in Yul code when stack limit evasion is enabled because it may produce different results pre and post optimization

Open
#11,257 5 comments 0 reactions 0 assignees View on GitHub
bug :bug: low effort low impact optimizer
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
1d 11h
Merged PRs (30d)
21

Description

## Description

```
object "main" {
code {
codecopy(0, dataoffset("deployed"), datasize("deployed"))
return(0, datasize("deployed"))
}
object "deployed" {
code {
{
mstore(0x40, memoryguard(0x60))
{
function foo_m_0(x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9, x_10, x_11, x_12, x_13, x_14, x_15, x_16, x_17, x_18, x_19, x_20, x_21, x_22, x_23, x_24, x_25, x_26) -> x_27, x_28, x_29, x_30, x_31, x_32, x_33, x_34, x_35, x_36, x_37, x_38, x_39, x_40, x_41, x_42, x_43, x_44, x_45, x_46, x_47, x_48, x_49, x_50, x_51, x_52, x_53, x_54, x_55
{
x_27 := mod(0x40000000000000000000000000000000000, 0x100)
x_28 := mod(0x400000000000000000000000000000000000, 0x100)
x_29 := mod(0x4000000000000000000000000000000000000, 0x100)
x_30 := mod(0x40000000000000000000000000000000000000, 0x100)
x_31 := mod(0x400000000000000000000000000000000000000, 0x100)
x_32 := mod(0x4000000000000000000000000000000000000000, 0x100)
x_33 := mod(0x40000000000000000000000000000000000000000, 0x100)
x_34 := mod(0x400000000000000000000000000000000000000000, 0x100)
x_35 := mod(0x4000000000000000000000000000000000000000000, 0x100)
x_36 := mod(0x40000000000000000000000000000000000000000000, 0x100)
x_37 := mod(0x400000000000000000000000000000000000000000000, 0x100)
x_38 := mod(0x4000000000000000000000000000000000000000000000, 0x100)
x_39 := mod(0x40000000000000000000000000000000000000000000000, 0x100)
x_40 := mod(0x400000000000000000000000000000000000000000000000, 0x100)
x_41 := mod(0x4000000000000000000000000000000000000000000000000, 0x100)
x_42 := mod(0x40000000000000000000000000000000000000000000000000, 0x100)
x_43 := mod(0x400000000000000000000000000000000000000000000000000, 0x100)
x_44 := mod(0x4000000000000000000000000000000000000000000000000000, 0x100)
x_45 := mod(0x40000000000000000000000000000000000000000000000000000, 0x100)
x_46 := mod(0x400000000000000000000000000000000000000000000000000000, 0x100)
x_47 := mod(0x4000000000000000000000000000000000000000000000000000000, 0x100)
x_48 := mod(0x40000000000000000000000000000000000000000000000000000000, 0x100)
x_49 := mod(0x400000000000000000000000000000000000000000000000000000000, 0x100)
x_50 := mod(0x4000000000000000000000000000000000000000000000000000000000, 0x100)
x_51 := mod(0x40000000000000000000000000000000000000000000000000000000000, 0x100)
x_52 := mod(0x400000000000000000000000000000000000000000000000000000000000, 0x100)
x_53 := mod(0x4000000000000000000000000000000000000000000000000000000000000, 0x100)
x_54 := mod(0x40000000000000000000000000000000000000000000000000000000000000, 0x100)
x_55 := mod(0x400000000000000000000000000000000000000000000000000000000000000, 0x100)
}
let x_86, x_87, x_88, x_89, x_90, x_91, x_92, x_93, x_94, x_95, x_96, x_97, x_98, x_99, x_100, x_101, x_102, x_103, x_104, x_105, x_106, x_107, x_108, x_109, x_110, x_111, x_112, x_113, x_114 := foo_m_0(calldataload(224),sload(288),calldataload(32),sload(96),calldataload(160),sload(224),calldataload(288),sload(32),calldataload(96),sload(160),calldataload(224),sload(288),calldataload(32),sload(96),calldataload(160),sload(224),calldataload(288),sload(32),calldataload(96),sload(160),calldataload(224),sload(288),calldataload(32),sload(96),calldataload(160),sload(224))
sstore(256, x_86)
sstore(288, x_87)
sstore(0, x_88)
sstore(32, x_89)
sstore(64, x_90)
sstore(96, x_91)
sstore(128, x_92)
sstore(160, x_93)
sstore(192, x_94)
sstore(224, x_95)
sstore(256, x_96)
sstore(288, x_97)
sstore(0, x_98)
sstore(32, x_99)
sstore(64, x_100)
sstore(96, x_101)
sstore(128, x_102)
sstore(160, x_103)
sstore(192, x_104)
sstore(224, x_105)
sstore(256, x_106)
sstore(288, x_107)
sstore(0, x_108)
sstore(32, x_109)
sstore(64, x_110)
sstore(96, x_111)
sstore(128, x_112)
sstore(160, x_113)
sstore(192, x_114)
sstore(mod(0x7ffffffffffffffffffffffffffffffffffffffffffffff, 0x100), msize())
}
}
}
}
}
```

produces different storage state pre and post optimisation. This boils down to the stack limit evader making use of memory to free up stack slots and in the process increasing `msize`.

## Steps to Reproduce

```
$ solc --strict-assembly --optimize test.yul
```

Copy the optimized yul code and run it on the yul interpreter.

Contributor guide

Open the contributing guide

Research direction

Start with the supplied test.yul and reproduce the mismatch using `solc --strict-assembly --optimize`, then compare the original and optimized Yul in the Yul interpreter. Trace the optimizer's stack limit evader and its memory use around `msize()`. Done means optimized and unoptimized execution produce identical storage state, with a regression test covering the case.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, solidity
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.