Skip to content

Messages with an immutable receiver should not be allowed to change state via ink_env #1969

@xermicus

Description

@xermicus

As per our docs:

An ink! message with a &self receiver may only read state whereas an ink! message with a &mut self receiver may mutate the contract's storage.

However this isn't enforced: Via the Environment, supposedly immutable contracts can change the state in many ways. Things that are currently possible in immutable contracts that should fail to compile:

  • writing to storage
  • emitting events
  • calling chain extensions
  • call_runtime
  • instantiating contracts
  • calling contracts
  • terminate
  • transfer value

Minimal reproducer

While direct storage writes are enforced by the &self receiver, this can easily be circumvented.

#![cfg_attr(not(feature = "std"), no_std, no_main)]

#[ink::contract]
mod mutable {
    use ink::storage::traits::ManualKey;
    use ink::storage::Lazy;

    /// A contract for testing `Mapping` functionality.
    #[ink(storage)]
    #[derive(Default)]
    pub struct Mutable {}

    impl Mutable {
        #[ink(constructor)]
        pub fn new() -> Self {
            Self {}
        }

        /// This function manipulates state despite receiving `&self`
        #[ink(message)]
        pub fn read_only(&self, a: u8) {
            ink::env::set_contract_storage(&a, &a);
            // The same just with an added layer of inderiction
            Lazy::<u8, ManualKey<127>>::new().set(&127);
        }

        #[ink(message)]
        pub fn get(&self, a: u8) -> (Option<u8>, Option<u8>) {
            (
                ink::env::get_contract_storage(&a).unwrap(),
                ink::env::get_contract_storage(&127).unwrap(),
            )
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions