Contract 0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd3

Contract Overview

Balance:
0 MATIC
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x1c11293276738d3f5dc6e8a560a4cc2cc9b8330630b7b859778b9ab51ec4ef42Execute Round276097242022-08-14 1:06:5620 hrs 54 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x83d8af96c98bccb147060e571b9e9e7e150f4c06a5bdc83fba41200ef2a7d579Execute Round276096622022-08-14 1:01:4020 hrs 59 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x1b1639c504543a9d208cb6118424fedc31f3718bc13d33d362e18a064c5c7508Execute Round276096302022-08-14 0:56:2021 hrs 4 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x4c2f085f6c1f52c7e23e4fba363736b696335f4e58220ed3ce37e42e02796013Execute Round276095972022-08-14 0:50:5921 hrs 10 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x405eedcef7f1d0e44d5d33a53044b7117065da2091359bad84248585a1d47e90Execute Round276095352022-08-14 0:45:4821 hrs 15 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x7abc9254cc8b533915f66a0f12845016e25821f08f93f1c1a1895ca2fbea228bExecute Round276095032022-08-14 0:40:2821 hrs 20 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x4f48784d78aaab8cd03a36c3050a06a954b3dcb9a72e9ca839fd03dbc867d82cExecute Round276094702022-08-14 0:35:0221 hrs 26 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000008
0x4639e2402da6ec222a452f472987e082d7bdbb521d20dadedff92f81c628824eExecute Round276094082022-08-14 0:29:5221 hrs 31 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x65879aacd7b5138fcf8880afecb529686662273ce386a97e793246b2d2c9e708Execute Round276093472022-08-14 0:24:4621 hrs 36 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0xb07953bec5cdbefdb20f37977eb810fd886dd1608bf9f84b196dd3ad74e86b08Execute Round276093142022-08-14 0:19:3521 hrs 41 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x9bf2e15560f79c1a71bd283f70c6728ca79506ff450e06b29b9975b5f594fb02Execute Round276092822022-08-14 0:14:1521 hrs 47 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x8f3c145e53459d03b84565ceb89d0fccbdb737ac8cdf27d9981db85314c5ee74Genesis Lock Rou...276092212022-08-14 0:08:5421 hrs 52 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.006304830001 30.000000008
0x0879b9dfb9c1cb63b73c6291bb3f1a93a0dd4f4e17b9b070c532430cf631f80fGenesis Start Ro...276091872022-08-14 0:03:4321 hrs 57 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.003969660001 30.000000008
0xd1c1da01a194965e7698e47fcb8fed66eeac09559610ba03fb3fd3e1e7e08546Unpause276091852022-08-14 0:03:2321 hrs 57 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.00114276 30.000000007
0xa6110a6b7cc3147087d072d200d539de57d9e3bbf10c0e621c1bd2ea8878075bPause276091652022-08-14 0:00:0322 hrs 1 min ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.00099351 30.000000007
0xd9d21be71fbb997174b0d731eb927c100a5e7fef99ec23334f5f6eca122f6060Execute Round276079112022-08-13 21:29:231 day 31 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x25c9c236a11089d762fe8dbd006730c35ccbf34e8686b06bf6953bb36a5e1051Execute Round276078792022-08-13 21:24:031 day 37 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x4ae06768f7cb95f661dd448cce7bec9c3eae890e4ebfa223fb03eb596ff60390Execute Round276078232022-08-13 21:18:421 day 42 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x7ec9300814caa5099afc85e01a7fdc41158f7502d934d2029d936ca50490fad2Execute Round276077842022-08-13 21:13:311 day 47 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0xb4537990951755de9bd7ca7e65500d151ef04bc1e6cb049b60d530cd7f50f5c0Execute Round276077522022-08-13 21:08:111 day 53 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x01960054a9cee98f9fd65f7ecd60b1f0526ff568ff3555ca489dd5c0ab0a4a71Execute Round276076972022-08-13 21:02:501 day 58 mins ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0xbf9f9ad19ba1faccdbccd50bf9309ae4bdd7c8fde448bdcf31c16abd06e4b31aExecute Round276076572022-08-13 20:57:391 day 1 hr ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x710d57db52f15a5a16616804f636b08423b88172e95b158ebec01fa118183623Execute Round276076252022-08-13 20:52:191 day 1 hr ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x305622bf7c52ddbcccb5117ff555774b3a0e83c53881fa150318b81cb548e6faExecute Round276075712022-08-13 20:46:581 day 1 hr ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
0x6e693ddd2d449ee047bb6b133b44d77b68aed2269c74b842355c382ae0305e10Execute Round276075302022-08-13 20:41:471 day 1 hr ago0x916f8e7566dd63d7c444468cadea37e80f7f8048 IN  0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30 MATIC0.008847330002 30.000000007
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x7bddc2e56514b29a4caa56b13df3b7edbaafabdfce68948f853de95620362528276051202022-08-13 15:51:251 day 6 hrs ago 0x6c6991de5a00d8534e80eb73dfe3dec8362d6dd30x916f8e7566dd63d7c444468cadea37e80f7f80482.891427641306080787 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ArkaPrediction

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : ArkaPrediction.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;
pragma abicoder v2;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import {IDIAOracle} from "./Interface/IDIAOracle.sol";

/**
 * @title ArkaPrediction
 */
