CRO Price: $0.08 (+0.95%)

Contract

0x0EcaB989101b5DFA0057992aF90d6548CB47184B

Overview

CRO Balance

Cronos Chain LogoCronos Chain LogoCronos Chain Logo0 CRO

CRO Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim Ownership131980802024-03-27 5:13:53387 days ago1711516433IN
0x0EcaB989...8CB47184B
0 CRO0.166019795,001.5
Transfer Ownersh...128304812024-03-03 9:14:07411 days ago1709457247IN
0x0EcaB989...8CB47184B
0 CRO0.4774972210,097
Set Prize Distri...107067222023-10-17 6:33:34549 days ago1697524414IN
0x0EcaB989...8CB47184B
0 CRO0.2744554,640.61086282
Set Prize Distri...107067052023-10-17 6:31:59549 days ago1697524319IN
0x0EcaB989...8CB47184B
0 CRO0.287541674,642.11163094
Set Prize Distri...107066162023-10-17 6:23:38549 days ago1697523818IN
0x0EcaB989...8CB47184B
0 CRO0.287603874,643.11565761
Set Prize Distri...107065482023-10-17 6:17:14549 days ago1697523434IN
0x0EcaB989...8CB47184B
0 CRO0.274455474,640.61876089
Set Manager96642112023-08-10 5:52:59617 days ago1691646779IN
0x0EcaB989...8CB47184B
0 CRO0.224334624,687.99496574

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PrizeDistributionBuffer

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 7 : PrizeDistributionBuffer.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

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

import "./libraries/DrawRingBufferLib.sol";
import "./interfaces/IPrizeDistributionBuffer.sol";

/**
  * @title  PoolTogether V4 PrizeDistributionBuffer
  * @author PoolTogether Inc Team
  * @notice The PrizeDistributionBuffer contract provides historical lookups of PrizeDistribution struct parameters (linked with a Draw ID) via a
            circular ring buffer. Historical PrizeDistribution parameters can be accessed on-chain using a drawId to calculate
            ring buffer storage slot. The PrizeDistribution parameters can be created by manager/owner and existing PrizeDistribution
            parameters can only be updated the owner. When adding a new PrizeDistribution basic sanity checks will be used to
            validate the incoming parameters.
*/
contract PrizeDistributionBuffer is IPrizeDistributionBuffer, Manageable {
    using DrawRingBufferLib for DrawRingBufferLib.Buffer;

    /// @notice The maximum cardinality of the prize distribution ring buffer.
    /// @dev even with daily draws, 256 will give us over 8 months of history.
    uint256 internal constant MAX_CARDINALITY = 256;

    /// @notice The ceiling for prize distributions.  1e9 = 100%.
    /// @dev It's fixed point 9 because 1e9 is the largest "1" that fits into 2**32
    uint256 internal constant TIERS_CEILING = 1e9;

    /// @notice Emitted when the contract is deployed.
    /// @param cardinality The maximum number of records in the buffer before they begin to expire.
    event Deployed(uint8 cardinality);

    /// @notice PrizeDistribution ring buffer history.
    IPrizeDistributionBuffer.PrizeDistribution[MAX_CARDINALITY]
        internal prizeDistributionRingBuffer;

    /// @notice Ring buffer metadata (nextIndex, lastId, cardinality)
    DrawRingBufferLib.Buffer internal bufferMetadata;

    /* ============ Constructor ============ */

    /**
     * @notice Constructor for PrizeDistributionBuffer
     * @param _owner Address of the PrizeDistributionBuffer owner
     * @param _cardinality Cardinality of the `bufferMetadata`
     */
    constructor(address _owner, uint8 _cardinality) Ownable(_owner) {
        bufferMetadata.cardinality = _cardinality;
        emit Deployed(_cardinality);
    }

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

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

    /// @inheritdoc IPrizeDistributionBuffer
    function getPrizeDistribution(uint32 _drawId)
        external
        view
        override
        returns (IPrizeDistributionBuffer.PrizeDistribution memory)
    {
        return _getPrizeDistribution(bufferMetadata, _drawId);
    }

    /// @inheritdoc IPrizeDistributionSource
    function getPrizeDistributions(uint32[] calldata _drawIds)
        external
        view
        override
        returns (IPrizeDistributionBuffer.PrizeDistribution[] memory)
    {
        uint256 drawIdsLength = _drawIds.length;
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;
        IPrizeDistributionBuffer.PrizeDistribution[]
            memory _prizeDistributions = new IPrizeDistributionBuffer.PrizeDistribution[](
                drawIdsLength
            );

        for (uint256 i = 0; i < drawIdsLength; i++) {
            _prizeDistributions[i] = _getPrizeDistribution(buffer, _drawIds[i]);
        }

        return _prizeDistributions;
    }

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

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

        uint32 bufferNextIndex = buffer.nextIndex;

        // If the buffer is full return the cardinality, else retun the nextIndex
        if (prizeDistributionRingBuffer[bufferNextIndex].matchCardinality != 0) {
            return buffer.cardinality;
        } else {
            return bufferNextIndex;
        }
    }

    /// @inheritdoc IPrizeDistributionBuffer
    function getNewestPrizeDistribution()
        external
        view
        override
        returns (IPrizeDistributionBuffer.PrizeDistribution memory prizeDistribution, uint32 drawId)
    {
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;

        return (prizeDistributionRingBuffer[buffer.getIndex(buffer.lastDrawId)], buffer.lastDrawId);
    }

    /// @inheritdoc IPrizeDistributionBuffer
    function getOldestPrizeDistribution()
        external
        view
        override
        returns (IPrizeDistributionBuffer.PrizeDistribution memory prizeDistribution, uint32 drawId)
    {
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;

        // if the ring buffer is full, the oldest is at the nextIndex
        prizeDistribution = prizeDistributionRingBuffer[buffer.nextIndex];

        // The PrizeDistribution at index 0 IS by default the oldest prizeDistribution.
        if (buffer.lastDrawId == 0) {
            drawId = 0; // return 0 to indicate no prizeDistribution ring buffer history
        } else if (prizeDistribution.bitRangeSize == 0) {
            // IF the next PrizeDistribution.bitRangeSize == 0 the ring buffer HAS NOT looped around so the oldest is the first entry.
            prizeDistribution = prizeDistributionRingBuffer[0];
            drawId = (buffer.lastDrawId + 1) - buffer.nextIndex;
        } else {
            // Calculates the drawId using the ring buffer cardinality
            // Sequential drawIds are gauranteed by DrawRingBufferLib.push()
            drawId = (buffer.lastDrawId + 1) - buffer.cardinality;
        }
    }

    /// @inheritdoc IPrizeDistributionBuffer
    function pushPrizeDistribution(
        uint32 _drawId,
        IPrizeDistributionBuffer.PrizeDistribution calldata _prizeDistribution
    ) external override onlyManagerOrOwner returns (bool) {
        return _pushPrizeDistribution(_drawId, _prizeDistribution);
    }

    /// @inheritdoc IPrizeDistributionBuffer
    function setPrizeDistribution(
        uint32 _drawId,
        IPrizeDistributionBuffer.PrizeDistribution calldata _prizeDistribution
    ) external override onlyOwner returns (uint32) {
        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;
        uint32 index = buffer.getIndex(_drawId);
        prizeDistributionRingBuffer[index] = _prizeDistribution;

        emit PrizeDistributionSet(_drawId, _prizeDistribution);

        return _drawId;
    }

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

    /**
     * @notice Gets the PrizeDistributionBuffer for a drawId
     * @param _buffer DrawRingBufferLib.Buffer
     * @param _drawId drawId
     */
    function _getPrizeDistribution(DrawRingBufferLib.Buffer memory _buffer, uint32 _drawId)
        internal
        view
        returns (IPrizeDistributionBuffer.PrizeDistribution memory)
    {
        return prizeDistributionRingBuffer[_buffer.getIndex(_drawId)];
    }

    /**
     * @notice Set newest PrizeDistributionBuffer in ring buffer storage.
     * @param _drawId       drawId
     * @param _prizeDistribution PrizeDistributionBuffer struct
     */
    function _pushPrizeDistribution(
        uint32 _drawId,
        IPrizeDistributionBuffer.PrizeDistribution calldata _prizeDistribution
    ) internal returns (bool) {
        require(_drawId > 0, "DrawCalc/draw-id-gt-0");
        require(_prizeDistribution.matchCardinality > 0, "DrawCalc/matchCardinality-gt-0");
        require(
            _prizeDistribution.bitRangeSize <= 256 / _prizeDistribution.matchCardinality,
            "DrawCalc/bitRangeSize-too-large"
        );

        require(_prizeDistribution.bitRangeSize > 0, "DrawCalc/bitRangeSize-gt-0");
        require(_prizeDistribution.maxPicksPerUser > 0, "DrawCalc/maxPicksPerUser-gt-0");
        require(_prizeDistribution.expiryDuration > 0, "DrawCalc/expiryDuration-gt-0");

        // ensure that the sum of the tiers are not gt 100%
        uint256 sumTotalTiers = 0;
        uint256 tiersLength = _prizeDistribution.tiers.length;

        for (uint256 index = 0; index < tiersLength; index++) {
            uint256 tier = _prizeDistribution.tiers[index];
            sumTotalTiers += tier;
        }

        // Each tier amount stored as uint32 - summed can't exceed 1e9
        require(sumTotalTiers <= TIERS_CEILING, "DrawCalc/tiers-gt-100%");

        DrawRingBufferLib.Buffer memory buffer = bufferMetadata;

        // store the PrizeDistribution in the ring buffer
        prizeDistributionRingBuffer[buffer.nextIndex] = _prizeDistribution;

        // update the ring buffer data
        bufferMetadata = buffer.push(_drawId);

        emit PrizeDistributionSet(_drawId, _prizeDistribution);

        return true;
    }
}

