1

Version 0.8.7

Solidity is complaining that several state modifier functions can be restricted to view, such as:

function updateStruct(
    uint256 dummyParam
) public onlyOwner {
    DummyStruct memory dummy = dummyStructArray[dummyParam];
    dummy.something = 1;
}

Basically, any function that is modifying struct has "function state mutability can be restricted to view" warning.

1

The view modifier documentation states that :

Functions can be declared view in which case they promise not to modify the state.

Additionally, the rules of assignment between storage and memory states :

Assignments between storage and memory (or from calldata) always create an independent copy.

So :

function updateStruct(uint256 dummyParam) public onlyOwner {
    // Creates a memory COPY of dummyStructArray[dummyParam]
    DummyStruct memory dummy = dummyStructArray[dummyParam];
    // Modified the memory COPY
    dummy.something = 1;
}

You did read the state when accessing dummyStructArray[dummyParam], but you only modifie a memory copy, not the state variable. Therefore, your function fits the view requirements as it does not modify the state.

The function state mutability can be restricted to view warning is perfectly valid.

The same behavior can be seen on this code, you can try it on Remix:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Example {
    uint256 public stateVariable = 0;

    function modifiesInMemory() public {
        uint256 memoryCopy = stateVariable;
        memoryCopy = 10;
    }
}

EDIT : Adding simple example as per OP's comment.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
    
contract Example {
    struct DummyStruct {
        uint256 something;
    }

    DummyStruct[1] public dummyStructArray;


    // Creates a memory copy and operates on it
    // "Assignments between storage and memory (or from calldata) always create an independent copy."
    function modifiesInMemory() public {
        DummyStruct memory memoryCopy = dummyStructArray[0];
        memoryCopy.something = 10;

        // ASSIGN THE MEMORY COPY BACK TO THE STATE VARIABLE
        dummyStructArray[0] = memoryCopy;
    }

    // Creates a local storage reference to the state variable
    // "Assignments from storage to a local storage variable also only assign a reference."
    function modifiedInLocalStorage() public {
         DummyStruct storage localStorageReference = dummyStructArray[0];
         localStorageReference.something = 10;
    }

    // Directly modifies the state variable
    function modifiesInState() public {
        // MODIFIES THE STATE VARIABLE IN PLACE
        dummyStructArray[0].something = 10;
    }
}
5
  • So basically at some point, it will update the original struct right?
    – Kaneda
    Nov 27 '21 at 9:59
  • 1
    No. You are updating an independent copy only with this code. You either need to directly modify the state variable, or assign your memory copy to it after your modifications are done.
    – hroussille
    Nov 27 '21 at 10:04
  • Can you please elaborate (or some code reference, link, etc) about assigning modifications on memory copy to original?
    – Kaneda
    Nov 27 '21 at 10:18
  • 1
    I added an example showing the 3 ways to do it. Memory copy / local storage reference / In place.
    – hroussille
    Nov 27 '21 at 10:28
  • Yep it makes sense now, thanks a lot
    – Kaneda
    Nov 27 '21 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.