ethereum / solidity

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

Solidity compiler produces incorrect bytecode - The semantics of the program are inconsistent after compilation. #14709

Closed jayden-sudo closed 8 months ago

jayden-sudo commented 8 months ago

Description: Solidity compiler produces incorrect bytecode - The semantics of the program are inconsistent after compilation.

Environment

Steps to Reproduce

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8;

contract test {
    mapping(uint256 => bool) public map;

    constructor() {
        map[1] = true;
        map[2] = true;
    }

    function tryClean(uint256 key) private returns (bool) {
        if (map[key]) {
            map[key] = false;
            return true;
        }
        return false;
    }

    function step_1() public returns (bool) {
        // clean <1> and <2>
        if (tryClean(1) == false && tryClean(2) == false) {
            return false;
        }
        return true;
    }

    function step_2() public view returns (bool) {
        // check if data cleaned
        return ((map[1] == false) && (map[2] == false));
    }
}

In the step_1 function, when using &&, the original intention expects both expressions to execute. However, it is incorrectly optimized by the compiler to:

if (tryClean(1) == true || tryClean(2) == true) {
    return true;
}
return false;

This leads to the execution differing from the original intent.

Note: The compiler, when optimizing code, should ensure semantic consistency and consider whether the tryClean function internally modifies the state with opcodes such as sstore, mstore, call, logN, create, revert, etc.

yzf0304 commented 6 months ago

Hello, I have also found the problem you raised in practice. Will this problem have a larger impact and cause more serious mistakes?

jayden-sudo commented 6 months ago

Hello, I have also found the problem you raised in practice. Will this problem have a larger impact and cause more serious mistakes?

My previous error stemmed from not carefully examining the code. Upon my second check, I found no issues. So, this problem does not exist, and it won't have any other impact.

yzf0304 commented 6 months ago

Then I have a question. We know that solidity has a logic short circuit optimization method. If you add some code about contract transfer to the tryClean function in your example, will it be optimized and have an impact?