ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
23.45k stars 5.8k forks source link

Different error codes are produced by solc under different optimization parameters #15553

Open lum7na opened 1 month ago

lum7na commented 1 month ago

Hi! When compiling the program below with --via-ir --optimize and using --optimize-runs 200 and --optimize-runs 99999999 respectively, different error codes are returned when the f() function is called. Specifically, --optimize-runs 200 yields 0x4e487b710000000000000000000000000000000000000000000000000000000000000032, while --optimize-runs 99999999 results in 0x0. I conducted tests on Remix using the 0.8.27 compiler version, and the issue can be reproduced on the latest compiler version as well.

I'm interested in knowing: are error codes always accurate, and what is the correct error code?

contract C {
  function f() public returns(uint, uint) {
    try this.f() {
    } catch Error(string memory x) {
      x;
    } catch (bytes memory x) {
      if (x.length > 0) {
        require(abi.decode(x, (bool)), hex"");
      }
      for (uint256 i = 0;i < 7; i++) {
        x[i] = x[i];
      }
      require(abi.decode(x, (bool)), hex"");
    }
  }
}
lum7na commented 2 weeks ago

Here's another example: at a lower optimization level (200), executing the transaction f() results in an error code of 0x32. However, at a higher optimization level (99999999), the transaction successfully returns.

contract C {
  function g(uint256 x, uint256 y) private returns(uint256) {
    return x;
  }

  function f() public returns(uint[] memory, uint) {
    try this.f() returns (uint[] memory x, uint y) {
      return (x, g(y, x[1]));
    } catch {
    }
  }
}