contract ArkaPrediction is Ownable, Pausable, ReentrancyGuard {
    using SafeERC20 for IERC20;

    AggregatorV3Interface public oracle;
    IDIAOracle public diaOracle;
    bool public isChainlink;

    bool public genesisLockOnce = false;
    bool public genesisStartOnce = false;

    address public adminAddress; // address of the admin
    address public operatorAddress; // address of the operator

    uint256 public bufferSeconds; // number of seconds for valid execution of a prediction round
    uint256 public intervalSeconds; // interval in seconds between two prediction rounds

    uint256 public minBetAmount; // minimum betting amount (denominated in wei)
    uint256 public treasuryFee; // treasury rate (e.g. 200 = 2%, 150 = 1.50%)
    uint256 public treasuryAmount; // treasury amount that was not claimed

    uint256 public currentEpoch; // current epoch for prediction round

    uint256 public oracleLatestRoundId; 

    uint256 public oracleUpdateAllowance; // seconds

    uint256 public constant MAX_TREASURY_FEE = 1000; // 10%

    string public pairPrice;
    uint256 private priceRoundCounter = 0;
    address private oracleAddress = address(0);

    mapping(uint256 => mapping(address => BetInfo)) public ledger;
    mapping(uint256 => Round) public rounds;
    mapping(address => uint256[]) public userRounds;

    enum Position {
        Bull,
        Bear
    }

    struct Round {
        uint256 epoch;
        uint256 startTimestamp;
        uint256 lockTimestamp;
        uint256 closeTimestamp;
        uint256 lockPrice;
        uint256 closePrice;
        uint256 lockOracleId;
        uint256 closeOracleId;
        uint256 totalAmount;
        uint256 bullAmount;
        uint256 bearAmount;
        uint256 rewardBaseCalAmount;
        uint256 rewardAmount;
        bool oracleCalled;
    }

    struct BetInfo {
        Position position;
        uint256 amount;
        bool claimed; // default false
    }

    event BetBear(
        address indexed sender,
        uint256 indexed epoch,
        uint256 amount
    );
    event BetBull(
        address indexed sender,
        uint256 indexed epoch,
        uint256 amount
    );
    event Claim(address indexed sender, uint256 indexed epoch, uint256 amount);
    event EndRound(
        uint256 indexed epoch,
        uint256 indexed roundId,
        uint256 price
    );
    event LockRound(
        uint256 indexed epoch,
        uint256 indexed roundId,
        uint256 price
    );

    event NewAdminAddress(address admin);
    event NewBufferAndIntervalSeconds(
        uint256 bufferSeconds,
        uint256 intervalSeconds
    );
    event NewMinBetAmount(uint256 indexed epoch, uint256 minBetAmount);
    event NewTreasuryFee(uint256 indexed epoch, uint256 treasuryFee);
    event NewOperatorAddress(address operator);
    event NewOracle(address oracle, bool isChainlink);
    event NewOracleUpdateAllowance(uint256 oracleUpdateAllowance);

    event Pause(uint256 indexed epoch);
    event RewardsCalculated(
        uint256 indexed epoch,
        uint256 rewardBaseCalAmount,
        uint256 rewardAmount,
        uint256 treasuryAmount
    );

    event StartRound(uint256 indexed epoch);
    event TokenRecovery(address indexed token, uint256 amount);
    event TreasuryClaim(uint256 amount);
    event Unpause(uint256 indexed epoch);

    modifier onlyAdmin() {
        require(msg.sender == adminAddress, "Not admin");
        _;
    }

    modifier onlyAdminOrOperator() {
        require(
            msg.sender == adminAddress || msg.sender == operatorAddress,
            "Not operator/admin"
        );
        _;
    }

    modifier onlyOperator() {
        require(msg.sender == operatorAddress, "Not operator");
        _;
    }

    modifier notContract() {
        require(!_isContract(msg.sender), "Contract not allowed");
        require(msg.sender == tx.origin, "Proxy contract not allowed");
        _;
    }

    /**
     * @notice Constructor
     * @param _adminAddress: admin address
     * @param _operatorAddress: operator address
     * @param _intervalSeconds: number of time within an interval
     * @param _bufferSeconds: buffer of time for resolution of price
     * @param _minBetAmount: minimum bet amounts (in wei)
     * @param _oracleUpdateAllowance: oracle update allowance
     * @param _treasuryFee: treasury fee (1000 = 10%)
     * @param _pairPrice: pair price
     */
    constructor(
        address _adminAddress,
        address _operatorAddress,
        uint256 _intervalSeconds,
        uint256 _bufferSeconds,
        uint256 _minBetAmount,
        uint256 _oracleUpdateAllowance,
        uint256 _treasuryFee,
        string memory _pairPrice
    ) {
        require(_treasuryFee <= MAX_TREASURY_FEE, "Treasury fee too high");
        
        adminAddress = _adminAddress;
        operatorAddress = _operatorAddress;
        intervalSeconds = _intervalSeconds;
        bufferSeconds = _bufferSeconds;
        minBetAmount = _minBetAmount;
        oracleUpdateAllowance = _oracleUpdateAllowance;
        treasuryFee = _treasuryFee;
        pairPrice = _pairPrice;
        // contract paused to be set the oracle address
        _pause();
    }

    /**
     * @notice Bet bear position
     * @param epoch: epoch
     */
    function betBear(uint256 epoch)
        external
        payable
        whenNotPaused
        nonReentrant
        notContract
    {
        require(epoch == currentEpoch, "Bet is too early/late");
        require(_bettable(epoch), "Round not bettable");
        require(
            msg.value >= minBetAmount,
            "Bet amount must be greater than minBetAmount"
        );
        require(
            ledger[epoch][msg.sender].amount == 0,
            "Can only bet once per round"
        );

        // Update round data
        uint256 amount = msg.value;
        Round storage round = rounds[epoch];
        round.totalAmount = round.totalAmount + amount;
        round.bearAmount = round.bearAmount + amount;

        // Update user data
        BetInfo storage betInfo = ledger[epoch][msg.sender];
        betInfo.position = Position.Bear;
        betInfo.amount = amount;
        userRounds[msg.sender].push(epoch);

        emit BetBear(msg.sender, epoch, amount);
    }

    /**
     * @notice Bet bull position
     * @param epoch: epoch
     */
    function betBull(uint256 epoch)
        external
        payable
        whenNotPaused
        nonReentrant
        notContract
    {
        require(epoch == currentEpoch, "Bet is too early/late");
        require(_bettable(epoch), "Round not bettable");
        require(
            msg.value >= minBetAmount,
            "Bet amount must be greater than minBetAmount"
        );
        require(
            ledger[epoch][msg.sender].amount == 0,
            "Can only bet once per round"
        );

        // Update round data
        uint256 amount = msg.value;
        Round storage round = rounds[epoch];
        round.totalAmount = round.totalAmount + amount;
        round.bullAmount = round.bullAmount + amount;

        // Update user data
        BetInfo storage betInfo = ledger[epoch][msg.sender];
        betInfo.position = Position.Bull;
        betInfo.amount = amount;
        userRounds[msg.sender].push(epoch);

        emit BetBull(msg.sender, epoch, amount);
    }

    /**
     * @notice Claim reward for an array of epochs
     * @param epochs: array of epochs
     */
    function claim(uint256[] calldata epochs)
        external
        nonReentrant
        notContract
    {
        uint256 reward; // Initializes reward

        for (uint256 i = 0; i < epochs.length; i++) {
            require(
                rounds[epochs[i]].startTimestamp != 0,
                "Round has not started"
            );
            require(
                block.timestamp > rounds[epochs[i]].closeTimestamp,
                "Round has not ended"
            );

            uint256 addedReward = 0;

            // Round valid, claim rewards
            if (rounds[epochs[i]].oracleCalled) {
                require(
                    claimable(epochs[i], msg.sender),
                    "Not eligible for claim"
                );
                Round memory round = rounds[epochs[i]];
                addedReward =
                    (ledger[epochs[i]][msg.sender].amount *
                        round.rewardAmount) /
                    round.rewardBaseCalAmount;
            }
            // Round invalid, refund bet amount
            else {
                require(
                    refundable(epochs[i], msg.sender),
                    "Not eligible for refund"
                );
                addedReward = ledger[epochs[i]][msg.sender].amount;
            }

            ledger[epochs[i]][msg.sender].claimed = true;
            reward += addedReward;

            emit Claim(msg.sender, epochs[i], addedReward);
        }

        if (reward > 0) {
            _safeTransferBNB(address(msg.sender), reward);
        }
    }

    /**
     * @notice Start the next round n, lock price for round n-1, end round n-2
     * @dev Callable by operator
     */
    function executeRound() external whenNotPaused onlyOperator {
        require(
            genesisStartOnce && genesisLockOnce,
            "Can only run after genesisStartRound and genesisLockRound is triggered"
        );

        priceRoundCounter += 1;
        (uint256 currentRoundId, uint256 currentPrice) = _getPriceFromOracle();

        oracleLatestRoundId = currentRoundId;

        // CurrentEpoch refers to previous round (n-1)
        _safeLockRound(currentEpoch, currentRoundId, currentPrice);
        _safeEndRound(currentEpoch - 1, currentRoundId, currentPrice);
        _calculateRewards(currentEpoch - 1);

        // Increment currentEpoch to current round (n)
        currentEpoch = currentEpoch + 1;
        _safeStartRound(currentEpoch);
    }

    /**
     * @notice Lock genesis round
     * @dev Callable by operator
     */
    function genesisLockRound() external whenNotPaused onlyOperator {
        require(
            genesisStartOnce,
            "Can only run after genesisStartRound is triggered"
        );
        require(!genesisLockOnce, "Can only run genesisLockRound once");

        priceRoundCounter += 1;
        (uint256 currentRoundId, uint256 currentPrice) = _getPriceFromOracle();

        oracleLatestRoundId = currentRoundId;

        _safeLockRound(currentEpoch, currentRoundId, currentPrice);

        currentEpoch = currentEpoch + 1;
        _startRound(currentEpoch);
        genesisLockOnce = true;
    }

    /**
     * @notice Start genesis round
     * @dev Callable by admin or operator
     */
    function genesisStartRound() external whenNotPaused onlyOperator {
        require(oracleAddress != address(0), "Cannot be zero address");
        require(!genesisStartOnce, "Can only run genesisStartRound once");

        currentEpoch = currentEpoch + 1;
        _startRound(currentEpoch);
        genesisStartOnce = true;
    }

    /**
     * @notice called by the admin to pause, triggers stopped state
     * @dev Callable by admin or operator
     */
    function pause() external whenNotPaused onlyAdminOrOperator {
        _pause();

        emit Pause(currentEpoch);
    }

    /**
     * @notice Claim all rewards in treasury
     * @dev Callable by admin
     */
    function claimTreasury() external nonReentrant onlyAdmin {
        uint256 currentTreasuryAmount = treasuryAmount;
        treasuryAmount = 0;
        _safeTransferBNB(adminAddress, currentTreasuryAmount);

        emit TreasuryClaim(currentTreasuryAmount);
    }

    /**
     * @notice called by the admin to unpause, returns to normal state
     * Reset genesis state. Once paused, the rounds would need to be kickstarted by genesis
     */
    function unpause() external whenPaused onlyAdmin {
        genesisStartOnce = false;
        genesisLockOnce = false;
        _unpause();

        emit Unpause(currentEpoch);
    }

    /**
     * @notice Set buffer and interval (in seconds)
     * @dev Callable by admin
     */
    function setBufferAndIntervalSeconds(
        uint256 _bufferSeconds,
        uint256 _intervalSeconds
    ) external whenPaused onlyAdmin {
        require(
            _bufferSeconds < _intervalSeconds,
            "bufferSeconds must be inferior to intervalSeconds"
        );
        bufferSeconds = _bufferSeconds;
        intervalSeconds = _intervalSeconds;

        emit NewBufferAndIntervalSeconds(_bufferSeconds, _intervalSeconds);
    }

    /**
     * @notice Set minBetAmount
     * @dev Callable by admin
     */
    function setMinBetAmount(uint256 _minBetAmount)
        external
        whenPaused
        onlyAdmin
    {
        require(_minBetAmount != 0, "Must be superior to 0");
        minBetAmount = _minBetAmount;

        emit NewMinBetAmount(currentEpoch, minBetAmount);
    }

    /**
     * @notice Set operator address
     * @dev Callable by admin
     */
    function setOperator(address _operatorAddress) external onlyAdmin {
        require(_operatorAddress != address(0), "Cannot be zero address");
        operatorAddress = _operatorAddress;

        emit NewOperatorAddress(_operatorAddress);
    }

    /**
     * @notice Set Oracle address
     * @dev Callable by admin
     */
    function setOracle(address _oracle, bool _isChainlink) external whenPaused onlyAdmin {
        require(_oracle != address(0), "Cannot be zero address");
        oracleAddress = _oracle;
        oracleLatestRoundId = 0;
        isChainlink = _isChainlink;
        if (_isChainlink) {
            oracle = AggregatorV3Interface(_oracle);
            // Dummy check to make sure the interface implements this function properly
            oracle.latestRoundData();
        } else {
            diaOracle = IDIAOracle(_oracle);
        }

        emit NewOracle(_oracle, _isChainlink);
    }

    /**
     * @notice Set oracle update allowance
     * @dev Callable by admin
     */
    function setOracleUpdateAllowance(uint256 _oracleUpdateAllowance)
        external
        whenPaused
        onlyAdmin
    {
        oracleUpdateAllowance = _oracleUpdateAllowance;

        emit NewOracleUpdateAllowance(_oracleUpdateAllowance);
    }

    /**
     * @notice Set treasury fee
     * @dev Callable by admin
     */
    function setTreasuryFee(uint256 _treasuryFee)
        external
        whenPaused
        onlyAdmin
    {
        require(_treasuryFee <= MAX_TREASURY_FEE, "Treasury fee too high");
        treasuryFee = _treasuryFee;

        emit NewTreasuryFee(currentEpoch, treasuryFee);
    }

    /**
     * @notice It allows the owner to recover tokens sent to the contract by mistake
     * @param _token: token address
     * @param _amount: token amount
     * @dev Callable by owner
     */
    function recoverToken(address _token, uint256 _amount) external onlyOwner {
        IERC20(_token).safeTransfer(address(msg.sender), _amount);

        emit TokenRecovery(_token, _amount);
    }

    /**
     * @notice Set admin address
     * @dev Callable by owner
     */
    function setAdmin(address _adminAddress) external onlyOwner {
        require(_adminAddress != address(0), "Cannot be zero address");
        adminAddress = _adminAddress;

        emit NewAdminAddress(_adminAddress);
    }

    /**
     * @notice Returns round epochs and bet information for a user that has participated
     * @param user: user address
     * @param cursor: cursor
     * @param size: size
     */
    function getUserRounds(
        address user,
        uint256 cursor,
        uint256 size
    )
        external
        view
        returns (
            uint256[] memory,
            BetInfo[] memory,
            uint256
        )
    {
        uint256 length = size;

        if (length > userRounds[user].length - cursor) {
            length = userRounds[user].length - cursor;
        }

        uint256[] memory values = new uint256[](length);
        BetInfo[] memory betInfo = new BetInfo[](length);

        for (uint256 i = 0; i < length; i++) {
            values[i] = userRounds[user][cursor + i];
            betInfo[i] = ledger[values[i]][user];
        }

        return (values, betInfo, cursor + length);
    }

    /**
     * @notice Returns round epochs length
     * @param user: user address
     */
    function getUserRoundsLength(address user) external view returns (uint256) {
        return userRounds[user].length;
    }

    /**
     * @notice Get the claimable stats of specific epoch and user account
     * @param epoch: epoch
     * @param user: user address
     */
    function claimable(uint256 epoch, address user) public view returns (bool) {
        BetInfo memory betInfo = ledger[epoch][user];
        Round memory round = rounds[epoch];
        if (round.lockPrice == round.closePrice) {
            return false;
        }
        return
            round.oracleCalled &&
            betInfo.amount != 0 &&
            !betInfo.claimed &&
            ((round.closePrice > round.lockPrice &&
                betInfo.position == Position.Bull) ||
                (round.closePrice < round.lockPrice &&
                    betInfo.position == Position.Bear));
    }

    /**
     * @notice Get the refundable stats of specific epoch and user account
     * @param epoch: epoch
     * @param user: user address
     */
    function refundable(uint256 epoch, address user)
        public
        view
        returns (bool)
    {
        BetInfo memory betInfo = ledger[epoch][user];
        Round memory round = rounds[epoch];
        return
            !round.oracleCalled &&
            !betInfo.claimed &&
            block.timestamp > round.closeTimestamp + bufferSeconds &&
            betInfo.amount != 0;
    }

    /**
     * @notice Calculate rewards for round
     * @param epoch: epoch
     */
    function _calculateRewards(uint256 epoch) internal {
        require(
            rounds[epoch].rewardBaseCalAmount == 0 &&
                rounds[epoch].rewardAmount == 0,
            "Rewards calculated"
        );
        Round storage round = rounds[epoch];
        uint256 rewardBaseCalAmount;
        uint256 treasuryAmt;
        uint256 rewardAmount;

        // Bull wins
        if (round.closePrice > round.lockPrice) {
            rewardBaseCalAmount = round.bullAmount;
            treasuryAmt = (round.totalAmount * treasuryFee) / 10000;
            rewardAmount = round.totalAmount - treasuryAmt;
        }
        // Bear wins
        else if (round.closePrice < round.lockPrice) {
            rewardBaseCalAmount = round.bearAmount;
            treasuryAmt = (round.totalAmount * treasuryFee) / 10000;
            rewardAmount = round.totalAmount - treasuryAmt;
        }
        // House wins
        //We need to change this part to something more fair
        else {
            rewardBaseCalAmount = 0;
            rewardAmount = 0;
            treasuryAmt = round.totalAmount;
        }
        round.rewardBaseCalAmount = rewardBaseCalAmount;
        round.rewardAmount = rewardAmount;

        // Add to treasury
        treasuryAmount += treasuryAmt;

        emit RewardsCalculated(
            epoch,
            rewardBaseCalAmount,
            rewardAmount,
            treasuryAmt
        );
    }

    /**
     * @notice End round
     * @param epoch: epoch
     * @param roundId: roundId
     * @param price: price of the round
     */
    function _safeEndRound(
        uint256 epoch,
        uint256 roundId,
        uint256 price
    ) internal {
        require(
            rounds[epoch].lockTimestamp != 0,
            "Can only end round after round has locked"
        );
        require(
            block.timestamp >= rounds[epoch].closeTimestamp,
            "Can only end round after closeTimestamp"
        );
        require(
            block.timestamp <= rounds[epoch].closeTimestamp + bufferSeconds,
            "Can only end round within bufferSeconds"
        );
        Round storage round = rounds[epoch];
        round.closePrice = price;
        round.closeOracleId = roundId;
        round.oracleCalled = true;

        emit EndRound(epoch, roundId, round.closePrice);
    }

    /**
     * @notice Lock round
     * @param epoch: epoch
     * @param roundId: roundId
     * @param price: price of the round
     */
    function _safeLockRound(
        uint256 epoch,
        uint256 roundId,
        uint256 price
    ) internal {
        require(
            rounds[epoch].startTimestamp != 0,
            "Can only lock round after round has started"
        );
        require(
            block.timestamp >= rounds[epoch].lockTimestamp,
            "Can only lock round after lockTimestamp"
        );
        require(
            block.timestamp <= rounds[epoch].lockTimestamp + bufferSeconds,
            "Can only lock round within bufferSeconds"
        );
        Round storage round = rounds[epoch];
        round.closeTimestamp = block.timestamp + intervalSeconds;
        round.lockPrice = price;
        round.lockOracleId = roundId;

        emit LockRound(epoch, roundId, round.lockPrice);
    }

    /**
     * @notice Start round
     * Previous round n-2 must end
     * @param epoch: epoch
     */
    function _safeStartRound(uint256 epoch) internal {
        require(
            genesisStartOnce,
            "Can only run after genesisStartRound is triggered"
        );
        require(
            rounds[epoch - 2].closeTimestamp != 0,
            "Can only start round after round n-2 has ended"
        );
        require(
            block.timestamp >= rounds[epoch - 2].closeTimestamp,
            "Can only start new round after round n-2 closeTimestamp"
        );
        _startRound(epoch);
    }

    /**
     * @notice Transfer BNB in a safe way
     * @param to: address to transfer BNB to
     * @param value: BNB amount to transfer (in wei)
     */
    function _safeTransferBNB(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}("");
        require(success, "TransferHelper: BNB_TRANSFER_FAILED");
    }

    /**
     * @notice Start round
     * Previous round n-2 must end
     * @param epoch: epoch
     */
    function _startRound(uint256 epoch) internal {
        Round storage round = rounds[epoch];
        round.startTimestamp = block.timestamp;
        round.lockTimestamp = block.timestamp + intervalSeconds;
        round.closeTimestamp = block.timestamp + (2 * intervalSeconds);
        round.epoch = epoch;
        round.totalAmount = 0;

        emit StartRound(epoch);
    }

    /**
     * @notice Determine if a round is valid for receiving bets
     * Round must have started and locked
     * Current timestamp must be within startTimestamp and closeTimestamp
     */
    function _bettable(uint256 epoch) internal view returns (bool) {
        return
            rounds[epoch].startTimestamp != 0 &&
            rounds[epoch].lockTimestamp != 0 &&
            block.timestamp > rounds[epoch].startTimestamp &&
            block.timestamp < rounds[epoch].lockTimestamp;
    }

    /**
     * @notice Get latest recorded price from oracle
     * If it falls below allowed buffer or has not updated, it would be invalid.
     */
    function _getPriceFromOracle() internal view returns (uint256, uint256) {
        uint256 leastAllowedTimestamp = block.timestamp + oracleUpdateAllowance;
        uint256 priceU256;
        uint256 timestampU256;
        uint256 _priceRoundCounter;
        if (isChainlink) {
            (uint80 roundId, int256 price, , uint256 timestamp, ) = oracle
                .latestRoundData();
            priceU256 = uint256(price);
            timestampU256 = uint256(timestamp);
            _priceRoundCounter = roundId;
        } else {
            (uint128 price, uint128 timestamp) = diaOracle.getValue(pairPrice);
            priceU256 = uint256(price);
            timestampU256 = uint256(timestamp);
            _priceRoundCounter = priceRoundCounter;
        }
        require(
            timestampU256 <= leastAllowedTimestamp,
            "Oracle update exceeded max timestamp allowance"
        );
        require(
            _priceRoundCounter > oracleLatestRoundId,
            "Oracle update roundId must be larger than oracleLatestRoundId"
        );
        return (priceRoundCounter, priceU256);
    }

    /**
     * @notice Returns true if `account` is a contract.
     * @param account: account address
     */
    function _isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }
}

