1

can someone explain me why can't i call Kill contract from Helper contract if i set modifier and constructor to owner == msg.sender in Kill contract ? When i try to call from Helper its reverting and saying im not the owner even though i call from owner address. When i call directly from Kill contract with the same address it's perfectly fine.

Code below:

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

contract Kill {

    address public owner;

    modifier onlyOwner() {
        require(owner == msg.sender, "You are not the owner");
        _;
    }

    constructor(address _owner) {
        owner = _owner;
    }
    
    function kill() external onlyOwner {
        selfdestruct(payable(msg.sender));
    }

    function testCall() external pure returns (uint) {
        return 123;
    }

    function getBalance() public onlyOwner view returns (uint) {
        return address(this).balance;
    }
}

contract Helper {

    address public owner;

    mapping(address => Kill) public _counters;

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }

    function kill() external {
        Kill(_counters[msg.sender]).kill();
    }

    function newCampaign() public {
    _counters[msg.sender] = new Kill(msg.sender);
}
}

1 Answer 1

5

Because, in the context of the Kill contract, the msg.sender is the Helper contract.

The tx.orign is and always be your address, but in your case you are calling Helper, and Helper is calling Kill. So kill checks that the msg.sender (i.e. Helper's address) is the same as the owner's address (i.e. your address) and revert everytime since they are not the same addresses.

That's also why your call works when you call Kill directly.

Edit: After discussion in the comments with Kapitankot, the code looks like this

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

contract Kill {

    address public owner;
    address public helper;

    modifier onlyOwner() {
        require(owner == msg.sender || helper == msg.sender, "You are not the owner");
        _;
    }

    constructor(address _owner) {
        owner = _owner;
        helper = tx.origin;
    }
    
    function kill() external onlyOwner {
        selfdestruct(payable(msg.sender));
    }

    function testCall() external pure returns (uint) {
        return 123;
    }

    function getBalance() public onlyOwner view returns (uint) {
        return address(this).balance;
    }
}

contract Helper {

    address public owner;

    mapping(address => Kill) public _counters;

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }

    function kill() external {
        Kill(_counters[msg.sender]).kill();
    }

    function newCampaign() public {
        _counters[msg.sender] = new Kill(address(this));
    }
}

that way the helper contract and the owner can kill the Kill contract. P.s. Do be careful of the fact that anybody can call the kill() function in helper contract

13
  • Olivier thank you for answer! So the only way is to set owner == tx.origin ?
    – kapitankot
    Nov 20, 2022 at 0:55
  • Or set the owner as the address of helper. Glad I could help! If you could mark my answer as valid or upvote it that would be great! Nov 20, 2022 at 1:16
  • Basically what i want to achieve is to make Helper contract to create new Kill contract and assign msg.sender to both. If you dont mind to check it, i have edited my code above. Thanks
    – kapitankot
    Nov 20, 2022 at 1:28
  • Given your edit, since you are creating a new kill contract with the msg.sender argument, the owner of Kill will be the wallet address, so the owner check in Kill (i.e. msg.sender == owner) will still fail. You could use "address(this)" as argument in the newCampaign() function, like this: "_counters[msg.sender] = new Kill(address(this));" That way, you can kill Kill from Helper Nov 20, 2022 at 1:59
  • Just checked: _counters[msg.sender] = new Kill(address(this));, and still when i try to call kill from Helper it says that Im not the owner .. do i need to change modifier ? Thanks
    – kapitankot
    Nov 20, 2022 at 10:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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