Contract 0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d5

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xd834651d09dd33aff7a700fcf23f0636de2cf2585b6541c7b9edb7774992225cJoin Tournament301275202022-06-29 7:03:323 days 16 hrs ago0xa71be828db65bd2dc3db91e13f9447edc2387372 IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.001267693001 33.950000041
0x88174cbc132247c4567dad84ee8892d1b843ec82df7033538a94849892a499f0Set Winner301163512022-06-29 0:05:173 days 23 hrs ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.381128220431 45.000000051
0xa221469c3e9ed2721347d42e5de68ed3cbacd0de0d2d01490bb4a3a1c8b49d6dSet Winner301162072022-06-29 0:00:213 days 23 hrs ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.394168230236 45.000000027
0xac35eb3009e139b83ad586f2ade811435e9532cd4331ac5d4df1d7349f3cd837Set Winner301160622022-06-28 23:55:233 days 23 hrs ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.389582055216 45.000000025
0x3240c8234d68009416d6f80bdc6da3796f9f040fdfc6a2911c3478e0e08dd0e1Set Winner301159162022-06-28 23:50:233 days 23 hrs ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.408903345172 45.000000019
0xd55b455dfceda44482c34dff40b86cf037740585850ef16c139fafe59aaf4ed7Set Winner301157722022-06-28 23:45:234 days 1 min ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.382890330161 45.000000019
0xda9246baa84f4a9e83c745bd2dbce2ae00f0abd01aeed69b84e799d9f49a2accSet Winner301156262022-06-28 23:40:234 days 6 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.389997540207 45.000000024
0x739548c1ce0ca2fbcd42b7cb3ecece803e861aaad0f7fde1b68396c2be83e7d8Set Winner301154872022-06-28 23:35:374 days 11 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.386490645214 45.000000025
0xc79aa70510b175a9bbf0ebb0be6874597fb0d8c78dc7497847bb60d62d53d67fSet Winner301154802022-06-28 23:35:234 days 11 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.393398730262 45.00000003
0xa0186f6e31651fbf0ae030becd972ef8d28c554ecef76ef4b5c78dec5b6082a5Set Winner301151942022-06-28 23:25:214 days 21 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.389690011506 45.000000174
0xe145cc30a2bfe84bcb0562b43b3ba7aee1db4c9c6c6832a41fca9fdd5aecb24cSet Winner301151092022-06-28 23:20:234 days 26 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.382782375153 45.000000018
0x43497407b1583459ada6add593c7f94ffc473f6faa471e3e413165e9ec6ffe3bSet Winner301149742022-06-28 23:15:454 days 31 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.386598600214 45.000000025
0x6e924c2629f45f94a87cebdca7953e0104a067ee7470c42d9e4b64eeb72af329Set Winner301149672022-06-28 23:15:314 days 31 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.383197230212 45.000000025
0xd67f23bd65c4687c62d178b32a4c2f3ae143baa714ec7784e47c27f7e82f0e24Set Winner301149602022-06-28 23:15:174 days 31 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.385668855162 45.000000019
0x3dc1e768d25c14fe350f8ce97e1d4dad8d2ffccba8ce392d7089b010f98d3d03Set Winner301145232022-06-28 23:00:154 days 46 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.389889585164 45.000000019
0xe6d68934d57c52b4ab8a20af8a276e13c5db97a34bcddd85ff8091999a9618a1Join Tournament301144202022-06-28 22:56:414 days 50 mins ago0x62144fbfc4051e714f161037299d0198efaa70c3 IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.013790160006 45.000000021
0x47df2d986af088e6b22b5192048ff266ebbc99bf7fed28289c2856012143e12fSet Winner301143812022-06-28 22:55:234 days 51 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.382773285178 45.000000021
0x50e6e2b5aeb7063925b0e3371a8dfaafb4f952bcad580642dca67b1fabeee3d6Join Tournament301143662022-06-28 22:54:494 days 51 mins ago0xe348fcd7073887ff6397b0e376aec3169a36c296 IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.012609450005 45.000000018
0x19bfc00488288d0c43fafa7510c3e975676cbcaea73c5e61241e58f36ccf159fJoin Tournament301142732022-06-28 22:51:394 days 55 mins ago0x9bac1e17c6d30eb8d75472ce1136aede39dbc1c3 IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.013240489516 47.250000058
0xd9162f3d150cca1715c335bea9d620ce1ff75c5fbfd0b9ee43895bb71a502f5eJoin Tournament301142442022-06-28 22:50:414 days 56 mins ago0x00edcd4f586a784624390b706adebb44ead6b74f IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.031619936407 47.250000235
0xd07e7ad1c7dac90c54e59c11c06decb963b5376f281f37b59e49505ba3efa2ccJoin Tournament301142382022-06-28 22:50:234 days 56 mins ago0xe348fcd7073887ff6397b0e376aec3169a36c296 IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.030380757856 47.250000165
0x30ee8743927728663a171e713e432405c4125f046cea53b37f90ea54d4a5bba6Set Winner301142372022-06-28 22:50:194 days 56 mins ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.405155001664 47.250000165
0x31e83f43e93761ea48c7e915379629f5fe41ae31f620df5bd1fecd2cd3b23507Join Tournament301141972022-06-28 22:47:394 days 59 mins ago0x850b651bd1daa2a60437dca5863b339d15a6564d IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.029829555015 45.000000024
0x63b3d7a469f3a7f5b006989814e4cdf62def72ef231889f2c484cff1fccad3dfSet Winner301141532022-06-28 22:45:234 days 1 hr ago0x9233c31669e9b0fc596297d57be24b11ceb8109e IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.389689470164 45.000000019
0x851d7fd50dcbe1aa8fdc728e6e7c6dbf96df0f7bc304b5511ead383e7857ce87Join Tournament301141302022-06-28 22:44:374 days 1 hr ago0xfd50d4d48896e076a02bd5f7534df1244948eaae IN  0xfdc93b0d7b22848f0fd25d8bf926037edfc4d2d50 MATIC0.02893405501345.000000021
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TRVBPTournament

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 8 : Tournament.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { AdminControl } from "./AdminControl.sol";
import { TRVBPWarrior } from "./Warrior.sol";
import { Map } from "./Libs.sol";
import { IWETH } from "./Interfaces.sol";

//
//   +-+ +-+ +-+   +-+ +-+ +-+   +-+ +-+ +-+ +-+ +-+ +-+ +-+
//   |T| |h| |e|   |R| |e| |d|   |V| |i| |l| |l| |a| |g| |e|
//   +-+ +-+ +-+   +-+ +-+ +-+   +-+ +-+ +-+ +-+ +-+ +-+ +-+
//
//
//   The Red Village + Pellar 2021
//

