Hacks Demonstrated and Explained Discussion

Feel free to ask questions or discuss below!

It’s instructive to replicate the DAO hack, thanks for the example.

One critical concept that I overlooked is the fact that the Attacker contract has to have a balance in the DAO contract which is accomplished by using the Attacker.payMe() function call when setting things up. It would’ve been more clear to me to name it say Attacker.contribute() to reiterate that the attacker contract is obtaining a balance in the DAO with it’s address so it can successfully pull off the hack.

On the DAO hacks section I didn’t know if you were going to include the code, like I’ve seen Filip do, so I started coding the contract from scratch as you did and that was educational on it’s own. I made a couple mistakes, one was not including payable on the anonymous function of the Attacker contract which was the hardest to trouble shoot, but it a learning experience to make it work like it should.

Great demonstration of DAO hack, thank you!

What is going in my mind is what basically happen if sending of Ether somehow fails
but balance was already set to 0. Does in this case contract trying to retrieve Ether is left without money,
because balance was set to 0, but transaction has failed?

I’m trying to create this case, but I can’t find the way to make transaction fail,
but surely in real world scenario this can happen.

RE: library freeze attack

One thing that wasn’t discussed is how the contract using the library could have protected itself from this vulnerability. Drawing from what Filip talked about in the last section, instead of hard coding the library address you could use the Proxy pattern.

I fiddled around with this concept a bit, but it seems the proxy pattern is a bit more complicated than the following- which complies but fails when the function is called. I’m guessing it doesn’t like redefining the lib variable.

// constructor
function Fundraiser(address libAddress) {
        lib = Library(libAddress);

// allow the owner to point the library to a different address if needed
function initLibrary(address addr) onlyOwner {
        lib = Library(addr);

An internet search for articles on the proxy pattern revealed something rather complicated using ‘delegatecall’:

1 Like

@ivan The solution you give to prevent the hack is missing one little thing:
You reset the balance of the sender from the mapping without storing it into a local variable, and therefore will then send 0 wei to the sender, even if his balance wasnt 0, because you are accessing the mapping after setting its value to 0.


Correct, just noticed that as well when I saw the video

1 Like

I was wondering how to withdraw funds from the Fundraiser using the other addresses? I get error when trying to withdraw. How to withdraw inital deposit for each address?

I think the contract reverts if it fails so that the balance reverts to the previous balance not zero… I haven’t looked at the code, but I think that’s how that works.

1 Like

How I am able to prevent the parity hack? Just use a constructor with setting adress owner=msg.sender ? This would be enough or?

In the parity hack the initialize function was the problem so without checking if the owner is calling this function you will still have an issue.

You should
initializing the library.
Creating a boolean to check if the init function has already been called or making it only accessible by the owner of the contract.
Making the init function internal.
or not creating a kill() function for a library were two ways to avoid this ““hack”” ^^

1 Like

Agree I think the video should be slightly updated to show correct way how to fix the hack @ivan @filip @gabba

Otherwise great job with the demonstration!

1 Like

Yes you are right we should do something for it, thank you for the feedback @Filipo24

1 Like

I noticed this as well. Apparently, the solution in the video is still flawed today.

As others have noted. The video “DAO Hack - Replicating the Vulnerability Part 2” correctly shows the attack, but the solution provided is incorrect since you are setting balances[msg.sender]=0 and then you send the value of balances[msg.sender which you have just made 0. :nerd_face:


balances[msg.sender] = 0;


uint balanceAmount = balances[msg.sender];
balances[msg.sender] = 0;