1

I am currently try to write two smart contracts. Here is the first one:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Token {
    mapping(address => uint) public userBalances;

    function buy() public payable {
        require(msg.value > 0, "Not enough coins sent");
        userBalances[msg.sender] += msg.value;
    }

    function withdrawBalance() public {
        uint amountToWithdraw = userBalances[msg.sender];
        // contains reentrancy attack vector here
        (bool success, ) = msg.sender.call{value: amountToWithdraw}("");
        require(success);
        userBalances[msg.sender] = 0;
    }
}

and here the second one:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

import "./Token.sol";

contract Attacker {
    Token public tokenContract;

    constructor(Token tokenContract) {
        tokenContract = tokenContract;
    }

    function buy() public payable {
        tokenContract.buy{ value: msg.value }();
    }
}

The attacker contract should forward the Ether in order to buy some tokens. Yet, I have a problem when calling the buy function of the attacker contract.

That's the error message I get in remix.

transact to Attacker.buy 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 am not sure what is wrong here. Anyone any idea?

0

1 Answer 1

1

I tell you what is wrong: the dev in front of the screen (facepalm)

The parameter in the constructor of the attacker contract uses tokenContract as name. This shadows the state variable, which leads to the problem. Here the corrected code:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

import "./Token.sol";

contract Attacker {
    Token public tokenContract;

    constructor(Token _token) {
        tokenContract = _token;
    }

    function buy() public payable {
        tokenContract.buy{ value: msg.value }();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.