Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage access issues with multi-level inheritance #106

Open
gwalen opened this issue Feb 23, 2024 · 0 comments
Open

Storage access issues with multi-level inheritance #106

gwalen opened this issue Feb 23, 2024 · 0 comments

Comments

@gwalen
Copy link

gwalen commented Feb 23, 2024

Stylus version: 0.4.2

Contract structure

I have 3 contracts:

  • Erc20 (abstract)
  • Erc20Burnable (abstract, inherits Erc20)
  • MyToken (concrete implementation, inherits Erc20 and Erc20Burnable)

Erc20 is standard erc20 impl, I will omit the methods implementation, just mention the ones used test cases:

sol_storage! {
  pub struct Erc20<T> {
      mapping(address => uint256) balances;
      mapping(address => mapping(address => uint256)) allowances;
      uint256 total_supply;
      PhantomData<T> phantom;
  }
}

impl<T: Erc20Params> Erc20<T> {

    pub fn mint(&mut self, account: Address, value: U256) -> Result<(), Erc20Error> { .... }

    pub fn burn(&mut self, account: Address, value: U256) -> Result<(), Erc20Error> { ....}

    pub fn update(&mut self, from: Address, to: Address, value: U256) -> Result<(), Erc20Error> { .... }
}

#[external]
impl<T: Erc20Params> Erc20<T> {
  ...
    pub fn balance_of(&self, address: Address) -> Result<U256, Erc20Error> {
        Ok(self.balances.get(address))
    }
  ... (other methods are also implemented)
}

Erc20Burnable is standard Erc20 extension link to solidity impl here

sol_storage! {
    pub struct Erc20Burnable  {
        #[borrow]
        Erc20<MyTokenParams> erc20;
    }
}

#[external]
#[inherit(Erc20<MyTokenParams>)]
impl Erc20Burnable  {

    pub fn burn(&mut self, account: Address, amount: U256) -> Result<(), Erc20Error> {
        self.erc20.burn(account, amount)
    }

    pub fn balance_of_burn(&self, address: Address) -> Result<U256, Erc20Error> {
        Ok(self.erc20.balances.get(address))
    }
}

MyToken is the concreate contract impl that extends Erc20 and Erc20Burnable

sol_storage! {
    #[entrypoint]
    pub struct MyToken {
        #[borrow]
        Erc20<MyTokenParams> erc20;
        #[borrow]
        Erc20Burnable erc20_burnable;
    }
}

#[external]
#[inherit(Erc20<MyTokenParams>, Erc20Burnable)]
impl MyToken {

    pub fn mint(&mut self, account: Address, amount: U256) -> Result<(), Erc20Error> {
        self.erc20.mint(account, amount)
    }

    pub fn balance_of_burn_erc(&self, address: Address) -> Result<U256, Erc20Error> {
        self.erc20_burnable.balance_of_burn(address)
    }

    pub fn balance_of_direct(&self, address: Address) -> Result<U256, Erc20Error> {
        Ok(self.erc20.balances.get(address))
    }
}

Issue

After minting tokens with MyToken::mint(..) when trying to access balances from Erc20Burnable methods instead of actual value the call returns 0. It looks like it can not access right storage. Contract code is called correctly (I checked with throwing errors inside the Erc20 methods) but storage is not accessed in proper way.

simplified code (I'm using ether-rs but full test will take a lot of lines)

// balance taken with Erc20 balance_of method
let alice_balance = token.balance_of_burn(alice_address).call().await.unwrap();

// balance taken with call to Erc20Burnable method 
let alice_balance_burn = token.balance_of_burn(alice_address).call().await.unwrap();

// balance taken from MyToken method calling Erc20Burnable method
let alice_balance_of_burn_erc = token.balance_of_burn_erc(alice_address).call().await.unwrap();

// balance taken from MyToken method directly reading Erc20 blances mapping
let alice_balance_of_direct = token.balance_of_direct(alice_address).call().await.unwrap();

All methods being called on Erc20Burnable (value of alice_balance_burn, alice_balance_of_burn_erc) are returning 0

@gwalen gwalen changed the title Storage access issues with mutilevel inheritance Storage access issues with multi-level inheritance Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant