Solidity – Why Is Constant Variable Value Changing in Yul?

solidityyul

I wrote a simple contract in solidity.Constant variable's value can be changed in Yul (assembly). But how and why is it changing?.

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract changeConstant {
    uint256 private constant v = 5;
    function increment() public {
        assembly{   
            sstore(v, add(sload(v), 1))
        }
    }
    function getValue() public view returns(uint256 result){
        assembly {
            result := sload(v)
        }
    }
}

docs explains:

For a constant variable, the expression assigned to it is copied to all the places where it is accessed and also re-evaluated each time

Best Answer

You don't change the constant, but you write to the storage slot v = 5 and read from it.

As can be read in the Assembly Docs, the sstore command takes the arguments p and v, where p is the pointer to the storage location and v is the value to be stored.

sstore(p, v) -> storage[p] := v
sload(p) -> storage[p]

This can be confirmed by making some small changes to your code:

//SPDX license identifier: MIT
pragma solidity ^0.8.7;

contract ChangeConstant {

uint256 public constant v = 5;

uint256 public emptySlot0;
uint256 public emptySlot1;
uint256 public emptySlot2;
uint256 public emptySlot3;
uint256 public emptySlot4;

uint256 public writtenSlot;

    function increment() public {
        assembly{
            sstore(v, add(sload(v), 1))
        }
    }
    function getValue() public view returns(uint256 result){
        assembly {
            result := sload(v)
        }
    }

}

When writing code in solidity each state variable is stored in a slot decided by the storage layout rules. That is why I had to define emptySlot0-emptySlot4. Inline assembly allows you to choose whatever slot you want to write to or read from.

Related Topic