Contract 0xfa06Db0587bc2876A8FbFF964F04d8b37A8a345C

Contract Overview

Balance:
0 MATIC
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x25a253ff71d72a17fac11ebff7481448cae17311997e8fef0015b58e85280c3cSet Manager293915922022-11-29 2:44:48180 days 19 hrs ago0x3a791e828fdd420fbe16416efdf509e4b9088dd4 IN  0xfa06db0587bc2876a8fbff964f04d8b37a8a345c0 MATIC0.001441698428 30.118209
0x1cb733ddaf4d018111140675f49727ed8ddf782ff18f5c4b2cf92fa94003ee410x60806040293915492022-11-29 2:41:12180 days 19 hrs ago0x3a791e828fdd420fbe16416efdf509e4b9088dd4 IN  Contract Creation0 MATIC0.044734437001 33.000000001
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x91493d48136b251e125a02a7e2a9AE1ab4A553C3

Contract Name:
DrawBuffer

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion
File 1 of 8 : DrawBuffer.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

import "@pooltogether/owner-manager-contracts/contracts/Manageable.sol";

import "./interfaces/IDrawBuffer.sol";
import "./interfaces/IDrawBeacon.sol";
import "./libraries/DrawRingBufferLib.sol";

/**
  * @title  PoolTogether V4 DrawBuffer
  * @author PoolTogether Inc Team
  * @notice The DrawBuffer provides historical lookups of Draws via a circular ring buffer.
            Historical Draws can be accessed on-chain using a drawId to calculate ring buffer storage slot.
            The Draw settings can be created by manager/owner and existing Draws can only be updated the owner.
            Once a starting Draw has been added to the ring buffer, all following draws must have a sequential Draw ID.
    @dev    A DrawBuffer store a limited number of Draws before beginning to overwrite (managed via the cardinality) previous Draws.
    @dev    All mainnet DrawBuffer(s) are updated directly from a DrawBeacon, but non-mainnet DrawBuffer(s) (Matic, Optimism, Arbitrum, etc...)
            will receive a cross-chain message, duplicating the mainnet Draw configuration - enabling a prize savings liquidity network.
*/
contract DrawBuffer is IDrawBuffer, Manageable {
    using DrawRingBufferLib for DrawRingBufferLib.Buffer;

    /// @notice Draws ring buffer max length.
    uint16 public constant MAX_CARDINALITY = 256;

    /// @notice Draws ring buffer array.
    IDrawBeacon.Draw[MAX_CARDINALITY] private drawRingBuffer;

    /// @notice Holds ring buffer information
    DrawRingBufferLib.Buffer internal bufferMetadata;

    /* ============ Deploy ============ */

    /**
     * @notice Deploy DrawBuffer smart contract.
     * @param _owner Address of the owner of the DrawBuffer.
     * @param _cardinality Draw ring buffer cardinality.
     */
    constructor(address _owner, uint8 _cardinality) Ownable(_owner) {
        bufferMetadata.cardinality = _cardinality;
    }

    /* ============ External Functions ============ */

    /// @inheritdoc IDrawBuffer
    function getBufferCardinality() external view override returns (uint32) {
        return bufferMetadata.cardinality;
    }

    /// @inheritdoc IDrawBuffer
    function getDraw(uint32 drawId) external view override returns (IDrawBeacon.Draw memory) {
        return drawRingBuffer[_drawIdToDrawIndex(bufferMetadata, drawId)];
    }

    /// @inheritdoc IDrawBuffer
    function getDraws(uint32[] calldata _drawIds)
        external
        view
        override
        returns (IDrawBeacon.Draw[] memory)
    {
        IDrawBeacon.Draw[] memory draws = new IDrawBeacon.Draw[](_drawIds.length);
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;

        for (uint256 index = 0; index < _drawIds.length; index++) {
            draws[index] = drawRingBuffer[_drawIdToDrawIndex(buffer, _drawIds[index])];
        }

        return draws;
    }

    /// @inheritdoc IDrawBuffer
    function getDrawCount() external view override returns (uint32) {
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;

        if (buffer.lastDrawId == 0) {
            return 0;
        }

        uint32 bufferNextIndex = buffer.nextIndex;

        if (drawRingBuffer[bufferNextIndex].timestamp != 0) {
            return buffer.cardinality;
        } else {
            return bufferNextIndex;
        }
    }

    /// @inheritdoc IDrawBuffer
    function getNewestDraw() external view override returns (IDrawBeacon.Draw memory) {
        return _getNewestDraw(bufferMetadata);
    }

    /// @inheritdoc IDrawBuffer
    function getOldestDraw() external view override returns (IDrawBeacon.Draw memory) {
        // oldest draw should be next available index, otherwise it's at 0
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;
        IDrawBeacon.Draw memory draw = drawRingBuffer[buffer.nextIndex];

        if (draw.timestamp == 0) {
            // if draw is not init, then use draw at 0
            draw = drawRingBuffer[0];
        }

        return draw;
    }

    /// @inheritdoc IDrawBuffer
    function pushDraw(IDrawBeacon.Draw memory _draw)
        external
        override
        onlyManagerOrOwner
        returns (uint32)
    {
        return _pushDraw(_draw);
    }

    /// @inheritdoc IDrawBuffer
    function setDraw(IDrawBeacon.Draw memory _newDraw) external override onlyOwner returns (uint32) {
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;
        uint32 index = buffer.getIndex(_newDraw.drawId);
        drawRingBuffer[index] = _newDraw;
        emit DrawSet(_newDraw.drawId, _newDraw);
        return _newDraw.drawId;
    }

    /* ============ Internal Functions ============ */

    /**
     * @notice Convert a Draw.drawId to a Draws ring buffer index pointer.
     * @dev    The getNewestDraw.drawId() is used to calculate a Draws ID delta position.
     * @param _drawId Draw.drawId
     * @return Draws ring buffer index pointer
     */
    function _drawIdToDrawIndex(DrawRingBufferLib.Buffer memory _buffer, uint32 _drawId)
        internal
        pure
        returns (uint32)
    {
        return _buffer.getIndex(_drawId);
    }

    /**
     * @notice Read newest Draw from the draws ring buffer.
     * @dev    Uses the lastDrawId to calculate the most recently added Draw.
     * @param _buffer Draw ring buffer
     * @return IDrawBeacon.Draw
     */
    function _getNewestDraw(DrawRingBufferLib.Buffer memory _buffer)
        internal
        view
        returns (IDrawBeacon.Draw memory)
    {
        return drawRingBuffer[_buffer.getIndex(_buffer.lastDrawId)];
    }

    /**
     * @notice Push Draw onto draws ring buffer history.
     * @dev    Push new draw onto draws list via authorized manager or owner.
     * @param _newDraw IDrawBeacon.Draw
     * @return Draw.drawId
     */
    function _pushDraw(IDrawBeacon.Draw memory _newDraw) internal returns (uint32) {
        DrawRingBufferLib.Buffer memory _buffer = bufferMetadata;
        drawRingBuffer[_buffer.nextIndex] = _newDraw;
        bufferMetadata = _buffer.push(_newDraw.drawId);

        emit DrawSet(_newDraw.drawId, _newDraw);

        return _newDraw.drawId;
    }
}

