1. 문제

gatekepper(문지기)를 통과하고 entrant(참가자)로 등록하라
pragma solidity ^0.8.0;

contract GatekeeperOne {
    address public entrant;

    modifier gateOne() {
        require(msg.sender != tx.origin);
        _;
    }

    modifier gateTwo() {
        require(gasleft() % 8191 == 0);
        _;
    }

    modifier gateThree(bytes8 _gateKey) {
        require(uint32(uint64(_gateKey)) == uint16(uint64(_gateKey)), "GatekeeperOne: invalid gateThree part one");
        require(uint32(uint64(_gateKey)) != uint64(_gateKey), "GatekeeperOne: invalid gateThree part two");
        require(uint32(uint64(_gateKey)) == uint16(uint160(tx.origin)), "GatekeeperOne: invalid gateThree part three");
        _;
    }

    function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) {
        entrant = tx.origin;
        return true;
    }
}

2. 코드 분석

총 3가지 gate를 뚫어야 해당 문제를 통과할 수 있다

gateOne()

modifier gateOne() {
    require(msg.sender != tx.origin);
    _;
}

이거는 contract 하나 만들어서 배포하면 풀리는 문제 아래에서 풀었던 문제당~

https://www.notion.so/4-Telephone-22571d824ff28069aee9e3337b38dbc9?source=copy_link

gateTwo()

modifier gateTwo() {
    require(gasleft() % 8191 == 0);
    _;
}

해당 로직을 호출했을 때 남은 가스비가 8191의 배수이면 통과하는 로직

8191의 배수로 brute force 돌려서 ㄱㄱㄱ

gateThree()

modifier gateThree(bytes8 _gateKey) {
    require(uint32(uint64(_gateKey)) == uint16(uint64(_gateKey)), "GatekeeperOne: invalid gateThree part one");
    require(uint32(uint64(_gateKey)) != uint64(_gateKey), "GatekeeperOne: invalid gateThree part two");
    require(uint32(uint64(_gateKey)) == uint16(uint160(tx.origin)), "GatekeeperOne: invalid gateThree part three");
    _;
}