abstract contract MinimalBeaconProxy is Proxy {

    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

    /**
     * @dev Sets the `beacon` for this contract.
     */
    constructor(address beacon) {
        assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1));
        _setBeacon(beacon);
    }

    /**
     * @dev Returns the `implementation` stored at the beacon.
     */
    function _implementation() internal view virtual override returns (address) {
        return IBeacon(_getBeacon()).implementation();
    }

    /**
     * @dev Returns the `beacon` for beacon proxy pattern.
     */
    function _getBeacon() internal view returns (address) {
        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
    }

    /**
     * @dev Sets the new beacon `newBeacon`.
     */
    function _setBeacon(address newBeacon) internal {
        require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
    }
}
function _implementation() internal view virtual override returns (address) {
    return IBeacon(_getBeacon()).implementation();
}

/**
 * @dev Returns the `implementation` stored at the beacon.
 */