File 2 of 8 : Manageable.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

import "./Ownable.sol";

/**
 * @title Abstract manageable contract that can be inherited by other contracts
 * @notice Contract module based on Ownable which provides a basic access control mechanism, where
 * there is an owner and a manager that can be granted exclusive access to specific functions.
 *
 * By default, the owner is the deployer of the contract.
 *
 * The owner account is set through a two steps process.
 *      1. The current `owner` calls {transferOwnership} to set a `pendingOwner`
 *      2. The `pendingOwner` calls {acceptOwnership} to accept the ownership transfer
 *
 * The manager account needs to be set using {setManager}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyManager`, which can be applied to your functions to restrict their use to
 * the manager.
 */
abstract contract Manageable is Ownable {
    address private _manager;

    /**
     * @dev Emitted when `_manager` has been changed.
     * @param previousManager previous `_manager` address.
     * @param newManager new `_manager` address.
     */
    event ManagerTransferred(address indexed previousManager, address indexed newManager);

    /* ============ External Functions ============ */

    /**
     * @notice Gets current `_manager`.
     * @return Current `_manager` address.
     */
    function manager() public view virtual returns (address) {
        return _manager;
    }

    /**
     * @notice Set or change of manager.
     * @dev Throws if called by any account other than the owner.
     * @param _newManager New _manager address.
     * @return Boolean to indicate if the operation was successful or not.
     */
    function setManager(address _newManager) external onlyOwner returns (bool) {
        return _setManager(_newManager);
    }

    /* ============ Internal Functions ============ */

    /**
     * @notice Set or change of manager.
     * @param _newManager New _manager address.
     * @return Boolean to indicate if the operation was successful or not.
     */
    function _setManager(address _newManager) private returns (bool) {
        address _previousManager = _manager;

        require(_newManager != _previousManager, "Manageable/existing-manager-address");

        _manager = _newManager;

        emit ManagerTransferred(_previousManager, _newManager);
        return true;
    }

    /* ============ Modifier Functions ============ */

    /**
     * @dev Throws if called by any account other than the manager.
     */
    modifier onlyManager() {
        require(manager() == msg.sender, "Manageable/caller-not-manager");
        _;
    }

    /**
     * @dev Throws if called by any account other than the manager or the owner.
     */
    modifier onlyManagerOrOwner() {
        require(manager() == msg.sender || owner() == msg.sender, "Manageable/caller-not-manager-or-owner");
        _;
    }
}

File 3 of 8 : IDrawBuffer.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

import "../interfaces/IDrawBeacon.sol";

/** @title  IDrawBuffer
  * @author PoolTogether Inc Team
  * @notice The DrawBuffer interface.
*/
interface IDrawBuffer {
    /**
     * @notice Emit when a new draw has been created.
     * @param drawId Draw id
     * @param draw The Draw struct
     */
    event DrawSet(uint32 indexed drawId, IDrawBeacon.Draw draw);

