0

I am currently taking a course in Solidity and we get presented with weekly challenges that we should try to solve. This time the general topic is SafeMath and the challenge looks the following:

contract HopAndMaltOracle{
    // Contract oracle
    address public oracle;

   modifier onlyOracle(){
        require(msg.sender == oracle);
       _;
    }
    uint public maltMarketCap;
    uint public hopMarketCap;

    // Callback function
    event MaltMarketCapChanged();
    event HopMarketCapChanged();

    constructor(uint _maltCap, uint _hopCap) public payable {
        oracle = msg.sender;
        maltMarketCap = _maltCap;
        hopMarketCap = _hopCap;
        emit MaltMarketCapChanged();
        emit HopMarketCapChanged();
    }

    function updateMaltMarketCap(uint _cap) public onlyOracle {
        maltMarketCap = _cap;
        emit MaltMarketCapChanged();
    }

    function updateHopMarketCap(uint _cap) public onlyOracle {
        hopMarketCap = _cap;
        emit HopMarketCapChanged();
    }

    function IDidIt() public{
        require(address(this).balance % 2 == 1);
        msg.sender.transfer(address(this).balance);
    }
}

The goal is to reduce the balance of the contract to 0 (by somehow calling IDidIt()). Now looking at the contract it seems to me like none of the methods can be invoked since all of them are either using the onlyOracle modifier or are the constructor (except for IDidIt() ).

My idea would be to send Ether to the contract in order to increase the balance to something that would satisfy

require(address(this).balance % 2 == 1);

but I can't find a way to do so since the fallback function is not acceppting my payments (tried with:

eth.sendTransaction({from:myAddress,to:contractAddress,value:1});

The starting balance of the contract is 2 Ether. I am not asking for a solution, but a nudge in the right direction would definitely help :)

1
  • Maybe you can create another contract, which will call this contract to transfer 1 wei to itself, and in between the "send" and "receive", call IDidIt. Commented May 7, 2018 at 11:49

3 Answers 3

0

The constructor is payable. The oracle stores the address of the deployer

5
  • yes, but we get access to an already instantiated version of the contract. So in my case i can access the instance, where the oracle has already been set to the professors address. I don't think it matters, but the values for maltMarketCap and hopMarketCap are also already set to 387763615 and 893425871 respectively
    – Stefan
    Commented May 7, 2018 at 10:12
  • maybe the oracle address is another contract
    – user38075
    Commented May 7, 2018 at 10:32
  • I did it, but I can't say you how. Let me know when you are ready for the next hint
    – user38075
    Commented May 7, 2018 at 10:51
  • I checked the oracle address, and it is the address of the professor (like with other challenges). I am drawing on a blank, can you give me that hint?
    – Stefan
    Commented May 7, 2018 at 11:31
  • I thought it was impossible
    – user38075
    Commented May 7, 2018 at 13:35
0

It turned out there are some ways to force Ether on a contract without having to directly send it through fallback or other functions, these are:

  • transfer to a contract named as the receiver of a mining reward by a coinbase transaction
  • transfer to a contract if it is the destination of a selfdestruct command
  • if Ether was sent to the address of the contract before it was deployed

The second option turned out to be the correct one for this exercise. I created a contract with a payable method, deposited 1 Wei on it and then called suicide(challengeContractAddress), which transfered the balance of 1 Wei to the challenge contract and allowed me to call IDidIt().

Thanks to everyone for helping!

-1

Firstly, why do you have your constructor as payable ? You don't even store the msg.value.

Secondly, you should have your fallback function as payable if you want to send it an ether value.

2
  • I did not define the contract. The contract is given by the challenge and I can access an instance of it. My task is to "hack it" in order to pay out its balance to me.
    – Stefan
    Commented May 7, 2018 at 11:27
  • Right. You cannot edit the contract in any way?
    – amportugal
    Commented May 7, 2018 at 12:33

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.