Invariants & Error Handling Discussion

Welcome to the discussion thread about this lecture section. Here you can feel free to discuss the topic at hand and ask questions.

1 Like

Would an assertion have prevented some of the big hacks like the DAO hack? There are many checks you can build into the code, but this code can quickly become larger than the code that actually does the work. It’s kinda like building unit tests into the production code.

For the DAO hack you could check that the contract balance was only reduced by the amount being withdrawn for the split, but this would require extra code to store the old balance and calculate approximately what the new balance should be (the gas cost makes this tricky). Is that too much work and why it may not have been done?

The underflow attack in the batchTransfer method of Beauty coin could have been reverted with something more simple like:

assert(balances[msg.sender] < oldBalance)

This would have caught that nothing was deducted from the sender (because the amount under flowed to zero).

I like the idea of invariants, but how often do they get used in practice and have they actually prevented a disaster?

In the code, do you know why the invariant is:
assert(address(this).balance >= totalSupply);

Why is it balance instead of balanceOf?:

assert(address(this).balanceOf >= totalSupply);

pragma solidity 0.5.12;

contract Token{

mapping(address => uint) public balanceOf;

uint public totalSupply;

function deposit() public payable{
    balanceOf[msg.sender] += msg.value;
    totalSupply += msg.value;
    assert(address(this).balance >= totalSupply);
    assert(balanceOf[msg.sender] >= msg.value);
}

}

Hi @andersbraath1
address(this).balance is a global variable available in every contract, it shows the contract balance.
balanceOf is a mapping created by the user, address(this).balance is automatically created when initializing a smart contract

1 Like