    /**
     * @notice Read a ring buffer cardinality
     * @return Ring buffer cardinality
     */
    function getBufferCardinality() external view returns (uint32);

    /**
     * @notice Read a Draw from the draws ring buffer.
     * @dev    Read a Draw using the Draw.drawId to calculate position in the draws ring buffer.
     * @param drawId Draw.drawId
     * @return IDrawBeacon.Draw
     */
    function getDraw(uint32 drawId) external view returns (IDrawBeacon.Draw memory);

    /**
     * @notice Read multiple Draws from the draws ring buffer.
     * @dev    Read multiple Draws using each drawId to calculate position in the draws ring buffer.
     * @param drawIds Array of drawIds
     * @return IDrawBeacon.Draw[]
     */
    function getDraws(uint32[] calldata drawIds) external view returns (IDrawBeacon.Draw[] memory);

    /**
     * @notice Gets the number of Draws held in the draw ring buffer.
     * @dev If no Draws have been pushed, it will return 0.
     * @dev If the ring buffer is full, it will return the cardinality.
     * @dev Otherwise, it will return the NewestDraw index + 1.
     * @return Number of Draws held in the draw ring buffer.
     */
    function getDrawCount() external view returns (uint32);

    /**
     * @notice Read newest Draw from draws ring buffer.
     * @dev    Uses the nextDrawIndex to calculate the most recently added Draw.
     * @return IDrawBeacon.Draw
     */
    function getNewestDraw() external view returns (IDrawBeacon.Draw memory);

    /**
     * @notice Read oldest Draw from draws ring buffer.
     * @dev    Finds the oldest Draw by comparing and/or diffing totalDraws with the cardinality.
     * @return IDrawBeacon.Draw
     */
    function getOldestDraw() external view returns (IDrawBeacon.Draw memory);

    /**
     * @notice Push Draw onto draws ring buffer history.
     * @dev    Push new draw onto draws history via authorized manager or owner.
     * @param draw IDrawBeacon.Draw
     * @return Draw.drawId
     */
    function pushDraw(IDrawBeacon.Draw calldata draw) external returns (uint32);

    /**
     * @notice Set existing Draw in draws ring buffer with new parameters.
     * @dev    Updating a Draw should be used sparingly and only in the event an incorrect Draw parameter has been stored.
     * @param newDraw IDrawBeacon.Draw
     * @return Draw.drawId
     */
    function setDraw(IDrawBeacon.Draw calldata newDraw) external returns (uint32);
}

File 4 of 8 : IDrawBeacon.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

import "@pooltogether/pooltogether-rng-contracts/contracts/RNGInterface.sol";
import "./IDrawBuffer.sol";

/** @title  IDrawBeacon
  * @author PoolTogether Inc Team
  * @notice The DrawBeacon interface.
*/
interface IDrawBeacon {

    /// @notice Draw struct created every draw
    /// @param winningRandomNumber The random number returned from the RNG service
    /// @param drawId The monotonically increasing drawId for each draw
    /// @param timestamp Unix timestamp of the draw. Recorded when the draw is created by the DrawBeacon.
    /// @param beaconPeriodStartedAt Unix timestamp of when the draw started
    /// @param beaconPeriodSeconds Unix timestamp of the beacon draw period for this draw.
    struct Draw {
        uint256 winningRandomNumber;
        uint32 drawId;
        uint64 timestamp;
        uint64 beaconPeriodStartedAt;
        uint32 beaconPeriodSeconds;
    }

    /**
     * @notice Emit when a new DrawBuffer has been set.
     * @param newDrawBuffer       The new DrawBuffer address
     */
    event DrawBufferUpdated(IDrawBuffer indexed newDrawBuffer);

    /**
     * @notice Emit when a draw has opened.
     * @param startedAt Start timestamp
     */
    event BeaconPeriodStarted(uint64 indexed startedAt);

    /**
     * @notice Emit when a draw has started.
     * @param rngRequestId  draw id
     * @param rngLockBlock  Block when draw becomes invalid
     */
    event DrawStarted(uint32 indexed rngRequestId, uint32 rngLockBlock);

    /**
     * @notice Emit when a draw has been cancelled.
     * @param rngRequestId  draw id
     * @param rngLockBlock  Block when draw becomes invalid
     */
    event DrawCancelled(uint32 indexed rngRequestId, uint32 rngLockBlock);

    /**
     * @notice Emit when a draw has been completed.
     * @param randomNumber  Random number generated from draw
     */
    event DrawCompleted(uint256 randomNumber);

    /**
     * @notice Emit when a RNG service address is set.
     * @param rngService  RNG service address
     */
    event RngServiceUpdated(RNGInterface indexed rngService);

    /**
     * @notice Emit when a draw timeout param is set.
     * @param rngTimeout  draw timeout param in seconds
     */
    event RngTimeoutSet(uint32 rngTimeout);