contract TRVBPTournament is TRVBPWarrior, AdminControl, ReentrancyGuard {

  enum TournamentState {
    AVAILABLE,
    READY,
    COMPLETED,
    CANCELLED
  }

  struct TournamentInfo {
    TournamentState state; // 1 = ready, 0 = available, 2 = completed
    uint256 prize_pool;
    Warrior[] warriors;
    uint256 first_winner;
    uint256 second_winner;
    uint256[] third_winners;
    uint256[] fourth_winners;
    string hashKey;
  }

  struct FrequencyInfo {
    uint256 timeCheckpoint;
    uint256 joinedCount;
  }

  // variables
  uint256 public countReady;
  uint256 public countComplete;
  uint256 public countCancel;

  uint256 public platformShare;
  mapping(uint256 => TournamentInfo) private tournaments;
  mapping(address => FrequencyInfo) public frequencyRestriction;

  // events
  event JoinedTournament(uint256 indexed tournamentId, uint256 indexed warriorId, uint256 amount, uint16 style, CLASSES class);
  event TournamentReady(uint256 indexed tournamentId);
  event CancelledTournament(uint256 indexed tournamentId);
  event SetWinners(uint256 indexed tournamentId, uint256 indexed firstWinner, uint256 indexed secondWinner);

  constructor() AdminControl() {
    setupRole(CANCEL_ROLE, 0x9233C31669E9B0fc596297D57BE24B11ceB8109E);
    setupRole(SET_WINNER_ROLE, 0x9233C31669E9B0fc596297D57BE24B11ceB8109E);

    setMaxFightingPerChamp(0, 10999, 1);

    setFrequency(7, 1 weeks);

    uint32 padding = 1000000;

    setSize(padding + 1, padding + 1000000, 8);
    setPayout(padding + 1, padding + 1000000, 0);

    setClass(padding + 1, padding + 200000, CLASSES.BLOODING);
    setClass(padding + 200001, padding + 400000, CLASSES.CLASS_3);
    setClass(padding + 400001, padding + 600000, CLASSES.CLASS_2);
    setClass(padding + 600001, padding + 800000, CLASSES.CLASS_1);
    setClass(padding + 800001, padding + 1000000, CLASSES.BLOODBATH);

    uint256[] memory prices = new uint256[](10);
    prices[0] = 0;
    prices[1] = 0.0008 ether;
    prices[2] = 0.002 ether;
    prices[3] = 0.004 ether;
    prices[4] = 0.0098 ether;
    prices[5] = 0.0196 ether;
    prices[6] = 0.0392 ether;
    prices[7] = 0.0784 ether;
    prices[8] = 0.1958 ether;
    prices[9] = 0.3916 ether;
    uint32 start = 1;
    for (uint8 i = 0; i < 5; i++) {
      for (uint8 j = 0; j < 10; j++) {
        setFee(padding + start, padding + start + 20000 - 1, prices[j]);
        start += 20000;
      }
    }
  }

  function joinTournament(
    uint256 _tournamentId,
    uint256 _warriorId,
    uint16 _style
  ) external {
    address ownerOfWarrior = TRVBPWarrior.getOwnerOf(TRVBP_ADDRESSES, _warriorId);

    // one player can not using warrior id of other players
    require(msg.sender == ownerOfWarrior, "Not allowed");

    (bool canJoin, string memory message) = eligibleJoin(_tournamentId, _warriorId);
    require(canJoin, message);

    // compute fee to join
    (, uint256 amount) = getFee(_tournamentId);

    // compute size to join
    (, uint256 size) = getSize(_tournamentId);

    // compute class to join
    (, uint256 class) = getClass(_tournamentId);


    // pay fee of tournament
    // amount == 0 => free tournament
    if (amount > 0) {
      IWETH(WETH_ADDRESS).transferFrom(ownerOfWarrior, address(this), amount);
    }

    // add warrior statistic
    TRVBPWarrior.updateJoinedStatistic(_tournamentId, _warriorId);

    // add tournament data
    tournaments[_tournamentId].warriors.push(Warrior(_warriorId, _style));
    tournaments[_tournamentId].prize_pool += amount;

    // update frequency checkpoint
    FrequencyInfo storage frequency = frequencyRestriction[msg.sender];
    if (frequency.timeCheckpoint + AdminControl.paddingTime > block.timestamp) {
      frequency.joinedCount++;
    } else {
      frequency.timeCheckpoint = block.timestamp;
      frequency.joinedCount = 1;
    }

    // add some events
    emit JoinedTournament(_tournamentId, _warriorId, amount, _style, CLASSES(class));

    // set state = ready if full room
    if (tournaments[_tournamentId].warriors.length == size) {
      tournaments[_tournamentId].state = TournamentState.READY;
      countReady++;
      // event
      emit TournamentReady(_tournamentId);
    }
  }

  function cancelTournament(uint256 _tournamentId) external nonReentrant onlyRoler(CANCEL_ROLE) {
    require(tournaments[_tournamentId].state == TournamentState.AVAILABLE, "Tournament not available");

    // set state = cancelled
    tournaments[_tournamentId].state = TournamentState.CANCELLED;

    // counting cancel
    countCancel++;

    uint256 warriorsCount = tournaments[_tournamentId].warriors.length;
    uint256 amount = warriorsCount > 0 ? tournaments[_tournamentId].prize_pool / warriorsCount : 0;
    tournaments[_tournamentId].prize_pool = 0;
    for (uint256 i = 0; i < warriorsCount; i++) {
      // get warrior joined this tournament
      Warrior memory warrior = tournaments[_tournamentId].warriors[i];

      // get owner of warrior
      address ownerOfWarrior = TRVBPWarrior.getOwnerOf(TRVBP_ADDRESSES, warrior.id);

      if (frequencyRestriction[ownerOfWarrior].joinedCount > 0) {
        frequencyRestriction[ownerOfWarrior].joinedCount--;
      }

      // cashback fee to owner of warrior
      IWETH(WETH_ADDRESS).transfer(ownerOfWarrior, amount);

      // update statistic data
      TRVBPWarrior.updateCancelledStatistic(_tournamentId, warrior.id);
    }

    // emit event
    emit CancelledTournament(_tournamentId);
  }

  function setWinner(
    uint256 _tournamentId,
    uint256 _firstWinner,
    uint256 _secondWinner,
    uint256[] calldata _thirdWinners,
    uint256[] calldata _fourthWinners,
    string calldata _hashKey
  ) external nonReentrant {
    TournamentInfo storage tournamentInfo = tournaments[_tournamentId];
    require(msg.sender == owner() || hasRole(SET_WINNER_ROLE, msg.sender), "Caller does not have permission");
    // can not set winner for not ready tournament
    require(tournamentInfo.state == TournamentState.READY, "Invalid state");
    (, uint256 size, , uint256 _class, uint256 payoutConfig) = getTournamentDetail(_tournamentId);
    require(1 + 1 + _thirdWinners.length + _fourthWinners.length == size, "Input mismatch");

    // confirm if winnerA and winnerB are in this tournament
    TRVBPWarrior.checkWinners(_tournamentId, _firstWinner, _secondWinner, _thirdWinners, _fourthWinners);

    // update counting
    if (countReady > 0) {
      countReady--;
    }
    countComplete++;

    {
      // update tournament data
      tournamentInfo.state = TournamentState.COMPLETED;
      tournamentInfo.first_winner = _firstWinner;
      tournamentInfo.second_winner = _secondWinner;
      tournamentInfo.third_winners = _thirdWinners;
      tournamentInfo.fourth_winners = _fourthWinners;
      tournamentInfo.hashKey = _hashKey;

      // reward
      address ownerOfFirstBest = TRVBPWarrior.getOwnerOf(TRVBP_ADDRESSES, _firstWinner);
      address ownerOfSecondBest = TRVBPWarrior.getOwnerOf(TRVBP_ADDRESSES, _secondWinner);
      uint256 payoutPool = tournamentInfo.prize_pool + payoutConfig;
      IWETH(WETH_ADDRESS).transfer(ownerOfFirstBest, (payoutPool * 700) / 1000); // 70%
      IWETH(WETH_ADDRESS).transfer(ownerOfSecondBest, (payoutPool * 275) / 1000); // 27.5%
      platformShare += (payoutPool * 25) / 1000;
    }

    // update warrior statistic data
    TRVBPWarrior.updateCompletedStatistic(_firstWinner, _secondWinner, tournamentInfo.warriors, CLASSES(_class) == CLASSES.BLOODING);
    TRVBPWarrior.updatePoints(_firstWinner, _secondWinner, _fourthWinners);

    // emit event
    emit SetWinners(_tournamentId, _firstWinner, _secondWinner);
  }

  // utility
  function getAccountFrequency(address _account) public view returns (uint256 maxPerTime, uint256 windowTime, uint256 currentJoinCount, uint256 checkpointTime) {
    FrequencyInfo memory frequency = frequencyRestriction[_account];
    maxPerTime = AdminControl.maxJoinPerTime;
    windowTime = AdminControl.paddingTime;
    currentJoinCount = frequency.joinedCount;
    checkpointTime = frequency.timeCheckpoint;
  }

  function getChampionsCanJoin(uint256 _tournamentId, address _account) public view returns (uint256, uint256[] memory) {
    uint256[] memory champions = TRVBPWarrior.getTokensByAddress(TRVBP_ADDRESSES, _account);
    uint256 total = 0;
    uint256[] memory output = new uint256[](champions.length);
    for (uint256 i = 0; i < champions.length; i++) {
      (bool eligible, ) = eligibleJoin(_tournamentId, champions[i]);
      if (eligible) {
        output[total] = champions[i];
        total++;
      }
    }
    return (total, output);
  }

  function eligibleJoin(uint256 _tournamentId, uint256 _warriorId) public view returns (bool, string memory) {
    if (tournaments[_tournamentId].state != TournamentState.AVAILABLE) {
      return (false, "Not available");
    }
    address ownerOfWarrior = TRVBPWarrior.getOwnerOf(TRVBP_ADDRESSES, _warriorId);
    (uint256 maxPerTime, uint256 windowTime, uint256 currentJoinCount, uint256 checkpointTime) = getAccountFrequency(ownerOfWarrior);
    if (checkpointTime + windowTime > block.timestamp && currentJoinCount >= maxPerTime) {
      return (false, "Exceed max join per window time");
    }
    (bool feeSuccess, ) = getFee(_tournamentId);
    if (!feeSuccess) {
      return (false, "Non-exists fee");
    }
    (bool sizeSuccess, ) = getSize(_tournamentId);
    if (!sizeSuccess) {
      return (false, "Non-exists size");
    }
    (bool classSuccess, uint256 class) = getClass(_tournamentId);
    if (!classSuccess) {
      return (false, "Non-exists class");
    }
    if (!TRVBPWarrior.eligibleClass(uint8(class), _warriorId)) {
      return (false, "Not eligible to join class");
    }
    return TRVBPWarrior.eligibleFighting(_tournamentId, _warriorId, getMaxFightingPerChamp(_warriorId));
  }

  function canChangeValue(uint256 _start, uint256 _end) public view virtual override returns (bool) {
    for (uint256 i = _start; i <= _end; i++) {
      // if tournament not available or exists player joined will can not change size and fee
      if (tournaments[i].state != TournamentState.AVAILABLE || tournaments[i].warriors.length > 0) {
        return false;
      }
    }
    return true;
  }

  function getTournaments(uint256 _start, uint256 _end)
    public
    view
    returns (
      TournamentInfo[] memory,
      uint256[] memory,
      uint256[] memory,
      uint256[] memory,
      uint256[] memory
    )
  {
    uint256 size = _end - _start + 1;
    TournamentInfo[] memory tournamentsInfo = new TournamentInfo[](size);
    uint256[] memory sizeList = new uint256[](size);
    uint256[] memory feeList = new uint256[](size);
    uint256[] memory classList = new uint256[](size);
    uint256[] memory payoutList = new uint256[](size);
    for (uint256 i = _start; i <= _end; i++) {
      (tournamentsInfo[i], sizeList[i], feeList[i], classList[i], payoutList[i]) = getTournamentDetail(i);
    }
    return (tournamentsInfo, sizeList, feeList, classList, payoutList);
  }

  function getTournamentsByState(
    uint256 _start,
    uint256 _end,
    TournamentState _state
  ) public view returns (uint256 total, TournamentInfo[] memory) {
    uint256 size = _end - _start + 1;
    total = 0;
    TournamentInfo[] memory tournamentsInfo = new TournamentInfo[](size);
    for (uint256 i = _start; i <= _end; i++) {
      if (tournaments[i].state == _state) {
        (tournamentsInfo[i], , , , ) = getTournamentDetail(i);
        total++;
      }
    }
    return (total, tournamentsInfo);
  }

  function getTournamentsByIds(uint256[] calldata _ids)
    public
    view
    returns (
      TournamentInfo[] memory,
      uint256[] memory,
      uint256[] memory,
      uint256[] memory,
      uint256[] memory
    )
  {
    uint256 size = _ids.length;
    TournamentInfo[] memory tournamentsInfo = new TournamentInfo[](size);
    uint256[] memory sizeList = new uint256[](size);
    uint256[] memory feeList = new uint256[](size);
    uint256[] memory classList = new uint256[](size);
    uint256[] memory payoutList = new uint256[](size);
    for (uint256 i = 0; i < size; i++) {
      (tournamentsInfo[i], sizeList[i], feeList[i], classList[i], payoutList[i]) = getTournamentDetail(_ids[i]);
    }
    return (tournamentsInfo, sizeList, feeList, classList, payoutList);
  }

  function getTournamentsByClass(
    uint256 _class,
    uint256 _start,
    uint256 _end
  )
    public
    view
    returns (
      TournamentInfo[] memory,
      uint256[] memory,
      uint256[] memory,
      uint256[] memory
    )
  {
    uint256 size = _end - _start + 1;
    TournamentInfo[] memory tournamentsInfo = new TournamentInfo[](size);
    uint256[] memory sizeList = new uint256[](size);
    uint256[] memory feeList = new uint256[](size);
    uint256[] memory payoutList = new uint256[](size);

    for (uint256 i = _start; i <= _end; i++) {
      (bool success, uint256 class) = getClass(i);
      if (success && class == _class) {
        (, sizeList[i], feeList[i], , payoutList[i]) = getTournamentDetail(i);
      }
    }
    return (tournamentsInfo, sizeList, feeList, payoutList);
  }

  function getTournamentConfigs(uint256 _start, uint256 _end)
    public
    view
    returns (
      uint256[] memory,
      uint256[] memory,
      uint256[] memory,
      uint256[] memory
    )
  {
    uint256 size = _end - _start + 1;
    uint256[] memory sizeList = new uint256[](size);
    uint256[] memory feeList = new uint256[](size);
    uint256[] memory classList = new uint256[](size);
    uint256[] memory payoutList = new uint256[](size);
    for (uint256 i = _start; i <= _end; i++) {
      (, sizeList[i], feeList[i], classList[i], payoutList[i]) = getTournamentDetail(i);
    }
    return (sizeList, feeList, classList, payoutList);
  }

  function getTournamentDetail(uint256 _tournamentId)
    public
    view
    returns (
      TournamentInfo memory,
      uint256 size,
      uint256 fee,
      uint256 class,
      uint256 payout
    )
  {
    // size, fee
    (, size) = getSize(_tournamentId);
    (, fee) = getFee(_tournamentId);
    (, class) = getClass(_tournamentId);
    (, payout) = getPayout(_tournamentId);
    return (tournaments[_tournamentId], size, fee, class, payout);
  }

  function withdrawFees() external onlyOwner {
    // withdraw WETH
    uint256 balance = platformShare;
    platformShare = 0;
    IWETH(WETH_ADDRESS).transfer(TREASURY_ADDRESS, balance);
  }

  function withdraw() external onlyOwner {
    // withdraw matic
    uint256 balance = address(this).balance;
    payable(msg.sender).transfer(balance);
  }
}