File 2 of 7 : 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 7 : 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 4 of 7 : IPrizeDistributionBuffer.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

import "./IPrizeDistributionSource.sol";

/** @title  IPrizeDistributionBuffer
 * @author PoolTogether Inc Team
 * @notice The PrizeDistributionBuffer interface.
 */
interface IPrizeDistributionBuffer is IPrizeDistributionSource {
    /**
     * @notice Emit when PrizeDistribution is set.
     * @param drawId       Draw id
     * @param prizeDistribution IPrizeDistributionBuffer.PrizeDistribution
     */
    event PrizeDistributionSet(
        uint32 indexed drawId,
        IPrizeDistributionBuffer.PrizeDistribution prizeDistribution
    );

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

    /**
     * @notice Read newest PrizeDistribution from prize distributions ring buffer.
     * @dev    Uses nextDrawIndex to calculate the most recently added PrizeDistribution.
     * @return prizeDistribution
     * @return drawId
     */
    function getNewestPrizeDistribution()
        external
        view
        returns (
            IPrizeDistributionBuffer.PrizeDistribution memory prizeDistribution,
            uint32 drawId
        );

    /**
     * @notice Read oldest PrizeDistribution from prize distributions ring buffer.
     * @dev    Finds the oldest Draw by buffer.nextIndex and buffer.lastDrawId
     * @return prizeDistribution
     * @return drawId
     */
    function getOldestPrizeDistribution()
        external
        view
        returns (
            IPrizeDistributionBuffer.PrizeDistribution memory prizeDistribution,
            uint32 drawId
        );

    /**
     * @notice Gets the PrizeDistributionBuffer for a drawId
     * @param drawId drawId
     * @return prizeDistribution
     */
    function getPrizeDistribution(uint32 drawId)
        external
        view
        returns (IPrizeDistributionBuffer.PrizeDistribution memory);