    /**
     * @notice Emit when the drawPeriodSeconds is set.
     * @param drawPeriodSeconds Time between draw
     */
    event BeaconPeriodSecondsUpdated(uint32 drawPeriodSeconds);

    /**
     * @notice Returns the number of seconds remaining until the beacon period can be complete.
     * @return The number of seconds remaining until the beacon period can be complete.
     */
    function beaconPeriodRemainingSeconds() external view returns (uint64);

    /**
     * @notice Returns the timestamp at which the beacon period ends
     * @return The timestamp at which the beacon period ends.
     */
    function beaconPeriodEndAt() external view returns (uint64);

    /**
     * @notice Returns whether a Draw can be started.
     * @return True if a Draw can be started, false otherwise.
     */
    function canStartDraw() external view returns (bool);

    /**
     * @notice Returns whether a Draw can be completed.
     * @return True if a Draw can be completed, false otherwise.
     */
    function canCompleteDraw() external view returns (bool);

    /**
     * @notice Calculates when the next beacon period will start.
     * @param time The timestamp to use as the current time
     * @return The timestamp at which the next beacon period would start
     */
    function calculateNextBeaconPeriodStartTime(uint64 time) external view returns (uint64);

    /**
     * @notice Can be called by anyone to cancel the draw request if the RNG has timed out.
     */
    function cancelDraw() external;

    /**
     * @notice Completes the Draw (RNG) request and pushes a Draw onto DrawBuffer.
     */
    function completeDraw() external;

    /**
     * @notice Returns the block number that the current RNG request has been locked to.
     * @return The block number that the RNG request is locked to
     */
    function getLastRngLockBlock() external view returns (uint32);

    /**
     * @notice Returns the current RNG Request ID.
     * @return The current Request ID
     */
    function getLastRngRequestId() external view returns (uint32);

    /**
     * @notice Returns whether the beacon period is over
     * @return True if the beacon period is over, false otherwise
     */
    function isBeaconPeriodOver() external view returns (bool);

    /**
     * @notice Returns whether the random number request has completed.
     * @return True if a random number request has completed, false otherwise.
     */
    function isRngCompleted() external view returns (bool);

    /**
     * @notice Returns whether a random number has been requested
     * @return True if a random number has been requested, false otherwise.
     */
    function isRngRequested() external view returns (bool);

    /**
     * @notice Returns whether the random number request has timed out.
     * @return True if a random number request has timed out, false otherwise.
     */
    function isRngTimedOut() external view returns (bool);

    /**
     * @notice Allows the owner to set the beacon period in seconds.
     * @param beaconPeriodSeconds The new beacon period in seconds.  Must be greater than zero.
     */
    function setBeaconPeriodSeconds(uint32 beaconPeriodSeconds) external;

    /**
     * @notice Allows the owner to set the RNG request timeout in seconds. This is the time that must elapsed before the RNG request can be cancelled and the pool unlocked.
     * @param rngTimeout The RNG request timeout in seconds.
     */
    function setRngTimeout(uint32 rngTimeout) external;

    /**
     * @notice Sets the RNG service that the Prize Strategy is connected to
     * @param rngService The address of the new RNG service interface
     */
    function setRngService(RNGInterface rngService) external;

    /**
     * @notice Starts the Draw process by starting random number request. The previous beacon period must have ended.
     * @dev The RNG-Request-Fee is expected to be held within this contract before calling this function
     */
    function startDraw() external;

    /**
     * @notice Set global DrawBuffer variable.
     * @dev    All subsequent Draw requests/completions will be pushed to the new DrawBuffer.
     * @param newDrawBuffer DrawBuffer address
     * @return DrawBuffer
     */
    function setDrawBuffer(IDrawBuffer newDrawBuffer) external returns (IDrawBuffer);
}

File 5 of 8 : DrawRingBufferLib.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

import "./RingBufferLib.sol";

/// @title Library for creating and managing a draw ring buffer.
library DrawRingBufferLib {
    /// @notice Draw buffer struct.
    struct Buffer {
        uint32 lastDrawId;
        uint32 nextIndex;
        uint32 cardinality;
    }

    /// @notice Helper function to know if the draw ring buffer has been initialized.
    /// @dev since draws start at 1 and are monotonically increased, we know we are uninitialized if nextIndex = 0 and lastDrawId = 0.
    /// @param _buffer The buffer to check.
    function isInitialized(Buffer memory _buffer) internal pure returns (bool) {
        return !(_buffer.nextIndex == 0 && _buffer.lastDrawId == 0);
    }

    /// @notice Push a draw to the buffer.
    /// @param _buffer The buffer to push to.
    /// @param _drawId The drawID to push.
    /// @return The new buffer.
    function push(Buffer memory _buffer, uint32 _drawId) internal pure returns (Buffer memory) {
        require(!isInitialized(_buffer) || _drawId == _buffer.lastDrawId + 1, "DRB/must-be-contig");

        return
            Buffer({
                lastDrawId: _drawId,
                nextIndex: uint32(RingBufferLib.nextIndex(_buffer.nextIndex, _buffer.cardinality)),
                cardinality: _buffer.cardinality
            });
    }

    /// @notice Get draw ring buffer index pointer.
    /// @param _buffer The buffer to get the `nextIndex` from.
    /// @param _drawId The draw id to get the index for.
    /// @return The draw ring buffer index pointer.
    function getIndex(Buffer memory _buffer, uint32 _drawId) internal pure returns (uint32) {
        require(isInitialized(_buffer) && _drawId <= _buffer.lastDrawId, "DRB/future-draw");

        uint32 indexOffset = _buffer.lastDrawId - _drawId;
        require(indexOffset < _buffer.cardinality, "DRB/expired-draw");

        uint256 mostRecent = RingBufferLib.newestIndex(_buffer.nextIndex, _buffer.cardinality);

        return uint32(RingBufferLib.offset(uint32(mostRecent), indexOffset, _buffer.cardinality));
    }
}