File 2 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT

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() {
        _setOwner(_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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 8 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

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 make 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 4 of 8 : AdminControl.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Stores, RoleHelper } from "./Libs.sol";

// Pellar 2022

abstract contract AdminControl is Ownable {
  using Stores for Stores.Store;
  using RoleHelper for RoleHelper.Roles;

  enum CLASSES {
    BLOODING,
    CLASS_3,
    CLASS_2,
    CLASS_1,
    BLOODBATH
  }

  // contracts
  address[] public TRVBP_ADDRESSES = [0x4055e3503D1221Af4b187CF3B4aa8744332A4d0b, 0x8A57D0CB88E5dEA66383B64669aa98c1ab48f03E];
  address public WETH_ADDRESS = 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619;
  address public TREASURY_ADDRESS = 0x909680a5E46a3401D4dD75148B61E129451fa266;

  // roles
  bytes32 public constant SET_SIZE_ROLE = keccak256("SET_SIZE_ROLE");
  bytes32 public constant SET_FEE_ROLE = keccak256("SET_FEE_ROLE");
  bytes32 public constant SET_PAYOUT_ROLE = keccak256("SET_PAYOUT_ROLE");
  bytes32 public constant SET_MAX_FIGHT_ROLE = keccak256("SET_MAX_FIGHT_ROLE");
  bytes32 public constant SET_CLASS_ROLE = keccak256("SET_CLASS_ROLE");
  bytes32 public constant SET_WINNER_ROLE = keccak256("SET_WINNER_ROLE");
  bytes32 public constant SET_FREQUENCY_ROLE = keccak256("SET_FREQUENCY_ROLE");
  bytes32 public constant CANCEL_ROLE = keccak256("CANCEL_ROLE");
  RoleHelper.Roles private roles;

  // stores
  Stores.Store public payoutTickets;
  Stores.Store public classTickets;
  Stores.Store public sizeTickets;
  Stores.Store public feeTickets;
  Stores.Store public maxFightingPerChampTickets;
  uint256 public maxJoinPerTime;
  uint256 public paddingTime;

  constructor() {}

  modifier onlyRoler(bytes32 _role) {
    require(msg.sender == owner() || hasRole(_role, msg.sender), "Caller does not have permission");
    _;
  }

  /* EXTERNAL CONTRACTS */
  function setTokenAddress(address[] calldata _tokens) public onlyOwner {
    TRVBP_ADDRESSES = _tokens;
  }

  function addTokenAddress(address[] calldata _tokens) public onlyOwner {
    for (uint16 i = 0; i < _tokens.length; i++) {
      TRVBP_ADDRESSES.push(_tokens[i]);
    }
  }

  function setWethAddress(address _weth) public onlyOwner {
    WETH_ADDRESS = _weth;
  }

  /* ROLES */
  function hasRole(bytes32 _role, address _account) public view returns (bool) {
    return roles.hasRole(_role, _account);
  }

  function setupRole(bytes32 _role, address _account) public onlyOwner {
    roles.setupRole(_role, _account);
  }

  function revokeRole(bytes32 _role, address _account) external onlyOwner {
    roles.revokeRole(_role, _account);
  }

  /* CONFIGS */
  function canChangeValue(uint256 _start, uint256 _end) public view virtual returns (bool);

  function setMaxFightingPerChamp(
    uint256 _start,
    uint256 _end,
    uint256 _count
  ) public onlyRoler(SET_MAX_FIGHT_ROLE) {
    require(_end >= _start, "Input invalid.");

    maxFightingPerChampTickets.addTicket(_start, _end, _count);
  }

  function getMaxFightingPerChamp(uint256 _championId) public view returns (uint256) {
    (bool success, uint256 index) = maxFightingPerChampTickets.findTicket(_championId);
    if (!success) {
      return 0;
    }
    return maxFightingPerChampTickets.getValue(index);
  }

  function setSize(
    uint256 _start,
    uint256 _end,
    uint256 _size
  ) public onlyRoler(SET_SIZE_ROLE) {
    require(_end >= _start, "Input invalid.");
    require(_size > 0, "Value invalid.");
    if (_start < sizeTickets.currentEnd + 1) {
      require(canChangeValue(_start, _end), "Tournament can not be changed.");
    }

    sizeTickets.addTicket(_start, _end, _size);
  }

  function getSize(uint256 _tournamentId) public view returns (bool, uint256) {
    (bool success, uint256 index) = sizeTickets.findTicket(_tournamentId);
    if (!success) {
      return (false, 0);
    }
    return (true, sizeTickets.getValue(index));
  }

  function setFee(
    uint256 _start,
    uint256 _end,
    uint256 _fee
  ) public onlyRoler(SET_FEE_ROLE) {
    require(_end >= _start, "Input invalid.");
    if (_start < feeTickets.currentEnd + 1) {
      require(canChangeValue(_start, _end), "Tournament can not be changed.");
    }

    feeTickets.addTicket(_start, _end, _fee);
  }

  function getFee(uint256 _tournamentId) public view returns (bool, uint256) {
    (bool success, uint256 index) = feeTickets.findTicket(_tournamentId);
    if (!success) {
      return (false, 0);
    }
    return (true, feeTickets.getValue(index));
  }

  function setPayout(
    uint256 _start,
    uint256 _end,
    uint256 _payout
  ) public onlyRoler(SET_PAYOUT_ROLE) {
    require(_end >= _start, "Input invalid.");
    if (_start < payoutTickets.currentEnd + 1) {
      require(canChangeValue(_start, _end), "Tournament can not be changed.");
    }

    payoutTickets.addTicket(_start, _end, _payout);
  }

  function getPayout(uint256 _tournamentId) public view returns (bool, uint256) {
    (bool success, uint256 index) = payoutTickets.findTicket(_tournamentId);
    if (!success) {
      return (false, 0);
    }
    return (true, payoutTickets.getValue(index));
  }

  function setClass(
    uint256 _start,
    uint256 _end,
    CLASSES _class
  ) public onlyRoler(SET_CLASS_ROLE) {
    require(_end >= _start, "Input invalid.");
    if (_start < classTickets.currentEnd + 1) {
      require(canChangeValue(_start, _end), "Tournament can not be changed.");
    }

    classTickets.addTicket(_start, _end, uint256(_class));
  }

  function getClass(uint256 _tournamentId) public view returns (bool, uint256) {
    (bool success, uint256 index) = classTickets.findTicket(_tournamentId);
    if (!success) {
      return (false, 0);
    }
    return (true, classTickets.getValue(index));
  }

  function setFrequency(uint256 _frequency, uint256 _paddingTime) public onlyRoler(SET_FREQUENCY_ROLE) {
    maxJoinPerTime = _frequency;
    paddingTime = _paddingTime;
  }
}

File 5 of 8 : Warrior.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import { Map, Guard } from "./Libs.sol";
import { ITRVBPToken } from "./Interfaces.sol";

//
//   +-+ +-+ +-+   +-+ +-+ +-+   +-+ +-+ +-+ +-+ +-+ +-+ +-+
//   |T| |h| |e|   |R| |e| |d|   |V| |i| |l| |l| |a| |g| |e|
//   +-+ +-+ +-+   +-+ +-+ +-+   +-+ +-+ +-+ +-+ +-+ +-+ +-+
//
//
//   The Red Village + Pellar 2021
//

contract TRVBPWarrior {
  using Map for Map.Record;

  struct Warrior {
    uint256 id;
    uint16 style;
  }

  struct WarriorRecord {
    Map.Record records;
    uint256 firstWins;
    uint256 secondWins;
    uint256 losses;
    uint256 bloodingWins;
    uint256 bloodingCount;
    uint256 fightingCount;
    uint256 fought;
    uint256 points;
  }

  uint8 public constant MIN_POINT = 1;
  mapping(uint256 => WarriorRecord) internal warriorRecords;

  // fought count, points, blooding count, blooding wins count, wins count
  function(uint256, uint256, uint256, uint256, uint256) internal pure returns (bool)[5] classGuards = [Guard.blooding, Guard.class3, Guard.class2, Guard.class1, Guard.bloodbath];

  function eligibleClass(uint8 _class, uint256 _warriorId) public view returns (bool) {
    uint256 fought = warriorRecords[_warriorId].fought;
    uint256 points = warriorRecords[_warriorId].points;
    uint256 bloodingCount = warriorRecords[_warriorId].bloodingCount;
    uint256 bloodingWins = warriorRecords[_warriorId].bloodingWins;
    uint256 wins = warriorRecords[_warriorId].firstWins + warriorRecords[_warriorId].secondWins;
    return classGuards[_class](fought, points, bloodingCount, bloodingWins, wins);
  }

  function eligibleFighting(uint256 _tournamentId, uint256 _warriorId, uint256 _maxFight) internal view returns (bool, string memory) {
    if (warriorRecords[_warriorId].fightingCount + 1 > _maxFight) {
      return (false, "Exceed max fighting");
    }
    if (warriorRecords[_warriorId].records.containsValue(_tournamentId)) {
      return (false, "Already joined");
    }
    return (true, "");
  }

  function getOriginalPoints() internal pure returns (uint16) {
    return 109;
  }

  function getOwnerOf(address[] memory _tokens, uint256 _warriorId) internal view returns (address) {
    if (_warriorId < 5000) {
      return ITRVBPToken(_tokens[0]).ownerOf(_warriorId);
    }
    return ITRVBPToken(_tokens[1]).ownerOf(_warriorId);
  }

  function getTokensByAddress(address[] memory _tokens, address _account) public view returns (uint256[] memory) {
    uint256 genesisBalance = ITRVBPToken(_tokens[0]).balanceOf(_account);
    uint256 championBalance = ITRVBPToken(_tokens[1]).balanceOf(_account);

    uint256[] memory ids = new uint256[](genesisBalance + championBalance);
    uint256 j = 0;
    for (uint256 i = 0; i < genesisBalance; i++) {
      ids[j] = ITRVBPToken(_tokens[0]).tokenOfOwnerByIndex(_account, i);
      j++;
    }
    for (uint256 i = 0; i < championBalance; i++) {
      ids[j] = ITRVBPToken(_tokens[1]).tokenOfOwnerByIndex(_account, i);
      j++;
    }
    return ids;
  }

  function checkWinners(uint256 _tournamentId, uint256 _firstWinner, uint256 _secondWinner, uint256[] memory _thirdWinners, uint256[] memory _fourthWinners) internal view {
    require(warriorRecords[_firstWinner].records.containsValue(_tournamentId), "First winner mismatch");
    require(warriorRecords[_secondWinner].records.containsValue(_tournamentId), "Second winner mismatch");
    for (uint16 i = 0; i < _thirdWinners.length; i++) {
      require(warriorRecords[_thirdWinners[i]].records.containsValue(_tournamentId), "Third winners mismatch");
    }
    for (uint16 i = 0; i < _fourthWinners.length; i++) {
      require(warriorRecords[_fourthWinners[i]].records.containsValue(_tournamentId), "Fourth winners mismatch");
    }
  }

  function updateJoinedStatistic(uint256 _tournamentId, uint256 _warriorId) internal {
    warriorRecords[_warriorId].records.addValue(_tournamentId);
    warriorRecords[_warriorId].fightingCount++; // increase fighting count
  }

  function updateCancelledStatistic(uint256 _tournamentId, uint256 _warriorId) internal {
    warriorRecords[_warriorId].records.removeValue(_tournamentId);
    if (warriorRecords[_warriorId].fightingCount > 0) {
      warriorRecords[_warriorId].fightingCount--; // descrease fighting count
    }
  }

  function updateCompletedStatistic(uint256 _firstWinner, uint256 _secondWinner, Warrior[] memory _warriors, bool _isBloodingClass) internal {
    // increase wins count
    warriorRecords[_firstWinner].firstWins++;
    warriorRecords[_secondWinner].secondWins++;

    // increase blooding wins count
    if (_isBloodingClass) {
      warriorRecords[_firstWinner].bloodingWins++;
      warriorRecords[_secondWinner].bloodingWins++;
    }

    uint256 warriorSize = _warriors.length;
    for (uint256 i = 0; i < warriorSize; i++) {
      if (_isBloodingClass) {
        warriorRecords[_warriors[i].id].bloodingCount++;
      }

      warriorRecords[_warriors[i].id].fought++;

      if (warriorRecords[_warriors[i].id].fightingCount > 0) {
        warriorRecords[_warriors[i].id].fightingCount--; // descrease fighting count
      }
      if (_warriors[i].id != _firstWinner && _warriors[i].id != _secondWinner) {
        warriorRecords[_warriors[i].id].losses++;
      }
    }
  }

  function updatePoints(uint256 _firstWinner, uint256 _secondWinner, uint256[] memory _fourthWinners) internal {
    if (warriorRecords[_firstWinner].points == 0) {
      // = 0 means null
      warriorRecords[_firstWinner].points = getOriginalPoints() + MIN_POINT + 8; // 1st
    } else {
      warriorRecords[_firstWinner].points += 8;
    }

    if (warriorRecords[_secondWinner].points == 0) {
      // = 0 means null
      warriorRecords[_secondWinner].points = getOriginalPoints() + MIN_POINT + 4; // 2nd
    } else {
      warriorRecords[_secondWinner].points += 4;
    }

    for (uint256 i = 0; i < _fourthWinners.length; i++) {
      if (warriorRecords[_fourthWinners[i]].points == 0) {
        warriorRecords[_fourthWinners[i]].points = getOriginalPoints() + MIN_POINT - 3;
      } else if (warriorRecords[_fourthWinners[i]].points > MIN_POINT) {
        // min will be 1 so need to greater than or equal 2
        uint256 currentPoints = warriorRecords[_fourthWinners[i]].points;
        warriorRecords[_fourthWinners[i]].points = currentPoints > 3 ? currentPoints - 3 : MIN_POINT;
      }
    }
  }

  function getWarriorRecords(uint256 _warriorId)
    public
    view
    returns (
      uint256 matches,
      uint256[] memory tournamentIds,
      uint256 firstWins,
      uint256 secondWins,
      uint256 losses,
      uint256 bloodingWins,
      uint256 bloodingCount,
      uint256 fightingCount,
      uint256 fought,
      uint256 points
    )
  {
    matches = warriorRecords[_warriorId].records.ids.length;
    tournamentIds = warriorRecords[_warriorId].records.ids;
    firstWins = warriorRecords[_warriorId].firstWins;
    secondWins = warriorRecords[_warriorId].secondWins;
    losses = warriorRecords[_warriorId].losses;
    fightingCount = warriorRecords[_warriorId].fightingCount;
    fought = warriorRecords[_warriorId].fought;
    if (warriorRecords[_warriorId].points == 0) {
      points = getOriginalPoints();
    } else {
      points = warriorRecords[_warriorId].points - 1;
    }
    bloodingWins = warriorRecords[_warriorId].bloodingWins;
    bloodingCount = warriorRecords[_warriorId].bloodingCount;
  }
}

File 6 of 8 : Libs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

// Pellar 2022

library Map {
  struct Record {
    uint256[] ids;
    mapping(uint256 => uint256) indexes; // value to index
  }

  function addValue(Record storage _record, uint256 _value) internal {
    if (_record.indexes[_value] != 0) return; // exist
    _record.ids.push(_value);
    _record.indexes[_value] = _record.ids.length;
  }

  function removeValue(Record storage _record, uint256 _value) internal {
    uint256 valueIndex = _record.indexes[_value];
    if (valueIndex == 0) return; // removed non-exist value
    uint256 toDeleteIndex = valueIndex - 1; // dealing with out of bounds
    uint256 lastIndex = _record.ids.length - 1;
    if (lastIndex != toDeleteIndex) {
      uint256 lastvalue = _record.ids[lastIndex];
      _record.ids[toDeleteIndex] = lastvalue;
      _record.indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
    }
    _record.ids.pop();
    _record.indexes[_value] = 0; // set to 0
  }

  function containsValue(Record storage _record, uint256 _value) internal view returns (bool) {
    return _record.indexes[_value] != 0;
  }
}

library RoleHelper {
  struct RoleData {
    mapping(address => bool) members;
    bytes32 role;
  }

  struct Roles {
    mapping(bytes32 => RoleData) roles;
  }

  function hasRole(
    Roles storage _roles,
    bytes32 _role,
    address _account
  ) internal view returns (bool) {
    return _roles.roles[_role].members[_account];
  }

  function setupRole(
    Roles storage _roles,
    bytes32 _role,
    address _account
  ) internal {
    if (!hasRole(_roles, _role, _account)) {
      _roles.roles[_role].members[_account] = true;
    }
  }

  function revokeRole(
    Roles storage _roles,
    bytes32 _role,
    address _account
  ) internal {
    if (hasRole(_roles, _role, _account)) {
      _roles.roles[_role].members[_account] = false;
    }
  }
}

library Stores {
  struct Ticket {
    uint256 startIdx;
    uint256 endIdx;
    uint256 value;
  }

  struct Store {
    uint256 currentEnd;
    Ticket[] values;
  }

  function addTicket(
    Store storage _store,
    uint256 _start,
    uint256 _end,
    uint256 _value
  ) internal {
    _store.values.push(Ticket(_start, _end, _value));
    _store.currentEnd = max(_store.currentEnd, _end);
  }

  function findTicket(Store storage _store, uint256 _element) internal view returns (bool, uint256) {
    uint256 len = _store.values.length;

    for (uint256 i = len; i > 0; i--) {
      Ticket memory ticket = _store.values[i - 1];
      if (ticket.startIdx <= _element && ticket.endIdx >= _element) {
        // finding first element match
        return (true, i - 1);
      }
    }
    return (false, 0);
  }

  function getValue(Store storage _store, uint256 _index) internal view returns (uint256) {
    return _store.values[_index].value;
  }

  /**
   * @dev Returns the largest of two numbers.
   */
  function max(uint256 a, uint256 b) internal pure returns (uint256) {
    return a >= b ? a : b;
  }
}

library Guard {
  function blooding(
    uint256,
    uint256,
    uint256,
    uint256,
    uint256 _wins
  ) internal pure returns (bool) {
    return _wins == 0;
  }

  function class3(
    uint256 _foughtCount,
    uint256 _points,
    uint256,
    uint256 _bloodingWins,
    uint256
  ) internal pure returns (bool) {
    return (_foughtCount >= 5 || _bloodingWins >= 1) && (_points < 100);
  }

  function class2(
    uint256 _foughtCount,
    uint256 _points,
    uint256,
    uint256 _bloodingWins,
    uint256
  ) internal pure returns (bool) {
    return (_foughtCount >= 5 || _bloodingWins >= 1) && (_points >= 100 && _points <= 122);
  }

  function class1(
    uint256 _foughtCount,
    uint256 _points,
    uint256,
    uint256 _bloodingWins,
    uint256
  ) internal pure returns (bool) {
    return (_foughtCount >= 5 || _bloodingWins >= 1) && (_points > 122);
  }

  function bloodbath(
    uint256,
    uint256,
    uint256 _bloodingCount,
    uint256 _bloodingWins,
    uint256
  ) internal pure returns (bool) {
    return (_bloodingCount >= 5) || (_bloodingWins >= 1);
  }
}

File 7 of 8 : Interfaces.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

// Pellar 2022

interface IWETH {
  function allowance(address owner, address spender) external view returns (uint256);

  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) external returns (bool);

  function transfer(address recipient, uint256 amount) external returns (bool);
}