File 2 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 3 of 10 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 4 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev 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 account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * 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 is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

    /**
     * @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() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 5 of 10 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 6 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 7 of 10 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AggregatorV3Interface {
  function decimals() external view returns (uint8);

  function description() external view returns (string memory);

  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}

File 8 of 10 : IDIAOracle.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

pragma abicoder v2;


/**
 * @title Interface for Collection Contract
 */
interface IDIAOracle {
 function getValue(string memory key) 
 external 
 view 
 returns (uint128, uint128);
}

File 9 of 10 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 10 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_adminAddress","type":"address"},{"internalType":"address","name":"_operatorAddress","type":"address"},{"internalType":"uint256","name":"_intervalSeconds","type":"uint256"},{"internalType":"uint256","name":"_bufferSeconds","type":"uint256"},{"internalType":"uint256","name":"_minBetAmount","type":"uint256"},{"internalType":"uint256","name":"_oracleUpdateAllowance","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"},{"internalType":"string","name":"_pairPrice","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BetBear","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BetBull","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"EndRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"LockRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"NewAdminAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"bufferSeconds","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"intervalSeconds","type":"uint256"}],"name":"NewBufferAndIntervalSeconds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minBetAmount","type":"uint256"}],"name":"NewMinBetAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"NewOperatorAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"bool","name":"isChainlink","type":"bool"}],"name":"NewOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oracleUpdateAllowance","type":"uint256"}],"name":"NewOracleUpdateAllowance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryFee","type":"uint256"}],"name":"NewTreasuryFee","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":"uint256","name":"epoch","type":"uint256"}],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardBaseCalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryAmount","type":"uint256"}],"name":"RewardsCalculated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"StartRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TreasuryClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"MAX_TREASURY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"betBear","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"betBull","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bufferSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"epochs","type":"uint256[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"claimable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"diaOracle","outputs":[{"internalType":"contract IDIAOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"executeRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genesisLockOnce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisLockRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genesisStartOnce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisStartRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"cursor","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"getUserRounds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"components":[{"internalType":"enum ArkaPrediction.Position","name":"position","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"internalType":"struct ArkaPrediction.BetInfo[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserRoundsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"intervalSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isChainlink","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"ledger","outputs":[{"internalType":"enum ArkaPrediction.Position","name":"position","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleLatestRoundId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleUpdateAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairPrice","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"refundable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rounds","outputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"lockTimestamp","type":"uint256"},{"internalType":"uint256","name":"closeTimestamp","type":"uint256"},{"internalType":"uint256","name":"lockPrice","type":"uint256"},{"internalType":"uint256","name":"closePrice","type":"uint256"},{"internalType":"uint256","name":"lockOracleId","type":"uint256"},{"internalType":"uint256","name":"closeOracleId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"bullAmount","type":"uint256"},{"internalType":"uint256","name":"bearAmount","type":"uint256"},{"internalType":"uint256","name":"rewardBaseCalAmount","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"bool","name":"oracleCalled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adminAddress","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bufferSeconds","type":"uint256"},{"internalType":"uint256","name":"_intervalSeconds","type":"uint256"}],"name":"setBufferAndIntervalSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBetAmount","type":"uint256"}],"name":"setMinBetAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operatorAddress","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"bool","name":"_isChainlink","type":"bool"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_oracleUpdateAllowance","type":"uint256"}],"name":"setOracleUpdateAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"setTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userRounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040526003805461ffff60a81b191690556000600f55601080546001600160a01b03191690553480156200003457600080fd5b506040516200411c3803806200411c83398101604081905262000057916200031a565b620000623362000142565b6000805460ff60a01b19169055600180556103e8821115620000cb5760405162461bcd60e51b815260206004820152601560248201527f54726561737572792066656520746f6f2068696768000000000000000000000060448201526064015b60405180910390fd5b600480546001600160a01b03808b166001600160a01b03199283161790925560058054928a1692909116919091179055600786905560068590556008849055600d839055600982905580516200012990600e90602084019062000241565b506200013462000192565b50505050505050506200048a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620001a6600054600160a01b900460ff1690565b15620001e85760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401620000c2565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620002243390565b6040516001600160a01b03909116815260200160405180910390a1565b8280546200024f906200044d565b90600052602060002090601f016020900481019282620002735760008555620002be565b82601f106200028e57805160ff1916838001178555620002be565b82800160010185558215620002be579182015b82811115620002be578251825591602001919060010190620002a1565b50620002cc929150620002d0565b5090565b5b80821115620002cc5760008155600101620002d1565b80516001600160a01b0381168114620002ff57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600080610100898b0312156200033857600080fd5b6200034389620002e7565b9750602062000354818b01620002e7565b975060408a0151965060608a0151955060808a0151945060a08a0151935060c08a0151925060e08a015160018060401b03808211156200039357600080fd5b818c0191508c601f830112620003a857600080fd5b815181811115620003bd57620003bd62000304565b604051601f8201601f19908116603f01168101908382118183101715620003e857620003e862000304565b816040528281528f868487010111156200040157600080fd5b600093505b8284101562000425578484018601518185018701529285019262000406565b82841115620004375760008684830101525b8096505050505050509295985092959890939650565b600181811c908216806200046257607f821691505b602082108114156200048457634e487b7160e01b600052602260045260246000fd5b50919050565b613c82806200049a6000396000f3fe6080604052600436106102715760003560e01c80637dc0d1d01161014f578063cc32d176116100c1578063ec3247031161007a578063ec32470314610826578063f2b3c8091461083c578063f2fde38b14610852578063f7fdec2814610872578063fa968eea14610893578063fc6f9468146108a957600080fd5b8063cc32d17614610784578063cf2f50391461079a578063d9d55eac146107ba578063dd1f7596146107cf578063e4cb1485146107ef578063eaba23611461081057600080fd5b80639491f94d116101135780639491f94d146106c0578063951fd600146106e2578063a0c7f71c14610711578063aa6b873a14610731578063b29a814014610744578063b3ab15fb1461076457600080fd5b80637dc0d1d0146105585780638456cb5914610578578063890dc7661461058d5780638c65c81f146105ad5780638da5cb5b146106a257600080fd5b806365360843116101e85780637285c58b116101ac5780637285c58b1461047c57806376671808146104d757806377e741c7146104ed5780637b3205f51461050d5780637bf41254146105225780637d1cd04f1461054257600080fd5b806365360843146103e75780636ba4c138146104075780636c18859314610427578063704b6c0214610447578063715018a61461046757600080fd5b8063368acb091161023a578063368acb091461035f5780633f4ba83a14610375578063452fd75a1461038a57806357fb096f1461039f5780635c975abb146103b257806360554011146103d157600080fd5b80623bdc74146102765780630f74174f1461028d578063127effb2146102c3578063273867d4146102fb5780632ce773cd1461033f575b600080fd5b34801561028257600080fd5b5061028b6108c9565b005b34801561029957600080fd5b506003546102ae90600160a81b900460ff1681565b60405190151581526020015b60405180910390f35b3480156102cf57600080fd5b506005546102e3906001600160a01b031681565b6040516001600160a01b0390911681526020016102ba565b34801561030757600080fd5b5061033161031636600461347e565b6001600160a01b031660009081526013602052604090205490565b6040519081526020016102ba565b34801561034b57600080fd5b506003546102e3906001600160a01b031681565b34801561036b57600080fd5b50610331600a5481565b34801561038157600080fd5b5061028b61097d565b34801561039657600080fd5b5061028b610a14565b61028b6103ad366004613499565b610b27565b3480156103be57600080fd5b50600054600160a01b900460ff166102ae565b3480156103dd57600080fd5b50610331600d5481565b3480156103f357600080fd5b5061028b6104023660046134c0565b610d93565b34801561041357600080fd5b5061028b6104223660046134f7565b610f49565b34801561043357600080fd5b5061028b610442366004613499565b61143a565b34801561045357600080fd5b5061028b61046236600461347e565b611511565b34801561047357600080fd5b5061028b6115b6565b34801561048857600080fd5b506104c861049736600461356c565b601160209081526000928352604080842090915290825290208054600182015460029092015460ff91821692911683565b6040516102ba939291906135d0565b3480156104e357600080fd5b50610331600b5481565b3480156104f957600080fd5b5061028b610508366004613499565b6115ec565b34801561051957600080fd5b5061028b6116c1565b34801561052e57600080fd5b506102ae61053d36600461356c565b611844565b34801561054e57600080fd5b5061033160075481565b34801561056457600080fd5b506002546102e3906001600160a01b031681565b34801561058457600080fd5b5061028b6119b4565b34801561059957600080fd5b5061028b6105a83660046135f4565b611a78565b3480156105b957600080fd5b506106386105c8366004613499565b601260205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600a8b0154600b8c0154600c8d0154600d909d01549b9c9a9b999a98999798969795969495939492939192909160ff168e565b604080519e8f5260208f019d909d529b8d019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e088015261010087015261012086015261014085015261016084015261018083015215156101a08201526101c0016102ba565b3480156106ae57600080fd5b506000546001600160a01b03166102e3565b3480156106cc57600080fd5b506106d5611b74565b6040516102ba9190613646565b3480156106ee57600080fd5b506107026106fd366004613679565b611c02565b6040516102ba939291906136ac565b34801561071d57600080fd5b506102ae61072c36600461356c565b611e59565b61028b61073f366004613499565b612021565b34801561075057600080fd5b5061028b61075f36600461374f565b612282565b34801561077057600080fd5b5061028b61077f36600461347e565b612307565b34801561079057600080fd5b5061033160095481565b3480156107a657600080fd5b5061028b6107b5366004613499565b6123a5565b3480156107c657600080fd5b5061028b61242d565b3480156107db57600080fd5b506103316107ea36600461374f565b61257e565b3480156107fb57600080fd5b506003546102ae90600160a01b900460ff1681565b34801561081c57600080fd5b5061033160065481565b34801561083257600080fd5b50610331600c5481565b34801561084857600080fd5b506103316103e881565b34801561085e57600080fd5b5061028b61086d36600461347e565b6125af565b34801561087e57600080fd5b506003546102ae90600160b01b900460ff1681565b34801561089f57600080fd5b5061033160085481565b3480156108b557600080fd5b506004546102e3906001600160a01b031681565b600260015414156108f55760405162461bcd60e51b81526004016108ec90613779565b60405180910390fd5b60026001556004546001600160a01b031633146109245760405162461bcd60e51b81526004016108ec906137b0565b600a80546000909155600454610943906001600160a01b03168261264a565b6040518181527fb9197c6b8e21274bd1e2d9c956a88af5cfee510f630fab3f046300f88b4223619060200160405180910390a15060018055565b600054600160a01b900460ff166109a65760405162461bcd60e51b81526004016108ec906137d3565b6004546001600160a01b031633146109d05760405162461bcd60e51b81526004016108ec906137b0565b6003805461ffff60a81b191690556109e66126fe565b600b546040517faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab790600090a2565b600054600160a01b900460ff1615610a3e5760405162461bcd60e51b81526004016108ec90613801565b6005546001600160a01b03163314610a685760405162461bcd60e51b81526004016108ec9061382b565b6010546001600160a01b0316610a905760405162461bcd60e51b81526004016108ec90613851565b600354600160b01b900460ff1615610af65760405162461bcd60e51b815260206004820152602360248201527f43616e206f6e6c792072756e2067656e657369735374617274526f756e64206f6044820152626e636560e81b60648201526084016108ec565b600b54610b04906001613897565b600b819055610b1290612774565b6003805460ff60b01b1916600160b01b179055565b600054600160a01b900460ff1615610b515760405162461bcd60e51b81526004016108ec90613801565b60026001541415610b745760405162461bcd60e51b81526004016108ec90613779565b6002600155333b15610b985760405162461bcd60e51b81526004016108ec906138af565b333214610bb75760405162461bcd60e51b81526004016108ec906138dd565b600b548114610c005760405162461bcd60e51b815260206004820152601560248201527442657420697320746f6f206561726c792f6c61746560581b60448201526064016108ec565b610c09816127f2565b610c4a5760405162461bcd60e51b8152602060048201526012602482015271526f756e64206e6f74206265747461626c6560701b60448201526064016108ec565b600854341015610c6c5760405162461bcd60e51b81526004016108ec90613914565b600081815260116020908152604080832033845290915290206001015415610cd65760405162461bcd60e51b815260206004820152601b60248201527f43616e206f6e6c7920626574206f6e63652070657220726f756e64000000000060448201526064016108ec565b60008181526012602052604090206008810154349190610cf7908390613897565b60088201556009810154610d0c908390613897565b6009820155600083815260116020908152604080832033808552908352818420805460ff1916815560018082018890556013855283862080549182018155865294849020909401879055905185815286927f438122d8cff518d18388099a5181f0d17a12b4f1b55faedf6e4a6acee0060c1291015b60405180910390a35050600180555050565b600054600160a01b900460ff16610dbc5760405162461bcd60e51b81526004016108ec906137d3565b6004546001600160a01b03163314610de65760405162461bcd60e51b81526004016108ec906137b0565b6001600160a01b038216610e0c5760405162461bcd60e51b81526004016108ec90613851565b601080546001600160a01b0319166001600160a01b0384161790556000600c556003805460ff60a01b1916600160a01b831580159190910291909117909155610ee557600280546001600160a01b0319166001600160a01b03841690811790915560408051633fabe5a360e21b8152905163feaf968c9160048082019260a092909190829003018186803b158015610ea357600080fd5b505afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edb919061397a565b5050505050610f01565b600380546001600160a01b0319166001600160a01b0384161790555b604080516001600160a01b038416815282151560208201527f6470162d280121500f158df7c52c1156a85ddac1b32c44dbaf0a8819d0e0431791015b60405180910390a15050565b60026001541415610f6c5760405162461bcd60e51b81526004016108ec90613779565b6002600155333b15610f905760405162461bcd60e51b81526004016108ec906138af565b333214610faf5760405162461bcd60e51b81526004016108ec906138dd565b6000805b828110156114205760126000858584818110610fd157610fd16139ca565b90506020020135815260200190815260200160002060010154600014156110325760405162461bcd60e51b8152602060048201526015602482015274149bdd5b99081a185cc81b9bdd081cdd185c9d1959605a1b60448201526064016108ec565b60126000858584818110611048576110486139ca565b9050602002013581526020019081526020016000206003015442116110a55760405162461bcd60e51b8152602060048201526013602482015272149bdd5b99081a185cc81b9bdd08195b991959606a1b60448201526064016108ec565b6000601260008686858181106110bd576110bd6139ca565b60209081029290920135835250810191909152604001600020600d015460ff1615611292576111048585848181106110f7576110f76139ca565b9050602002013533611e59565b6111495760405162461bcd60e51b81526020600482015260166024820152754e6f7420656c696769626c6520666f7220636c61696d60501b60448201526064016108ec565b600060126000878786818110611161576111616139ca565b60209081029290920135835250818101929092526040908101600090812082516101c081018452815481526001820154948101949094526002810154928401929092526003820154606084015260048201546080840152600582015460a0840152600682015460c0840152600782015460e084015260088201546101008401526009820154610120840152600a820154610140840152600b8201546101608401819052600c8301546101808501819052600d9093015460ff1615156101a085015292935060119089898881811061123a5761123a6139ca565b9050602002013581526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000206001015461128091906139e0565b61128a91906139ff565b915050611355565b6112b48585848181106112a7576112a76139ca565b9050602002013533611844565b6113005760405162461bcd60e51b815260206004820152601760248201527f4e6f7420656c696769626c6520666f7220726566756e6400000000000000000060448201526064016108ec565b60116000868685818110611316576113166139ca565b9050602002013581526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000206001015490505b60016011600087878681811061136d5761136d6139ca565b6020908102929092013583525081810192909252604090810160009081203382529092529020600201805460ff19169115159190911790556113af8184613897565b92508484838181106113c3576113c36139ca565b90506020020135336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf78360405161140591815260200190565b60405180910390a3508061141881613a21565b915050610fb3565b50801561143157611431338261264a565b50506001805550565b600054600160a01b900460ff166114635760405162461bcd60e51b81526004016108ec906137d3565b6004546001600160a01b0316331461148d5760405162461bcd60e51b81526004016108ec906137b0565b806114d25760405162461bcd60e51b815260206004820152601560248201527404d757374206265207375706572696f7220746f203605c1b60448201526064016108ec565b6008819055600b546040518281527f90eb87c560a0213754ceb3a7fa3012f01acab0a35602c1e1995adf69dabc9d50906020015b60405180910390a250565b6000546001600160a01b0316331461153b5760405162461bcd60e51b81526004016108ec90613a3c565b6001600160a01b0381166115615760405162461bcd60e51b81526004016108ec90613851565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f137b621413925496477d46e5055ac0d56178bdd724ba8bf843afceef18268ba3906020015b60405180910390a150565b6000546001600160a01b031633146115e05760405162461bcd60e51b81526004016108ec90613a3c565b6115ea600061285d565b565b600054600160a01b900460ff166116155760405162461bcd60e51b81526004016108ec906137d3565b6004546001600160a01b0316331461163f5760405162461bcd60e51b81526004016108ec906137b0565b6103e88111156116895760405162461bcd60e51b81526020600482015260156024820152740a8e4cac2e6eae4f240cccaca40e8dede40d0d2ced605b1b60448201526064016108ec565b6009819055600b546040518281527fb1c4ee38d35556741133da7ff9b6f7ab0fa88d0406133126ff128f635490a85790602001611506565b600054600160a01b900460ff16156116eb5760405162461bcd60e51b81526004016108ec90613801565b6005546001600160a01b031633146117155760405162461bcd60e51b81526004016108ec9061382b565b600354600160b01b900460ff1680156117375750600354600160a81b900460ff165b6117b85760405162461bcd60e51b815260206004820152604660248201527f43616e206f6e6c792072756e2061667465722067656e6573697353746172745260448201527f6f756e6420616e642067656e657369734c6f636b526f756e642069732074726960648201526519d9d95c995960d21b608482015260a4016108ec565b6001600f60008282546117cb9190613897565b9091555060009050806117dc6128ad565b9150915081600c819055506117f4600b548383612b10565b61180d6001600b546118069190613a71565b8383612cde565b6118246001600b5461181f9190613a71565b612e9f565b600b54611832906001613897565b600b8190556118409061301d565b5050565b60008281526011602090815260408083206001600160a01b0385168452909152808220815160608101909252805483929190829060ff16600181111561188c5761188c613598565b600181111561189d5761189d613598565b815260018281015460208084019190915260029384015460ff908116151560409485015260008a81526012835284902084516101c08101865281548152938101549284019290925293810154928201929092526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d909101549091161580156101a08301819052929350909161197e57508160400151155b801561199a575060065481606001516119979190613897565b42115b80156119a95750602082015115155b925050505b92915050565b600054600160a01b900460ff16156119de5760405162461bcd60e51b81526004016108ec90613801565b6004546001600160a01b0316331480611a0157506005546001600160a01b031633145b611a425760405162461bcd60e51b81526020600482015260126024820152712737ba1037b832b930ba37b917b0b236b4b760711b60448201526064016108ec565b611a4a61316d565b600b546040517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d90600090a2565b600054600160a01b900460ff16611aa15760405162461bcd60e51b81526004016108ec906137d3565b6004546001600160a01b03163314611acb5760405162461bcd60e51b81526004016108ec906137b0565b808210611b345760405162461bcd60e51b815260206004820152603160248201527f6275666665725365636f6e6473206d75737420626520696e666572696f7220746044820152706f20696e74657276616c5365636f6e647360781b60648201526084016108ec565b6006829055600781905560408051838152602081018390527fe60149e0431fec12df63dfab5fce2a9cefe9a4d3df5f41cb626f579ae1f2b91a9101610f3d565b600e8054611b8190613a88565b80601f0160208091040260200160405190810160405280929190818152602001828054611bad90613a88565b8015611bfa5780601f10611bcf57610100808354040283529160200191611bfa565b820191906000526020600020905b815481529060010190602001808311611bdd57829003601f168201915b505050505081565b6001600160a01b03831660009081526013602052604081205460609182918490611c2d908790613a71565b811115611c5b576001600160a01b038716600090815260136020526040902054611c58908790613a71565b90505b60008167ffffffffffffffff811115611c7657611c76613ac3565b604051908082528060200260200182016040528015611c9f578160200160208202803683370190505b50905060008267ffffffffffffffff811115611cbd57611cbd613ac3565b604051908082528060200260200182016040528015611d0857816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181611cdb5790505b50905060005b83811015611e3a576001600160a01b038a166000908152601360205260409020611d38828b613897565b81548110611d4857611d486139ca565b9060005260206000200154838281518110611d6557611d656139ca565b60200260200101818152505060116000848381518110611d8757611d876139ca565b602090810291909101810151825281810192909252604090810160009081206001600160a01b038e168252909252908190208151606081019092528054829060ff166001811115611dda57611dda613598565b6001811115611deb57611deb613598565b81526001820154602082015260029091015460ff1615156040909101528251839083908110611e1c57611e1c6139ca565b60200260200101819052508080611e3290613a21565b915050611d0e565b508181611e47858b613897565b95509550955050505093509350939050565b60008281526011602090815260408083206001600160a01b0385168452909152808220815160608101909252805483929190829060ff166001811115611ea157611ea1613598565b6001811115611eb257611eb2613598565b815260018281015460208084019190915260029384015460ff908116151560409485015260008a81526012835284902084516101c081018652815481529381015492840192909252938101549282019290925260038201546060820152600482015460808201819052600583015460a08301819052600684015460c0840152600784015460e084015260088401546101008401526009840154610120840152600a840154610140840152600b840154610160840152600c840154610180840152600d9093015490931615156101a08201529293501415611f97576000925050506119ae565b806101a001518015611fac5750602082015115155b8015611fba57508160400151155b80156119a9575080608001518160a00151118015611fea5750600082516001811115611fe857611fe8613598565b145b806119a9575080608001518160a001511080156119a9575060018251600181111561201757612017613598565b1495945050505050565b600054600160a01b900460ff161561204b5760405162461bcd60e51b81526004016108ec90613801565b6002600154141561206e5760405162461bcd60e51b81526004016108ec90613779565b6002600155333b156120925760405162461bcd60e51b81526004016108ec906138af565b3332146120b15760405162461bcd60e51b81526004016108ec906138dd565b600b5481146120fa5760405162461bcd60e51b815260206004820152601560248201527442657420697320746f6f206561726c792f6c61746560581b60448201526064016108ec565b612103816127f2565b6121445760405162461bcd60e51b8152602060048201526012602482015271526f756e64206e6f74206265747461626c6560701b60448201526064016108ec565b6008543410156121665760405162461bcd60e51b81526004016108ec90613914565b6000818152601160209081526040808320338452909152902060010154156121d05760405162461bcd60e51b815260206004820152601b60248201527f43616e206f6e6c7920626574206f6e63652070657220726f756e64000000000060448201526064016108ec565b600081815260126020526040902060088101543491906121f1908390613897565b6008820155600a810154612206908390613897565b600a820155600083815260116020908152604080832033808552908352818420805460ff1916600190811782558082018890556013855283862080549182018155865294849020909401879055905185815286927f0d8c1fe3e67ab767116a81f122b83c2557a8c2564019cb7c4f83de1aeb1f1f0d9101610d81565b6000546001600160a01b031633146122ac5760405162461bcd60e51b81526004016108ec90613a3c565b6122c06001600160a01b03831633836131d2565b816001600160a01b03167f14f11966a996e0629572e51064726d2057a80fbd34efc066682c06a71dbb6e98826040516122fb91815260200190565b60405180910390a25050565b6004546001600160a01b031633146123315760405162461bcd60e51b81526004016108ec906137b0565b6001600160a01b0381166123575760405162461bcd60e51b81526004016108ec90613851565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fc47d127c07bdd56c5ccba00463ce3bd3c1bca71b4670eea6e5d0c02e4aa156e2906020016115ab565b600054600160a01b900460ff166123ce5760405162461bcd60e51b81526004016108ec906137d3565b6004546001600160a01b031633146123f85760405162461bcd60e51b81526004016108ec906137b0565b600d8190556040518181527f93ccaceac092ffb842c46b8718667a13a80e9058dcd0bd403d0b47215b30da07906020016115ab565b600054600160a01b900460ff16156124575760405162461bcd60e51b81526004016108ec90613801565b6005546001600160a01b031633146124815760405162461bcd60e51b81526004016108ec9061382b565b600354600160b01b900460ff166124aa5760405162461bcd60e51b81526004016108ec90613ad9565b600354600160a81b900460ff161561250f5760405162461bcd60e51b815260206004820152602260248201527f43616e206f6e6c792072756e2067656e657369734c6f636b526f756e64206f6e604482015261636560f01b60648201526084016108ec565b6001600f60008282546125229190613897565b9091555060009050806125336128ad565b9150915081600c8190555061254b600b548383612b10565b600b54612559906001613897565b600b81905561256790612774565b50506003805460ff60a81b1916600160a81b179055565b6013602052816000526040600020818154811061259a57600080fd5b90600052602060002001600091509150505481565b6000546001600160a01b031633146125d95760405162461bcd60e51b81526004016108ec90613a3c565b6001600160a01b03811661263e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ec565b6126478161285d565b50565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612697576040519150601f19603f3d011682016040523d82523d6000602084013e61269c565b606091505b50509050806126f95760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a20424e425f5452414e534645525f46414960448201526213115160ea1b60648201526084016108ec565b505050565b600054600160a01b900460ff166127275760405162461bcd60e51b81526004016108ec906137d3565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000818152601260205260409020426001820181905560075461279691613897565b6002808301919091556007546127ab916139e0565b6127b59042613897565b600382015581815560006008820181905560405183917f939f42374aa9bf1d8d8cd56d8a9110cb040cd8dfeae44080c6fcf2645e51b45291a25050565b60008181526012602052604081206001015415801590612822575060008281526012602052604090206002015415155b801561283e575060008281526012602052604090206001015442115b80156119ae575050600090815260126020526040902060020154421090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000600d54426128c09190613897565b90506000806000600360149054906101000a900460ff1615612986576000806000600260009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561292f57600080fd5b505afa158015612943573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612967919061397a565b509198509096505069ffffffffffffffffffff169350612a2492505050565b6003546040516304b01c2560e51b815260009182916001600160a01b039091169063960384a0906129bc90600e90600401613b2a565b604080518083038186803b1580156129d357600080fd5b505afa1580156129e7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0b9190613be9565b600f546001600160801b03928316975091169450925050505b83821115612a8b5760405162461bcd60e51b815260206004820152602e60248201527f4f7261636c6520757064617465206578636565646564206d61782074696d657360448201526d74616d7020616c6c6f77616e636560901b60648201526084016108ec565b600c548111612b025760405162461bcd60e51b815260206004820152603d60248201527f4f7261636c652075706461746520726f756e644964206d757374206265206c6160448201527f72676572207468616e206f7261636c654c6174657374526f756e64496400000060648201526084016108ec565b5050600f5494909350915050565b600083815260126020526040902060010154612b825760405162461bcd60e51b815260206004820152602b60248201527f43616e206f6e6c79206c6f636b20726f756e6420616674657220726f756e642060448201526a1a185cc81cdd185c9d195960aa1b60648201526084016108ec565b600083815260126020526040902060020154421015612bf35760405162461bcd60e51b815260206004820152602760248201527f43616e206f6e6c79206c6f636b20726f756e64206166746572206c6f636b546960448201526606d657374616d760cc1b60648201526084016108ec565b600654600084815260126020526040902060020154612c129190613897565b421115612c725760405162461bcd60e51b815260206004820152602860248201527f43616e206f6e6c79206c6f636b20726f756e642077697468696e206275666665604482015267725365636f6e647360c01b60648201526084016108ec565b6000838152601260205260409020600754612c8d9042613897565b60038201556004810182905560068101839055604051828152839085907f8cce2cd32b6fe99b5bfd14b18d216efc4141239cfc480872bc95986699f6774d906020015b60405180910390a350505050565b600083815260126020526040902060020154612d4e5760405162461bcd60e51b815260206004820152602960248201527f43616e206f6e6c7920656e6420726f756e6420616674657220726f756e642068604482015268185cc81b1bd8dad95960ba1b60648201526084016108ec565b600083815260126020526040902060030154421015612dbf5760405162461bcd60e51b815260206004820152602760248201527f43616e206f6e6c7920656e6420726f756e6420616674657220636c6f7365546960448201526606d657374616d760cc1b60648201526084016108ec565b600654600084815260126020526040902060030154612dde9190613897565b421115612e3d5760405162461bcd60e51b815260206004820152602760248201527f43616e206f6e6c7920656e6420726f756e642077697468696e206275666665726044820152665365636f6e647360c81b60648201526084016108ec565b600083815260126020526040908190206005810183905560078101849055600d8101805460ff191660011790559051839085907f069bbf284b72705c059a0531d72f09e26a45db7b75ad535c9e925f2dccf039af90612cd09086815260200190565b6000818152601260205260409020600b0154158015612ecd57506000818152601260205260409020600c0154155b612f0e5760405162461bcd60e51b815260206004820152601260248201527114995dd85c991cc818d85b18dd5b185d195960721b60448201526064016108ec565b600081815260126020526040812060048101546005820154919291829182911115612f7257836009015492506127106009548560080154612f4f91906139e0565b612f5991906139ff565b9150818460080154612f6b9190613a71565b9050612fab565b836004015484600501541015612f9e5783600a015492506127106009548560080154612f4f91906139e0565b5050506008810154600090815b600b8401839055600c8401819055600a8054839190600090612fce908490613897565b9091555050604080518481526020810183905290810183905285907f6dfdfcb09c8804d0058826cd2539f1acfbe3cb887c9be03d928035bce0f1a58d9060600160405180910390a25050505050565b600354600160b01b900460ff166130465760405162461bcd60e51b81526004016108ec90613ad9565b60126000613055600284613a71565b815260200190815260200160002060030154600014156130ce5760405162461bcd60e51b815260206004820152602e60248201527f43616e206f6e6c7920737461727420726f756e6420616674657220726f756e6460448201526d081b8b4c881a185cc8195b99195960921b60648201526084016108ec565b601260006130dd600284613a71565b8152602001908152602001600020600301544210156131645760405162461bcd60e51b815260206004820152603760248201527f43616e206f6e6c79207374617274206e657720726f756e64206166746572207260448201527f6f756e64206e2d3220636c6f736554696d657374616d7000000000000000000060648201526084016108ec565b61264781612774565b600054600160a01b900460ff16156131975760405162461bcd60e51b81526004016108ec90613801565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586127573390565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908401526126f9928692916000916132629185169084906132df565b8051909150156126f957808060200190518101906132809190613c13565b6126f95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016108ec565b60606132ee84846000856132f8565b90505b9392505050565b6060824710156133595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016108ec565b6001600160a01b0385163b6133b05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ec565b600080866001600160a01b031685876040516133cc9190613c30565b60006040518083038185875af1925050503d8060008114613409576040519150601f19603f3d011682016040523d82523d6000602084013e61340e565b606091505b509150915061341e828286613429565b979650505050505050565b606083156134385750816132f1565b8251156134485782518084602001fd5b8160405162461bcd60e51b81526004016108ec9190613646565b80356001600160a01b038116811461347957600080fd5b919050565b60006020828403121561349057600080fd5b6132f182613462565b6000602082840312156134ab57600080fd5b5035919050565b801515811461264757600080fd5b600080604083850312156134d357600080fd5b6134dc83613462565b915060208301356134ec816134b2565b809150509250929050565b6000806020838503121561350a57600080fd5b823567ffffffffffffffff8082111561352257600080fd5b818501915085601f83011261353657600080fd5b81358181111561354557600080fd5b8660208260051b850101111561355a57600080fd5b60209290920196919550909350505050565b6000806040838503121561357f57600080fd5b8235915061358f60208401613462565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600281106135cc57634e487b7160e01b600052602160045260246000fd5b9052565b606081016135de82866135ae565b8360208301528215156040830152949350505050565b6000806040838503121561360757600080fd5b50508035926020909101359150565b60005b83811015613631578181015183820152602001613619565b83811115613640576000848401525b50505050565b6020815260008251806020840152613665816040850160208701613616565b601f01601f19169190910160400192915050565b60008060006060848603121561368e57600080fd5b61369784613462565b95602085013595506040909401359392505050565b60608082528451828201819052600091906020906080850190828901855b828110156136e6578151845292840192908401906001016136ca565b5050508481038286015286518082528783019183019060005b818110156137385783516137148482516135ae565b808601518487015260409081015115159084015292840192918501916001016136ff565b505080945050505050826040830152949350505050565b6000806040838503121561376257600080fd5b61376b83613462565b946020939093013593505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600990820152682737ba1030b236b4b760b91b604082015260600190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252600c908201526b2737ba1037b832b930ba37b960a11b604082015260600190565b60208082526016908201527543616e6e6f74206265207a65726f206164647265737360501b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156138aa576138aa613881565b500190565b60208082526014908201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604082015260600190565b6020808252601a908201527f50726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000604082015260600190565b6020808252602c908201527f42657420616d6f756e74206d7573742062652067726561746572207468616e2060408201526b1b5a5b90995d105b5bdd5b9d60a21b606082015260800190565b805169ffffffffffffffffffff8116811461347957600080fd5b600080600080600060a0868803121561399257600080fd5b61399b86613960565b94506020860151935060408601519250606086015191506139be60808701613960565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156139fa576139fa613881565b500290565b600082613a1c57634e487b7160e01b600052601260045260246000fd5b500490565b6000600019821415613a3557613a35613881565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082821015613a8357613a83613881565b500390565b600181811c90821680613a9c57607f821691505b60208210811415613abd57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60208082526031908201527f43616e206f6e6c792072756e2061667465722067656e657369735374617274526040820152701bdd5b99081a5cc81d1c9a59d9d95c9959607a1b606082015260800190565b600060208083526000845481600182811c915080831680613b4c57607f831692505b858310811415613b6a57634e487b7160e01b85526022600452602485fd5b878601838152602001818015613b875760018114613b9857613bc3565b60ff19861682528782019650613bc3565b60008b81526020902060005b86811015613bbd57815484820152908501908901613ba4565b83019750505b50949998505050505050505050565b80516001600160801b038116811461347957600080fd5b60008060408385031215613bfc57600080fd5b613c0583613bd2565b915061358f60208401613bd2565b600060208284031215613c2557600080fd5b81516132f1816134b2565b60008251613c42818460208701613616565b919091019291505056fea26469706673582212204ea3a1fda91dc527df86e35744875da5d7b8626b6de4a1509062a9eae484f80e64736f6c63430008090033000000000000000000000000916f8e7566dd63d7c444468cadea37e80f7f8048000000000000000000000000916f8e7566dd63d7c444468cadea37e80f7f8048000000000000000000000000000000000000000000000000000000000000012b000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000094d415449432f5553440000000000000000000000000000000000000000000000

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

000000000000000000000000916f8e7566dd63d7c444468cadea37e80f7f8048000000000000000000000000916f8e7566dd63d7c444468cadea37e80f7f8048000000000000000000000000000000000000000000000000000000000000012b000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000094d415449432f5553440000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _adminAddress (address): 0x916f8e7566dd63d7c444468cadea37e80f7f8048
Arg [1] : _operatorAddress (address): 0x916f8e7566dd63d7c444468cadea37e80f7f8048
Arg [2] : _intervalSeconds (uint256): 299
Arg [3] : _bufferSeconds (uint256): 117
Arg [4] : _minBetAmount (uint256): 1000
Arg [5] : _oracleUpdateAllowance (uint256): 143
Arg [6] : _treasuryFee (uint256): 300
Arg [7] : _pairPrice (string): MATIC/USD

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000916f8e7566dd63d7c444468cadea37e80f7f8048
Arg [1] : 000000000000000000000000916f8e7566dd63d7c444468cadea37e80f7f8048
Arg [2] : 000000000000000000000000000000000000000000000000000000000000012b
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000075
Arg [4] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [5] : 000000000000000000000000000000000000000000000000000000000000008f
Arg [6] : 000000000000000000000000000000000000000000000000000000000000012c
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [9] : 4d415449432f5553440000000000000000000000000000000000000000000000


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