File 6 of 8 : Ownable.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

/**
 * @title Abstract ownable contract that can be inherited by other contracts
 * @notice Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner is the deployer of the contract.
 *
 * The owner account is set through a two steps process.
 *      1. The current `owner` calls {transferOwnership} to set a `pendingOwner`
 *      2. The `pendingOwner` calls {acceptOwnership} to accept the ownership transfer
 *
 * The manager account needs to be set using {setManager}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable {
    address private _owner;
    address private _pendingOwner;

    /**
     * @dev Emitted when `_pendingOwner` has been changed.
     * @param pendingOwner new `_pendingOwner` address.
     */
    event OwnershipOffered(address indexed pendingOwner);

    /**
     * @dev Emitted when `_owner` has been changed.
     * @param previousOwner previous `_owner` address.
     * @param newOwner new `_owner` address.
     */
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /* ============ Deploy ============ */

    /**
     * @notice Initializes the contract setting `_initialOwner` as the initial owner.
     * @param _initialOwner Initial owner of the contract.
     */
    constructor(address _initialOwner) {
        _setOwner(_initialOwner);
    }

    /* ============ External Functions ============ */

    /**
     * @notice Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @notice Gets current `_pendingOwner`.
     * @return Current `_pendingOwner` address.
     */
    function pendingOwner() external view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @notice Renounce ownership of the contract.
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() external virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
    * @notice Allows current owner to set the `_pendingOwner` address.
    * @param _newOwner Address to transfer ownership to.
    */
    function transferOwnership(address _newOwner) external onlyOwner {
        require(_newOwner != address(0), "Ownable/pendingOwner-not-zero-address");

        _pendingOwner = _newOwner;

        emit OwnershipOffered(_newOwner);
    }

    /**
    * @notice Allows the `_pendingOwner` address to finalize the transfer.
    * @dev This function is only callable by the `_pendingOwner`.
    */
    function claimOwnership() external onlyPendingOwner {
        _setOwner(_pendingOwner);
        _pendingOwner = address(0);
    }

    /* ============ Internal Functions ============ */

    /**
     * @notice Internal function to set the `_owner` of the contract.
     * @param _newOwner New `_owner` address.
     */
    function _setOwner(address _newOwner) private {
        address _oldOwner = _owner;
        _owner = _newOwner;
        emit OwnershipTransferred(_oldOwner, _newOwner);
    }

    /* ============ Modifier Functions ============ */

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == msg.sender, "Ownable/caller-not-owner");
        _;
    }

    /**
    * @dev Throws if called by any account other than the `pendingOwner`.
    */
    modifier onlyPendingOwner() {
        require(msg.sender == _pendingOwner, "Ownable/caller-not-pendingOwner");
        _;
    }
}

File 7 of 8 : RNGInterface.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

/**
 * @title Random Number Generator Interface
 * @notice Provides an interface for requesting random numbers from 3rd-party RNG services (Chainlink VRF, Starkware VDF, etc..)
 */
interface RNGInterface {
  /**
   * @notice Emitted when a new request for a random number has been submitted
   * @param requestId The indexed ID of the request used to get the results of the RNG service
   * @param sender The indexed address of the sender of the request
   */
  event RandomNumberRequested(uint32 indexed requestId, address indexed sender);

  /**
   * @notice Emitted when an existing request for a random number has been completed
   * @param requestId The indexed ID of the request used to get the results of the RNG service
   * @param randomNumber The random number produced by the 3rd-party service
   */
  event RandomNumberCompleted(uint32 indexed requestId, uint256 randomNumber);

  /**
   * @notice Gets the last request id used by the RNG service
   * @return requestId The last request id used in the last request
   */
  function getLastRequestId() external view returns (uint32 requestId);

  /**
   * @notice Gets the Fee for making a Request against an RNG service
   * @return feeToken The address of the token that is used to pay fees
   * @return requestFee The fee required to be paid to make a request
   */
  function getRequestFee() external view returns (address feeToken, uint256 requestFee);