interface ITRVBPToken {
  function balanceOf(address owner) external view returns (uint256 balance);

  function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

  function ownerOf(uint256 tokenId) external view returns (address owner);
}

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

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 Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tournamentId","type":"uint256"}],"name":"CancelledTournament","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tournamentId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"warriorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"style","type":"uint16"},{"indexed":false,"internalType":"enum AdminControl.CLASSES","name":"class","type":"uint8"}],"name":"JoinedTournament","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":"tournamentId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"firstWinner","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"secondWinner","type":"uint256"}],"name":"SetWinners","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tournamentId","type":"uint256"}],"name":"TournamentReady","type":"event"},{"inputs":[],"name":"CANCEL_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_POINT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_CLASS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_FEE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_FREQUENCY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_MAX_FIGHT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_PAYOUT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_SIZE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_WINNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"TRVBP_ADDRESSES","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"addTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"canChangeValue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"}],"name":"cancelTournament","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"classTickets","outputs":[{"internalType":"uint256","name":"currentEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"countCancel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"countComplete","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"countReady","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_class","type":"uint8"},{"internalType":"uint256","name":"_warriorId","type":"uint256"}],"name":"eligibleClass","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"},{"internalType":"uint256","name":"_warriorId","type":"uint256"}],"name":"eligibleJoin","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTickets","outputs":[{"internalType":"uint256","name":"currentEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"frequencyRestriction","outputs":[{"internalType":"uint256","name":"timeCheckpoint","type":"uint256"},{"internalType":"uint256","name":"joinedCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountFrequency","outputs":[{"internalType":"uint256","name":"maxPerTime","type":"uint256"},{"internalType":"uint256","name":"windowTime","type":"uint256"},{"internalType":"uint256","name":"currentJoinCount","type":"uint256"},{"internalType":"uint256","name":"checkpointTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"getChampionsCanJoin","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"}],"name":"getClass","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"}],"name":"getFee","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_championId","type":"uint256"}],"name":"getMaxFightingPerChamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"}],"name":"getPayout","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"}],"name":"getSize","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"address","name":"_account","type":"address"}],"name":"getTokensByAddress","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"getTournamentConfigs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"}],"name":"getTournamentDetail","outputs":[{"components":[{"internalType":"enum TRVBPTournament.TournamentState","name":"state","type":"uint8"},{"internalType":"uint256","name":"prize_pool","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint16","name":"style","type":"uint16"}],"internalType":"struct TRVBPWarrior.Warrior[]","name":"warriors","type":"tuple[]"},{"internalType":"uint256","name":"first_winner","type":"uint256"},{"internalType":"uint256","name":"second_winner","type":"uint256"},{"internalType":"uint256[]","name":"third_winners","type":"uint256[]"},{"internalType":"uint256[]","name":"fourth_winners","type":"uint256[]"},{"internalType":"string","name":"hashKey","type":"string"}],"internalType":"struct TRVBPTournament.TournamentInfo","name":"","type":"tuple"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"class","type":"uint256"},{"internalType":"uint256","name":"payout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"getTournaments","outputs":[{"components":[{"internalType":"enum TRVBPTournament.TournamentState","name":"state","type":"uint8"},{"internalType":"uint256","name":"prize_pool","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint16","name":"style","type":"uint16"}],"internalType":"struct TRVBPWarrior.Warrior[]","name":"warriors","type":"tuple[]"},{"internalType":"uint256","name":"first_winner","type":"uint256"},{"internalType":"uint256","name":"second_winner","type":"uint256"},{"internalType":"uint256[]","name":"third_winners","type":"uint256[]"},{"internalType":"uint256[]","name":"fourth_winners","type":"uint256[]"},{"internalType":"string","name":"hashKey","type":"string"}],"internalType":"struct TRVBPTournament.TournamentInfo[]","name":"","type":"tuple[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_class","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"getTournamentsByClass","outputs":[{"components":[{"internalType":"enum TRVBPTournament.TournamentState","name":"state","type":"uint8"},{"internalType":"uint256","name":"prize_pool","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint16","name":"style","type":"uint16"}],"internalType":"struct TRVBPWarrior.Warrior[]","name":"warriors","type":"tuple[]"},{"internalType":"uint256","name":"first_winner","type":"uint256"},{"internalType":"uint256","name":"second_winner","type":"uint256"},{"internalType":"uint256[]","name":"third_winners","type":"uint256[]"},{"internalType":"uint256[]","name":"fourth_winners","type":"uint256[]"},{"internalType":"string","name":"hashKey","type":"string"}],"internalType":"struct TRVBPTournament.TournamentInfo[]","name":"","type":"tuple[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getTournamentsByIds","outputs":[{"components":[{"internalType":"enum TRVBPTournament.TournamentState","name":"state","type":"uint8"},{"internalType":"uint256","name":"prize_pool","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint16","name":"style","type":"uint16"}],"internalType":"struct TRVBPWarrior.Warrior[]","name":"warriors","type":"tuple[]"},{"internalType":"uint256","name":"first_winner","type":"uint256"},{"internalType":"uint256","name":"second_winner","type":"uint256"},{"internalType":"uint256[]","name":"third_winners","type":"uint256[]"},{"internalType":"uint256[]","name":"fourth_winners","type":"uint256[]"},{"internalType":"string","name":"hashKey","type":"string"}],"internalType":"struct TRVBPTournament.TournamentInfo[]","name":"","type":"tuple[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"enum TRVBPTournament.TournamentState","name":"_state","type":"uint8"}],"name":"getTournamentsByState","outputs":[{"internalType":"uint256","name":"total","type":"uint256"},{"components":[{"internalType":"enum TRVBPTournament.TournamentState","name":"state","type":"uint8"},{"internalType":"uint256","name":"prize_pool","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint16","name":"style","type":"uint16"}],"internalType":"struct TRVBPWarrior.Warrior[]","name":"warriors","type":"tuple[]"},{"internalType":"uint256","name":"first_winner","type":"uint256"},{"internalType":"uint256","name":"second_winner","type":"uint256"},{"internalType":"uint256[]","name":"third_winners","type":"uint256[]"},{"internalType":"uint256[]","name":"fourth_winners","type":"uint256[]"},{"internalType":"string","name":"hashKey","type":"string"}],"internalType":"struct TRVBPTournament.TournamentInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_warriorId","type":"uint256"}],"name":"getWarriorRecords","outputs":[{"internalType":"uint256","name":"matches","type":"uint256"},{"internalType":"uint256[]","name":"tournamentIds","type":"uint256[]"},{"internalType":"uint256","name":"firstWins","type":"uint256"},{"internalType":"uint256","name":"secondWins","type":"uint256"},{"internalType":"uint256","name":"losses","type":"uint256"},{"internalType":"uint256","name":"bloodingWins","type":"uint256"},{"internalType":"uint256","name":"bloodingCount","type":"uint256"},{"internalType":"uint256","name":"fightingCount","type":"uint256"},{"internalType":"uint256","name":"fought","type":"uint256"},{"internalType":"uint256","name":"points","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"},{"internalType":"uint256","name":"_warriorId","type":"uint256"},{"internalType":"uint16","name":"_style","type":"uint16"}],"name":"joinTournament","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxFightingPerChampTickets","outputs":[{"internalType":"uint256","name":"currentEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxJoinPerTime","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":"paddingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payoutTickets","outputs":[{"internalType":"uint256","name":"currentEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"enum AdminControl.CLASSES","name":"_class","type":"uint8"}],"name":"setClass","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_frequency","type":"uint256"},{"internalType":"uint256","name":"_paddingTime","type":"uint256"}],"name":"setFrequency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"setMaxFightingPerChamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"uint256","name":"_payout","type":"uint256"}],"name":"setPayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"setTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_weth","type":"address"}],"name":"setWethAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tournamentId","type":"uint256"},{"internalType":"uint256","name":"_firstWinner","type":"uint256"},{"internalType":"uint256","name":"_secondWinner","type":"uint256"},{"internalType":"uint256[]","name":"_thirdWinners","type":"uint256[]"},{"internalType":"uint256[]","name":"_fourthWinners","type":"uint256[]"},{"internalType":"string","name":"_hashKey","type":"string"}],"name":"setWinner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"setupRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sizeTickets","outputs":[{"internalType":"uint256","name":"currentEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610120604052620005dc602090811b62003665176001600160401b039081166080908152620005e5831b6200366e17821660a05262000610831b6200369717821660c05262000648831b620036cc17821660e0526200067290921b620036f4171661010052620000749060019060056200106c565b5060408051808201909152734055e3503d1221af4b187cf3b4aa8744332a4d0b8152738a57d0cb88e5dea66383b64669aa98c1ab48f03e6020820152620000c090600490600262001118565b50600580546001600160a01b0319908116737ceb23fd6bc0add59e62ac25578270cff1b9f619179091556006805490911673909680a5e46a3401d4dd75148b61e129451fa2661790553480156200011657600080fd5b5062000122336200068d565b6001601455620001677f9f959e00d95122f5cbd677010436cf273ef535b86b056afc172852144b9491d7739233c31669e9b0fc596297d57be24b11ceb8109e620006df565b620001a77f1c5962f118a5358622b52b94af2a74626038f9b55cf6e8bf9cf822dc59ebf997739233c31669e9b0fc596297d57be24b11ceb8109e620006df565b620001b86000612af7600162000760565b620001c8600762093a8062000860565b620f424062000200620001dd8260016200119d565b63ffffffff16620001f283620f42406200119d565b63ffffffff16600862000904565b62000234620002118260016200119d565b63ffffffff166200022683620f42406200119d565b63ffffffff16600062000aa2565b62000268620002458260016200119d565b63ffffffff166200025a8362030d406200119d565b63ffffffff16600062000bfd565b6200029e6200027b8262030d416200119d565b63ffffffff16620002908362061a806200119d565b63ffffffff16600162000bfd565b620002d4620002b18262061a816200119d565b63ffffffff16620002c683620927c06200119d565b63ffffffff16600262000bfd565b6200030a620002e782620927c16200119d565b63ffffffff16620002fc83620c35006200119d565b63ffffffff16600362000bfd565b620003406200031d82620c35016200119d565b63ffffffff166200033283620f42406200119d565b63ffffffff16600462000bfd565b60408051600a808252610160820190925260009160208201610140803683370190505090506000816000815181106200037d576200037d620011c8565b6020026020010181815250506602d79883d2000081600181518110620003a757620003a7620011c8565b60200260200101818152505066071afd498d000081600281518110620003d157620003d1620011c8565b602002602001018181525050660e35fa931a000081600381518110620003fb57620003fb620011c8565b6020026020010181815250506622d10c4ecc800081600481518110620004255762000425620011c8565b6020026020010181815250506645a2189d990000816005815181106200044f576200044f620011c8565b602002602001018181525050668b44313b32000081600681518110620004795762000479620011c8565b60200260200101818152505067011688627664000081600781518110620004a457620004a4620011c8565b6020026020010181815250506702b79f100705800081600881518110620004cf57620004cf620011c8565b60200260200101818152505067056f3e200e0b000081600981518110620004fa57620004fa620011c8565b6020908102919091010152600160005b60058160ff161015620005d25760005b600a8160ff161015620005bc57620005976200053784876200119d565b63ffffffff1660016200054b86896200119d565b6200055990614e206200119d565b620005659190620011de565b63ffffffff16868460ff1681518110620005835762000583620011c8565b602002602001015162000d6c60201b60201c565b620005a5614e20846200119d565b925080620005b38162001206565b9150506200051a565b5080620005c98162001206565b9150506200050a565b5050505062001278565b15949350505050565b6000600586101580620005f9575060018310155b8015620006065750606485105b9695505050505050565b600060058610158062000624575060018310155b8015620006065750606485101580156200060657505050607a909211159392505050565b60006005861015806200065c575060018310155b801562000606575050607a909311949350505050565b60006005841015806200060657505050600111159392505050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6003546001600160a01b031633146200073f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6200075c8282600762000ec760201b6200370e179092919060201c565b5050565b7f7e8f706637bdc5bc3260cbbc6fbc973ddf8b15e858e8180ab021f8a467f02b64620007946003546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480620007bb5750620007bb813362000f21565b620007f85760405162461bcd60e51b815260206004820152601f6024820152600080516020620062f6833981519152604482015260640162000736565b838310156200083b5760405162461bcd60e51b815260206004820152600e60248201526d24b7383aba1034b73b30b634b21760911b604482015260640162000736565b6200085a848484601062000f4960201b6200374a17909392919060201c565b50505050565b7f7b8fe6df618213203554e5db4b7f968bcc08097a4830c9090cadf36b6f4b8980620008946003546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480620008bb5750620008bb813362000f21565b620008f85760405162461bcd60e51b815260206004820152601f6024820152600080516020620062f6833981519152604482015260640162000736565b50601291909155601355565b7fc9c130a1412d72f4d79081ca47a83fb21e212d7ff57949aadd2c1356e17ee837620009386003546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806200095f57506200095f813362000f21565b6200099c5760405162461bcd60e51b815260206004820152601f6024820152600080516020620062f6833981519152604482015260640162000736565b83831015620009df5760405162461bcd60e51b815260206004820152600e60248201526d24b7383aba1034b73b30b634b21760911b604482015260640162000736565b6000821162000a225760405162461bcd60e51b815260206004820152600e60248201526d2b30b63ab29034b73b30b634b21760911b604482015260640162000736565b600c5462000a3290600162001229565b84101562000a835762000a46848462000fac565b62000a835760405162461bcd60e51b815260206004820152601e6024820152600080516020620062d6833981519152604482015260640162000736565b6200085a848484600c62000f4960201b6200374a17909392919060201c565b7f3116cfb2e0ffe9736d139a69abb6d25c70afd28ad1935ecf9cb3f047aaa65b5062000ad66003546001600160a01b031690565b6001600160a01b0316336001600160a01b0316148062000afd575062000afd813362000f21565b62000b3a5760405162461bcd60e51b815260206004820152601f6024820152600080516020620062f6833981519152604482015260640162000736565b8383101562000b7d5760405162461bcd60e51b815260206004820152600e60248201526d24b7383aba1034b73b30b634b21760911b604482015260640162000736565b60085462000b8d90600162001229565b84101562000bde5762000ba1848462000fac565b62000bde5760405162461bcd60e51b815260206004820152601e6024820152600080516020620062d6833981519152604482015260640162000736565b6200085a848484600862000f4960201b6200374a17909392919060201c565b7fcc7e2eae385e81293fb04f40acb1f5f7316bf89cf8ea59ac96991079c975fdbe62000c316003546001600160a01b031690565b6001600160a01b0316336001600160a01b0316148062000c58575062000c58813362000f21565b62000c955760405162461bcd60e51b815260206004820152601f6024820152600080516020620062f6833981519152604482015260640162000736565b8383101562000cd85760405162461bcd60e51b815260206004820152600e60248201526d24b7383aba1034b73b30b634b21760911b604482015260640162000736565b600a5462000ce890600162001229565b84101562000d395762000cfc848462000fac565b62000d395760405162461bcd60e51b815260206004820152601e6024820152600080516020620062d6833981519152604482015260640162000736565b6200085a848484600481111562000d545762000d5462001244565b600a62000f4960201b6200374a17909392919060201c565b7f8cf807f6970720f8e2c208c7c5037595982c7bd9ed93c380d09df743d0dcc3fb62000da06003546001600160a01b031690565b6001600160a01b0316336001600160a01b0316148062000dc7575062000dc7813362000f21565b62000e045760405162461bcd60e51b815260206004820152601f6024820152600080516020620062f6833981519152604482015260640162000736565b8383101562000e475760405162461bcd60e51b815260206004820152600e60248201526d24b7383aba1034b73b30b634b21760911b604482015260640162000736565b600e5462000e5790600162001229565b84101562000ea85762000e6b848462000fac565b62000ea85760405162461bcd60e51b815260206004820152601e6024820152600080516020620062d6833981519152604482015260640162000736565b6200085a848484600e62000f4960201b6200374a17909392919060201c565b6000828152602084815260408083206001600160a01b038516845290915290205460ff1662000f1c576000828152602084815260408083206001600160a01b03851684529091529020805460ff191660011790555b505050565b600062000f40838360076200102c60201b620037ab179092919060201c565b90505b92915050565b6040805160608101825284815260208082018581529282018481526001808901805480830182556000918252939020935160039093029093019182559251918101919091559051600290910155835462000fa4908362001053565b909355505050565b6000825b828111620010225760008181526019602052604081205460ff16600381111562000fde5762000fde62001244565b14158062000ffc575060008181526019602052604090206002015415155b156200100d57600091505062000f43565b8062001019816200125a565b91505062000fb0565b5060019392505050565b6000918252602092835260408083206001600160a01b039290921683529252205460ff1690565b60008183101562001065578162000f40565b5090919050565b600283019183908215620011065791602002820160005b83821115620010cf57835183826101000a8154816001600160401b0302191690836001600160401b03160217905550926020019260080160208160070104928301926001030262001083565b8015620011045782816101000a8154906001600160401b030219169055600801602081600701049283019260010302620010cf565b505b506200111492915062001170565b5090565b82805482825590600052602060002090810192821562001106579160200282015b828111156200110657825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062001139565b5b8082111562001114576000815560010162001171565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff808316818516808303821115620011bf57620011bf62001187565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff83811690831681811015620011fe57620011fe62001187565b039392505050565b600060ff821660ff81141562001220576200122062001187565b60010192915050565b600082198211156200123f576200123f62001187565b500190565b634e487b7160e01b600052602160045260246000fd5b600060001982141562001271576200127162001187565b5060010190565b61504e80620012886000396000f3fe608060405234801561001057600080fd5b50600436106103ba5760003560e01c80637765f5c3116101f4578063a0f467b51161011a578063eb984f8b116100ad578063f901162b1161007c578063f901162b1461095d578063f9fd8d3b14610970578063fa82ac761461097a578063fcee45f41461098d57600080fd5b8063eb984f8b1461091a578063f246a1dd14610924578063f2fde38b14610937578063f4a7152d1461094a57600080fd5b8063c1087c39116100e9578063c1087c39146108c4578063d547741f146108d7578063e3bac7d6146108ea578063e46c5f4c146108f357600080fd5b8063a0f467b514610842578063a96e242314610869578063a98f80d81461087c578063ae90ae5c146108a357600080fd5b80638e075a521161019257806398d15e131161016157806398d15e13146107fc578063992aa5e0146108055780639c038235146108265780639d496c381461083957600080fd5b80638e075a521461079057806391ce82201461079a57806391d14854146107d657806392fe12f9146107e957600080fd5b8063877bd0d0116101ce578063877bd0d01461072c5780638b9938aa1461074f5780638da5cb5b146107585780638dcdba7a1461076957600080fd5b80637765f5c3146106b15780637a7fe4ef146106d857806384e97dce146106f957600080fd5b80633ccfd60b116102e45780635405a4651161027757806369dfac061161024657806369dfac06146106835780636b00a5511461068c5780636d065fb814610696578063715018a6146106a957600080fd5b80635405a465146106275780635b65b9ab1461063a5780635e723a761461064d57806363f241111461066057600080fd5b80634732ff4e116102b35780634732ff4e146105c8578063476343ee146105ec5780634b939b07146105f4578063512d62df1461061457600080fd5b80633ccfd60b146105635780633e56f9f91461056b57806340e6eef01461057e57806343949531146105a157600080fd5b806313c27ca71161035c578063324322331161032b57806332432233146105195780633641207d1461052c578063366ba61314610550578063366e69ff1461055a57600080fd5b806313c27ca714610497578063175f1e38146104cc5780631d64811a146104f357806322e8571c1461050657600080fd5b806309735ac61161039857806309735ac61461042c5780630b20e4f0146104555780630d35894c1461046f5780631313c5581461048457600080fd5b8063023c23db146103bf578063040141e5146103ee57806307604b1a14610419575b600080fd5b6103d26103cd366004614564565b6109a0565b6040805192151583526020830191909152015b60405180910390f35b600554610401906001600160a01b031681565b6040516001600160a01b0390911681526020016103e5565b600654610401906001600160a01b031681565b61043f61043a366004614564565b6109de565b6040516103e59a999897969594939291906145b8565b61045d600181565b60405160ff90911681526020016103e5565b61048261047d366004614614565b610b3b565b005b610482610492366004614698565b610e74565b6104be7f9f959e00d95122f5cbd677010436cf273ef535b86b056afc172852144b9491d781565b6040519081526020016103e5565b6104be7f1c5962f118a5358622b52b94af2a74626038f9b55cf6e8bf9cf822dc59ebf99781565b6104826105013660046146d9565b610eaf565b61048261051436600461470b565b610fa4565b610482610527366004614564565b611023565b61053f61053a366004614698565b6113cd565b6040516103e59594939291906148d4565b600e546104be9081565b6104be60125481565b610482611626565b6103d2610579366004614564565b611683565b61059161058c366004614941565b6116b6565b60405190151581526020016103e5565b6104be7f3116cfb2e0ffe9736d139a69abb6d25c70afd28ad1935ecf9cb3f047aaa65b5081565b6105db6105d6366004614564565b611752565b6040516103e5959493929190614973565b6104826119cc565b6106076106023660046149e5565b611a87565b6040516103e59190614abb565b6103d2610622366004614564565b611dec565b610482610635366004614ace565b611e1f565b610482610648366004614ace565b611f3b565b61053f61065b36600461470b565b612016565b61067361066e366004614ace565b612258565b6040516103e59493929190614afa565b6104be60135481565b6010546104be9081565b6105916106a436600461470b565b612457565b6104826124cd565b6104be7f8cf807f6970720f8e2c208c7c5037595982c7bd9ed93c380d09df743d0dcc3fb81565b6106eb6106e6366004614b52565b612503565b6040516103e5929190614b84565b61070c610707366004614b9d565b612617565b6040805194855260208501939093529183015260608201526080016103e5565b61073f61073a36600461470b565b61265a565b6040516103e59493929190614bba565b6104be60175481565b6003546001600160a01b0316610401565b6104be7fc9c130a1412d72f4d79081ca47a83fb21e212d7ff57949aadd2c1356e17ee83781565b600a546104be9081565b6107c16107a8366004614b9d565b601a602052600090815260409020805460019091015482565b604080519283526020830191909152016103e5565b6105916107e4366004614bcd565b61283e565b6104826107f7366004614ace565b612853565b6104be60185481565b610818610813366004614bcd565b61292e565b6040516103e5929190614bfd565b6104be610834366004614564565b612a83565b6104be60155481565b6104be7f7e8f706637bdc5bc3260cbbc6fbc973ddf8b15e858e8180ab021f8a467f02b6481565b610482610877366004614b9d565b612ab8565b6104be7fcc7e2eae385e81293fb04f40acb1f5f7316bf89cf8ea59ac96991079c975fdbe81565b6108b66108b136600461470b565b612b04565b6040516103e5929190614c16565b6104826108d2366004614c31565b612dac565b6104826108e5366004614bcd565b6133b7565b6104be60165481565b6104be7f7b8fe6df618213203554e5db4b7f968bcc08097a4830c9090cadf36b6f4b898081565b6008546104be9081565b610482610932366004614698565b6133ed565b610482610945366004614b9d565b613497565b610401610958366004614564565b613532565b61048261096b366004614ace565b61355c565b600c546104be9081565b610482610988366004614bcd565b6135fc565b6103d261099b366004614564565b613632565b60008080806109b0600c866137d2565b91509150816109c6575060009485945092505050565b60016109d3600c83613896565b935093505050915091565b6000818152602081815260408083208054825181850281018501909352808352936060939092839283928392839283928392839290918c90830182828015610a4557602002820191906000526020600020905b815481526020019060010190808311610a31575b505050505098506000808c81526020019081526020016000206002015497506000808c81526020019081526020016000206003015496506000808c81526020019081526020016000206004015495506000808c81526020019081526020016000206007015492506000808c81526020019081526020016000206008015491506000808c81526020019081526020016000206009015460001415610aea5750606d610b0b565b60008b815260208190526040902060090154610b0890600190614d29565b90505b60009a8b5260208b90526040909a206005810154600690910154999b989a97999698959790969592945090925090565b6000610ba16004805480602002602001604051908101604052809291908181526020018280548015610b9657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b78575b5050505050846138c7565b9050336001600160a01b03821614610bee5760405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b60448201526064015b60405180910390fd5b600080610bfb8686612b04565b91509150818190610c1f5760405162461bcd60e51b8152600401610be59190614d40565b506000610c2b87613632565b9150506000610c39886109a0565b9150506000610c4789611dec565b9150508215610cde576005546040516323b872dd60e01b81526001600160a01b03888116600483015230602483015260448201869052909116906323b872dd90606401602060405180830381600087803b158015610ca457600080fd5b505af1158015610cb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cdc9190614d53565b505b610ce88989613a0a565b600089815260196020818152604080842081518083019092528c825261ffff8c81168385019081526002808401805460018082018355918a52878a20965192029095019081559051908401805461ffff1916919092161790558d855292909152018054859290610d59908490614d75565b9091555050336000908152601a6020526040902060135481544291610d7d91614d75565b1115610d9f57600181018054906000610d9583614d8d565b9190505550610da9565b4281556001808201555b888a7f58719c5c10efddf021fc89302a7dd15998c3ad49618ead44557301e17c604236868b866004811115610de057610de061472d565b604051610def93929190614da8565b60405180910390a360008a815260196020526040902060020154831415610e685760008a8152601960205260408120805460ff191660011790556015805491610e3783614d8d565b90915550506040518a907f6e76bfe5740ba786b9a01129ec8a9ff50e8b628ef29c139dd5b771e76aecaf4590600090a25b50505050505050505050565b6003546001600160a01b03163314610e9e5760405162461bcd60e51b8152600401610be590614dd7565b610eaa600483836143f0565b505050565b7fcc7e2eae385e81293fb04f40acb1f5f7316bf89cf8ea59ac96991079c975fdbe610ee26003546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480610f065750610f06813361283e565b610f225760405162461bcd60e51b8152600401610be590614e0c565b83831015610f425760405162461bcd60e51b8152600401610be590614e43565b600a54610f50906001614d75565b841015610f7d57610f618484612457565b610f7d5760405162461bcd60e51b8152600401610be590614e6b565b610f9e8484846004811115610f9457610f9461472d565b600a92919061374a565b50505050565b7f7b8fe6df618213203554e5db4b7f968bcc08097a4830c9090cadf36b6f4b8980610fd76003546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480610ffb5750610ffb813361283e565b6110175760405162461bcd60e51b8152600401610be590614e0c565b50601291909155601355565b600260145414156110765760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610be5565b60026014557f9f959e00d95122f5cbd677010436cf273ef535b86b056afc172852144b9491d76110ae6003546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806110d257506110d2813361283e565b6110ee5760405162461bcd60e51b8152600401610be590614e0c565b60008281526019602052604081205460ff1660038111156111115761111161472d565b1461115e5760405162461bcd60e51b815260206004820152601860248201527f546f75726e616d656e74206e6f7420617661696c61626c6500000000000000006044820152606401610be5565b6000828152601960205260408120805460ff19166003179055601780549161118583614d8d565b909155505060008281526019602052604081206002015490816111a95760006111c6565b6000848152601960205260409020600101546111c6908390614ea2565b60008581526019602052604081206001018190559091505b8281101561139657600085815260196020526040812060020180548390811061120957611209614ec4565b600091825260208083206040805180820182526002909402909101805484526001015461ffff16838301526004805482518185028101850190935280835293955061129b93919290919083018282801561128c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161126e575b505050505083600001516138c7565b6001600160a01b0381166000908152601a6020526040902060010154909150156112ec576001600160a01b0381166000908152601a602052604081206001018054916112e683614eda565b91905055505b60055460405163a9059cbb60e01b81526001600160a01b038381166004830152602482018790529091169063a9059cbb90604401602060405180830381600087803b15801561133a57600080fd5b505af115801561134e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113729190614d53565b50611381878360000151613a48565b5050808061138e90614d8d565b9150506111de565b5060405184907fce191e003b15c88fdc6735fb4e062865debb727c6225dc10e5454bed6220198e90600090a2505060016014555050565b606080808080856000816001600160401b038111156113ee576113ee6149aa565b60405190808252806020026020018201604052801561142757816020015b611414614453565b81526020019060019003908161140c5790505b5090506000826001600160401b03811115611444576114446149aa565b60405190808252806020026020018201604052801561146d578160200160208202803683370190505b5090506000836001600160401b0381111561148a5761148a6149aa565b6040519080825280602002602001820160405280156114b3578160200160208202803683370190505b5090506000846001600160401b038111156114d0576114d06149aa565b6040519080825280602002602001820160405280156114f9578160200160208202803683370190505b5090506000856001600160401b03811115611516576115166149aa565b60405190808252806020026020018201604052801561153f578160200160208202803683370190505b50905060005b868110156116115761156e8e8e8381811061156257611562614ec4565b90506020020135611752565b8a868151811061158057611580614ec4565b602002602001018a878151811061159957611599614ec4565b602002602001018a88815181106115b2576115b2614ec4565b602002602001018a89815181106115cb576115cb614ec4565b602002602001018a8a815181106115e4576115e4614ec4565b6020908102919091010194909452939092529290915291909152528061160981614d8d565b915050611545565b50939c929b5090995097509095509350505050565b6003546001600160a01b031633146116505760405162461bcd60e51b8152600401610be590614dd7565b6040514790339082156108fc029083906000818181858888f1935050505015801561167f573d6000803e3d6000fd5b5050565b60008080806116936008866137d2565b91509150816116a9575060009485945092505050565b60016109d3600883613896565b600081815260208190526040812060088101546009820154600683015460058401546003850154600290950154939492939192909186916116f691614d75565b9050611744858585858560018e60ff166005811061171657611716614ec4565b600491828204019190066008029054906101000a9004801561449902176001600160401b031663ffffffff16565b955050505050505b92915050565b61175a614453565b600080600080611769866109a0565b9450611776905086613632565b9350611783905086611dec565b9250611790905086611683565b6000888152601960205260409081902081516101008101909252805492945092508691869186918691908690829060ff1660038111156117d2576117d261472d565b60038111156117e3576117e361472d565b81526020016001820154815260200160028201805480602002602001604051908101604052809291908181526020016000905b8282101561185957600084815260209081902060408051808201909152600285029091018054825260019081015461ffff16828401529083529092019101611816565b5050505081526020016003820154815260200160048201548152602001600582018054806020026020016040519081016040528092919081815260200182805480156118c457602002820191906000526020600020905b8154815260200190600101908083116118b0575b505050505081526020016006820180548060200260200160405190810160405280929190818152602001828054801561191c57602002820191906000526020600020905b815481526020019060010190808311611908575b5050505050815260200160078201805461193590614ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461196190614ef1565b80156119ae5780601f10611983576101008083540402835291602001916119ae565b820191906000526020600020905b81548152906001019060200180831161199157829003601f168201915b50505050508152505094509450945094509450945091939590929450565b6003546001600160a01b031633146119f65760405162461bcd60e51b8152600401610be590614dd7565b60188054600090915560055460065460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb90604401602060405180830381600087803b158015611a4f57600080fd5b505af1158015611a63573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167f9190614d53565b6060600083600081518110611a9e57611a9e614ec4565b60209081029190910101516040516370a0823160e01b81526001600160a01b038581166004830152909116906370a082319060240160206040518083038186803b158015611aeb57600080fd5b505afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190614f2c565b9050600084600181518110611b3a57611b3a614ec4565b60209081029190910101516040516370a0823160e01b81526001600160a01b038681166004830152909116906370a082319060240160206040518083038186803b158015611b8757600080fd5b505afa158015611b9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbf9190614f2c565b90506000611bcd8284614d75565b6001600160401b03811115611be457611be46149aa565b604051908082528060200260200182016040528015611c0d578160200160208202803683370190505b5090506000805b84811015611cf85787600081518110611c2f57611c2f614ec4565b6020908102919091010151604051632f745c5960e01b81526001600160a01b0389811660048301526024820184905290911690632f745c599060440160206040518083038186803b158015611c8357600080fd5b505afa158015611c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cbb9190614f2c565b838381518110611ccd57611ccd614ec4565b602090810291909101015281611ce281614d8d565b9250508080611cf090614d8d565b915050611c14565b5060005b83811015611de05787600181518110611d1757611d17614ec4565b6020908102919091010151604051632f745c5960e01b81526001600160a01b0389811660048301526024820184905290911690632f745c599060440160206040518083038186803b158015611d6b57600080fd5b505afa158015611d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da39190614f2c565b838381518110611db557611db5614ec4565b602090810291909101015281611dca81614d8d565b9250508080611dd890614d8d565b915050611cfc565b50909695505050505050565b6000808080611dfc600a866137d2565b9150915081611e12575060009485945092505050565b60016109d3600a83613896565b7fc9c130a1412d72f4d79081ca47a83fb21e212d7ff57949aadd2c1356e17ee837611e526003546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480611e765750611e76813361283e565b611e925760405162461bcd60e51b8152600401610be590614e0c565b83831015611eb25760405162461bcd60e51b8152600401610be590614e43565b60008211611ef35760405162461bcd60e51b815260206004820152600e60248201526d2b30b63ab29034b73b30b634b21760911b6044820152606401610be5565b600c54611f01906001614d75565b841015611f2e57611f128484612457565b611f2e5760405162461bcd60e51b8152600401610be590614e6b565b610f9e600c85858561374a565b7f8cf807f6970720f8e2c208c7c5037595982c7bd9ed93c380d09df743d0dcc3fb611f6e6003546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480611f925750611f92813361283e565b611fae5760405162461bcd60e51b8152600401610be590614e0c565b83831015611fce5760405162461bcd60e51b8152600401610be590614e43565b600e54611fdc906001614d75565b84101561200957611fed8484612457565b6120095760405162461bcd60e51b8152600401610be590614e6b565b610f9e600e85858561374a565b60608080808060006120288888614d29565b612033906001614d75565b90506000816001600160401b0381111561204f5761204f6149aa565b60405190808252806020026020018201604052801561208857816020015b612075614453565b81526020019060019003908161206d5790505b5090506000826001600160401b038111156120a5576120a56149aa565b6040519080825280602002602001820160405280156120ce578160200160208202803683370190505b5090506000836001600160401b038111156120eb576120eb6149aa565b604051908082528060200260200182016040528015612114578160200160208202803683370190505b5090506000846001600160401b03811115612131576121316149aa565b60405190808252806020026020018201604052801561215a578160200160208202803683370190505b5090506000856001600160401b03811115612177576121776149aa565b6040519080825280602002602001820160405280156121a0578160200160208202803683370190505b5090508c5b8c8111611611576121b581611752565b8a86815181106121c7576121c7614ec4565b602002602001018a87815181106121e0576121e0614ec4565b602002602001018a88815181106121f9576121f9614ec4565b602002602001018a898151811061221257612212614ec4565b602002602001018a8a8151811061222b5761222b614ec4565b6020908102919091010194909452939092529290915291909152528061225081614d8d565b9150506121a5565b606080808060006122698787614d29565b612274906001614d75565b90506000816001600160401b03811115612290576122906149aa565b6040519080825280602002602001820160405280156122c957816020015b6122b6614453565b8152602001906001900390816122ae5790505b5090506000826001600160401b038111156122e6576122e66149aa565b60405190808252806020026020018201604052801561230f578160200160208202803683370190505b5090506000836001600160401b0381111561232c5761232c6149aa565b604051908082528060200260200182016040528015612355578160200160208202803683370190505b5090506000846001600160401b03811115612372576123726149aa565b60405190808252806020026020018201604052801561239b578160200160208202803683370190505b5090508a5b8a8111612444576000806123b383611dec565b915091508180156123c357508e81145b1561242f576123d183611752565b909192935090508886815181106123ea576123ea614ec4565b6020026020010188878151811061240357612403614ec4565b6020026020010188888151811061241c5761241c614ec4565b6020908102919091010192909252919052525b5050808061243c90614d8d565b9150506123a0565b50929b919a509850909650945050505050565b6000825b8281116124c35760008181526019602052604081205460ff1660038111156124855761248561472d565b1415806124a2575060008181526019602052604090206002015415155b156124b157600091505061174c565b806124bb81614d8d565b91505061245b565b5060019392505050565b6003546001600160a01b031633146124f75760405162461bcd60e51b8152600401610be590614dd7565b6125016000613a94565b565b60006060816125128686614d29565b61251d906001614d75565b9050600092506000816001600160401b0381111561253d5761253d6149aa565b60405190808252806020026020018201604052801561257657816020015b612563614453565b81526020019060019003908161255b5790505b509050865b86811161260a578560038111156125945761259461472d565b60008281526019602052604090205460ff1660038111156125b7576125b761472d565b14156125f8576125c681611752565b5050845185925084915081106125de576125de614ec4565b602002602001018190525084806125f490614d8d565b9550505b8061260281614d8d565b91505061257b565b509150505b935093915050565b6001600160a01b03166000908152601a60209081526040918290208251808401909352805480845260019091015492909101829052601254601354909390929190565b6060808080600061266b8787614d29565b612676906001614d75565b90506000816001600160401b03811115612692576126926149aa565b6040519080825280602002602001820160405280156126bb578160200160208202803683370190505b5090506000826001600160401b038111156126d8576126d86149aa565b604051908082528060200260200182016040528015612701578160200160208202803683370190505b5090506000836001600160401b0381111561271e5761271e6149aa565b604051908082528060200260200182016040528015612747578160200160208202803683370190505b5090506000846001600160401b03811115612764576127646149aa565b60405190808252806020026020018201604052801561278d578160200160208202803683370190505b5090508a5b8a811161282c576127a281611752565b90919293508885815181106127b9576127b9614ec4565b602002602001018886815181106127d2576127d2614ec4565b602002602001018887815181106127eb576127eb614ec4565b6020026020010188888151811061280457612804614ec4565b602090810291909101019390935292909152919052528061282481614d8d565b915050612792565b50929a91995097509095509350505050565b600061284c600784846137ab565b9392505050565b7f3116cfb2e0ffe9736d139a69abb6d25c70afd28ad1935ecf9cb3f047aaa65b506128866003546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806128aa57506128aa813361283e565b6128c65760405162461bcd60e51b8152600401610be590614e0c565b838310156128e65760405162461bcd60e51b8152600401610be590614e43565b6008546128f4906001614d75565b841015612921576129058484612457565b6129215760405162461bcd60e51b8152600401610be590614e6b565b610f9e600885858561374a565b600060606000612998600480548060200260200160405190810160405280929190818152602001828054801561298d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161296f575b505050505085611a87565b905060008082516001600160401b038111156129b6576129b66149aa565b6040519080825280602002602001820160405280156129df578160200160208202803683370190505b50905060005b8351811015612a74576000612a1389868481518110612a0657612a06614ec4565b6020026020010151612b04565b5090508015612a6157848281518110612a2e57612a2e614ec4565b6020026020010151838581518110612a4857612a48614ec4565b602090810291909101015283612a5d81614d8d565b9450505b5080612a6c81614d8d565b9150506129e5565b509093509150505b9250929050565b60008080612a926010856137d2565b9150915081612aa5575060009392505050565b612ab0601082613896565b949350505050565b6003546001600160a01b03163314612ae25760405162461bcd60e51b8152600401610be590614dd7565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b600060608160008581526019602052604090205460ff166003811115612b2c57612b2c61472d565b14612b5f57505060408051808201909152600d81526c4e6f7420617661696c61626c6560981b6020820152600090612a7c565b6000612bc56004805480602002602001604051908101604052809291908181526020018280548015612bba57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612b9c575b5050505050856138c7565b9050600080600080612bd685612617565b9350935093509350428382612beb9190614d75565b118015612bf85750838210155b15612c435760006040518060400160405280601f81526020017f457863656564206d6178206a6f696e207065722077696e646f772074696d6500815250965096505050505050612a7c565b6000612c4e8a613632565b50905080612c8e5760006040518060400160405280600e81526020016d4e6f6e2d6578697374732066656560901b81525097509750505050505050612a7c565b6000612c998b6109a0565b50905080612cdb5760006040518060400160405280600f81526020016e4e6f6e2d6578697374732073697a6560881b8152509850985050505050505050612a7c565b600080612ce78d611dec565b9150915081612d2d5760006040518060400160405280601081526020016f4e6f6e2d65786973747320636c61737360801b8152509a509a50505050505050505050612a7c565b612d37818d6116b6565b612d855760006040518060400160405280601a81526020017f4e6f7420656c696769626c6520746f206a6f696e20636c6173730000000000008152509a509a50505050505050505050612a7c565b612d988d8d612d938f612a83565b613ae6565b9a509a505050505050505050509250929050565b60026014541415612dff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610be5565b600260145560008981526019602052604090206003546001600160a01b0316331480612e505750612e507f1c5962f118a5358622b52b94af2a74626038f9b55cf6e8bf9cf822dc59ebf9973361283e565b612e6c5760405162461bcd60e51b8152600401610be590614e0c565b6001815460ff166003811115612e8457612e8461472d565b14612ec15760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420737461746560981b6044820152606401610be5565b6000806000612ecf8d611752565b9296509450909250849150889050612ee88b6002614d75565b612ef29190614d75565b14612f305760405162461bcd60e51b815260206004820152600e60248201526d092dce0eae840dad2e6dac2e8c6d60931b6044820152606401610be5565b612fb18d8d8d8d8d80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613bad92505050565b60155415612fcf5760158054906000612fc983614eda565b91905055505b60168054906000612fdf83614d8d565b9091555050835460ff19166002178455600384018c9055600484018b905561300b600585018b8b6144a1565b5061301a6006850189896144a1565b506130296007850187876144dc565b506000613090600480548060200260200160405190810160405280929190818152602001828054801561308557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613067575b50505050508e6138c7565b905060006130f66004805480602002602001604051908101604052809291908181526020018280548015613085576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116130675750505050508e6138c7565b9050600083876001015461310a9190614d75565b6005549091506001600160a01b031663a9059cbb846103e861312e856102bc614f45565b6131389190614ea2565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131b69190614d53565b506005546001600160a01b031663a9059cbb836103e86131d885610113614f45565b6131e29190614ea2565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561322857600080fd5b505af115801561323c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132609190614d53565b506103e861326f826019614f45565b6132799190614ea2565b6018600082825461328a9190614d75565b925050819055505050506133368c8c86600201805480602002602001604051908101604052809291908181526020016000905b8282101561330057600084815260209081902060408051808201909152600285029091018054825260019081015461ffff168284015290835290920191016132bd565b506000925061330d915050565b86600481111561331f5761331f61472d565b60048111156133305761333061472d565b14613dab565b6133748c8c8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061400c92505050565b8a8c8e7fcd382af5b59bf986d08ffea77b67990a529674a39e81f387997d9f3a3055bad460405160405180910390a4505060016014555050505050505050505050565b6003546001600160a01b031633146133e15760405162461bcd60e51b8152600401610be590614dd7565b61167f60078383614259565b6003546001600160a01b031633146134175760405162461bcd60e51b8152600401610be590614dd7565b60005b61ffff8116821115610eaa57600483838361ffff1681811061343e5761343e614ec4565b90506020020160208101906134539190614b9d565b81546001810183556000928352602090922090910180546001600160a01b0319166001600160a01b039092169190911790558061348f81614f64565b91505061341a565b6003546001600160a01b031633146134c15760405162461bcd60e51b8152600401610be590614dd7565b6001600160a01b0381166135265760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610be5565b61352f81613a94565b50565b6004818154811061354257600080fd5b6000918252602090912001546001600160a01b0316905081565b7f7e8f706637bdc5bc3260cbbc6fbc973ddf8b15e858e8180ab021f8a467f02b6461358f6003546001600160a01b031690565b6001600160a01b0316336001600160a01b031614806135b357506135b3813361283e565b6135cf5760405162461bcd60e51b8152600401610be590614e0c565b838310156135ef5760405162461bcd60e51b8152600401610be590614e43565b610f9e601085858561374a565b6003546001600160a01b031633146136265760405162461bcd60e51b8152600401610be590614dd7565b61167f6007838361370e565b6000808080613642600e866137d2565b9150915081613658575060009485945092505050565b60016109d3600e83613896565b15949350505050565b6000600586101580613681575060018310155b801561368d5750606485105b9695505050505050565b60006005861015806136aa575060018310155b801561368d57506064851015801561368d57505050607a909211159392505050565b60006005861015806136df575060018310155b801561368d575050607a909311949350505050565b600060058410158061368d57505050600111159392505050565b6137198383836137ab565b610eaa576000918252602092835260408083206001600160a01b03929092168352925220805460ff19166001179055565b604080516060810182528481526020808201858152928201848152600180890180548083018255600091825293902093516003909302909301918255925191810191909155905160029091015583546137a39083614293565b909355505050565b6000918252602092835260408083206001600160a01b039290921683529252205460ff1690565b60018201546000908190805b8015613888576000866001016001836137f79190614d29565b8154811061380757613807614ec4565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905085816000015111158015613858575085816020015110155b156138755760016138698184614d29565b94509450505050612a7c565b508061388081614eda565b9150506137de565b506000958695509350505050565b60008260010182815481106138ad576138ad614ec4565b906000526020600020906003020160020154905092915050565b600061138882101561397257826000815181106138e6576138e6614ec4565b60200260200101516001600160a01b0316636352211e836040518263ffffffff1660e01b815260040161391b91815260200190565b60206040518083038186803b15801561393357600080fd5b505afa158015613947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061396b9190614f86565b905061174c565b8260018151811061398557613985614ec4565b60200260200101516001600160a01b0316636352211e836040518263ffffffff1660e01b81526004016139ba91815260200190565b60206040518083038186803b1580156139d257600080fd5b505afa1580156139e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284c9190614f86565b6000818152602081905260409020613a2290836142aa565b6000818152602081905260408120600701805491613a3f83614d8d565b91905055505050565b6000818152602081905260409020613a6090836142ee565b6000818152602081905260409020600701541561167f576000818152602081905260408120600701805491613a3f83614eda565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000828152602081905260408120600701546060908390613b08906001614d75565b1115613b42575050604080518082019091526013815272457863656564206d6178206669676874696e6760681b602082015260009061260f565b60008481526020818152604080832088845260010190915290205415613b9157505060408051808201909152600e81526d105b1c9958591e481a9bda5b995960921b602082015260009061260f565b5050604080516020810190915260008152600190935093915050565b600084815260208181526040808320888452600101909152902054613c0c5760405162461bcd60e51b815260206004820152601560248201527408cd2e4e6e840eed2dcdccae440dad2e6dac2e8c6d605b1b6044820152606401610be5565b600083815260208181526040808320888452600101909152902054613c6c5760405162461bcd60e51b81526020600482015260166024820152750a6cac6dedcc840eed2dcdccae440dad2e6dac2e8c6d60531b6044820152606401610be5565b60005b82518161ffff161015613d1757613cc086600080868561ffff1681518110613c9957613c99614ec4565b602002602001015181526020019081526020016000206000016143d890919063ffffffff16565b613d055760405162461bcd60e51b81526020600482015260166024820152750a8d0d2e4c840eed2dcdccae4e640dad2e6dac2e8c6d60531b6044820152606401610be5565b80613d0f81614f64565b915050613c6f565b5060005b81518161ffff161015613da357613d4586600080858561ffff1681518110613c9957613c99614ec4565b613d915760405162461bcd60e51b815260206004820152601760248201527f466f757274682077696e6e657273206d69736d617463680000000000000000006044820152606401610be5565b80613d9b81614f64565b915050613d1b565b505050505050565b6000848152602081905260408120600201805491613dc883614d8d565b90915550506000838152602081905260408120600301805491613dea83614d8d565b91905055508015613e3a576000848152602081905260408120600501805491613e1283614d8d565b90915550506000838152602081905260408120600501805491613e3483614d8d565b91905055505b815160005b81811015613da3578215613e9657600080858381518110613e6257613e62614ec4565b60200260200101516000015181526020019081526020016000206006016000815480929190613e9090614d8d565b91905055505b600080858381518110613eab57613eab614ec4565b60200260200101516000015181526020019081526020016000206008016000815480929190613ed990614d8d565b91905055506000806000868481518110613ef557613ef5614ec4565b6020026020010151600001518152602001908152602001600020600701541115613f6257600080858381518110613f2e57613f2e614ec4565b60200260200101516000015181526020019081526020016000206007016000815480929190613f5c90614eda565b91905055505b85848281518110613f7557613f75614ec4565b60200260200101516000015114158015613fac575084848281518110613f9d57613f9d614ec4565b60200260200101516000015114155b15613ffa57600080858381518110613fc657613fc6614ec4565b60200260200101516000015181526020019081526020016000206004016000815480929190613ff490614d8d565b91905055505b8061400481614d8d565b915050613e3f565b6000838152602081905260409020600901546140595761402e6001606d614fa3565b614039906008614fa3565b600084815260208190526040902061ffff91909116600990910155614081565b600083815260208190526040812060090180546008929061407b908490614d75565b90915550505b6000828152602081905260409020600901546140ce576140a36001606d614fa3565b6140ae906004614fa3565b600083815260208190526040902061ffff919091166009909101556140f6565b60008281526020819052604081206009018054600492906140f0908490614d75565b90915550505b60005b8151811015610f9e5760008083838151811061411757614117614ec4565b60200260200101518152602001908152602001600020600901546000141561418c5760036141476001606d614fa3565b6141519190614fc9565b61ffff1660008084848151811061416a5761416a614ec4565b6020026020010151815260200190815260200160002060090181905550614247565b600160ff166000808484815181106141a6576141a6614ec4565b602002602001015181526020019081526020016000206009015411156142475760008060008484815181106141dd576141dd614ec4565b6020026020010151815260200190815260200160002060090154905060038111614208576001614213565b614213600382614d29565b60008085858151811061422857614228614ec4565b6020026020010151815260200190815260200160002060090181905550505b8061425181614d8d565b9150506140f9565b6142648383836137ab565b15610eaa576000918252602092835260408083206001600160a01b03929092168352925220805460ff19169055565b6000818310156142a3578161284c565b5090919050565b6000818152600183016020526040902054156142c4575050565b81546001818101845560008481526020808220909301849055845493815293019052604090912055565b60008181526001830160205260409020548061430957505050565b6000614316600183614d29565b845490915060009061432a90600190614d29565b905081811461438f57600085600001828154811061434a5761434a614ec4565b906000526020600020015490508086600001848154811061436d5761436d614ec4565b6000918252602080832090910192909255918252600187019052604090208390555b84548590806143a0576143a0614fec565b600190038181906000526020600020016000905590556000856001016000868152602001908152602001600020819055505050505050565b60009081526001919091016020526040902054151590565b828054828255906000526020600020908101928215614443579160200282015b828111156144435781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614410565b5061444f92915061454f565b5090565b6040805161010081019091528060008152602001600081526020016060815260200160008152602001600081526020016060815260200160608152602001606081525090565b612501615002565b828054828255906000526020600020908101928215614443579160200282015b828111156144435782358255916020019190600101906144c1565b8280546144e890614ef1565b90600052602060002090601f01602090048101928261450a5760008555614443565b82601f106145235782800160ff19823516178555614443565b8280016001018555821561444357918201828111156144435782358255916020019190600101906144c1565b5b8082111561444f5760008155600101614550565b60006020828403121561457657600080fd5b5035919050565b600081518084526020808501945080840160005b838110156145ad57815187529582019590820190600101614591565b509495945050505050565b60006101408c83528060208401526145d28184018d61457d565b604084019b909b5250506060810197909752608087019590955260a086019390935260c085019190915260e08401526101008301526101209091015292915050565b60008060006060848603121561462957600080fd5b8335925060208401359150604084013561ffff8116811461464957600080fd5b809150509250925092565b60008083601f84011261466657600080fd5b5081356001600160401b0381111561467d57600080fd5b6020830191508360208260051b8501011115612a7c57600080fd5b600080602083850312156146ab57600080fd5b82356001600160401b038111156146c157600080fd5b6146cd85828601614654565b90969095509350505050565b6000806000606084860312156146ee57600080fd5b833592506020840135915060408401356005811061464957600080fd5b6000806040838503121561471e57600080fd5b50508035926020909101359150565b634e487b7160e01b600052602160045260246000fd5b600481106147535761475361472d565b9052565b600081518084526020808501945080840160005b838110156145ad5781518051885283015161ffff16838801526040909601959082019060010161476b565b6000815180845260005b818110156147bc576020818501810151868301820152016147a0565b818111156147ce576000602083870101525b50601f01601f19169290920160200192915050565b60006101006147f3848451614743565b60208301516020850152604083015181604086015261481482860182614757565b915050606083015160608501526080830151608085015260a083015184820360a0860152614842828261457d565b91505060c083015184820360c086015261485c828261457d565b91505060e083015184820360e08601526148768282614796565b95945050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156148c75782840389526148b58483516147e3565b9885019893509084019060010161489d565b5091979650505050505050565b60a0815260006148e760a083018861487f565b82810360208401526148f9818861457d565b9050828103604084015261490d818761457d565b90508281036060840152614921818661457d565b90508281036080840152614935818561457d565b98975050505050505050565b6000806040838503121561495457600080fd5b823560ff8116811461496557600080fd5b946020939093013593505050565b60a08152600061498660a08301886147e3565b90508560208301528460408301528360608301528260808301529695505050505050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461352f57600080fd5b80356149e0816149c0565b919050565b600080604083850312156149f857600080fd5b82356001600160401b0380821115614a0f57600080fd5b818501915085601f830112614a2357600080fd5b8135602082821115614a3757614a376149aa565b8160051b604051601f19603f83011681018181108682111715614a5c57614a5c6149aa565b604052928352818301935084810182019289841115614a7a57600080fd5b948201945b83861015614a9f57614a90866149d5565b85529482019493820193614a7f565b9650614aae90508782016149d5565b9450505050509250929050565b60208152600061284c602083018461457d565b600080600060608486031215614ae357600080fd5b505081359360208301359350604090920135919050565b608081526000614b0d608083018761487f565b8281036020840152614b1f818761457d565b90508281036040840152614b33818661457d565b90508281036060840152614b47818561457d565b979650505050505050565b600080600060608486031215614b6757600080fd5b833592506020840135915060408401356004811061464957600080fd5b828152604060208201526000612ab0604083018461487f565b600060208284031215614baf57600080fd5b813561284c816149c0565b608081526000614b0d608083018761457d565b60008060408385031215614be057600080fd5b823591506020830135614bf2816149c0565b809150509250929050565b828152604060208201526000612ab0604083018461457d565b8215158152604060208201526000612ab06040830184614796565b600080600080600080600080600060c08a8c031215614c4f57600080fd5b8935985060208a0135975060408a0135965060608a01356001600160401b0380821115614c7b57600080fd5b614c878d838e01614654565b909850965060808c0135915080821115614ca057600080fd5b614cac8d838e01614654565b909650945060a08c0135915080821115614cc557600080fd5b818c0191508c601f830112614cd957600080fd5b813581811115614ce857600080fd5b8d6020828501011115614cfa57600080fd5b6020830194508093505050509295985092959850929598565b634e487b7160e01b600052601160045260246000fd5b600082821015614d3b57614d3b614d13565b500390565b60208152600061284c6020830184614796565b600060208284031215614d6557600080fd5b8151801515811461284c57600080fd5b60008219821115614d8857614d88614d13565b500190565b6000600019821415614da157614da1614d13565b5060010190565b83815261ffff831660208201526060810160058310614dc957614dc961472d565b826040830152949350505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f43616c6c657220646f6573206e6f742068617665207065726d697373696f6e00604082015260600190565b6020808252600e908201526d24b7383aba1034b73b30b634b21760911b604082015260600190565b6020808252601e908201527f546f75726e616d656e742063616e206e6f74206265206368616e6765642e0000604082015260600190565b600082614ebf57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600081614ee957614ee9614d13565b506000190190565b600181811c90821680614f0557607f821691505b60208210811415614f2657634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215614f3e57600080fd5b5051919050565b6000816000190483118215151615614f5f57614f5f614d13565b500290565b600061ffff80831681811415614f7c57614f7c614d13565b6001019392505050565b600060208284031215614f9857600080fd5b815161284c816149c0565b600061ffff808316818516808303821115614fc057614fc0614d13565b01949350505050565b600061ffff83811690831681811015614fe457614fe4614d13565b039392505050565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052605160045260246000fdfea2646970667358221220c217878a6b7e5c11151ea284459ba159519d4bc19f6f3230bd35c29f60fb075764736f6c63430008090033546f75726e616d656e742063616e206e6f74206265206368616e6765642e000043616c6c657220646f6573206e6f742068617665207065726d697373696f6e00

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.