    /**
     * @notice Gets the number of PrizeDistributions stored in the prize distributions 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 NewestPrizeDistribution index + 1.
     * @return Number of PrizeDistributions stored in the prize distributions ring buffer.
     */
    function getPrizeDistributionCount() external view returns (uint32);

    /**
     * @notice Adds new PrizeDistribution record to ring buffer storage.
     * @dev    Only callable by the owner or manager
     * @param drawId            Draw ID linked to PrizeDistribution parameters
     * @param prizeDistribution PrizeDistribution parameters struct
     */
    function pushPrizeDistribution(
        uint32 drawId,
        IPrizeDistributionBuffer.PrizeDistribution calldata prizeDistribution
    ) external returns (bool);

    /**
     * @notice Sets existing PrizeDistribution with new PrizeDistribution parameters in ring buffer storage.
     * @dev    Retroactively updates an existing PrizeDistribution and should be thought of as a "safety"
               fallback. If the manager is setting invalid PrizeDistribution parameters the Owner can update
               the invalid parameters with correct parameters.
     * @return drawId
     */
    function setPrizeDistribution(
        uint32 drawId,
        IPrizeDistributionBuffer.PrizeDistribution calldata draw
    ) external returns (uint32);
}

File 5 of 7 : IPrizeDistributionSource.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

/** @title IPrizeDistributionSource
 * @author PoolTogether Inc Team
 * @notice The PrizeDistributionSource interface.
 */
interface IPrizeDistributionSource {
    ///@notice PrizeDistribution struct created every draw
    ///@param bitRangeSize Decimal representation of bitRangeSize
    ///@param matchCardinality The number of numbers to consider in the 256 bit random number. Must be > 1 and < 256/bitRangeSize.
    ///@param startTimestampOffset The starting time offset in seconds from which Ticket balances are calculated.
    ///@param endTimestampOffset The end time offset in seconds from which Ticket balances are calculated.
    ///@param maxPicksPerUser Maximum number of picks a user can make in this draw
    ///@param expiryDuration Length of time in seconds the PrizeDistribution is valid for. Relative to the Draw.timestamp.
    ///@param numberOfPicks Number of picks this draw has (may vary across networks according to how much the network has contributed to the Reserve)
    ///@param tiers Array of prize tiers percentages, expressed in fraction form with base 1e9. Ordering: index0: grandPrize, index1: runnerUp, etc.
    ///@param prize Total prize amount available in this draw calculator for this draw (may vary from across networks)
    struct PrizeDistribution {
        uint8 bitRangeSize;
        uint8 matchCardinality;
        uint32 startTimestampOffset;
        uint32 endTimestampOffset;
        uint32 maxPicksPerUser;
        uint32 expiryDuration;
        uint104 numberOfPicks;
        uint32[16] tiers;
        uint256 prize;
    }

    /**
     * @notice Gets PrizeDistribution list from array of drawIds
     * @param drawIds drawIds to get PrizeDistribution for
     * @return prizeDistributionList
     */
    function getPrizeDistributions(uint32[] calldata drawIds)
        external
        view
        returns (PrizeDistribution[] memory);
}