  /**
   * @notice Sends a request for a random number to the 3rd-party service
   * @dev Some services will complete the request immediately, others may have a time-delay
   * @dev Some services require payment in the form of a token, such as $LINK for Chainlink VRF
   * @return requestId The ID of the request used to get the results of the RNG service
   * @return lockBlock The block number at which the RNG service will start generating time-delayed randomness.
   * The calling contract should "lock" all activity until the result is available via the `requestId`
   */
  function requestRandomNumber() external returns (uint32 requestId, uint32 lockBlock);

  /**
   * @notice Checks if the request for randomness from the 3rd-party service has completed
   * @dev For time-delayed requests, this function is used to check/confirm completion
   * @param requestId The ID of the request used to get the results of the RNG service
   * @return isCompleted True if the request has completed and a random number is available, false otherwise
   */
  function isRequestComplete(uint32 requestId) external view returns (bool isCompleted);

  /**
   * @notice Gets the random number produced by the 3rd-party service
   * @param requestId The ID of the request used to get the results of the RNG service
   * @return randomNum The random number
   */
  function randomNumber(uint32 requestId) external returns (uint256 randomNum);
}

File 8 of 8 : RingBufferLib.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

library RingBufferLib {
    /**
    * @notice Returns wrapped TWAB index.
    * @dev  In order to navigate the TWAB circular buffer, we need to use the modulo operator.
    * @dev  For example, if `_index` is equal to 32 and the TWAB circular buffer is of `_cardinality` 32,
    *       it will return 0 and will point to the first element of the array.
    * @param _index Index used to navigate through the TWAB circular buffer.
    * @param _cardinality TWAB buffer cardinality.
    * @return TWAB index.
    */
    function wrap(uint256 _index, uint256 _cardinality) internal pure returns (uint256) {
        return _index % _cardinality;
    }

    /**
    * @notice Computes the negative offset from the given index, wrapped by the cardinality.
    * @dev  We add `_cardinality` to `_index` to be able to offset even if `_amount` is superior to `_cardinality`.
    * @param _index The index from which to offset
    * @param _amount The number of indices to offset.  This is subtracted from the given index.
    * @param _cardinality The number of elements in the ring buffer
    * @return Offsetted index.
     */
    function offset(
        uint256 _index,
        uint256 _amount,
        uint256 _cardinality
    ) internal pure returns (uint256) {
        return wrap(_index + _cardinality - _amount, _cardinality);
    }

    /// @notice Returns the index of the last recorded TWAB
    /// @param _nextIndex The next available twab index.  This will be recorded to next.
    /// @param _cardinality The cardinality of the TWAB history.
    /// @return The index of the last recorded TWAB
    function newestIndex(uint256 _nextIndex, uint256 _cardinality)
        internal
        pure
        returns (uint256)
    {
        if (_cardinality == 0) {
            return 0;
        }

        return wrap(_nextIndex + _cardinality - 1, _cardinality);
    }

    /// @notice Computes the ring buffer index that follows the given one, wrapped by cardinality
    /// @param _index The index to increment
    /// @param _cardinality The number of elements in the Ring Buffer
    /// @return The next index relative to the given index.  Will wrap around to 0 if the next index == cardinality
    function nextIndex(uint256 _index, uint256 _cardinality)
        internal
        pure
        returns (uint256)
    {
        return wrap(_index + 1, _cardinality);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 2000
  },
  "evmVersion": "berlin",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint8","name":"_cardinality","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"drawId","type":"uint32"},{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"indexed":false,"internalType":"struct IDrawBeacon.Draw","name":"draw","type":"tuple"}],"name":"DrawSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousManager","type":"address"},{"indexed":true,"internalType":"address","name":"newManager","type":"address"}],"name":"ManagerTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipOffered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"MAX_CARDINALITY","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBufferCardinality","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"drawId","type":"uint32"}],"name":"getDraw","outputs":[{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"internalType":"struct IDrawBeacon.Draw","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDrawCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_drawIds","type":"uint32[]"}],"name":"getDraws","outputs":[{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"internalType":"struct IDrawBeacon.Draw[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNewestDraw","outputs":[{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"internalType":"struct IDrawBeacon.Draw","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOldestDraw","outputs":[{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"internalType":"struct IDrawBeacon.Draw","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"internalType":"struct IDrawBeacon.Draw","name":"_draw","type":"tuple"}],"name":"pushDraw","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"winningRandomNumber","type":"uint256"},{"internalType":"uint32","name":"drawId","type":"uint32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"beaconPeriodStartedAt","type":"uint64"},{"internalType":"uint32","name":"beaconPeriodSeconds","type":"uint32"}],"internalType":"struct IDrawBeacon.Draw","name":"_newDraw","type":"tuple"}],"name":"setDraw","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newManager","type":"address"}],"name":"setManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506040516117cb3803806117cb83398101604081905261002f916100b6565b8161003981610066565b50610203805463ffffffff60401b191660ff92909216680100000000000000000291909117905550610102565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080604083850312156100c957600080fd5b82516001600160a01b03811681146100e057600080fd5b602084015190925060ff811681146100f757600080fd5b809150509250929050565b6116ba806101116000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638da5cb5b11610097578063d0ebdbe711610066578063d0ebdbe714610209578063d7bcb86b1461022c578063e30c39781461023f578063f2fde38b1461025057600080fd5b80638da5cb5b146101b5578063c4df5fed146101c6578063caeef7ec146101ce578063d0bb78f3146101e957600080fd5b8063648b1b4f116100d3578063648b1b4f14610176578063715018a61461017e5780638200d8731461018657806383c34aaf146101a257600080fd5b8063089eb925146101055780630edb1d2e14610132578063481c6a75146101475780634e71e0c81461016c575b600080fd5b6101186101133660046113ed565b610263565b60405163ffffffff90911681526020015b60405180910390f35b61013a61032e565b6040516101299190611533565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610129565b6101746103a3565b005b61013a610431565b610174610586565b61018f61010081565b60405161ffff9091168152602001610129565b61013a6101b0366004611482565b6105fb565b6000546001600160a01b0316610154565b6101186106f6565b6102035468010000000000000000900463ffffffff16610118565b6101fc6101f7366004611378565b610798565b604051610129919061149d565b61021c61021736600461134f565b610948565b6040519015158152602001610129565b61011861023a3660046113ed565b6109bc565b6001546001600160a01b0316610154565b61017461025e36600461134f565b610ba9565b6000336102786002546001600160a01b031690565b6001600160a01b031614806102a657503361029b6000546001600160a01b031690565b6001600160a01b0316145b61031d5760405162461bcd60e51b815260206004820152602660248201527f4d616e61676561626c652f63616c6c65722d6e6f742d6d616e616765722d6f7260448201527f2d6f776e6572000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61032682610ce5565b90505b919050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152604080516060810182526102035463ffffffff808216835264010000000082048116602084015268010000000000000000909104169181019190915261039e90610ee7565b905090565b6001546001600160a01b031633146103fd5760405162461bcd60e51b815260206004820152601f60248201527f4f776e61626c652f63616c6c65722d6e6f742d70656e64696e674f776e6572006044820152606401610314565b600154610412906001600160a01b0316610f22565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152604080516060810182526102035463ffffffff808216835264010000000082048116602084018190526801000000000000000090920416928201929092529060009060039061010081106104b2576104b2611658565b6040805160a08101825260029290920292909201805482526001015463ffffffff808216602084015267ffffffffffffffff640100000000830481169484018590526c010000000000000000000000008304166060840152600160a01b909104166080820152915061058057506040805160a081018252600354815260045463ffffffff808216602084015267ffffffffffffffff64010000000083048116948401949094526c0100000000000000000000000082049093166060830152600160a01b900490911660808201525b92915050565b336105996000546001600160a01b031690565b6001600160a01b0316146105ef5760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e657200000000000000006044820152606401610314565b6105f96000610f22565b565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152604080516060810182526102035463ffffffff808216835264010000000082048116602084015268010000000000000000909104169181019190915260039061066f9084610f7f565b63ffffffff16610100811061068657610686611658565b6040805160a08101825260029290920292909201805482526001015463ffffffff808216602084015267ffffffffffffffff64010000000083048116948401949094526c0100000000000000000000000082049093166060830152600160a01b9004909116608082015292915050565b604080516060810182526102035463ffffffff80821680845264010000000083048216602085015268010000000000000000909204169282019290925260009161074257600091505090565b6020810151600363ffffffff8216610100811061076157610761611658565b6002020160010160049054906101000a900467ffffffffffffffff1667ffffffffffffffff16600014610580575060400151919050565b606060008267ffffffffffffffff8111156107b5576107b561166e565b60405190808252806020026020018201604052801561080e57816020015b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282526000199092019101816107d35790505b50604080516060810182526102035463ffffffff808216835264010000000082048116602084015268010000000000000000909104169181019190915290915060005b8481101561093e57600361088b8388888581811061087157610871611658565b90506020020160208101906108869190611482565b610f7f565b63ffffffff1661010081106108a2576108a2611658565b6040805160a08101825260029290920292909201805482526001015463ffffffff808216602084015267ffffffffffffffff64010000000083048116948401949094526c0100000000000000000000000082049093166060830152600160a01b90049091166080820152835184908390811061092057610920611658565b6020026020010181905250808061093690611605565b915050610851565b5090949350505050565b60003361095d6000546001600160a01b031690565b6001600160a01b0316146109b35760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e657200000000000000006044820152606401610314565b61032682610f92565b6000336109d16000546001600160a01b031690565b6001600160a01b031614610a275760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e657200000000000000006044820152606401610314565b604080516060810182526102035463ffffffff808216835264010000000082048116602080850191909152680100000000000000009092048116938301939093528401519091600091610a7d9184919061107e16565b90508360038263ffffffff166101008110610a9a57610a9a611658565b82516002919091029190910190815560208083015160019092018054604080860151606087015160809097015163ffffffff9687166bffffffffffffffffffffffff199094169390931764010000000067ffffffffffffffff92831602177fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c0100000000000000000000000091909716027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff1695909517600160a01b9185169190910217905586015191519116907fc6f337e5507fd1bdebc6d79ed14168145e8c109d7b7139459692e24f06baed1790610b97908790611533565b60405180910390a25050506020015190565b33610bbc6000546001600160a01b031690565b6001600160a01b031614610c125760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e657200000000000000006044820152606401610314565b6001600160a01b038116610c8e5760405162461bcd60e51b815260206004820152602560248201527f4f776e61626c652f70656e64696e674f776e65722d6e6f742d7a65726f2d616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610314565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f239a2ddded15777fa246aed5f7e1a9bc69a39d4eb4a397034d1d85766cca7d4c90600090a250565b604080516060810182526102035463ffffffff8082168352640100000000820481166020840181905268010000000000000000909204169282019290925260009183906003906101008110610d3c57610d3c611658565b825160029190910291909101908155602080830151600190920180546040850151606086015160809096015163ffffffff9586166bffffffffffffffffffffffff199093169290921764010000000067ffffffffffffffff92831602177fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c0100000000000000000000000091909616027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff1694909417600160a01b948416949094029390931790925590840151610e18918391906111ae16565b8051610203805460208085015160409586015163ffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff928216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909516968216969096179390931716939093179091559085015191519116907fc6f337e5507fd1bdebc6d79ed14168145e8c109d7b7139459692e24f06baed1790610ed6908690611533565b60405180910390a250506020015190565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152815160039061066f90849061107e565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000610f8b838361107e565b9392505050565b6002546000906001600160a01b0390811690831681141561101b5760405162461bcd60e51b815260206004820152602360248201527f4d616e61676561626c652f6578697374696e672d6d616e616765722d6164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610314565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385811691821790925560405190918316907f9cb45c728de594dab506a1f1a8554e24c8eeaf983618d5ec5dd7bc6f3c49feee90600090a350600192915050565b600061108983611299565b80156110a55750826000015163ffffffff168263ffffffff1611155b6110f15760405162461bcd60e51b815260206004820152600f60248201527f4452422f6675747572652d6472617700000000000000000000000000000000006044820152606401610314565b82516000906111019084906115e0565b9050836040015163ffffffff168163ffffffff16106111625760405162461bcd60e51b815260206004820152601060248201527f4452422f657870697265642d64726177000000000000000000000000000000006044820152606401610314565b6000611182856020015163ffffffff16866040015163ffffffff166112c1565b90506111a58163ffffffff168363ffffffff16876040015163ffffffff166112ef565b95945050505050565b60408051606081018252600080825260208201819052918101919091526111d483611299565b15806111f7575082516111e89060016115a1565b63ffffffff168263ffffffff16145b6112435760405162461bcd60e51b815260206004820152601260248201527f4452422f6d7573742d62652d636f6e74696700000000000000000000000000006044820152606401610314565b60405180606001604052808363ffffffff168152602001611278856020015163ffffffff16866040015163ffffffff16611307565b63ffffffff168152602001846040015163ffffffff16815250905092915050565b6000816020015163ffffffff1660001480156112ba5750815163ffffffff16155b1592915050565b6000816112d057506000610580565b610f8b60016112df8486611589565b6112e991906115c9565b83611317565b60006112ff836112df8487611589565b949350505050565b6000610f8b6112e9846001611589565b6000610f8b8284611620565b803563ffffffff8116811461032957600080fd5b803567ffffffffffffffff8116811461032957600080fd5b60006020828403121561136157600080fd5b81356001600160a01b0381168114610f8b57600080fd5b6000806020838503121561138b57600080fd5b823567ffffffffffffffff808211156113a357600080fd5b818501915085601f8301126113b757600080fd5b8135818111156113c657600080fd5b8660208260051b85010111156113db57600080fd5b60209290920196919550909350505050565b600060a082840312156113ff57600080fd5b60405160a0810181811067ffffffffffffffff8211171561143057634e487b7160e01b600052604160045260246000fd5b6040528235815261144360208401611323565b602082015261145460408401611337565b604082015261146560608401611337565b606082015261147660808401611323565b60808201529392505050565b60006020828403121561149457600080fd5b610f8b82611323565b6020808252825182820181905260009190848201906040850190845b818110156115275761151483855180518252602081015163ffffffff80821660208501526040830151915067ffffffffffffffff80831660408601528060608501511660608601525080608084015116608085015250505050565b9284019260a092909201916001016114b9565b50909695505050505050565b60a08101610580828480518252602081015163ffffffff80821660208501526040830151915067ffffffffffffffff80831660408601528060608501511660608601525080608084015116608085015250505050565b6000821982111561159c5761159c611642565b500190565b600063ffffffff8083168185168083038211156115c0576115c0611642565b01949350505050565b6000828210156115db576115db611642565b500390565b600063ffffffff838116908316818110156115fd576115fd611642565b039392505050565b600060001982141561161957611619611642565b5060010190565b60008261163d57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212200b97b7480c29687762a9b5b9d489d241913aa15911658b25fde2f6a2380c13b064736f6c63430008060033000000000000000000000000e0f4217390221af47855e094f6e112d43c8698fe00000000000000000000000000000000000000000000000000000000000000ff

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading