Find Vulnerabilityūüźě In Smart-Contract | Unexpected Ether

Hack a game smart contract and learn its measures

photo credit: Stillness InMotion

A typical defensive programming technique that is valuable in enforcing correct state transitions or validating operations is invariant checking. This method involves defining a set of invariants (metrics or parameters that do not need to be changed) and checking that they do not change after one (or more) operations. An example of an invariant is totalSupply a fixed-issuance ERC20 token. Because no function should change this invariant.

1. Self-destruct

Each contract will be able to perform selfdestruct function that removes all bytecode from the contract address and sends all ether stored there to the address specified by the parameter. If the specified address is also a contract, no functions (including the fallback) get called. Therefore, the selfdestruct function can be forced to send ether to any contract regardless of any code that may exist in the contract, even contracts without payable functions. This means an attacker can create a contract with a selfdestruct function, send ether to it, call selfdestruct(target) and force ether to be sent to a target contract.

2. Pre-sent ether

Another way to get ether into a contract is to preload the contract address with ether. Contract addresses are deterministic ‚ÄĒ in fact, the address is calculated from the Keccak-256 (similar to SHA-3) hash of the address creating the contract and the transaction nonce that creates the contract. Specifically, it is of the form:

address = sha3(rlp.encode([account_address,transaction_nonce]))

This sort of vulnerability often arises due to misuse of this.balance. Contract logic, when possible, should prevent relying on exact values ‚Äč‚Äčof the balance of the contract because it can be artificially manipulated. If applying logic based on this.balanceyou will have to deal with unexpected balances.

Leave a Comment