File 6 of 7 : 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 7 of 7 : 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
{
  "evmVersion": "berlin",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 2000
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint8","name":"_cardinality","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"cardinality","type":"uint8"}],"name":"Deployed","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"drawId","type":"uint32"},{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"indexed":false,"internalType":"struct IPrizeDistributionSource.PrizeDistribution","name":"prizeDistribution","type":"tuple"}],"name":"PrizeDistributionSet","type":"event"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBufferCardinality","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNewestPrizeDistribution","outputs":[{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"internalType":"struct IPrizeDistributionSource.PrizeDistribution","name":"prizeDistribution","type":"tuple"},{"internalType":"uint32","name":"drawId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOldestPrizeDistribution","outputs":[{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"internalType":"struct IPrizeDistributionSource.PrizeDistribution","name":"prizeDistribution","type":"tuple"},{"internalType":"uint32","name":"drawId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_drawId","type":"uint32"}],"name":"getPrizeDistribution","outputs":[{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"internalType":"struct IPrizeDistributionSource.PrizeDistribution","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrizeDistributionCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_drawIds","type":"uint32[]"}],"name":"getPrizeDistributions","outputs":[{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"internalType":"struct IPrizeDistributionSource.PrizeDistribution[]","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":[{"internalType":"uint32","name":"_drawId","type":"uint32"},{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"internalType":"struct IPrizeDistributionSource.PrizeDistribution","name":"_prizeDistribution","type":"tuple"}],"name":"pushPrizeDistribution","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"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":"uint32","name":"_drawId","type":"uint32"},{"components":[{"internalType":"uint8","name":"bitRangeSize","type":"uint8"},{"internalType":"uint8","name":"matchCardinality","type":"uint8"},{"internalType":"uint32","name":"startTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"endTimestampOffset","type":"uint32"},{"internalType":"uint32","name":"maxPicksPerUser","type":"uint32"},{"internalType":"uint32","name":"expiryDuration","type":"uint32"},{"internalType":"uint104","name":"numberOfPicks","type":"uint104"},{"internalType":"uint32[16]","name":"tiers","type":"uint32[16]"},{"internalType":"uint256","name":"prize","type":"uint256"}],"internalType":"struct IPrizeDistributionSource.PrizeDistribution","name":"_prizeDistribution","type":"tuple"}],"name":"setPrizeDistribution","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620020b2380380620020b28339810160408190526200003491620000f2565b816200004081620000a2565b50610403805463ffffffff60401b191660ff8316680100000000000000008102919091179091556040519081527f7da7688769fade6088b3de366e63c95090bc5b0db6e9b43f043dee741d7544fe9060200160405180910390a1505062000141565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080604083850312156200010657600080fd5b82516001600160a01b03811681146200011e57600080fd5b602084015190925060ff811681146200013657600080fd5b809150509250929050565b611f6180620001516000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063715018a611610097578063d0ebdbe711610066578063d0ebdbe7146101f3578063d30a5daf14610206578063e30c397814610226578063f2fde38b1461023757600080fd5b8063715018a6146101ac5780638da5cb5b146101b4578063caeef7ec146101c5578063ce336ce9146101e057600080fd5b806324c21446116100d357806324c21446146101555780633cd8e2d51461015d578063481c6a751461017d5780634e71e0c8146101a257600080fd5b80631124e1dc146100fa57806321e98ad9146101225780632439093a1461013f575b600080fd5b61010d610108366004611822565b61024a565b60405190151581526020015b60405180910390f35b61012a610317565b60405163ffffffff9091168152602001610119565b61014761039e565b604051610119929190611adb565b610147610671565b61017061016b366004611805565b610804565b6040516101199190611acc565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610119565b6101aa610852565b005b6101aa6108e0565b6000546001600160a01b031661018a565b6104035468010000000000000000900463ffffffff1661012a565b61012a6101ee366004611822565b610955565b61010d610201366004611760565b610a84565b610219610214366004611790565b610afd565b60405161011991906119b9565b6001546001600160a01b031661018a565b6101aa610245366004611760565b610c08565b60003361025f6002546001600160a01b031690565b6001600160a01b0316148061028d5750336102826000546001600160a01b031690565b6001600160a01b0316145b6103045760405162461bcd60e51b815260206004820152602660248201527f4d616e61676561626c652f63616c6c65722d6e6f742d6d616e616765722d6f7260448201527f2d6f776e6572000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61030e8383610d44565b90505b92915050565b604080516060810182526104035463ffffffff80821680845264010000000083048216602085015268010000000000000000909204169282019290925260009161036357600091505090565b6020810151600363ffffffff8216610100811061038257610382611c7d565b6004020154610100900460ff1615610311575060400151919050565b6103a66116cd565b604080516060810182526104035463ffffffff8082168352640100000000820481166020840181905268010000000000000000909204169282019290925260009160039061010081106103fb576103fb611c7d565b604080516101208101825260049290920292909201805460ff8082168452610100820416602084015262010000810463ffffffff9081168486015266010000000000008204811660608501526a01000000000000000000008204811660808501526e01000000000000000000000000000082041660a0840152720100000000000000000000000000000000000090046cffffffffffffffffffffffffff1660c083015282516102008101938490529192909160e08401916001840190601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116104bf5750505092845250505060039190910154602090910152815190935063ffffffff166105275760009150509091565b825160ff1661065f5760408051610120810182526003805460ff8082168452610100820416602084015263ffffffff62010000820481168486015266010000000000008204811660608501526a01000000000000000000008204811660808501526e01000000000000000000000000000082041660a08401526cffffffffffffffffffffffffff72010000000000000000000000000000000000009091041660c083015282516102008101938490529192909160e0840191600490601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116105ea575050509284525050506003919091015460209182015282015182519194509061064e906001611b16565b6106589190611b76565b9150509091565b6040810151815161064e906001611b16565b6106796116cd565b604080516060810182526104035463ffffffff808216808452640100000000830482166020850152680100000000000000009092048116938301939093526000926003916106ca9184919061119916565b63ffffffff1661010081106106e1576106e1611c7d565b8251604080516101208101825260049390930293909301805460ff8082168552610100820416602085015262010000810463ffffffff9081168587015266010000000000008204811660608601526a01000000000000000000008204811660808601526e01000000000000000000000000000082041660a0850152720100000000000000000000000000000000000090046cffffffffffffffffffffffffff1660c084015283516102008101948590529093919291849160e08401916001840190601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116107aa57905050505050508152602001600382015481525050915092509250509091565b61080c6116cd565b604080516060810182526104035463ffffffff808216835264010000000082048116602084015268010000000000000000909104169181019190915261031190836112c9565b6001546001600160a01b031633146108ac5760405162461bcd60e51b815260206004820152601f60248201527f4f776e61626c652f63616c6c65722d6e6f742d70656e64696e674f776e65720060448201526064016102fb565b6001546108c1906001600160a01b031661140f565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055565b336108f36000546001600160a01b031690565b6001600160a01b0316146109495760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b610953600061140f565b565b60003361096a6000546001600160a01b031690565b6001600160a01b0316146109c05760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b604080516060810182526104035463ffffffff80821683526401000000008204811660208401526801000000000000000090910481169282019290925290600090610a0f908390879061119916565b90508360038263ffffffff166101008110610a2c57610a2c611c7d565b60040201610a3a8282611cc3565b9050508463ffffffff167f2d81da839b2f3db2ed762907f74df3acecdc30461dba4813694c225ba911e1f685604051610a739190611a08565b60405180910390a250929392505050565b600033610a996000546001600160a01b031690565b6001600160a01b031614610aef5760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b6103118261146c565b919050565b60408051606081810183526104035463ffffffff8082168452640100000000820481166020850152680100000000000000009091041692820192909252829060008267ffffffffffffffff811115610b5757610b57611c93565b604051908082528060200260200182016040528015610b9057816020015b610b7d6116cd565b815260200190600190039081610b755790505b50905060005b83811015610bfe57610bce83888884818110610bb457610bb4611c7d565b9050602002016020810190610bc99190611805565b6112c9565b828281518110610be057610be0611c7d565b60200260200101819052508080610bf690611c04565b915050610b96565b5095945050505050565b33610c1b6000546001600160a01b031690565b6001600160a01b031614610c715760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b6001600160a01b038116610ced5760405162461bcd60e51b815260206004820152602560248201527f4f776e61626c652f70656e64696e674f776e65722d6e6f742d7a65726f2d616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016102fb565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f239a2ddded15777fa246aed5f7e1a9bc69a39d4eb4a397034d1d85766cca7d4c90600090a250565b6000808363ffffffff1611610d9b5760405162461bcd60e51b815260206004820152601560248201527f4472617743616c632f647261772d69642d67742d30000000000000000000000060448201526064016102fb565b6000610dad6040840160208501611883565b60ff1611610dfd5760405162461bcd60e51b815260206004820152601e60248201527f4472617743616c632f6d6174636843617264696e616c6974792d67742d30000060448201526064016102fb565b610e0d6040830160208401611883565b610e1c9060ff16610100611b3e565b61ffff16610e2d6020840184611883565b60ff161115610e7e5760405162461bcd60e51b815260206004820152601f60248201527f4472617743616c632f62697452616e676553697a652d746f6f2d6c617267650060448201526064016102fb565b6000610e8d6020840184611883565b60ff1611610edd5760405162461bcd60e51b815260206004820152601a60248201527f4472617743616c632f62697452616e676553697a652d67742d3000000000000060448201526064016102fb565b6000610eef60a0840160808501611805565b63ffffffff1611610f425760405162461bcd60e51b815260206004820152601d60248201527f4472617743616c632f6d61785069636b73506572557365722d67742d3000000060448201526064016102fb565b6000610f5460c0840160a08501611805565b63ffffffff1611610fa75760405162461bcd60e51b815260206004820152601c60248201527f4472617743616c632f6578706972794475726174696f6e2d67742d300000000060448201526064016102fb565b60006010815b818110156110075760008560e0018260108110610fcc57610fcc611c7d565b602002016020810190610fdf9190611805565b63ffffffff169050610ff18185611afe565b9350508080610fff90611c04565b915050610fad565b50633b9aca0082111561105c5760405162461bcd60e51b815260206004820152601660248201527f4472617743616c632f74696572732d67742d313030250000000000000000000060448201526064016102fb565b604080516060810182526104035463ffffffff8082168352640100000000820481166020840181905268010000000000000000909204169282019290925290859060039061010081106110b1576110b1611c7d565b600402016110bf8282611cc3565b506110cc90508187611558565b80516104038054602084015160409485015163ffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff928216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009094169582169590951792909217169290921790559051908716907f2d81da839b2f3db2ed762907f74df3acecdc30461dba4813694c225ba911e1f690611185908890611a08565b60405180910390a250600195945050505050565b60006111a483611643565b80156111c05750826000015163ffffffff168263ffffffff1611155b61120c5760405162461bcd60e51b815260206004820152600f60248201527f4452422f6675747572652d64726177000000000000000000000000000000000060448201526064016102fb565b825160009061121c908490611b76565b9050836040015163ffffffff168163ffffffff161061127d5760405162461bcd60e51b815260206004820152601060248201527f4452422f657870697265642d647261770000000000000000000000000000000060448201526064016102fb565b600061129d856020015163ffffffff16866040015163ffffffff1661166b565b90506112c08163ffffffff168363ffffffff16876040015163ffffffff16611699565b95945050505050565b6112d16116cd565b60036112dd8484611199565b63ffffffff1661010081106112f4576112f4611c7d565b604080516101208101825260049290920292909201805460ff8082168452610100820416602084015262010000810463ffffffff9081168486015266010000000000008204811660608501526a01000000000000000000008204811660808501526e01000000000000000000000000000082041660a0840152720100000000000000000000000000000000000090046cffffffffffffffffffffffffff1660c083015282516102008101938490529192909160e08401916001840190601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113b857905050505050508152602001600382015481525050905092915050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002546000906001600160a01b039081169083168114156114f55760405162461bcd60e51b815260206004820152602360248201527f4d616e61676561626c652f6578697374696e672d6d616e616765722d6164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016102fb565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385811691821790925560405190918316907f9cb45c728de594dab506a1f1a8554e24c8eeaf983618d5ec5dd7bc6f3c49feee90600090a350600192915050565b604080516060810182526000808252602082018190529181019190915261157e83611643565b15806115a157508251611592906001611b16565b63ffffffff168263ffffffff16145b6115ed5760405162461bcd60e51b815260206004820152601260248201527f4452422f6d7573742d62652d636f6e746967000000000000000000000000000060448201526064016102fb565b60405180606001604052808363ffffffff168152602001611622856020015163ffffffff16866040015163ffffffff166116b1565b63ffffffff168152602001846040015163ffffffff16815250905092915050565b6000816020015163ffffffff1660001480156116645750815163ffffffff16155b1592915050565b60008161167a57506000610311565b61030e60016116898486611afe565b6116939190611b5f565b836116c1565b60006116a9836116898487611afe565b949350505050565b600061030e611693846001611afe565b600061030e8284611c3d565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915260e08101611713611720565b8152602001600081525090565b6040518061020001604052806010906020820280368337509192915050565b8035610af881611eec565b8035610af881611f0a565b8035610af881611f1c565b60006020828403121561177257600080fd5b81356001600160a01b038116811461178957600080fd5b9392505050565b600080602083850312156117a357600080fd5b823567ffffffffffffffff808211156117bb57600080fd5b818501915085601f8301126117cf57600080fd5b8135818111156117de57600080fd5b8660208260051b85010111156117f357600080fd5b60209290920196919550909350505050565b60006020828403121561181757600080fd5b813561178981611f0a565b60008082840361032081121561183757600080fd5b833561184281611f0a565b92506103007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561187557600080fd5b506020830190509250929050565b60006020828403121561189557600080fd5b813561178981611f1c565b8060005b60108110156118d35781356118b881611f0a565b63ffffffff16845260209384019391909101906001016118a4565b50505050565b8060005b60108110156118d357815163ffffffff168452602093840193909101906001016118dd565b60ff815116825260ff6020820151166020830152604081015161192d604084018263ffffffff169052565b506060810151611945606084018263ffffffff169052565b50608081015161195d608084018263ffffffff169052565b5060a081015161197560a084018263ffffffff169052565b5060c081015161199660c08401826cffffffffffffffffffffffffff169052565b5060e08101516119a960e08401826118d9565b5061010001516102e09190910152565b6020808252825182820181905260009190848201906040850190845b818110156119fc576119e8838551611902565b9284019261030092909201916001016119d5565b50909695505050505050565b61030081018235611a1881611f1c565b60ff168252611a2960208401611755565b60ff166020830152611a3d6040840161174a565b63ffffffff166040830152611a546060840161174a565b63ffffffff166060830152611a6b6080840161174a565b63ffffffff166080830152611a8260a0840161174a565b63ffffffff1660a0830152611a9960c0840161173f565b6cffffffffffffffffffffffffff1660c0830152611abd60e08084019085016118a0565b6102e092830135919092015290565b61030081016103118284611902565b6103208101611aea8285611902565b63ffffffff83166103008301529392505050565b60008219821115611b1157611b11611c51565b500190565b600063ffffffff808316818516808303821115611b3557611b35611c51565b01949350505050565b600061ffff80841680611b5357611b53611c67565b92169190910492915050565b600082821015611b7157611b71611c51565b500390565b600063ffffffff83811690831681811015611b9357611b93611c51565b039392505050565b81816000805b6010811015611bfc578335611bb581611f0a565b835463ffffffff600385901b81811b801990931693909116901b1617835560209390930192600490910190601c821115611bf457600091506001830192505b600101611ba1565b505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611c3657611c36611c51565b5060010190565b600082611c4c57611c4c611c67565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6000813561031181611eec565b6000813561031181611f0a565b8135611cce81611f1c565b60ff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082161783556020840135611d0b81611f1c565b61ff008160081b16837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000841617178455505050611d84611d4d60408401611cb6565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff1660109190911b65ffffffff000016178255565b611dce611d9360608401611cb6565b82547fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1660309190911b69ffffffff00000000000016178255565b611e1c611ddd60808401611cb6565b82547fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff1660509190911b6dffffffff0000000000000000000016178255565b611e6e611e2b60a08401611cb6565b82547fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff1660709190911b71ffffffff000000000000000000000000000016178255565b611ecd611e7d60c08401611ca9565b82547fff00000000000000000000000000ffffffffffffffffffffffffffffffffffff1660909190911b7effffffffffffffffffffffffff00000000000000000000000000000000000016178255565b611edd60e0830160018301611b9b565b6102e082013560038201555050565b6cffffffffffffffffffffffffff81168114611f0757600080fd5b50565b63ffffffff81168114611f0757600080fd5b60ff81168114611f0757600080fdfea2646970667358221220132fa1799f3f662436d462c6e531bb3bab5097313ee0d229d38502db694a319e64736f6c634300080600330000000000000000000000000a506e58ba76671476c9aae1205dab69234c714800000000000000000000000000000000000000000000000000000000000000ff

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063715018a611610097578063d0ebdbe711610066578063d0ebdbe7146101f3578063d30a5daf14610206578063e30c397814610226578063f2fde38b1461023757600080fd5b8063715018a6146101ac5780638da5cb5b146101b4578063caeef7ec146101c5578063ce336ce9146101e057600080fd5b806324c21446116100d357806324c21446146101555780633cd8e2d51461015d578063481c6a751461017d5780634e71e0c8146101a257600080fd5b80631124e1dc146100fa57806321e98ad9146101225780632439093a1461013f575b600080fd5b61010d610108366004611822565b61024a565b60405190151581526020015b60405180910390f35b61012a610317565b60405163ffffffff9091168152602001610119565b61014761039e565b604051610119929190611adb565b610147610671565b61017061016b366004611805565b610804565b6040516101199190611acc565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610119565b6101aa610852565b005b6101aa6108e0565b6000546001600160a01b031661018a565b6104035468010000000000000000900463ffffffff1661012a565b61012a6101ee366004611822565b610955565b61010d610201366004611760565b610a84565b610219610214366004611790565b610afd565b60405161011991906119b9565b6001546001600160a01b031661018a565b6101aa610245366004611760565b610c08565b60003361025f6002546001600160a01b031690565b6001600160a01b0316148061028d5750336102826000546001600160a01b031690565b6001600160a01b0316145b6103045760405162461bcd60e51b815260206004820152602660248201527f4d616e61676561626c652f63616c6c65722d6e6f742d6d616e616765722d6f7260448201527f2d6f776e6572000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61030e8383610d44565b90505b92915050565b604080516060810182526104035463ffffffff80821680845264010000000083048216602085015268010000000000000000909204169282019290925260009161036357600091505090565b6020810151600363ffffffff8216610100811061038257610382611c7d565b6004020154610100900460ff1615610311575060400151919050565b6103a66116cd565b604080516060810182526104035463ffffffff8082168352640100000000820481166020840181905268010000000000000000909204169282019290925260009160039061010081106103fb576103fb611c7d565b604080516101208101825260049290920292909201805460ff8082168452610100820416602084015262010000810463ffffffff9081168486015266010000000000008204811660608501526a01000000000000000000008204811660808501526e01000000000000000000000000000082041660a0840152720100000000000000000000000000000000000090046cffffffffffffffffffffffffff1660c083015282516102008101938490529192909160e08401916001840190601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116104bf5750505092845250505060039190910154602090910152815190935063ffffffff166105275760009150509091565b825160ff1661065f5760408051610120810182526003805460ff8082168452610100820416602084015263ffffffff62010000820481168486015266010000000000008204811660608501526a01000000000000000000008204811660808501526e01000000000000000000000000000082041660a08401526cffffffffffffffffffffffffff72010000000000000000000000000000000000009091041660c083015282516102008101938490529192909160e0840191600490601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116105ea575050509284525050506003919091015460209182015282015182519194509061064e906001611b16565b6106589190611b76565b9150509091565b6040810151815161064e906001611b16565b6106796116cd565b604080516060810182526104035463ffffffff808216808452640100000000830482166020850152680100000000000000009092048116938301939093526000926003916106ca9184919061119916565b63ffffffff1661010081106106e1576106e1611c7d565b8251604080516101208101825260049390930293909301805460ff8082168552610100820416602085015262010000810463ffffffff9081168587015266010000000000008204811660608601526a01000000000000000000008204811660808601526e01000000000000000000000000000082041660a0850152720100000000000000000000000000000000000090046cffffffffffffffffffffffffff1660c084015283516102008101948590529093919291849160e08401916001840190601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116107aa57905050505050508152602001600382015481525050915092509250509091565b61080c6116cd565b604080516060810182526104035463ffffffff808216835264010000000082048116602084015268010000000000000000909104169181019190915261031190836112c9565b6001546001600160a01b031633146108ac5760405162461bcd60e51b815260206004820152601f60248201527f4f776e61626c652f63616c6c65722d6e6f742d70656e64696e674f776e65720060448201526064016102fb565b6001546108c1906001600160a01b031661140f565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055565b336108f36000546001600160a01b031690565b6001600160a01b0316146109495760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b610953600061140f565b565b60003361096a6000546001600160a01b031690565b6001600160a01b0316146109c05760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b604080516060810182526104035463ffffffff80821683526401000000008204811660208401526801000000000000000090910481169282019290925290600090610a0f908390879061119916565b90508360038263ffffffff166101008110610a2c57610a2c611c7d565b60040201610a3a8282611cc3565b9050508463ffffffff167f2d81da839b2f3db2ed762907f74df3acecdc30461dba4813694c225ba911e1f685604051610a739190611a08565b60405180910390a250929392505050565b600033610a996000546001600160a01b031690565b6001600160a01b031614610aef5760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b6103118261146c565b919050565b60408051606081810183526104035463ffffffff8082168452640100000000820481166020850152680100000000000000009091041692820192909252829060008267ffffffffffffffff811115610b5757610b57611c93565b604051908082528060200260200182016040528015610b9057816020015b610b7d6116cd565b815260200190600190039081610b755790505b50905060005b83811015610bfe57610bce83888884818110610bb457610bb4611c7d565b9050602002016020810190610bc99190611805565b6112c9565b828281518110610be057610be0611c7d565b60200260200101819052508080610bf690611c04565b915050610b96565b5095945050505050565b33610c1b6000546001600160a01b031690565b6001600160a01b031614610c715760405162461bcd60e51b815260206004820152601860248201527f4f776e61626c652f63616c6c65722d6e6f742d6f776e6572000000000000000060448201526064016102fb565b6001600160a01b038116610ced5760405162461bcd60e51b815260206004820152602560248201527f4f776e61626c652f70656e64696e674f776e65722d6e6f742d7a65726f2d616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016102fb565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f239a2ddded15777fa246aed5f7e1a9bc69a39d4eb4a397034d1d85766cca7d4c90600090a250565b6000808363ffffffff1611610d9b5760405162461bcd60e51b815260206004820152601560248201527f4472617743616c632f647261772d69642d67742d30000000000000000000000060448201526064016102fb565b6000610dad6040840160208501611883565b60ff1611610dfd5760405162461bcd60e51b815260206004820152601e60248201527f4472617743616c632f6d6174636843617264696e616c6974792d67742d30000060448201526064016102fb565b610e0d6040830160208401611883565b610e1c9060ff16610100611b3e565b61ffff16610e2d6020840184611883565b60ff161115610e7e5760405162461bcd60e51b815260206004820152601f60248201527f4472617743616c632f62697452616e676553697a652d746f6f2d6c617267650060448201526064016102fb565b6000610e8d6020840184611883565b60ff1611610edd5760405162461bcd60e51b815260206004820152601a60248201527f4472617743616c632f62697452616e676553697a652d67742d3000000000000060448201526064016102fb565b6000610eef60a0840160808501611805565b63ffffffff1611610f425760405162461bcd60e51b815260206004820152601d60248201527f4472617743616c632f6d61785069636b73506572557365722d67742d3000000060448201526064016102fb565b6000610f5460c0840160a08501611805565b63ffffffff1611610fa75760405162461bcd60e51b815260206004820152601c60248201527f4472617743616c632f6578706972794475726174696f6e2d67742d300000000060448201526064016102fb565b60006010815b818110156110075760008560e0018260108110610fcc57610fcc611c7d565b602002016020810190610fdf9190611805565b63ffffffff169050610ff18185611afe565b9350508080610fff90611c04565b915050610fad565b50633b9aca0082111561105c5760405162461bcd60e51b815260206004820152601660248201527f4472617743616c632f74696572732d67742d313030250000000000000000000060448201526064016102fb565b604080516060810182526104035463ffffffff8082168352640100000000820481166020840181905268010000000000000000909204169282019290925290859060039061010081106110b1576110b1611c7d565b600402016110bf8282611cc3565b506110cc90508187611558565b80516104038054602084015160409485015163ffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff928216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009094169582169590951792909217169290921790559051908716907f2d81da839b2f3db2ed762907f74df3acecdc30461dba4813694c225ba911e1f690611185908890611a08565b60405180910390a250600195945050505050565b60006111a483611643565b80156111c05750826000015163ffffffff168263ffffffff1611155b61120c5760405162461bcd60e51b815260206004820152600f60248201527f4452422f6675747572652d64726177000000000000000000000000000000000060448201526064016102fb565b825160009061121c908490611b76565b9050836040015163ffffffff168163ffffffff161061127d5760405162461bcd60e51b815260206004820152601060248201527f4452422f657870697265642d647261770000000000000000000000000000000060448201526064016102fb565b600061129d856020015163ffffffff16866040015163ffffffff1661166b565b90506112c08163ffffffff168363ffffffff16876040015163ffffffff16611699565b95945050505050565b6112d16116cd565b60036112dd8484611199565b63ffffffff1661010081106112f4576112f4611c7d565b604080516101208101825260049290920292909201805460ff8082168452610100820416602084015262010000810463ffffffff9081168486015266010000000000008204811660608501526a01000000000000000000008204811660808501526e01000000000000000000000000000082041660a0840152720100000000000000000000000000000000000090046cffffffffffffffffffffffffff1660c083015282516102008101938490529192909160e08401916001840190601090826000855b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116113b857905050505050508152602001600382015481525050905092915050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002546000906001600160a01b039081169083168114156114f55760405162461bcd60e51b815260206004820152602360248201527f4d616e61676561626c652f6578697374696e672d6d616e616765722d6164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016102fb565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385811691821790925560405190918316907f9cb45c728de594dab506a1f1a8554e24c8eeaf983618d5ec5dd7bc6f3c49feee90600090a350600192915050565b604080516060810182526000808252602082018190529181019190915261157e83611643565b15806115a157508251611592906001611b16565b63ffffffff168263ffffffff16145b6115ed5760405162461bcd60e51b815260206004820152601260248201527f4452422f6d7573742d62652d636f6e746967000000000000000000000000000060448201526064016102fb565b60405180606001604052808363ffffffff168152602001611622856020015163ffffffff16866040015163ffffffff166116b1565b63ffffffff168152602001846040015163ffffffff16815250905092915050565b6000816020015163ffffffff1660001480156116645750815163ffffffff16155b1592915050565b60008161167a57506000610311565b61030e60016116898486611afe565b6116939190611b5f565b836116c1565b60006116a9836116898487611afe565b949350505050565b600061030e611693846001611afe565b600061030e8284611c3d565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915260e08101611713611720565b8152602001600081525090565b6040518061020001604052806010906020820280368337509192915050565b8035610af881611eec565b8035610af881611f0a565b8035610af881611f1c565b60006020828403121561177257600080fd5b81356001600160a01b038116811461178957600080fd5b9392505050565b600080602083850312156117a357600080fd5b823567ffffffffffffffff808211156117bb57600080fd5b818501915085601f8301126117cf57600080fd5b8135818111156117de57600080fd5b8660208260051b85010111156117f357600080fd5b60209290920196919550909350505050565b60006020828403121561181757600080fd5b813561178981611f0a565b60008082840361032081121561183757600080fd5b833561184281611f0a565b92506103007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561187557600080fd5b506020830190509250929050565b60006020828403121561189557600080fd5b813561178981611f1c565b8060005b60108110156118d35781356118b881611f0a565b63ffffffff16845260209384019391909101906001016118a4565b50505050565b8060005b60108110156118d357815163ffffffff168452602093840193909101906001016118dd565b60ff815116825260ff6020820151166020830152604081015161192d604084018263ffffffff169052565b506060810151611945606084018263ffffffff169052565b50608081015161195d608084018263ffffffff169052565b5060a081015161197560a084018263ffffffff169052565b5060c081015161199660c08401826cffffffffffffffffffffffffff169052565b5060e08101516119a960e08401826118d9565b5061010001516102e09190910152565b6020808252825182820181905260009190848201906040850190845b818110156119fc576119e8838551611902565b9284019261030092909201916001016119d5565b50909695505050505050565b61030081018235611a1881611f1c565b60ff168252611a2960208401611755565b60ff166020830152611a3d6040840161174a565b63ffffffff166040830152611a546060840161174a565b63ffffffff166060830152611a6b6080840161174a565b63ffffffff166080830152611a8260a0840161174a565b63ffffffff1660a0830152611a9960c0840161173f565b6cffffffffffffffffffffffffff1660c0830152611abd60e08084019085016118a0565b6102e092830135919092015290565b61030081016103118284611902565b6103208101611aea8285611902565b63ffffffff83166103008301529392505050565b60008219821115611b1157611b11611c51565b500190565b600063ffffffff808316818516808303821115611b3557611b35611c51565b01949350505050565b600061ffff80841680611b5357611b53611c67565b92169190910492915050565b600082821015611b7157611b71611c51565b500390565b600063ffffffff83811690831681811015611b9357611b93611c51565b039392505050565b81816000805b6010811015611bfc578335611bb581611f0a565b835463ffffffff600385901b81811b801990931693909116901b1617835560209390930192600490910190601c821115611bf457600091506001830192505b600101611ba1565b505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611c3657611c36611c51565b5060010190565b600082611c4c57611c4c611c67565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6000813561031181611eec565b6000813561031181611f0a565b8135611cce81611f1c565b60ff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082161783556020840135611d0b81611f1c565b61ff008160081b16837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000841617178455505050611d84611d4d60408401611cb6565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff1660109190911b65ffffffff000016178255565b611dce611d9360608401611cb6565b82547fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1660309190911b69ffffffff00000000000016178255565b611e1c611ddd60808401611cb6565b82547fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff1660509190911b6dffffffff0000000000000000000016178255565b611e6e611e2b60a08401611cb6565b82547fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff1660709190911b71ffffffff000000000000000000000000000016178255565b611ecd611e7d60c08401611ca9565b82547fff00000000000000000000000000ffffffffffffffffffffffffffffffffffff1660909190911b7effffffffffffffffffffffffff00000000000000000000000000000000000016178255565b611edd60e0830160018301611b9b565b6102e082013560038201555050565b6cffffffffffffffffffffffffff81168114611f0757600080fd5b50565b63ffffffff81168114611f0757600080fd5b60ff81168114611f0757600080fdfea2646970667358221220132fa1799f3f662436d462c6e531bb3bab5097313ee0d229d38502db694a319e64736f6c63430008060033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000a506e58ba76671476c9aae1205dab69234c714800000000000000000000000000000000000000000000000000000000000000ff

-----Decoded View---------------
Arg [0] : _owner (address): 0x0a506e58BA76671476C9AAE1205DAB69234c7148
Arg [1] : _cardinality (uint8): 255

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000a506e58ba76671476c9aae1205dab69234c7148
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000ff


Block Transaction Gas Used Reward
view all blocks validated

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.