caracal icon indicating copy to clipboard operation
caracal copied to clipboard

Storage variables not written back to storage

Open enitrat opened this issue 2 years ago • 1 comments

Describe the desired feature

Detect if the value read from a storage variable is mutated, but the updated value is not written back to storage.

Associated example:

#[contract]
mod StorageVarNotUpdated {
    struct Storage {
        _value: u128
    }

    #[external]
    fn bad() {
        let mut value = _value::read();
        value += 1;
    }

    #[external]
    fn good() {
        let mut value = _value::read();
        value += 1;
        _value::write(value);
    }

    #[external]
    fn good2() {
        update_value();
    }

    // update value in a private function
    fn update_value() {
        let mut value = _value::read();
        value += 1;
        _value::write(value);
    }
}

This is probably a bit tricky to do at the Sierra level, because we don't know whether a storage variable is read as mut or not; which makes it hard to catch mutability intents at the Cairo level.

enitrat avatar Jul 16 '23 10:07 enitrat

Hi, thanks for the great idea. I looked into it and i think at the moment by using only sierra it's not possible to implement a detector without too many false positives because for example these two functions have the same sierra. I keep the issue open to revisit when there will be sierra to source code mapping.

    #[external(v0)]
    fn good(ref self: ContractState) {
        let mut value = self.a.read();
        value += 435;
        self.a.write(value);
    }

    #[external(v0)]
    fn good2(ref self: ContractState) {
        let mut value = self.a.read();
        let b = value + 435;
        self.a.write(b);
    }

smonicas avatar Aug 08 '23 16:08 smonicas