use-ink / ink

Polkadot's ink! to write smart contracts.

Home Page:https://use.ink

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Linter: Warn when conditional behavior depends on contract's balance

cmichi opened this issue · comments

We should add a lint that checks if the contract's balance (env().balance()) is used in a comparison. Such usage is an anti-pattern for smart contract development, as there's no way of preventing anyone from sending value to the contract, thus possibly invalidating the check.

Possibly it makes sense to only lint for equality operations ==.

It makes sense to use it with any comparison operations.

@SkymanOne Not really. The point is that the conditions with strict balance equality could be used to perform an attack, when the attacker forcefully sends some funds using self.env().terminate_contract(target).

For example, in the following contract:

#[ink::contract]
pub mod target {
  // ...
  #[ink(message)]
  pub fn do_something(&mut self) {
      if self.env().balance() != 100 { // Bad: Strict balance equality
          // ... some logic
      }
  }
}

There is a condition with strict balance equality, which could be manipulated by the attacker using the following contract:

#[ink::contract]
pub mod attacker {
  // ...
  #[ink(message)]
  pub fn attack(&mut self, target: &AccountId) {
      self.env().terminate_contract(target);
  }
}

Therefore, introducing non-strict equality comparison with the balance (>, <, >=, <=) will fix that problem in the most cases. For example, if a balance is used as some threshold, it will be safer to use < instead of strict equality.