Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GamesOddsObtainer
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-4.4.1/utils/Strings.sol";
// internal
import "../../utils/proxy/solidity-0.8.0/ProxyOwned.sol";
import "../../utils/proxy/solidity-0.8.0/ProxyPausable.sol";
// interface
import "../../interfaces/ISportPositionalMarketManager.sol";
import "../../interfaces/ITherundownConsumerVerifier.sol";
import "../../interfaces/ITherundownConsumer.sol";
import "../../interfaces/IGamesOddsObtainer.sol";
/// @title Contract, which works on odds obtain
/// @author gruja
contract GamesOddsObtainer is Initializable, ProxyOwned, ProxyPausable {
/* ========== CONSTANTS =========== */
uint public constant MIN_TAG_NUMBER = 9000;
uint public constant TAG_NUMBER_SPREAD = 10001;
uint public constant TAG_NUMBER_TOTAL = 10002;
uint public constant CANCELLED = 0;
uint public constant HOME_WIN = 1;
uint public constant AWAY_WIN = 2;
/* ========== CONSUMER STATE VARIABLES ========== */
ITherundownConsumer public consumer;
ITherundownConsumerVerifier public verifier;
ISportPositionalMarketManager public sportsManager;
// game properties
mapping(bytes32 => IGamesOddsObtainer.GameOdds) public gameOdds;
mapping(bytes32 => IGamesOddsObtainer.GameOdds) public backupOdds;
mapping(address => bool) public invalidOdds;
mapping(bytes32 => uint) public oddsLastPulledForGame;
mapping(address => bytes32) public gameIdPerChildMarket;
mapping(uint => bool) public doesSportSupportSpreadAndTotal;
// market props
mapping(address => mapping(uint => address)) public mainMarketChildMarketIndex;
mapping(address => uint) public numberOfChildMarkets;
mapping(address => mapping(int16 => address)) public mainMarketSpreadChildMarket;
mapping(address => mapping(uint24 => address)) public mainMarketTotalChildMarket;
mapping(address => address) public childMarketMainMarket;
mapping(address => int16) public childMarketSread;
mapping(address => uint24) public childMarketTotal;
mapping(address => address) public currentActiveTotalChildMarket;
mapping(address => address) public currentActiveSpreadChildMarket;
mapping(address => bool) public isSpreadChildMarket;
mapping(address => bool) public childMarketCreated;
mapping(address => bool) public normalizedOddsForMarketFulfilled;
mapping(address => uint[]) public normalizedOddsForMarket;
address public oddsReceiver;
mapping(address => uint) public playersReportTimestamp;
uint public waitTimePlayersReport;
/* ========== CONSTRUCTOR ========== */
function initialize(
address _owner,
address _consumer,
address _verifier,
address _sportsManager,
uint[] memory _supportedSportIds
) external initializer {
setOwner(_owner);
consumer = ITherundownConsumer(_consumer);
verifier = ITherundownConsumerVerifier(_verifier);
sportsManager = ISportPositionalMarketManager(_sportsManager);
for (uint i; i < _supportedSportIds.length; i++) {
doesSportSupportSpreadAndTotal[_supportedSportIds[i]] = true;
}
}
/* ========== OBTAINER MAIN FUNCTIONS ========== */
/// @notice main function for odds obtaining
/// @param requestId chainlnink request ID
/// @param _game game odds struct see @ IGamesOddsObtainer.GameOdds
function obtainOdds(
bytes32 requestId,
IGamesOddsObtainer.GameOdds memory _game,
uint _sportId,
address _main,
bool _isTwoPositional,
bool _playersReport
) external canUpdateOdds {
bool _isMainMarketPaused = sportsManager.isMarketPaused(_main);
if (_areOddsValid(_game, _isTwoPositional)) {
uint[] memory currentNormalizedOdd = _getNormalizedOdds(_game.gameId);
IGamesOddsObtainer.GameOdds memory currentOddsBeforeSave = gameOdds[_game.gameId];
gameOdds[_game.gameId] = _game;
oddsLastPulledForGame[_game.gameId] = block.timestamp;
_setNormalizedOdds(_main, _game.gameId, true);
if (doesSportSupportSpreadAndTotal[_sportId] || numberOfChildMarkets[_main] > 0) {
_obtainTotalAndSpreadOdds(_game, _main);
}
bool _inThreshold = verifier.areOddsArrayInThreshold(
_sportId,
currentNormalizedOdd,
normalizedOddsForMarket[_main],
_isTwoPositional
);
// if was paused and paused by invalid odds unpause
if (_isMainMarketPaused) {
if (invalidOdds[_main] || consumer.isPausedByCanceledStatus(_main)) {
consumer.setPausedByCanceledStatus(_main, false);
if (!_inThreshold) {
invalidOdds[_main] = false;
backupOdds[_game.gameId] = currentOddsBeforeSave;
_pauseOrUnpauseMarkets(_game, _main, true, true);
emit OddsCircuitBreaker(_main, _game.gameId);
} else {
if (
playersReportTimestamp[_main] > 0 &&
block.timestamp - playersReportTimestamp[_main] < waitTimePlayersReport
) {
_pauseOrUnpauseMarkets(_game, _main, true, true);
} else {
invalidOdds[_main] = false;
_pauseOrUnpauseMarkets(_game, _main, false, true);
playersReportTimestamp[_main] = 0;
}
}
}
} else if (
//if market is not paused but odd are not in threshold, pause parket
!_isMainMarketPaused && !_inThreshold
) {
_pauseOrUnpauseMarkets(_game, _main, true, true);
_pauseOrUnpausePlayerProps(_main, true, false, true);
backupOdds[_game.gameId] = currentOddsBeforeSave;
emit OddsCircuitBreaker(_main, _game.gameId);
}
emit GameOddsAdded(requestId, _game.gameId, _game, normalizedOddsForMarket[_main]);
} else {
if (!_isMainMarketPaused) {
invalidOdds[_main] = true;
if (_playersReport) {
playersReportTimestamp[_main] = block.timestamp;
}
_pauseOrUnpauseMarkets(_game, _main, true, true);
_pauseOrUnpausePlayerProps(_main, true, true, false);
}
emit InvalidOddsForMarket(requestId, _main, _game.gameId, _game);
}
}
/// @notice set first odds on creation
/// @param _gameId game id
/// @param _homeOdds home odds for a game
/// @param _awayOdds away odds for a game
/// @param _drawOdds draw odds for a game
function setFirstOdds(
bytes32 _gameId,
int24 _homeOdds,
int24 _awayOdds,
int24 _drawOdds
) external onlyConsumer {
gameOdds[_gameId] = IGamesOddsObtainer.GameOdds(_gameId, _homeOdds, _awayOdds, _drawOdds, 0, 0, 0, 0, 0, 0, 0, 0);
oddsLastPulledForGame[_gameId] = block.timestamp;
}
/// @notice set first odds on creation market
/// @param _gameId game id
/// @param _market market
/// @param _isTwoPositional is sport two positional
function setFirstNormalizedOdds(
bytes32 _gameId,
address _market,
bool _isTwoPositional
) external onlyConsumer {
_setNormalizedOdds(_market, _gameId, true);
if (!_areOddsValid(gameOdds[_gameId], _isTwoPositional)) {
invalidOdds[_market] = true;
_pauseOrUnpauseMarkets(gameOdds[_gameId], _market, true, true);
emit InvalidOddsForMarket(_gameId, _market, _gameId, gameOdds[_gameId]);
}
}
/// @notice set backup odds to be main odds
/// @param _gameId game id which is using backup odds
function setBackupOddsAsMainOddsForGame(bytes32 _gameId) external onlyConsumer {
gameOdds[_gameId] = backupOdds[_gameId];
address _main = _getMarketPerGameId(_gameId);
_setNormalizedOdds(_main, _gameId, true);
emit GameOddsAdded(
_gameId, // // no req. from CL (manual cancel) so just put gameID
_gameId,
gameOdds[_gameId],
normalizedOddsForMarket[_main]
);
}
/// @notice pause/unpause all child markets
/// @param _main parent market for which we are pause/unpause child markets
/// @param _flag pause -> true, unpause -> false
function pauseUnpauseChildMarkets(address _main, bool _flag) external onlyConsumer {
// number of childs more then 0
for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
_pauseOrUnpauseSingleMarket(mainMarketChildMarketIndex[_main][i], _flag);
}
}
/// @notice pause/unpause current active child markets
/// @param _gameId game id for spread and totals checking
/// @param _main parent market for which we are pause/unpause child markets
/// @param _flag pause -> true, unpause -> false
function pauseUnpauseCurrentActiveChildMarket(
bytes32 _gameId,
address _main,
bool _flag
) external onlyConsumer {
_pauseOrUnpauseMarkets(gameOdds[_gameId], _main, _flag, true);
}
function setChildMarketGameId(bytes32 gameId, address market) external onlyManager {
consumer.setGameIdPerChildMarket(gameId, market);
}
/// @notice resolve all child markets
/// @param _main parent market for which we are resolving
/// @param _outcome poitions thet is winning (homw, away, cancel)
/// @param _homeScore points that home team score
/// @param _awayScore points that away team score
function resolveChildMarkets(
address _main,
uint _outcome,
uint8 _homeScore,
uint8 _awayScore
) external onlyConsumer {
for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
address child = mainMarketChildMarketIndex[_main][i];
if (_outcome == CANCELLED) {
sportsManager.resolveMarket(child, _outcome);
} else if (isSpreadChildMarket[child]) {
_resolveMarketSpread(child, uint16(_homeScore), uint16(_awayScore));
} else {
_resolveMarketTotal(child, uint24(_homeScore), uint24(_awayScore));
}
}
}
/* ========== VIEW FUNCTIONS ========== */
/// @notice view function which returns normalized odds up to 100 (Example: 50-40-10)
/// @param _gameId game id for which game is looking
/// @return uint[] odds array normalized
function getNormalizedOdds(bytes32 _gameId) external view returns (uint[] memory) {
return _getNormalizedOdds(_gameId);
}
/// @notice view function which returns normalized odds up to 100 (Example: 50-50)
/// @param _market market
/// @return uint[] odds array normalized
function getNormalizedOddsForMarket(address _market) external view returns (uint[] memory) {
return _getNormalizedChildOdds(_market);
}
/// @notice function which retrievers all markert addresses for given parent market
/// @param _parent parent market
/// @return address[] child addresses
function getAllChildMarketsFromParent(address _parent) external view returns (address[] memory) {
address[] memory allMarkets = new address[](numberOfChildMarkets[_parent]);
for (uint i = 0; i < numberOfChildMarkets[_parent]; i++) {
allMarkets[i] = mainMarketChildMarketIndex[_parent][i];
}
return allMarkets;
}
/// @notice function which retrievers all markert addresses for given parent market
/// @param _parent parent market
/// @return totalsMarket totals child address
/// @return spreadsMarket spread child address
function getActiveChildMarketsFromParent(address _parent)
external
view
returns (address totalsMarket, address spreadsMarket)
{
totalsMarket = currentActiveTotalChildMarket[_parent];
spreadsMarket = currentActiveSpreadChildMarket[_parent];
}
/// @notice are odds valid or not
/// @param _gameId game id for which game is looking
/// @param _useBackup see if looking at backupOdds
/// @return bool true/false (valid or not)
function areOddsValid(
bytes32 _gameId,
bool _useBackup,
bool _isTwoPositional
) external view returns (bool) {
return
_useBackup
? _areOddsValid(backupOdds[_gameId], _isTwoPositional)
: _areOddsValid(gameOdds[_gameId], _isTwoPositional);
}
/// @notice view function which returns odds
/// @param _gameId game id
/// @return spreadHome points difference between home and away
/// @return spreadAway points difference between home and away
/// @return totalOver points total in a game over limit
/// @return totalUnder points total in game under limit
function getLinesForGame(bytes32 _gameId)
public
view
returns (
int16,
int16,
uint24,
uint24
)
{
return (
gameOdds[_gameId].spreadHome,
gameOdds[_gameId].spreadAway,
gameOdds[_gameId].totalOver,
gameOdds[_gameId].totalUnder
);
}
/// @notice view function which returns odds
/// @param _gameId game id
/// @return homeOdds moneyline odd in a two decimal places
/// @return awayOdds moneyline odd in a two decimal places
/// @return drawOdds moneyline odd in a two decimal places
/// @return spreadHomeOdds moneyline odd in a two decimal places
/// @return spreadAwayOdds moneyline odd in a two decimal places
/// @return totalOverOdds moneyline odd in a two decimal places
/// @return totalUnderOdds moneyline odd in a two decimal places
function getOddsForGame(bytes32 _gameId)
public
view
returns (
int24,
int24,
int24,
int24,
int24,
int24,
int24
)
{
return (
gameOdds[_gameId].homeOdds,
gameOdds[_gameId].awayOdds,
gameOdds[_gameId].drawOdds,
gameOdds[_gameId].spreadHomeOdds,
gameOdds[_gameId].spreadAwayOdds,
gameOdds[_gameId].totalOverOdds,
gameOdds[_gameId].totalUnderOdds
);
}
/* ========== INTERNALS ========== */
function _getNormalizedOdds(bytes32 _gameId) internal view returns (uint[] memory) {
address _market = _getMarketPerGameId(_gameId);
return
normalizedOddsForMarketFulfilled[_market]
? normalizedOddsForMarket[_market]
: _getNormalizedOddsFromGameOddsStruct(_gameId);
}
function _getNormalizedChildOdds(address _market) internal view returns (uint[] memory) {
return
normalizedOddsForMarketFulfilled[_market]
? normalizedOddsForMarket[_market]
: _getNormalizedChildOddsFromGameOddsStruct(_market);
}
function _getNormalizedOddsFromGameOddsStruct(bytes32 _gameId) internal view returns (uint[] memory) {
int[] memory odds = new int[](3);
odds[0] = gameOdds[_gameId].homeOdds;
odds[1] = gameOdds[_gameId].awayOdds;
odds[2] = gameOdds[_gameId].drawOdds;
return verifier.calculateAndNormalizeOdds(odds);
}
function _getNormalizedChildOddsFromGameOddsStruct(address _market) internal view returns (uint[] memory) {
bytes32 gameId = gameIdPerChildMarket[_market];
int[] memory odds = new int[](2);
odds[0] = isSpreadChildMarket[_market] ? gameOdds[gameId].spreadHomeOdds : gameOdds[gameId].totalOverOdds;
odds[1] = isSpreadChildMarket[_market] ? gameOdds[gameId].spreadAwayOdds : gameOdds[gameId].totalUnderOdds;
return verifier.calculateAndNormalizeOdds(odds);
}
function _areOddsValid(IGamesOddsObtainer.GameOdds memory _game, bool _isTwoPositional) internal view returns (bool) {
return verifier.areOddsValid(_isTwoPositional, _game.homeOdds, _game.awayOdds, _game.drawOdds);
}
function _obtainTotalAndSpreadOdds(IGamesOddsObtainer.GameOdds memory _game, address _main) internal {
if (_areTotalOddsValid(_game)) {
_obtainSpreadTotal(_game, _main, false);
emit GamedOddsAddedChild(
_game.gameId,
currentActiveTotalChildMarket[_main],
_game,
_getNormalizedChildOdds(currentActiveTotalChildMarket[_main]),
TAG_NUMBER_TOTAL
);
} else {
_pauseTotalSpreadMarkets(_game, false);
}
if (_areSpreadOddsValid(_game)) {
_obtainSpreadTotal(_game, _main, true);
emit GamedOddsAddedChild(
_game.gameId,
currentActiveSpreadChildMarket[_main],
_game,
_getNormalizedChildOdds(currentActiveSpreadChildMarket[_main]),
TAG_NUMBER_SPREAD
);
} else {
_pauseTotalSpreadMarkets(_game, true);
}
}
function _areTotalOddsValid(IGamesOddsObtainer.GameOdds memory _game) internal view returns (bool) {
return verifier.areTotalOddsValid(_game.totalOver, _game.totalOverOdds, _game.totalUnder, _game.totalUnderOdds);
}
function _areSpreadOddsValid(IGamesOddsObtainer.GameOdds memory _game) internal view returns (bool) {
return verifier.areSpreadOddsValid(_game.spreadHome, _game.spreadHomeOdds, _game.spreadAway, _game.spreadAwayOdds);
}
function _obtainSpreadTotal(
IGamesOddsObtainer.GameOdds memory _game,
address _main,
bool _isSpread
) internal {
bool isNewMarket = numberOfChildMarkets[_main] == 0;
address currentActiveChildMarket = _isSpread
? currentActiveSpreadChildMarket[_main]
: currentActiveTotalChildMarket[_main];
address currentMarket = _isSpread
? mainMarketSpreadChildMarket[_main][_game.spreadHome]
: mainMarketTotalChildMarket[_main][_game.totalOver];
if (isNewMarket || currentMarket == address(0)) {
address newMarket = _createMarketSpreadTotalMarket(
_game.gameId,
_main,
_isSpread,
_game.spreadHome,
_game.totalOver
);
_setCurrentChildMarkets(_main, newMarket, _isSpread);
if (currentActiveChildMarket != address(0)) {
_pauseOrUnpauseSingleMarket(currentActiveChildMarket, true);
}
_setNormalizedOdds(newMarket, _game.gameId, false);
} else if (currentMarket != currentActiveChildMarket) {
_pauseOrUnpauseSingleMarket(currentMarket, false);
_pauseOrUnpauseSingleMarket(currentActiveChildMarket, true);
_setCurrentChildMarkets(_main, currentMarket, _isSpread);
_setNormalizedOdds(currentMarket, _game.gameId, false);
} else {
_pauseOrUnpauseSingleMarket(currentActiveChildMarket, false);
_setNormalizedOdds(currentActiveChildMarket, _game.gameId, false);
}
}
function _pauseOrUnpauseSingleMarket(address _market, bool _pause) internal {
consumer.pauseOrUnpauseMarket(_market, _pause);
}
function _pauseOrUnpausePlayerProps(
address _market,
bool _pause,
bool _invalidOdds,
bool _circuitBreaker
) internal {
consumer.pauseOrUnpauseMarketForPlayerProps(_market, _pause, _invalidOdds, _circuitBreaker);
}
function _setNormalizedOdds(
address _market,
bytes32 _gameId,
bool _isParent
) internal {
normalizedOddsForMarket[_market] = _isParent
? _getNormalizedOddsFromGameOddsStruct(_gameId)
: _getNormalizedChildOddsFromGameOddsStruct(_market);
normalizedOddsForMarketFulfilled[_market] = true;
}
function _createMarketSpreadTotalMarket(
bytes32 _gameId,
address _mainMarket,
bool _isSpread,
int16 _spreadHome,
uint24 _totalOver
) internal returns (address _childMarket) {
// create
uint[] memory tags = _calculateTags(consumer.sportsIdPerGame(_gameId), _isSpread);
sportsManager.createMarket(
_gameId,
_append(_gameId, _isSpread, _spreadHome, _totalOver), // gameLabel
consumer.getGameCreatedById(_gameId).startTime, //maturity
0, //initialMint
2, // always two positions for spread/total
tags, //tags
true, // is child
_mainMarket
);
_childMarket = sportsManager.getActiveMarketAddress(sportsManager.numActiveMarkets() - 1);
// adding child markets
_setChildMarkets(_gameId, _mainMarket, _childMarket, _isSpread, _spreadHome, _totalOver, tags[1]);
}
function _calculateTags(uint _sportsId, bool _isSpread) internal pure returns (uint[] memory) {
uint[] memory result = new uint[](2);
result[0] = MIN_TAG_NUMBER + _sportsId;
result[1] = _isSpread ? TAG_NUMBER_SPREAD : TAG_NUMBER_TOTAL;
return result;
}
function _append(
bytes32 _gameId,
bool _isSpread,
int16 _spreadHome,
uint24 _totalOver
) internal view returns (string memory) {
string memory teamVsTeam = string(
abi.encodePacked(
consumer.getGameCreatedById(_gameId).homeTeam,
" vs ",
consumer.getGameCreatedById(_gameId).awayTeam
)
);
if (_isSpread) {
return string(abi.encodePacked(teamVsTeam, "(", _parseSpread(_spreadHome), ")"));
} else {
return string(abi.encodePacked(teamVsTeam, " - ", Strings.toString(_totalOver)));
}
}
function _parseSpread(int16 _spreadHome) internal pure returns (string memory) {
return
_spreadHome > 0
? Strings.toString(uint16(_spreadHome))
: string(abi.encodePacked("-", Strings.toString(uint16(_spreadHome * (-1)))));
}
function _pauseOrUnpauseMarkets(
IGamesOddsObtainer.GameOdds memory _game,
address _main,
bool _flag,
bool _unpauseMain
) internal {
if (_unpauseMain) {
_pauseOrUnpauseSingleMarket(_main, _flag);
}
if (numberOfChildMarkets[_main] > 0) {
if (_flag) {
for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
_pauseOrUnpauseSingleMarket(mainMarketChildMarketIndex[_main][i], _flag);
}
} else {
if (_areTotalOddsValid(_game)) {
address totalChildMarket = mainMarketTotalChildMarket[_main][_game.totalOver];
if (totalChildMarket == address(0)) {
address newMarket = _createMarketSpreadTotalMarket(
_game.gameId,
_main,
false,
_game.spreadHome,
_game.totalOver
);
_setCurrentChildMarkets(_main, newMarket, false);
} else {
_pauseOrUnpauseSingleMarket(totalChildMarket, _flag);
_setCurrentChildMarkets(_main, totalChildMarket, false);
}
}
if (_areSpreadOddsValid(_game)) {
address spreadChildMarket = mainMarketSpreadChildMarket[_main][_game.spreadHome];
if (spreadChildMarket == address(0)) {
address newMarket = _createMarketSpreadTotalMarket(
_game.gameId,
_main,
true,
_game.spreadHome,
_game.totalOver
);
_setCurrentChildMarkets(_main, newMarket, true);
} else {
_pauseOrUnpauseSingleMarket(spreadChildMarket, _flag);
_setCurrentChildMarkets(_main, spreadChildMarket, true);
}
}
}
}
}
function _pauseTotalSpreadMarkets(IGamesOddsObtainer.GameOdds memory _game, bool _isSpread) internal {
address _main = _getMarketPerGameId(_game.gameId);
// in number of childs more then 0
if (numberOfChildMarkets[_main] > 0) {
for (uint i = 0; i < numberOfChildMarkets[_main]; i++) {
address _child = mainMarketChildMarketIndex[_main][i];
if (isSpreadChildMarket[_child] == _isSpread) {
_pauseOrUnpauseSingleMarket(_child, true);
}
}
}
}
function _getMarketPerGameId(bytes32 _gameId) internal view returns (address) {
return consumer.marketPerGameId(_gameId);
}
function _setCurrentChildMarkets(
address _main,
address _child,
bool _isSpread
) internal {
if (_isSpread) {
currentActiveSpreadChildMarket[_main] = _child;
} else {
currentActiveTotalChildMarket[_main] = _child;
}
}
function _setChildMarkets(
bytes32 _gameId,
address _main,
address _child,
bool _isSpread,
int16 _spreadHome,
uint24 _totalOver,
uint _type
) internal {
consumer.setGameIdPerChildMarket(_gameId, _child);
gameIdPerChildMarket[_child] = _gameId;
childMarketCreated[_child] = true;
// adding child markets
childMarketMainMarket[_child] = _main;
mainMarketChildMarketIndex[_main][numberOfChildMarkets[_main]] = _child;
numberOfChildMarkets[_main] = numberOfChildMarkets[_main] + 1;
if (_isSpread) {
mainMarketSpreadChildMarket[_main][_spreadHome] = _child;
childMarketSread[_child] = _spreadHome;
currentActiveSpreadChildMarket[_main] = _child;
isSpreadChildMarket[_child] = true;
emit CreateChildSpreadSportsMarket(_main, _child, _gameId, _spreadHome, _getNormalizedChildOdds(_child), _type);
} else {
mainMarketTotalChildMarket[_main][_totalOver] = _child;
childMarketTotal[_child] = _totalOver;
currentActiveTotalChildMarket[_main] = _child;
emit CreateChildTotalSportsMarket(_main, _child, _gameId, _totalOver, _getNormalizedChildOdds(_child), _type);
}
}
function _resolveMarketTotal(
address _child,
uint24 _homeScore,
uint24 _awayScore
) internal {
uint24 totalLine = childMarketTotal[_child];
uint outcome = (_homeScore + _awayScore) * 100 > totalLine ? HOME_WIN : (_homeScore + _awayScore) * 100 < totalLine
? AWAY_WIN
: CANCELLED;
sportsManager.resolveMarket(_child, outcome);
emit ResolveChildMarket(_child, outcome, childMarketMainMarket[_child], _homeScore, _awayScore);
}
function _resolveMarketSpread(
address _child,
uint16 _homeScore,
uint16 _awayScore
) internal {
int16 homeScoreWithSpread = int16(_homeScore) * 100 + childMarketSread[_child];
int16 newAwayScore = int16(_awayScore) * 100;
uint outcome = homeScoreWithSpread > newAwayScore ? HOME_WIN : homeScoreWithSpread < newAwayScore
? AWAY_WIN
: CANCELLED;
sportsManager.resolveMarket(_child, outcome);
emit ResolveChildMarket(_child, outcome, childMarketMainMarket[_child], uint24(_homeScore), uint24(_awayScore));
}
/* ========== CONTRACT MANAGEMENT ========== */
/// @notice sets consumer, verifier, manager address
/// @param _consumer consumer address
/// @param _verifier verifier address
/// @param _sportsManager sport manager address
function setContracts(
address _consumer,
address _verifier,
address _sportsManager,
address _receiver
) external onlyOwner {
consumer = ITherundownConsumer(_consumer);
verifier = ITherundownConsumerVerifier(_verifier);
sportsManager = ISportPositionalMarketManager(_sportsManager);
oddsReceiver = _receiver;
emit NewContractAddresses(_consumer, _verifier, _sportsManager, _receiver);
}
/// @notice sets if sport is suported or not (delete from supported sport)
/// @param _sportId sport id which needs to be supported or not
/// @param _isSupported true/false (supported or not)
function setSupportedSportForTotalAndSpread(uint _sportId, bool _isSupported) external onlyOwner {
doesSportSupportSpreadAndTotal[_sportId] = _isSupported;
emit SupportedSportForTotalAndSpreadAdded(_sportId, _isSupported);
}
/// @notice sets wait time for unpausing markets
/// @param _waitTime time in seconds
function setWaitTime(uint _waitTime) external onlyOwner {
waitTimePlayersReport = _waitTime;
emit NewWaitTime(_waitTime);
}
/* ========== MODIFIERS ========== */
modifier canUpdateOdds() {
require(msg.sender == address(consumer) || msg.sender == oddsReceiver, "Invalid sender");
_;
}
modifier onlyConsumer() {
require(msg.sender == address(consumer), "Only consumer");
_;
}
modifier onlyManager() {
require(msg.sender == address(sportsManager), "Only manager");
_;
}
/* ========== EVENTS ========== */
event GameOddsAdded(bytes32 _requestId, bytes32 _id, IGamesOddsObtainer.GameOdds _game, uint[] _normalizedOdds);
event GamedOddsAddedChild(
bytes32 _id,
address _market,
IGamesOddsObtainer.GameOdds _game,
uint[] _normalizedChildOdds,
uint _type
);
event InvalidOddsForMarket(bytes32 _requestId, address _marketAddress, bytes32 _id, IGamesOddsObtainer.GameOdds _game);
event OddsCircuitBreaker(address _marketAddress, bytes32 _id);
event NewContractAddresses(address _consumer, address _verifier, address _sportsManager, address _receiver);
event CreateChildSpreadSportsMarket(
address _main,
address _child,
bytes32 _id,
int16 _spread,
uint[] _normalizedOdds,
uint _type
);
event CreateChildTotalSportsMarket(
address _main,
address _child,
bytes32 _id,
uint24 _total,
uint[] _normalizedOdds,
uint _type
);
event SupportedSportForTotalAndSpreadAdded(uint _sportId, bool _isSupported);
event ResolveChildMarket(address _child, uint _outcome, address _main, uint24 _homeScore, uint24 _awayScore);
event NewWaitTime(uint _waitTime);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Context_init_unchained();
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)
pragma solidity ^0.8.0;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
// contract may have been reentered.
require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} modifier, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Clone of syntetix contract without constructor
contract ProxyOwned {
address public owner;
address public nominatedOwner;
bool private _initialized;
bool private _transferredAtInit;
function setOwner(address _owner) public {
require(_owner != address(0), "Owner address cannot be 0");
require(!_initialized, "Already initialized, use nominateNewOwner");
_initialized = true;
owner = _owner;
emit OwnerChanged(address(0), _owner);
}
function nominateNewOwner(address _owner) external onlyOwner {
nominatedOwner = _owner;
emit OwnerNominated(_owner);
}
function acceptOwnership() external {
require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
emit OwnerChanged(owner, nominatedOwner);
owner = nominatedOwner;
nominatedOwner = address(0);
}
function transferOwnershipAtInit(address proxyAddress) external onlyOwner {
require(proxyAddress != address(0), "Invalid address");
require(!_transferredAtInit, "Already transferred");
owner = proxyAddress;
_transferredAtInit = true;
emit OwnerChanged(owner, proxyAddress);
}
modifier onlyOwner {
_onlyOwner();
_;
}
function _onlyOwner() private view {
require(msg.sender == owner, "Only the contract owner may perform this action");
}
event OwnerNominated(address newOwner);
event OwnerChanged(address oldOwner, address newOwner);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Inheritance
import "./ProxyOwned.sol";
// Clone of syntetix contract without constructor
contract ProxyPausable is ProxyOwned {
uint public lastPauseTime;
bool public paused;
/**
* @notice Change the paused state of the contract
* @dev Only the contract owner may call this.
*/
function setPaused(bool _paused) external onlyOwner {
// Ensure we're actually changing the state before we do anything
if (_paused == paused) {
return;
}
// Set our paused state.
paused = _paused;
// If applicable, set the last pause time.
if (paused) {
lastPauseTime = block.timestamp;
}
// Let everyone know that our pause state has changed.
emit PauseChanged(paused);
}
event PauseChanged(bool isPaused);
modifier notPaused {
require(!paused, "This action cannot be performed while the contract is paused");
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../interfaces/ISportPositionalMarket.sol";
interface ISportPositionalMarketManager {
/* ========== VIEWS / VARIABLES ========== */
function marketCreationEnabled() external view returns (bool);
function totalDeposited() external view returns (uint);
function numActiveMarkets() external view returns (uint);
function activeMarkets(uint index, uint pageSize) external view returns (address[] memory);
function numMaturedMarkets() external view returns (uint);
function maturedMarkets(uint index, uint pageSize) external view returns (address[] memory);
function isActiveMarket(address candidate) external view returns (bool);
function isDoubleChanceMarket(address candidate) external view returns (bool);
function doesSportSupportDoubleChance(uint _sport) external view returns (bool);
function isDoubleChanceSupported() external view returns (bool);
function isKnownMarket(address candidate) external view returns (bool);
function getActiveMarketAddress(uint _index) external view returns (address);
function transformCollateral(uint value) external view returns (uint);
function reverseTransformCollateral(uint value) external view returns (uint);
function isMarketPaused(address _market) external view returns (bool);
function expiryDuration() external view returns (uint);
function isWhitelistedAddress(address _address) external view returns (bool);
function getOddsObtainer() external view returns (address obtainer);
/* ========== MUTATIVE FUNCTIONS ========== */
function createMarket(
bytes32 gameId,
string memory gameLabel,
uint maturity,
uint initialMint, // initial sUSD to mint options for,
uint positionCount,
uint[] memory tags,
bool isChild,
address parentMarket
) external returns (ISportPositionalMarket);
function setMarketPaused(address _market, bool _paused) external;
function updateDatesForMarket(address _market, uint256 _newStartTime) external;
function resolveMarket(address market, uint outcome) external;
function expireMarkets(address[] calldata market) external;
function transferSusdTo(
address sender,
address receiver,
uint amount
) external;
function queryMintsAndMaturityStatusForPlayerProps(address[] memory _playerPropsMarkets)
external
view
returns (
bool[] memory _hasAnyMintsArray,
bool[] memory _isMaturedArray,
bool[] memory _isResolvedArray,
uint[] memory _maturities
);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ITherundownConsumerVerifier {
// view functions
function isInvalidNames(string memory _teamA, string memory _teamB) external view returns (bool);
function areTeamsEqual(string memory _teamA, string memory _teamB) external view returns (bool);
function isSupportedMarketType(string memory _market) external view returns (bool);
function areOddsArrayInThreshold(
uint _sportId,
uint[] memory _currentOddsArray,
uint[] memory _newOddsArray,
bool _isTwoPositionalSport
) external view returns (bool);
function areOddsValid(
bool _isTwoPositionalSport,
int24 _homeOdds,
int24 _awayOdds,
int24 _drawOdds
) external view returns (bool);
function areSpreadOddsValid(
int16 spreadHome,
int24 spreadHomeOdds,
int16 spreadAway,
int24 spreadAwayOdds
) external view returns (bool);
function areTotalOddsValid(
uint24 totalOver,
int24 totalOverOdds,
uint24 totalUnder,
int24 totalUnderOdds
) external view returns (bool);
function areOddsAndLinesValidForPlayer(
uint16 _line,
int24 _overOdds,
int24 _underOdds
) external pure returns (bool);
function isValidOutcomeForGame(bool _isTwoPositionalSport, uint _outcome) external view returns (bool);
function isValidOutcomeWithResult(
uint _outcome,
uint _homeScore,
uint _awayScore
) external view returns (bool);
function calculateAndNormalizeOdds(int[] memory _americanOdds) external view returns (uint[] memory);
function getBookmakerIdsBySportId(uint256 _sportId) external view returns (uint256[] memory);
function getBookmakerIdsBySportIdForPlayerProps(uint256 _sportId) external view returns (uint256[] memory);
function getStringIDsFromBytesArrayIDs(bytes32[] memory _ids) external view returns (string[] memory);
function convertUintToString(uint8[] memory _options) external view returns (string[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ITherundownConsumer {
struct GameCreate {
bytes32 gameId;
uint256 startTime;
int24 homeOdds;
int24 awayOdds;
int24 drawOdds;
string homeTeam;
string awayTeam;
}
// view functions
function supportedSport(uint _sportId) external view returns (bool);
function gameOnADate(bytes32 _gameId) external view returns (uint);
function isGameResolvedOrCanceled(bytes32 _gameId) external view returns (bool);
function getNormalizedOddsForMarket(address _market) external view returns (uint[] memory);
function getGamesPerDatePerSport(uint _sportId, uint _date) external view returns (bytes32[] memory);
function getGamePropsForOdds(address _market)
external
view
returns (
uint,
uint,
bytes32
);
function gameIdPerMarket(address _market) external view returns (bytes32);
function getGameCreatedById(bytes32 _gameId) external view returns (GameCreate memory);
function isChildMarket(address _market) external view returns (bool);
function gameFulfilledCreated(bytes32 _gameId) external view returns (bool);
function playerProps() external view returns (address);
function oddsObtainer() external view returns (address);
// write functions
function fulfillGamesCreated(
bytes32 _requestId,
bytes[] memory _games,
uint _sportsId,
uint _date
) external;
function fulfillGamesResolved(
bytes32 _requestId,
bytes[] memory _games,
uint _sportsId
) external;
function fulfillGamesOdds(bytes32 _requestId, bytes[] memory _games) external;
function setPausedByCanceledStatus(address _market, bool _flag) external;
function setGameIdPerChildMarket(bytes32 _gameId, address _child) external;
function pauseOrUnpauseMarket(address _market, bool _pause) external;
function pauseOrUnpauseMarketForPlayerProps(
address _market,
bool _pause,
bool _invalidOdds,
bool _circuitBreakerMain
) external;
function setChildMarkets(
bytes32 _gameId,
address _main,
address _child,
bool _isSpread,
int16 _spreadHome,
uint24 _totalOver
) external;
function resolveMarketManually(
address _market,
uint _outcome,
uint8 _homeScore,
uint8 _awayScore,
bool _usebackupOdds
) external;
function getOddsForGame(bytes32 _gameId)
external
view
returns (
int24,
int24,
int24
);
function sportsIdPerGame(bytes32 _gameId) external view returns (uint);
function getGameStartTime(bytes32 _gameId) external view returns (uint256);
function getLastUpdatedFromGameResolve(bytes32 _gameId) external view returns (uint40);
function marketPerGameId(bytes32 _gameId) external view returns (address);
function marketResolved(address _market) external view returns (bool);
function marketCanceled(address _market) external view returns (bool);
function invalidOdds(address _market) external view returns (bool);
function isPausedByCanceledStatus(address _market) external view returns (bool);
function isSportOnADate(uint _date, uint _sportId) external view returns (bool);
function isSportTwoPositionsSport(uint _sportsId) external view returns (bool);
function marketForTeamName(string memory _teamName) external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IGamesOddsObtainer {
struct GameOdds {
bytes32 gameId;
int24 homeOdds;
int24 awayOdds;
int24 drawOdds;
int16 spreadHome;
int24 spreadHomeOdds;
int16 spreadAway;
int24 spreadAwayOdds;
uint24 totalOver;
int24 totalOverOdds;
uint24 totalUnder;
int24 totalUnderOdds;
}
// view
function getActiveChildMarketsFromParent(address _parent) external view returns (address, address);
function getSpreadTotalsChildMarketsFromParent(address _parent)
external
view
returns (
uint numOfSpreadMarkets,
address[] memory spreadMarkets,
uint numOfTotalsMarkets,
address[] memory totalMarkets
);
function areOddsValid(
bytes32 _gameId,
bool _useBackup,
bool _isTwoPositional
) external view returns (bool);
function invalidOdds(address _market) external view returns (bool);
function playersReportTimestamp(address _market) external view returns (uint);
function getNormalizedOdds(bytes32 _gameId) external view returns (uint[] memory);
function getNormalizedOddsForMarket(address _market) external view returns (uint[] memory);
function getOddsForGames(bytes32[] memory _gameIds) external view returns (int24[] memory odds);
function mainMarketChildMarketIndex(address _main, uint _index) external view returns (address);
function numberOfChildMarkets(address _main) external view returns (uint);
function mainMarketSpreadChildMarket(address _main, int16 _spread) external view returns (address);
function mainMarketTotalChildMarket(address _main, uint24 _total) external view returns (address);
function childMarketMainMarket(address _market) external view returns (address);
function childMarketTotal(address _market) external view returns (uint24);
function currentActiveTotalChildMarket(address _main) external view returns (address);
function currentActiveSpreadChildMarket(address _main) external view returns (address);
function isSpreadChildMarket(address _child) external view returns (bool);
function childMarketCreated(address _child) external view returns (bool);
function getOddsForGame(bytes32 _gameId)
external
view
returns (
int24,
int24,
int24,
int24,
int24,
int24,
int24
);
function getLinesForGame(bytes32 _gameId)
external
view
returns (
int16,
int16,
uint24,
uint24
);
// executable
function obtainOdds(
bytes32 requestId,
GameOdds memory _game,
uint _sportId,
address _main,
bool _isTwoPositional,
bool _isPlayersReport
) external;
function setFirstOdds(
bytes32 _gameId,
int24 _homeOdds,
int24 _awayOdds,
int24 _drawOdds
) external;
function setFirstNormalizedOdds(
bytes32 _gameId,
address _market,
bool _isTwoPositional
) external;
function setBackupOddsAsMainOddsForGame(bytes32 _gameId) external;
function pauseUnpauseChildMarkets(address _main, bool _flag) external;
function pauseUnpauseCurrentActiveChildMarket(
bytes32 _gameId,
address _main,
bool _flag
) external;
function resolveChildMarkets(
address _market,
uint _outcome,
uint8 _homeScore,
uint8 _awayScore
) external;
function setChildMarketGameId(bytes32 gameId, address market) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @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 ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
__Context_init_unchained();
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;
import "../interfaces/IPositionalMarketManager.sol";
import "../interfaces/IPosition.sol";
import "../interfaces/IPriceFeed.sol";
interface ISportPositionalMarket {
/* ========== TYPES ========== */
enum Phase {
Trading,
Maturity,
Expiry
}
enum Side {
Cancelled,
Home,
Away,
Draw
}
/* ========== VIEWS / VARIABLES ========== */
function getOptions()
external
view
returns (
IPosition home,
IPosition away,
IPosition draw
);
function times() external view returns (uint maturity, uint destruction);
function getGameDetails() external view returns (bytes32 gameId, string memory gameLabel);
function getGameId() external view returns (bytes32);
function deposited() external view returns (uint);
function optionsCount() external view returns (uint);
function creator() external view returns (address);
function resolved() external view returns (bool);
function cancelled() external view returns (bool);
function paused() external view returns (bool);
function phase() external view returns (Phase);
function canResolve() external view returns (bool);
function result() external view returns (Side);
function isChild() external view returns (bool);
function optionsInitialized() external view returns (bool);
function tags(uint idx) external view returns (uint);
function getTags() external view returns (uint tag1, uint tag2);
function getTagsLength() external view returns (uint tagsLength);
function getParentMarketPositions() external view returns (IPosition position1, IPosition position2);
function getParentMarketPositionsUint() external view returns (uint position1, uint position2);
function getStampedOdds()
external
view
returns (
uint,
uint,
uint
);
function balancesOf(address account)
external
view
returns (
uint home,
uint away,
uint draw
);
function totalSupplies()
external
view
returns (
uint home,
uint away,
uint draw
);
function isDoubleChance() external view returns (bool);
function parentMarket() external view returns (ISportPositionalMarket);
/* ========== MUTATIVE FUNCTIONS ========== */
function setPaused(bool _paused) external;
function updateDates(uint256 _maturity, uint256 _expiry) external;
function mint(uint value) external;
function exerciseOptions() external;
function restoreInvalidOdds(
uint _homeOdds,
uint _awayOdds,
uint _drawOdds
) external;
function initializeOptions() external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;
import "../interfaces/IPositionalMarket.sol";
interface IPositionalMarketManager {
/* ========== VIEWS / VARIABLES ========== */
function durations() external view returns (uint expiryDuration, uint maxTimeToMaturity);
function capitalRequirement() external view returns (uint);
function marketCreationEnabled() external view returns (bool);
function onlyAMMMintingAndBurning() external view returns (bool);
function transformCollateral(uint value) external view returns (uint);
function reverseTransformCollateral(uint value) external view returns (uint);
function totalDeposited() external view returns (uint);
function numActiveMarkets() external view returns (uint);
function activeMarkets(uint index, uint pageSize) external view returns (address[] memory);
function numMaturedMarkets() external view returns (uint);
function maturedMarkets(uint index, uint pageSize) external view returns (address[] memory);
function isActiveMarket(address candidate) external view returns (bool);
function isKnownMarket(address candidate) external view returns (bool);
function getThalesAMM() external view returns (address);
/* ========== MUTATIVE FUNCTIONS ========== */
function createMarket(
bytes32 oracleKey,
uint strikePrice,
uint maturity,
uint initialMint // initial sUSD to mint options for,
) external returns (IPositionalMarket);
function resolveMarket(address market) external;
function expireMarkets(address[] calldata market) external;
function transferSusdTo(
address sender,
address receiver,
uint amount
) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;
import "./IPositionalMarket.sol";
interface IPosition {
/* ========== VIEWS / VARIABLES ========== */
function getBalanceOf(address account) external view returns (uint);
function getTotalSupply() external view returns (uint);
function exerciseWithAmount(address claimant, uint amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;
interface IPriceFeed {
// Structs
struct RateAndUpdatedTime {
uint216 rate;
uint40 time;
}
// Mutative functions
function addAggregator(bytes32 currencyKey, address aggregatorAddress) external;
function removeAggregator(bytes32 currencyKey) external;
// Views
function rateForCurrency(bytes32 currencyKey) external view returns (uint);
function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time);
function getRates() external view returns (uint[] memory);
function getCurrencies() external view returns (bytes32[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16;
import "../interfaces/IPositionalMarketManager.sol";
import "../interfaces/IPosition.sol";
import "../interfaces/IPriceFeed.sol";
interface IPositionalMarket {
/* ========== TYPES ========== */
enum Phase {
Trading,
Maturity,
Expiry
}
enum Side {
Up,
Down
}
/* ========== VIEWS / VARIABLES ========== */
function getOptions() external view returns (IPosition up, IPosition down);
function times() external view returns (uint maturity, uint destructino);
function getOracleDetails()
external
view
returns (
bytes32 key,
uint strikePrice,
uint finalPrice
);
function fees() external view returns (uint poolFee, uint creatorFee);
function deposited() external view returns (uint);
function creator() external view returns (address);
function resolved() external view returns (bool);
function phase() external view returns (Phase);
function oraclePrice() external view returns (uint);
function oraclePriceAndTimestamp() external view returns (uint price, uint updatedAt);
function canResolve() external view returns (bool);
function result() external view returns (Side);
function balancesOf(address account) external view returns (uint up, uint down);
function totalSupplies() external view returns (uint up, uint down);
function getMaximumBurnable(address account) external view returns (uint amount);
/* ========== MUTATIVE FUNCTIONS ========== */
function mint(uint value) external;
function exerciseOptions() external returns (uint);
function burnOptions(uint amount) external;
function burnOptionsMaximum() external;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"address","name":"_child","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"int16","name":"_spread","type":"int16"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"CreateChildSpreadSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"address","name":"_child","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"_total","type":"uint24"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"CreateChildTotalSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"indexed":false,"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"GameOddsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_market","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"indexed":false,"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedChildOdds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"_type","type":"uint256"}],"name":"GamedOddsAddedChild","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"indexed":false,"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"}],"name":"InvalidOddsForMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_consumer","type":"address"},{"indexed":false,"internalType":"address","name":"_verifier","type":"address"},{"indexed":false,"internalType":"address","name":"_sportsManager","type":"address"},{"indexed":false,"internalType":"address","name":"_receiver","type":"address"}],"name":"NewContractAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_waitTime","type":"uint256"}],"name":"NewWaitTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"OddsCircuitBreaker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_child","type":"address"},{"indexed":false,"internalType":"uint256","name":"_outcome","type":"uint256"},{"indexed":false,"internalType":"address","name":"_main","type":"address"},{"indexed":false,"internalType":"uint24","name":"_homeScore","type":"uint24"},{"indexed":false,"internalType":"uint24","name":"_awayScore","type":"uint24"}],"name":"ResolveChildMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedSportForTotalAndSpreadAdded","type":"event"},{"inputs":[],"name":"AWAY_WIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CANCELLED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HOME_WIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TAG_NUMBER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAG_NUMBER_SPREAD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAG_NUMBER_TOTAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"bool","name":"_useBackup","type":"bool"},{"internalType":"bool","name":"_isTwoPositional","type":"bool"}],"name":"areOddsValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"backupOdds","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketMainMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketSread","outputs":[{"internalType":"int16","name":"","type":"int16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childMarketTotal","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"consumer","outputs":[{"internalType":"contract ITherundownConsumer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"currentActiveSpreadChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"currentActiveTotalChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"doesSportSupportSpreadAndTotal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gameIdPerChildMarket","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameOdds","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_parent","type":"address"}],"name":"getActiveChildMarketsFromParent","outputs":[{"internalType":"address","name":"totalsMarket","type":"address"},{"internalType":"address","name":"spreadsMarket","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_parent","type":"address"}],"name":"getAllChildMarketsFromParent","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getLinesForGame","outputs":[{"internalType":"int16","name":"","type":"int16"},{"internalType":"int16","name":"","type":"int16"},{"internalType":"uint24","name":"","type":"uint24"},{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getNormalizedOdds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"getNormalizedOddsForMarket","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getOddsForGame","outputs":[{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"},{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_consumer","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"uint256[]","name":"_supportedSportIds","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"invalidOdds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSpreadChildMarket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mainMarketChildMarketIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int16","name":"","type":"int16"}],"name":"mainMarketSpreadChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint24","name":"","type":"uint24"}],"name":"mainMarketTotalChildMarket","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"normalizedOddsForMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"normalizedOddsForMarketFulfilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numberOfChildMarkets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"int24","name":"homeOdds","type":"int24"},{"internalType":"int24","name":"awayOdds","type":"int24"},{"internalType":"int24","name":"drawOdds","type":"int24"},{"internalType":"int16","name":"spreadHome","type":"int16"},{"internalType":"int24","name":"spreadHomeOdds","type":"int24"},{"internalType":"int16","name":"spreadAway","type":"int16"},{"internalType":"int24","name":"spreadAwayOdds","type":"int24"},{"internalType":"uint24","name":"totalOver","type":"uint24"},{"internalType":"int24","name":"totalOverOdds","type":"int24"},{"internalType":"uint24","name":"totalUnder","type":"uint24"},{"internalType":"int24","name":"totalUnderOdds","type":"int24"}],"internalType":"struct IGamesOddsObtainer.GameOdds","name":"_game","type":"tuple"},{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_isTwoPositional","type":"bool"},{"internalType":"bool","name":"_playersReport","type":"bool"}],"name":"obtainOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"oddsLastPulledForGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oddsReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"pauseUnpauseChildMarkets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"address","name":"_main","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"pauseUnpauseCurrentActiveChildMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"playersReportTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_main","type":"address"},{"internalType":"uint256","name":"_outcome","type":"uint256"},{"internalType":"uint8","name":"_homeScore","type":"uint8"},{"internalType":"uint8","name":"_awayScore","type":"uint8"}],"name":"resolveChildMarkets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"setBackupOddsAsMainOddsForGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"address","name":"market","type":"address"}],"name":"setChildMarketGameId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_consumer","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"setContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"address","name":"_market","type":"address"},{"internalType":"bool","name":"_isTwoPositional","type":"bool"}],"name":"setFirstNormalizedOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"int24","name":"_homeOdds","type":"int24"},{"internalType":"int24","name":"_awayOdds","type":"int24"},{"internalType":"int24","name":"_drawOdds","type":"int24"}],"name":"setFirstOdds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sportId","type":"uint256"},{"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"setSupportedSportForTotalAndSpread","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_waitTime","type":"uint256"}],"name":"setWaitTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sportsManager","outputs":[{"internalType":"contract ISportPositionalMarketManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract ITherundownConsumerVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"waitTimePlayersReport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50615a2580620000216000396000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c806360b4df85116101e9578063b0275fa01161010f578063c480977c116100ad578063db0d45791161007c578063db0d457914610bec578063df351aaf14610bff578063e38f273814610c12578063fa043f4014610c2557600080fd5b8063c480977c14610b83578063cc5cea2714610b96578063ceda8e9014610ba9578063d28231bd14610bc957600080fd5b8063b4fd7296116100e9578063b4fd729614610b1c578063b613d8ee14610b34578063bf989b6e14610b5d578063c3b83f5f14610b7057600080fd5b8063b0275fa014610a52578063b09bd9e314610a72578063b103feb014610b0957600080fd5b806393f4452e116101875780639aceb36e116101565780639aceb36e146109fe578063a12695ca14610a1e578063a4f096e814610a41578063ae71dcdf14610a4a57600080fd5b806393f4452e1461089f57806393ff69d7146109a95780639971441b146109e25780639a196e33146109f557600080fd5b80638d220d99116101c35780638d220d99146107ea5780638da5cb5b1461082057806391b4ded914610839578063937a314f1461084257600080fd5b806360b4df85146107115780636c35b775146107b957806379ba5097146107e257600080fd5b80632fff7020116102ce578063447b1d581161026c578063574ef5d91161023b578063574ef5d9146106845780635a2f7731146106a75780635c975abb146106d05780635d134bc2146106dd57600080fd5b8063447b1d58146105fd5780634adf7219146106315780635034c5881461065157806353a47bb71461067157600080fd5b8063352fe4ee116102a8578063352fe4ee1461059e578063366c16a5146105b157806336c0d855146105d15780633ea921ae146105f457600080fd5b80632fff70201461050c578063300a02981461051457806332b566a91461051c57600080fd5b806316c38b3c1161033b578063263737e211610315578063263737e21461049f57806329bfb6cd146104d35780632b7ac3f3146104e65780632da3f9ce146104f957600080fd5b806316c38b3c146104625780631afed5cc146104755780631e864c3b1461048c57600080fd5b806310063fdc1161037757806310063fdc146103ee57806313af40351461041957806314bdaa891461042c5780631627540c1461044f57600080fd5b806301a5627e1461039e578063091c9b96146103b35780630caf0e0c146103db575b600080fd5b6103b16103ac366004614ba1565b610c38565b005b6103c66103c1366004614df9565b610cda565b60405190151581526020015b60405180910390f35b6103b16103e9366004614db8565b610eda565b600554610401906001600160a01b031681565b6040516001600160a01b0390911681526020016103d2565b6103b1610427366004614a29565b611003565b6103c661043a366004614a29565b60176020526000908152604090205460ff1681565b6103b161045d366004614a29565b61113e565b6103b1610470366004614d44565b611194565b61047e61232881565b6040519081526020016103d2565b601954610401906001600160a01b031681565b6104016104ad366004614c0d565b600f6020908152600092835260408084209091529082529020546001600160a01b031681565b6103b16104e1366004614e66565b61120a565b600454610401906001600160a01b031681565b6103b1610507366004614abc565b611f08565b61047e600181565b61047e600281565b61056c61052a366004614d7c565b6000908152600660205260409020600190810154600160481b8104820b92600160701b820490920b9162ffffff600160981b8304811692600160c81b90041690565b60408051600195860b81529390940b602084015262ffffff9182169383019390935290911660608201526080016103d2565b6103b16105ac366004614db8565b612091565b6105c46105bf366004614a29565b61232f565b6040516103d2919061549d565b6103c66105df366004614a29565b60086020526000908152604090205460ff1681565b61047e61271181565b61040161060b366004614c38565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b61047e61063f366004614a29565b600a6020526000908152604090205481565b61047e61065f366004614d7c565b60096020526000908152604090205481565b600154610401906001600160a01b031681565b6103c6610692366004614d7c565b600b6020526000908152604090205460ff1681565b6104016106b5366004614a29565b6014602052600090815260409020546001600160a01b031681565b6003546103c69060ff1681565b6104016106eb366004614bd9565b600e6020908152600092835260408084209091529082529020546001600160a01b031681565b61077661071f366004614d7c565b600090815260066020526040902060010154600281810b9263010000008304820b92600160301b8104830b92600160581b8204810b92600160801b8304820b92600160b01b8104830b92600160e01b909104900b90565b60408051600298890b815296880b602088015294870b9486019490945291850b6060850152840b6080840152830b60a083015290910b60c082015260e0016103d2565b6104016107c7366004614a29565b6010602052600090815260409020546001600160a01b031681565b6103b161243c565b61080d6107f8366004614a29565b60116020526000908152604090205460010b81565b60405160019190910b81526020016103d2565b600054610401906201000090046001600160a01b031681565b61047e60025481565b61087f610850366004614a29565b6001600160a01b0390811660009081526013602090815260408083205460149092529091205490821692911690565b604080516001600160a01b039384168152929091166020830152016103d2565b6109366108ad366004614d7c565b600660205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b604080519c8d5260029b8c0b60208e0152998b0b998c019990995296890b60608b0152600195860b60808b015293880b60a08a01529190930b60c088015291850b60e087015262ffffff918216610100870152840b61012086015216610140840152900b610160820152610180016103d2565b6109ce6109b7366004614a29565b60126020526000908152604090205462ffffff1681565b60405162ffffff90911681526020016103d2565b6103b16109f0366004614d7c565b612539565b61047e601b5481565b610a11610a0c366004614d7c565b6127c6565b6040516103d29190615522565b6103c6610a2c366004614a29565b60156020526000908152604090205460ff1681565b61047e61271281565b61047e600081565b61047e610a60366004614a29565b601a6020526000908152604090205481565b610936610a80366004614d7c565b600760205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b61047e610b17366004614c38565b6127d7565b6003546104019061010090046001600160a01b031681565b610401610b42366004614a29565b6013602052600090815260409020546001600160a01b031681565b6103b1610b6b366004614a61565b612808565b6103b1610b7e366004614a29565b6128ba565b6103b1610b91366004614e1f565b6129d3565b6103b1610ba4366004615097565b612c71565b61047e610bb7366004614a29565b600d6020526000908152604090205481565b6103c6610bd7366004614a29565b60166020526000908152604090205460ff1681565b610a11610bfa366004614a29565b612ccb565b6103b1610c0d366004614d7c565b612cd6565b6103b1610c20366004614d94565b612d13565b6103b1610c33366004614c63565b612dc4565b60035461010090046001600160a01b03163314610c705760405162461bcd60e51b8152600401610c67906156b8565b60405180910390fd5b60005b6001600160a01b0383166000908152600d6020526040902054811015610cd5576001600160a01b038084166000908152600c60209081526040808320858452909152902054610cc3911683612f0e565b80610ccd8161594c565b915050610c73565b505050565b600082610ddc5760008481526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610dd79083612f4e565b610ed2565b60008481526007602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610ed29083612f4e565b949350505050565b60035461010090046001600160a01b03163314610f095760405162461bcd60e51b8152600401610c67906156b8565b60008381526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b820b60c0820152600160801b8404830b830b830b60e082015262ffffff600160981b85048116610100830152600160b01b8504840b840b840b610120830152600160c81b850416610140820152600160e01b909304820b820b90910b610160830152610cd5919084908490612fff565b6001600160a01b0381166110595760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610c67565b600154600160a01b900460ff16156110c55760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610c67565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6111466131bb565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001611133565b61119c6131bb565b60035460ff16151581151514156111b05750565b6003805460ff191682151590811790915560ff16156111ce57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001611133565b50565b60035461010090046001600160a01b031633148061123257506019546001600160a01b031633145b61126f5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610c67565b6005546040516333dfec9960e21b81526001600160a01b038581166004830152600092169063cf7fb2649060240160206040518083038186803b1580156112b557600080fd5b505afa1580156112c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ed9190614d60565b90506112f98684612f4e565b15611e5b57600061130d8760000151613235565b90506000600660008960000151815260200190815260200160002060405180610180016040529081600082015481526020016001820160009054906101000a900460020b60020b60020b81526020016001820160039054906101000a900460020b60020b60020b81526020016001820160069054906101000a900460020b60020b60020b81526020016001820160099054906101000a900460010b60010b60010b815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a900460010b60010b60010b81526020016001820160109054906101000a900460020b60020b60020b81526020016001820160139054906101000a900462ffffff1662ffffff1662ffffff1681526020016001820160169054906101000a900460020b60020b60020b81526020016001820160199054906101000a900462ffffff1662ffffff1662ffffff16815260200160018201601c9054906101000a900460020b60020b60020b81525050905087600660008a6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008a6000015181526020019081526020016000208190555061168e86896000015160016132dd565b6000878152600b602052604090205460ff16806116c257506001600160a01b0386166000908152600d602052604090205415155b156116d1576116d1888761334d565b600480546001600160a01b03888116600090815260186020526040808220905163217d323560e11b8152919492909316926342fa646a9261171a928d92899290918d91016156df565b60206040518083038186803b15801561173257600080fd5b505afa158015611746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176a9190614d60565b90508315611ba7576001600160a01b03871660009081526008602052604090205460ff16806118175750600354604051630a928f9f60e21b81526001600160a01b03898116600483015261010090920490911690632a4a3e7c9060240160206040518083038186803b1580156117df57600080fd5b505afa1580156117f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118179190614d60565b15611b5557600354604051630259f5fd60e01b81526001600160a01b0389811660048301526000602483015261010090920490911690630259f5fd90604401600060405180830381600087803b15801561187057600080fd5b505af1158015611884573d6000803e3d6000fd5b5050505080611af957600060086000896001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555081600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff160217905550905050611aaf8988600180612fff565b8851604080516001600160a01b038a16815260208101929092527fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a910160405180910390a1611dfd565b6001600160a01b0387166000908152601a602052604090205415801590611b435750601b546001600160a01b0388166000908152601a6020526040902054611b419042615909565b105b15611b5a57611b558988600180612fff565b611dfd565b6001600160a01b0387166000908152600860205260408120805460ff19169055611b89908a9089906001612fff565b6001600160a01b0387166000908152601a6020526040812055611dfd565b83158015611bb3575080155b15611dfd57611bc58988600180612fff565b611bd487600160006001613464565b81600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff1602179055509050507fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a878a60000151604051611df49291906001600160a01b03929092168252602082015260400190565b60405180910390a15b88516001600160a01b0388166000908152601860205260409081902090517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe92611e4b928e928e91906155df565b60405180910390a1505050611eff565b80611ec0576001600160a01b0384166000908152600860205260409020805460ff191660011790558115611ea5576001600160a01b0384166000908152601a602052604090204290555b611eb28685600180612fff565b611ec0846001806000613464565b85516040517f420dbf4677c8331a5938fcc5890c5ae453dd3344f80f9a669d6adb2fea7de3d091611ef6918a9188918b90615535565b60405180910390a15b50505050505050565b600054610100900460ff16611f235760005460ff1615611f27565b303b155b611f8a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c67565b600054610100900460ff16158015611fac576000805461ffff19166101011790555b611fb586611003565b600380546001600160a01b0380881661010002610100600160a81b031990921691909117909155600480548683166001600160a01b031991821617909155600580549286169290911691909117905560005b8251811015612076576001600b600085848151811061203657634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550808061206e9061594c565b915050612007565b508015612089576000805461ff00191690555b505050505050565b60035461010090046001600160a01b031633146120c05760405162461bcd60e51b8152600401610c67906156b8565b6120cc828460016132dd565b60008381526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b6101608201526121c29082612f4e565b610cd5576001600160a01b0382166000908152600860209081526040808320805460ff1916600190811790915586845260068352928190208151610180810183528154815290840154600281810b810b810b9483019490945263010000008104840b840b840b92820192909252600160301b8204830b830b830b6060820152600160481b8204840b840b840b6080820152600160581b8204830b830b830b60a0820152600160701b8204840b840b840b60c0820152600160801b8204830b830b830b60e082015262ffffff600160981b83048116610100830152600160b01b8304840b840b840b610120830152600160c81b830416610140820152600160e01b909104820b820b90910b6101608201526122de91849080612fff565b6000838152600660205260409081902090517f420dbf4677c8331a5938fcc5890c5ae453dd3344f80f9a669d6adb2fea7de3d0916123229186918691839190615569565b60405180910390a1505050565b6001600160a01b0381166000908152600d60205260408120546060919067ffffffffffffffff81111561237257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561239b578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600d6020526040902054811015612435576001600160a01b038085166000908152600c60209081526040808320858452909152902054835191169083908390811061240b57634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101528061242d8161594c565b9150506123a1565b5092915050565b6001546001600160a01b031633146124b45760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610c67565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60035461010090046001600160a01b031633146125685760405162461bcd60e51b8152600401610c67906156b8565b60008181526007602090815260408083206006909252822081548155600191820180549183018054600293840b840b62ffffff90811662ffffff198316811784558454630100000090819004870b870b83160265ffffffffffff1990931617919091178083558354600160301b90819004860b860b83160268ffffff000000000000198216811784558454600160481b90819004880b880b61ffff9081169091026affff000000000000000000199092166affffffffff0000000000001990931692909217178084558454600160581b90819004870b870b84160262ffffff60581b198216811785558554600160701b90819004890b90980b90921690960261ffff60701b1990911664ffffffffff60581b1990961695909517949094178082558254600160801b90819004850b850b86160262ffffff60801b198216811783558354600160981b9081900487160262ffffff60981b1990911665ffffffffffff60801b1990921691909117178082558254600160b01b90819004850b850b86160262ffffff60b01b198216811783558354600160c81b9081900487160262ffffff60c81b1990911665ffffffffffff60b01b1990921691909117178082559154600160e01b90819004840b90930b90931690910262ffffff60e01b19909116179055612754826134e7565b9050612762818360016132dd565b60008281526006602090815260408083206001600160a01b038516845260189092529182902091517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe926127ba928692839290615618565b60405180910390a15050565b60606127d182613235565b92915050565b601860205281600052604060002081815481106127f357600080fd5b90600052602060002001600091509150505481565b6128106131bb565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155601980549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b6128c26131bb565b6001600160a01b03811661290a5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610c67565b600154600160a81b900460ff161561295a5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610c67565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101611133565b60035461010090046001600160a01b03163314612a025760405162461bcd60e51b8152600401610c67906156b8565b6040518061018001604052808581526020018460020b81526020018360020b81526020018260020b8152602001600060010b8152602001600060020b8152602001600060010b8152602001600060020b8152602001600062ffffff168152602001600060020b8152602001600062ffffff168152602001600060020b815250600660008681526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008681526020019081526020016000208190555050505050565b612c796131bb565b6000828152600b6020908152604091829020805460ff19168415159081179091558251858152918201527f388428bda48903bbd0180b2e70447674064e582855a643dd2df349c85b0683f691016127ba565b60606127d182613569565b612cde6131bb565b601b8190556040518181527fcf94ac0e8dccd8a891f16d217c94137033687f7fcffbfa4cfc4e16d85a52320790602001611133565b6005546001600160a01b03163314612d5c5760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610c67565b600354604051624dc46d60e41b8152600481018490526001600160a01b038381166024830152610100909204909116906304dc46d0906044015b600060405180830381600087803b158015612db057600080fd5b505af1158015612089573d6000803e3d6000fd5b60035461010090046001600160a01b03163314612df35760405162461bcd60e51b8152600401610c67906156b8565b60005b6001600160a01b0385166000908152600d6020526040902054811015612f07576001600160a01b038086166000908152600c602090815260408083208584529091529020541684612eac5760055460405163b91f5e3560e01b81526001600160a01b038381166004830152602482018890529091169063b91f5e3590604401600060405180830381600087803b158015612e8f57600080fd5b505af1158015612ea3573d6000803e3d6000fd5b50505050612ef4565b6001600160a01b03811660009081526015602052604090205460ff1615612ee357612ede818560ff168560ff16613603565b612ef4565b612ef4818560ff168560ff16613745565b5080612eff8161594c565b915050612df6565b5050505050565b60035460405163ed5e00eb60e01b81526001600160a01b03848116600483015283151560248301526101009092049091169063ed5e00eb90604401612d96565b60048054602084015160408086015160608701519151631578f73160e31b815286151595810195909552600292830b6024860152820b6044850152900b60648301526000916001600160a01b039091169063abc7b9889060840160206040518083038186803b158015612fc057600080fd5b505afa158015612fd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff89190614d60565b9392505050565b801561300f5761300f8383612f0e565b6001600160a01b0383166000908152600d6020526040902054156131b557811561309e5760005b6001600160a01b0384166000908152600d6020526040902054811015613098576001600160a01b038085166000908152600c60209081526040808320858452909152902054613086911684612f0e565b806130908161594c565b915050613036565b506131b5565b6130a784613885565b1561312a576001600160a01b038084166000908152600f6020908152604080832061010089015162ffffff16845290915290205416806131125760006130fe866000015186600089608001518a610100015161393c565b905061310c85826000613c32565b50613128565b61311c8184612f0e565b61312884826000613c32565b505b61313384613c96565b156131b5576001600160a01b038084166000908152600e602090815260408083206080890151600190810b900b8452909152902054168061319f57600061318b866000015186600189608001518a610100015161393c565b905061319985826001613c32565b50612f07565b6131a98184612f0e565b612f0784826001613c32565b50505050565b6000546201000090046001600160a01b031633146132335760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610c67565b565b60606000613242836134e7565b6001600160a01b03811660009081526017602052604090205490915060ff166132735761326e83613cfb565b612ff8565b6001600160a01b038116600090815260186020908152604091829020805483518184028101840190945280845290918301828280156132d157602002820191906000526020600020905b8154815260200190600101908083116132bd575b50505050509392505050565b806132f0576132eb83613e90565b6132f9565b6132f982613cfb565b6001600160a01b038416600090815260186020908152604090912082516133269391929190910190614900565b5050506001600160a01b03166000908152601760205260409020805460ff19166001179055565b61335682613885565b156133d25761336782826000614070565b81516001600160a01b038083166000908152601360205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c929116846133b182613569565b6127126040516133c5959493929190615594565b60405180910390a16133dd565b6133dd826000614219565b6133e682613c96565b15613455576133f782826001614070565b81516001600160a01b038083166000908152601460205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c9291168461344182613569565b6127116040516127ba959493929190615594565b613460826001614219565b5050565b6003546040516302830aeb60e41b81526001600160a01b03868116600483015285151560248301528415156044830152831515606483015261010090920490911690632830aeb090608401600060405180830381600087803b1580156134c957600080fd5b505af11580156134dd573d6000803e3d6000fd5b5050505050505050565b600354604051631f138de360e31b81526004810183905260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561353157600080fd5b505afa158015613545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d19190614a45565b6001600160a01b03811660009081526017602052604090205460609060ff1661359a5761359582613e90565b6127d1565b6001600160a01b038216600090815260186020908152604091829020805483518184028101840190945280845290918301828280156135f857602002820191906000526020600020905b8154815260200190600101908083116135e4575b505050505092915050565b6001600160a01b03831660009081526011602052604081205460010b61362a846064615857565b61363491906157c0565b90506000613643836064615857565b905060008160010b8360010b1361366f578160010b8360010b12613668576000613672565b6002613672565b60015b60055460405163b91f5e3560e01b81526001600160a01b0389811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b1580156136c257600080fd5b505af11580156136d6573d6000803e3d6000fd5b5050506001600160a01b03808816600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b69350613735928a92869291169061ffff808c1691908b1690615465565b60405180910390a1505050505050565b6001600160a01b03831660009081526012602052604081205462ffffff16908161376f8486615804565b61377a9060646158de565b62ffffff16116137b75762ffffff82166137948486615804565b61379f9060646158de565b62ffffff16106137b05760006137ba565b60026137ba565b60015b60055460405163b91f5e3560e01b81526001600160a01b0388811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b15801561380a57600080fd5b505af115801561381e573d6000803e3d6000fd5b5050506001600160a01b03808716600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b69350613876928992869291169089908990615465565b60405180910390a15050505050565b60048054610100830151610120840151610140850151610160860151604051634e3a53b760e11b815262ffffff94851696810196909652600292830b6024870152921660448501520b60648301526000916001600160a01b0390911690639c74a76e906084015b60206040518083038186803b15801561390457600080fd5b505afa158015613918573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d19190614d60565b600354604051631c2ab73160e21b81526004810187905260009182916139ca9161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b15801561398c57600080fd5b505afa1580156139a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c4919061507f565b866142cc565b6005549091506001600160a01b0316634cde32ce886139eb8189898961436e565b60035460405163c48e62f160e01b8152600481018d90526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b158015613a3357600080fd5b505afa158015613a47573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a6f9190810190614fac565b60200151600060028760018e6040518963ffffffff1660e01b8152600401613a9e989796959493929190615633565b602060405180830381600087803b158015613ab857600080fd5b505af1158015613acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af09190614a45565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b158015613b3f57600080fd5b505afa158015613b53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b77919061507f565b613b819190615909565b6040518263ffffffff1660e01b8152600401613b9f91815260200190565b60206040518083038186803b158015613bb757600080fd5b505afa158015613bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bef9190614a45565b9150613c2887878488888887600181518110613c1b57634e487b7160e01b600052603260045260246000fd5b60200260200101516144fe565b5095945050505050565b8015613c6757506001600160a01b03918216600090815260146020526040902080546001600160a01b03191691909216179055565b506001600160a01b03918216600090815260136020526040902080546001600160a01b03191691909216179055565b60048054608083015160a084015160c085015160e0860151604051630df2ba2560e41b8152600194850b96810196909652600292830b6024870152920b60448501520b60648301526000916001600160a01b039091169063df2ba250906084016138ec565b60408051600380825260808201909252606091600091906020820184803683375050506000848152600660205260408120600101548251929350600290810b900b91839190613d5a57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160039054906101000a900460020b60020b81600181518110613dae57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160069054906101000a900460020b60020b81600281518110613e0257634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613e3c918591016154ea565b60006040518083038186803b158015613e5457600080fd5b505afa158015613e68573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ff89190810190614cb1565b6001600160a01b0381166000908152600a602052604080822054815160028082526060828101909452929391928160200160208202803683375050506001600160a01b03851660009081526015602052604090205490915060ff16613f1057600082815260066020526040902060010154600160b01b900460020b613f2d565b600082815260066020526040902060010154600160581b900460020b5b60020b81600081518110613f5157634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526001600160a01b03851660009081526015909152604090205460ff16613fa157600082815260066020526040902060010154600160e01b900460020b613fbe565b600082815260066020526040902060010154600160801b900460020b5b60020b81600181518110613fe257634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d9749161401c918591016154ea565b60006040518083038186803b15801561403457600080fd5b505afa158015614048573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed29190810190614cb1565b6001600160a01b0382166000908152600d60205260408120541590826140b0576001600160a01b03808516600090815260136020526040902054166140cc565b6001600160a01b03808516600090815260146020526040902054165b905060008361410a576001600160a01b038086166000908152600f602090815260408083206101008b015162ffffff1684529091529020541661413c565b6001600160a01b038086166000908152600e6020908152604080832060808b0151600190810b900b8452909152902054165b9050828061415157506001600160a01b038116155b156141af576000614172876000015187878a608001518b610100015161393c565b905061417f868287613c32565b6001600160a01b0383161561419957614199836001612f0e565b6141a981886000015160006132dd565b50612089565b816001600160a01b0316816001600160a01b0316146141fe576141d3816000612f0e565b6141de826001612f0e565b6141e9858286613c32565b6141f981876000015160006132dd565b612089565b614209826000612f0e565b61208982876000015160006132dd565b600061422883600001516134e7565b6001600160a01b0381166000908152600d602052604090205490915015610cd55760005b6001600160a01b0382166000908152600d60205260409020548110156131b5576001600160a01b038083166000908152600c6020908152604080832085845282528083205490931680835260159091529190205460ff16151584151514156142b9576142b9816001612f0e565b50806142c48161594c565b91505061424c565b604080516002808252606080830184529260009291906020830190803683370190505090506142fd8461232861582b565b8160008151811061431e57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050826143375761271261433b565b6127115b8160018151811061435c57634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b60035460405163c48e62f160e01b8152600481018690526060916000916101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b1580156143bc57600080fd5b505afa1580156143d0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526143f89190810190614fac565b60a0015160035460405163c48e62f160e01b8152600481018990526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561444457600080fd5b505afa158015614458573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526144809190810190614fac565b60c0015160405160200161449592919061536f565b604051602081830303815290604052905084156144de57806144b685614794565b6040516020016144c79291906152e7565b604051602081830303815290604052915050610ed2565b806144ed8462ffffff166147e6565b6040516020016144c7929190615331565b600354604051624dc46d60e41b8152600481018990526001600160a01b038781166024830152610100909204909116906304dc46d090604401600060405180830381600087803b15801561455157600080fd5b505af1158015614565573d6000803e3d6000fd5b5050506001600160a01b038087166000818152600a602090815260408083208d905560168252808320805460ff19166001908117909155601083528184208054968e166001600160a01b03199788168117909155808552600c8452828520600d8086528487208054885291865293862080549098169096179096559490925252546145f192509061582b565b6001600160a01b0387166000908152600d602052604090205583156146e8576001600160a01b038681166000818152600e60209081526040808320600189810b80820b865291845282852080546001600160a01b0319908116988e1698891790915587865260118552838620805461ffff191661ffff90941693909317909255948452601483528184208054909116861790559382526015905291909120805460ff191690911790557f41525405a5e10a7f61a75ce8fb247811dadc00a10ad9bd82d09ddab453a686d3868689866146c883613569565b866040516146db969594939291906153d7565b60405180910390a1611eff565b6001600160a01b038087166000818152600f6020908152604080832062ffffff88168085529083528184208054968c166001600160a01b0319978816811790915580855260128452828520805462ffffff19169092179091559383526013909152902080549092161790557f2fb9c2a6ac1646a705c03b0657053182a32ea93c368b719a84e352ab42dcb8f88686898561478183613569565b86604051611ef696959493929190615427565b606060008260010b136147dd576147b96147b083600019615857565b61ffff166147e6565b6040516020016147c991906153ae565b6040516020818303038152906040526127d1565b6127d18261ffff165b60608161480a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614834578061481e8161594c565b915061482d9050600a83615843565b915061480e565b60008167ffffffffffffffff81111561485d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614887576020820181803683370190505b5090505b8415610ed25761489c600183615909565b91506148a9600a86615967565b6148b490603061582b565b60f81b8183815181106148d757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506148f9600a86615843565b945061488b565b82805482825590600052602060002090810192821561493b579160200282015b8281111561493b578251825591602001919060010190614920565b5061494792915061494b565b5090565b5b80821115614947576000815560010161494c565b803561496b816159bd565b919050565b803561496b816159d2565b8035600181900b811461496b57600080fd5b803561496b816159e0565b805161496b816159e0565b600082601f8301126149b3578081fd5b815167ffffffffffffffff8111156149cd576149cd6159a7565b6149e0601f8201601f191660200161576b565b8181528460208386010111156149f4578283fd5b610ed2826020830160208701615920565b803562ffffff8116811461496b57600080fd5b803560ff8116811461496b57600080fd5b600060208284031215614a3a578081fd5b8135612ff8816159bd565b600060208284031215614a56578081fd5b8151612ff8816159bd565b60008060008060808587031215614a76578283fd5b8435614a81816159bd565b93506020850135614a91816159bd565b92506040850135614aa1816159bd565b91506060850135614ab1816159bd565b939692955090935050565b600080600080600060a08688031215614ad3578283fd5b8535614ade816159bd565b9450602086810135614aef816159bd565b94506040870135614aff816159bd565b93506060870135614b0f816159bd565b9250608087013567ffffffffffffffff811115614b2a578283fd5b8701601f81018913614b3a578283fd5b8035614b4d614b488261579c565b61576b565b8082825284820191508484018c868560051b8701011115614b6c578687fd5b8694505b83851015614b8e578035835260019490940193918501918501614b70565b5080955050505050509295509295909350565b60008060408385031215614bb3578182fd5b8235614bbe816159bd565b91506020830135614bce816159d2565b809150509250929050565b60008060408385031215614beb578182fd5b8235614bf6816159bd565b9150614c046020840161497b565b90509250929050565b60008060408385031215614c1f578182fd5b8235614c2a816159bd565b9150614c0460208401614a05565b60008060408385031215614c4a578182fd5b8235614c55816159bd565b946020939093013593505050565b60008060008060808587031215614c78578182fd5b8435614c83816159bd565b935060208501359250614c9860408601614a18565b9150614ca660608601614a18565b905092959194509250565b60006020808385031215614cc3578182fd5b825167ffffffffffffffff811115614cd9578283fd5b8301601f81018513614ce9578283fd5b8051614cf7614b488261579c565b80828252848201915084840188868560051b8701011115614d16578687fd5b8694505b83851015614d38578051835260019490940193918501918501614d1a565b50979650505050505050565b600060208284031215614d55578081fd5b8135612ff8816159d2565b600060208284031215614d71578081fd5b8151612ff8816159d2565b600060208284031215614d8d578081fd5b5035919050565b60008060408385031215614da6578182fd5b823591506020830135614bce816159bd565b600080600060608486031215614dcc578081fd5b833592506020840135614dde816159bd565b91506040840135614dee816159d2565b809150509250925092565b600080600060608486031215614e0d578081fd5b833592506020840135614dde816159d2565b60008060008060808587031215614e34578182fd5b843593506020850135614e46816159e0565b92506040850135614e56816159e0565b91506060850135614ab1816159e0565b600080600080600080868803610220811215614e80578485fd5b8735965061018080601f1983011215614e97578586fd5b614e9f61571e565b915060208901358252614eb460408a0161498d565b6020830152614ec560608a0161498d565b6040830152614ed660808a0161498d565b6060830152614ee760a08a0161497b565b6080830152614ef860c08a0161498d565b60a0830152614f0960e08a0161497b565b60c0830152610100614f1c818b0161498d565b60e0840152610120614f2f818c01614a05565b828501526101409150614f43828c0161498d565b90840152610160614f558b8201614a05565b82850152614f64838c0161498d565b9084015250909550506101a08701359350614f826101c08801614960565b9250614f916101e08801614970565b9150614fa06102008801614970565b90509295509295509295565b600060208284031215614fbd578081fd5b815167ffffffffffffffff80821115614fd4578283fd5b9083019060e08286031215614fe7578283fd5b614fef615748565b825181526020830151602082015261500960408401614998565b604082015261501a60608401614998565b606082015261502b60808401614998565b608082015260a083015182811115615041578485fd5b61504d878286016149a3565b60a08301525060c083015182811115615064578485fd5b615070878286016149a3565b60c08301525095945050505050565b600060208284031215615090578081fd5b5051919050565b600080604083850312156150a9578182fd5b823591506020830135614bce816159d2565b6000815180845260208085019450808401835b838110156150ea578151875295820195908201906001016150ce565b509495945050505050565b6000815480845260208085019450838352808320835b838110156150ea5781548752958201956001918201910161510b565b80518252602081015161513f602084018260020b9052565b506040810151615154604084018260020b9052565b506060810151615169606084018260020b9052565b50608081015161517e608084018260010b9052565b5060a081015161519360a084018260020b9052565b5060c08101516151a860c084018260010b9052565b5060e08101516151bd60e084018260020b9052565b506101008181015162ffffff169083015261012080820151600281900b8285015250506101408181015162ffffff169083015261016080820151600281900b828501526131b5565b805482526001810154600281810b810b602085015261522e604085018360181c830b60020b9052565b615242606085018360301c830b60020b9052565b615257608085018360481c60010b60010b9052565b61526b60a085018360581c830b60020b9052565b61528060c085018360701c60010b60010b9052565b61529460e085018360801c830b60020b9052565b62ffffff609883901c81166101008601526152ba61012086018460b01c840b60020b9052565b6152d16101408601828560c81c1662ffffff169052565b506131b561016085018360e01c830b60020b9052565b600083516152f9818460208801615920565b600560fb1b9083019081528351615317816001840160208801615920565b602960f81b60019290910191820152600201949350505050565b60008351615343818460208801615920565b6201016960ed1b9083019081528351615363816003840160208801615920565b01600301949350505050565b60008351615381818460208801615920565b630103b39960e51b90830190815283516153a2816004840160208801615920565b01600401949350505050565b602d60f81b8152600082516153ca816001850160208701615920565b9190910160010192915050565b6001600160a01b0387811682528616602082015260408101859052600184900b606082015260c060808201819052600090615414908301856150bb565b90508260a0830152979650505050505050565b6001600160a01b038781168252861660208201526040810185905262ffffff8416606082015260c060808201819052600090615414908301856150bb565b6001600160a01b039586168152602081019490945291909316604083015262ffffff9283166060830152909116608082015260a00190565b6020808252825182820181905260009190848201906040850190845b818110156154de5783516001600160a01b0316835292840192918401916001016154b9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156154de57835183529284019291840191600101615506565b602081526000612ff860208301846150bb565b8481526001600160a01b0384166020820152604081018390526101e081016155606060830184615127565b95945050505050565b8481526001600160a01b0384166020820152604081018390526101e081016155606060830184615205565b8581526001600160a01b038516602082015260006102006155b86040840187615127565b806101c08401526155cb818401866150bb565b915050826101e08301529695505050505050565b60006101e08683528560208401526155fa6040840186615127565b806101c084015261560d818401856150f5565b979650505050505050565b60006101e08683528560208401526155fa6040840186615205565b60006101008a835280602084015289518082850152610120915061565d8183860160208e01615920565b604084018a90526060840189905260808401889052601f01601f19168301838103820160a0850152615691828201886150bb565b95151560c08501525050506001600160a01b039190911660e0909101529695505050505050565b6020808252600d908201526c27b7363c9031b7b739bab6b2b960991b604082015260600190565b8481526080602082015260006156f860808301866150bb565b828103604084015261570a81866150f5565b915050821515606083015295945050505050565b604051610180810167ffffffffffffffff81118282101715615742576157426159a7565b60405290565b60405160e0810167ffffffffffffffff81118282101715615742576157426159a7565b604051601f8201601f1916810167ffffffffffffffff81118282101715615794576157946159a7565b604052919050565b600067ffffffffffffffff8211156157b6576157b66159a7565b5060051b60200190565b60008160010b8360010b82821282617fff038213811516156157e4576157e461597b565b82617fff190382128116156157fb576157fb61597b565b50019392505050565b600062ffffff8083168185168083038211156158225761582261597b565b01949350505050565b6000821982111561583e5761583e61597b565b500190565b60008261585257615852615991565b500490565b60008160010b8360010b617fff838213848413838304851182821616156158805761588061597b565b617fff198685128281168783058712161561589d5761589d61597b565b8787129250858205871284841616156158b8576158b861597b565b858505871281841616156158ce576158ce61597b565b5050509290910295945050505050565b600062ffffff808316818516818304811182151516156159005761590061597b565b02949350505050565b60008282101561591b5761591b61597b565b500390565b60005b8381101561593b578181015183820152602001615923565b838111156131b55750506000910152565b60006000198214156159605761596061597b565b5060010190565b60008261597657615976615991565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461120757600080fd5b801515811461120757600080fd5b8060020b811461120757600080fdfea2646970667358221220b0fc4f8db6f34f4598842dd294869a0a414e61768861a4697a8c574f6fa944fd64736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103995760003560e01c806360b4df85116101e9578063b0275fa01161010f578063c480977c116100ad578063db0d45791161007c578063db0d457914610bec578063df351aaf14610bff578063e38f273814610c12578063fa043f4014610c2557600080fd5b8063c480977c14610b83578063cc5cea2714610b96578063ceda8e9014610ba9578063d28231bd14610bc957600080fd5b8063b4fd7296116100e9578063b4fd729614610b1c578063b613d8ee14610b34578063bf989b6e14610b5d578063c3b83f5f14610b7057600080fd5b8063b0275fa014610a52578063b09bd9e314610a72578063b103feb014610b0957600080fd5b806393f4452e116101875780639aceb36e116101565780639aceb36e146109fe578063a12695ca14610a1e578063a4f096e814610a41578063ae71dcdf14610a4a57600080fd5b806393f4452e1461089f57806393ff69d7146109a95780639971441b146109e25780639a196e33146109f557600080fd5b80638d220d99116101c35780638d220d99146107ea5780638da5cb5b1461082057806391b4ded914610839578063937a314f1461084257600080fd5b806360b4df85146107115780636c35b775146107b957806379ba5097146107e257600080fd5b80632fff7020116102ce578063447b1d581161026c578063574ef5d91161023b578063574ef5d9146106845780635a2f7731146106a75780635c975abb146106d05780635d134bc2146106dd57600080fd5b8063447b1d58146105fd5780634adf7219146106315780635034c5881461065157806353a47bb71461067157600080fd5b8063352fe4ee116102a8578063352fe4ee1461059e578063366c16a5146105b157806336c0d855146105d15780633ea921ae146105f457600080fd5b80632fff70201461050c578063300a02981461051457806332b566a91461051c57600080fd5b806316c38b3c1161033b578063263737e211610315578063263737e21461049f57806329bfb6cd146104d35780632b7ac3f3146104e65780632da3f9ce146104f957600080fd5b806316c38b3c146104625780631afed5cc146104755780631e864c3b1461048c57600080fd5b806310063fdc1161037757806310063fdc146103ee57806313af40351461041957806314bdaa891461042c5780631627540c1461044f57600080fd5b806301a5627e1461039e578063091c9b96146103b35780630caf0e0c146103db575b600080fd5b6103b16103ac366004614ba1565b610c38565b005b6103c66103c1366004614df9565b610cda565b60405190151581526020015b60405180910390f35b6103b16103e9366004614db8565b610eda565b600554610401906001600160a01b031681565b6040516001600160a01b0390911681526020016103d2565b6103b1610427366004614a29565b611003565b6103c661043a366004614a29565b60176020526000908152604090205460ff1681565b6103b161045d366004614a29565b61113e565b6103b1610470366004614d44565b611194565b61047e61232881565b6040519081526020016103d2565b601954610401906001600160a01b031681565b6104016104ad366004614c0d565b600f6020908152600092835260408084209091529082529020546001600160a01b031681565b6103b16104e1366004614e66565b61120a565b600454610401906001600160a01b031681565b6103b1610507366004614abc565b611f08565b61047e600181565b61047e600281565b61056c61052a366004614d7c565b6000908152600660205260409020600190810154600160481b8104820b92600160701b820490920b9162ffffff600160981b8304811692600160c81b90041690565b60408051600195860b81529390940b602084015262ffffff9182169383019390935290911660608201526080016103d2565b6103b16105ac366004614db8565b612091565b6105c46105bf366004614a29565b61232f565b6040516103d2919061549d565b6103c66105df366004614a29565b60086020526000908152604090205460ff1681565b61047e61271181565b61040161060b366004614c38565b600c6020908152600092835260408084209091529082529020546001600160a01b031681565b61047e61063f366004614a29565b600a6020526000908152604090205481565b61047e61065f366004614d7c565b60096020526000908152604090205481565b600154610401906001600160a01b031681565b6103c6610692366004614d7c565b600b6020526000908152604090205460ff1681565b6104016106b5366004614a29565b6014602052600090815260409020546001600160a01b031681565b6003546103c69060ff1681565b6104016106eb366004614bd9565b600e6020908152600092835260408084209091529082529020546001600160a01b031681565b61077661071f366004614d7c565b600090815260066020526040902060010154600281810b9263010000008304820b92600160301b8104830b92600160581b8204810b92600160801b8304820b92600160b01b8104830b92600160e01b909104900b90565b60408051600298890b815296880b602088015294870b9486019490945291850b6060850152840b6080840152830b60a083015290910b60c082015260e0016103d2565b6104016107c7366004614a29565b6010602052600090815260409020546001600160a01b031681565b6103b161243c565b61080d6107f8366004614a29565b60116020526000908152604090205460010b81565b60405160019190910b81526020016103d2565b600054610401906201000090046001600160a01b031681565b61047e60025481565b61087f610850366004614a29565b6001600160a01b0390811660009081526013602090815260408083205460149092529091205490821692911690565b604080516001600160a01b039384168152929091166020830152016103d2565b6109366108ad366004614d7c565b600660205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b604080519c8d5260029b8c0b60208e0152998b0b998c019990995296890b60608b0152600195860b60808b015293880b60a08a01529190930b60c088015291850b60e087015262ffffff918216610100870152840b61012086015216610140840152900b610160820152610180016103d2565b6109ce6109b7366004614a29565b60126020526000908152604090205462ffffff1681565b60405162ffffff90911681526020016103d2565b6103b16109f0366004614d7c565b612539565b61047e601b5481565b610a11610a0c366004614d7c565b6127c6565b6040516103d29190615522565b6103c6610a2c366004614a29565b60156020526000908152604090205460ff1681565b61047e61271281565b61047e600081565b61047e610a60366004614a29565b601a6020526000908152604090205481565b610936610a80366004614d7c565b600760205260009081526040902080546001918201549091600282810b9263010000008104820b92600160301b8204830b92600160481b8304820b92600160581b8104820b92600160701b8204900b91600160801b8204810b9162ffffff600160981b8204811692600160b01b8304810b92600160c81b810490921691600160e01b9004900b8c565b61047e610b17366004614c38565b6127d7565b6003546104019061010090046001600160a01b031681565b610401610b42366004614a29565b6013602052600090815260409020546001600160a01b031681565b6103b1610b6b366004614a61565b612808565b6103b1610b7e366004614a29565b6128ba565b6103b1610b91366004614e1f565b6129d3565b6103b1610ba4366004615097565b612c71565b61047e610bb7366004614a29565b600d6020526000908152604090205481565b6103c6610bd7366004614a29565b60166020526000908152604090205460ff1681565b610a11610bfa366004614a29565b612ccb565b6103b1610c0d366004614d7c565b612cd6565b6103b1610c20366004614d94565b612d13565b6103b1610c33366004614c63565b612dc4565b60035461010090046001600160a01b03163314610c705760405162461bcd60e51b8152600401610c67906156b8565b60405180910390fd5b60005b6001600160a01b0383166000908152600d6020526040902054811015610cd5576001600160a01b038084166000908152600c60209081526040808320858452909152902054610cc3911683612f0e565b80610ccd8161594c565b915050610c73565b505050565b600082610ddc5760008481526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610dd79083612f4e565b610ed2565b60008481526007602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b610160820152610ed29083612f4e565b949350505050565b60035461010090046001600160a01b03163314610f095760405162461bcd60e51b8152600401610c67906156b8565b60008381526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b820b60c0820152600160801b8404830b830b830b60e082015262ffffff600160981b85048116610100830152600160b01b8504840b840b840b610120830152600160c81b850416610140820152600160e01b909304820b820b90910b610160830152610cd5919084908490612fff565b6001600160a01b0381166110595760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f742062652030000000000000006044820152606401610c67565b600154600160a01b900460ff16156110c55760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610c67565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6111466131bb565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001611133565b61119c6131bb565b60035460ff16151581151514156111b05750565b6003805460ff191682151590811790915560ff16156111ce57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001611133565b50565b60035461010090046001600160a01b031633148061123257506019546001600160a01b031633145b61126f5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606401610c67565b6005546040516333dfec9960e21b81526001600160a01b038581166004830152600092169063cf7fb2649060240160206040518083038186803b1580156112b557600080fd5b505afa1580156112c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ed9190614d60565b90506112f98684612f4e565b15611e5b57600061130d8760000151613235565b90506000600660008960000151815260200190815260200160002060405180610180016040529081600082015481526020016001820160009054906101000a900460020b60020b60020b81526020016001820160039054906101000a900460020b60020b60020b81526020016001820160069054906101000a900460020b60020b60020b81526020016001820160099054906101000a900460010b60010b60010b815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a900460010b60010b60010b81526020016001820160109054906101000a900460020b60020b60020b81526020016001820160139054906101000a900462ffffff1662ffffff1662ffffff1681526020016001820160169054906101000a900460020b60020b60020b81526020016001820160199054906101000a900462ffffff1662ffffff1662ffffff16815260200160018201601c9054906101000a900460020b60020b60020b81525050905087600660008a6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008a6000015181526020019081526020016000208190555061168e86896000015160016132dd565b6000878152600b602052604090205460ff16806116c257506001600160a01b0386166000908152600d602052604090205415155b156116d1576116d1888761334d565b600480546001600160a01b03888116600090815260186020526040808220905163217d323560e11b8152919492909316926342fa646a9261171a928d92899290918d91016156df565b60206040518083038186803b15801561173257600080fd5b505afa158015611746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176a9190614d60565b90508315611ba7576001600160a01b03871660009081526008602052604090205460ff16806118175750600354604051630a928f9f60e21b81526001600160a01b03898116600483015261010090920490911690632a4a3e7c9060240160206040518083038186803b1580156117df57600080fd5b505afa1580156117f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118179190614d60565b15611b5557600354604051630259f5fd60e01b81526001600160a01b0389811660048301526000602483015261010090920490911690630259f5fd90604401600060405180830381600087803b15801561187057600080fd5b505af1158015611884573d6000803e3d6000fd5b5050505080611af957600060086000896001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555081600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff160217905550905050611aaf8988600180612fff565b8851604080516001600160a01b038a16815260208101929092527fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a910160405180910390a1611dfd565b6001600160a01b0387166000908152601a602052604090205415801590611b435750601b546001600160a01b0388166000908152601a6020526040902054611b419042615909565b105b15611b5a57611b558988600180612fff565b611dfd565b6001600160a01b0387166000908152600860205260408120805460ff19169055611b89908a9089906001612fff565b6001600160a01b0387166000908152601a6020526040812055611dfd565b83158015611bb3575080155b15611dfd57611bc58988600180612fff565b611bd487600160006001613464565b81600760008b6000015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff1602179055509050507fcb6e87c3d70eab47f84a42c3021b86de43cf8d37ebe9cfa494c4f89b75205a8a878a60000151604051611df49291906001600160a01b03929092168252602082015260400190565b60405180910390a15b88516001600160a01b0388166000908152601860205260409081902090517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe92611e4b928e928e91906155df565b60405180910390a1505050611eff565b80611ec0576001600160a01b0384166000908152600860205260409020805460ff191660011790558115611ea5576001600160a01b0384166000908152601a602052604090204290555b611eb28685600180612fff565b611ec0846001806000613464565b85516040517f420dbf4677c8331a5938fcc5890c5ae453dd3344f80f9a669d6adb2fea7de3d091611ef6918a9188918b90615535565b60405180910390a15b50505050505050565b600054610100900460ff16611f235760005460ff1615611f27565b303b155b611f8a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c67565b600054610100900460ff16158015611fac576000805461ffff19166101011790555b611fb586611003565b600380546001600160a01b0380881661010002610100600160a81b031990921691909117909155600480548683166001600160a01b031991821617909155600580549286169290911691909117905560005b8251811015612076576001600b600085848151811061203657634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550808061206e9061594c565b915050612007565b508015612089576000805461ff00191690555b505050505050565b60035461010090046001600160a01b031633146120c05760405162461bcd60e51b8152600401610c67906156b8565b6120cc828460016132dd565b60008381526006602090815260409182902082516101808101845281548152600191820154600281810b810b810b9483019490945263010000008104840b840b840b94820194909452600160301b8404830b830b830b6060820152600160481b8404820b820b820b6080820152600160581b8404830b830b830b60a0820152600160701b8404820b820b90910b60c0820152600160801b8304820b820b820b60e082015262ffffff600160981b84048116610100830152600160b01b8404830b830b830b610120830152600160c81b840416610140820152600160e01b909204810b810b900b6101608201526121c29082612f4e565b610cd5576001600160a01b0382166000908152600860209081526040808320805460ff1916600190811790915586845260068352928190208151610180810183528154815290840154600281810b810b810b9483019490945263010000008104840b840b840b92820192909252600160301b8204830b830b830b6060820152600160481b8204840b840b840b6080820152600160581b8204830b830b830b60a0820152600160701b8204840b840b840b60c0820152600160801b8204830b830b830b60e082015262ffffff600160981b83048116610100830152600160b01b8304840b840b840b610120830152600160c81b830416610140820152600160e01b909104820b820b90910b6101608201526122de91849080612fff565b6000838152600660205260409081902090517f420dbf4677c8331a5938fcc5890c5ae453dd3344f80f9a669d6adb2fea7de3d0916123229186918691839190615569565b60405180910390a1505050565b6001600160a01b0381166000908152600d60205260408120546060919067ffffffffffffffff81111561237257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561239b578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600d6020526040902054811015612435576001600160a01b038085166000908152600c60209081526040808320858452909152902054835191169083908390811061240b57634e487b7160e01b600052603260045260246000fd5b6001600160a01b03909216602092830291909101909101528061242d8161594c565b9150506123a1565b5092915050565b6001546001600160a01b031633146124b45760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610c67565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60035461010090046001600160a01b031633146125685760405162461bcd60e51b8152600401610c67906156b8565b60008181526007602090815260408083206006909252822081548155600191820180549183018054600293840b840b62ffffff90811662ffffff198316811784558454630100000090819004870b870b83160265ffffffffffff1990931617919091178083558354600160301b90819004860b860b83160268ffffff000000000000198216811784558454600160481b90819004880b880b61ffff9081169091026affff000000000000000000199092166affffffffff0000000000001990931692909217178084558454600160581b90819004870b870b84160262ffffff60581b198216811785558554600160701b90819004890b90980b90921690960261ffff60701b1990911664ffffffffff60581b1990961695909517949094178082558254600160801b90819004850b850b86160262ffffff60801b198216811783558354600160981b9081900487160262ffffff60981b1990911665ffffffffffff60801b1990921691909117178082558254600160b01b90819004850b850b86160262ffffff60b01b198216811783558354600160c81b9081900487160262ffffff60c81b1990911665ffffffffffff60b01b1990921691909117178082559154600160e01b90819004840b90930b90931690910262ffffff60e01b19909116179055612754826134e7565b9050612762818360016132dd565b60008281526006602090815260408083206001600160a01b038516845260189092529182902091517f5d8fed649db8e5d2dd77ea4f51ee8548f87d2679e2f5407f8db9793f701f8dfe926127ba928692839290615618565b60405180910390a15050565b60606127d182613235565b92915050565b601860205281600052604060002081815481106127f357600080fd5b90600052602060002001600091509150505481565b6128106131bb565b60038054610100600160a81b0319166101006001600160a01b0387811691820292909217909255600480546001600160a01b0319908116878416908117909255600580548216878516908117909155601980549092169386169384179091556040805194855260208501929092529083015260608201527fa2cad6ae2699ea86ba233a96ca0e57d895983eeed04f6bd0a770187c58b820dd9060800160405180910390a150505050565b6128c26131bb565b6001600160a01b03811661290a5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610c67565b600154600160a81b900460ff161561295a5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610c67565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101611133565b60035461010090046001600160a01b03163314612a025760405162461bcd60e51b8152600401610c67906156b8565b6040518061018001604052808581526020018460020b81526020018360020b81526020018260020b8152602001600060010b8152602001600060020b8152602001600060010b8152602001600060020b8152602001600062ffffff168152602001600060020b8152602001600062ffffff168152602001600060020b815250600660008681526020019081526020016000206000820151816000015560208201518160010160006101000a81548162ffffff021916908360020b62ffffff16021790555060408201518160010160036101000a81548162ffffff021916908360020b62ffffff16021790555060608201518160010160066101000a81548162ffffff021916908360020b62ffffff16021790555060808201518160010160096101000a81548161ffff021916908360010b61ffff16021790555060a082015181600101600b6101000a81548162ffffff021916908360020b62ffffff16021790555060c082015181600101600e6101000a81548161ffff021916908360010b61ffff16021790555060e08201518160010160106101000a81548162ffffff021916908360020b62ffffff1602179055506101008201518160010160136101000a81548162ffffff021916908362ffffff1602179055506101208201518160010160166101000a81548162ffffff021916908360020b62ffffff1602179055506101408201518160010160196101000a81548162ffffff021916908362ffffff16021790555061016082015181600101601c6101000a81548162ffffff021916908360020b62ffffff16021790555090505042600960008681526020019081526020016000208190555050505050565b612c796131bb565b6000828152600b6020908152604091829020805460ff19168415159081179091558251858152918201527f388428bda48903bbd0180b2e70447674064e582855a643dd2df349c85b0683f691016127ba565b60606127d182613569565b612cde6131bb565b601b8190556040518181527fcf94ac0e8dccd8a891f16d217c94137033687f7fcffbfa4cfc4e16d85a52320790602001611133565b6005546001600160a01b03163314612d5c5760405162461bcd60e51b815260206004820152600c60248201526b27b7363c9036b0b730b3b2b960a11b6044820152606401610c67565b600354604051624dc46d60e41b8152600481018490526001600160a01b038381166024830152610100909204909116906304dc46d0906044015b600060405180830381600087803b158015612db057600080fd5b505af1158015612089573d6000803e3d6000fd5b60035461010090046001600160a01b03163314612df35760405162461bcd60e51b8152600401610c67906156b8565b60005b6001600160a01b0385166000908152600d6020526040902054811015612f07576001600160a01b038086166000908152600c602090815260408083208584529091529020541684612eac5760055460405163b91f5e3560e01b81526001600160a01b038381166004830152602482018890529091169063b91f5e3590604401600060405180830381600087803b158015612e8f57600080fd5b505af1158015612ea3573d6000803e3d6000fd5b50505050612ef4565b6001600160a01b03811660009081526015602052604090205460ff1615612ee357612ede818560ff168560ff16613603565b612ef4565b612ef4818560ff168560ff16613745565b5080612eff8161594c565b915050612df6565b5050505050565b60035460405163ed5e00eb60e01b81526001600160a01b03848116600483015283151560248301526101009092049091169063ed5e00eb90604401612d96565b60048054602084015160408086015160608701519151631578f73160e31b815286151595810195909552600292830b6024860152820b6044850152900b60648301526000916001600160a01b039091169063abc7b9889060840160206040518083038186803b158015612fc057600080fd5b505afa158015612fd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff89190614d60565b9392505050565b801561300f5761300f8383612f0e565b6001600160a01b0383166000908152600d6020526040902054156131b557811561309e5760005b6001600160a01b0384166000908152600d6020526040902054811015613098576001600160a01b038085166000908152600c60209081526040808320858452909152902054613086911684612f0e565b806130908161594c565b915050613036565b506131b5565b6130a784613885565b1561312a576001600160a01b038084166000908152600f6020908152604080832061010089015162ffffff16845290915290205416806131125760006130fe866000015186600089608001518a610100015161393c565b905061310c85826000613c32565b50613128565b61311c8184612f0e565b61312884826000613c32565b505b61313384613c96565b156131b5576001600160a01b038084166000908152600e602090815260408083206080890151600190810b900b8452909152902054168061319f57600061318b866000015186600189608001518a610100015161393c565b905061319985826001613c32565b50612f07565b6131a98184612f0e565b612f0784826001613c32565b50505050565b6000546201000090046001600160a01b031633146132335760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610c67565b565b60606000613242836134e7565b6001600160a01b03811660009081526017602052604090205490915060ff166132735761326e83613cfb565b612ff8565b6001600160a01b038116600090815260186020908152604091829020805483518184028101840190945280845290918301828280156132d157602002820191906000526020600020905b8154815260200190600101908083116132bd575b50505050509392505050565b806132f0576132eb83613e90565b6132f9565b6132f982613cfb565b6001600160a01b038416600090815260186020908152604090912082516133269391929190910190614900565b5050506001600160a01b03166000908152601760205260409020805460ff19166001179055565b61335682613885565b156133d25761336782826000614070565b81516001600160a01b038083166000908152601360205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c929116846133b182613569565b6127126040516133c5959493929190615594565b60405180910390a16133dd565b6133dd826000614219565b6133e682613c96565b15613455576133f782826001614070565b81516001600160a01b038083166000908152601460205260409020547fe796f6828b37337b49eb42b13232da29af82340b30005e54115fadb4a569e85c9291168461344182613569565b6127116040516127ba959493929190615594565b613460826001614219565b5050565b6003546040516302830aeb60e41b81526001600160a01b03868116600483015285151560248301528415156044830152831515606483015261010090920490911690632830aeb090608401600060405180830381600087803b1580156134c957600080fd5b505af11580156134dd573d6000803e3d6000fd5b5050505050505050565b600354604051631f138de360e31b81526004810183905260009161010090046001600160a01b03169063f89c6f189060240160206040518083038186803b15801561353157600080fd5b505afa158015613545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d19190614a45565b6001600160a01b03811660009081526017602052604090205460609060ff1661359a5761359582613e90565b6127d1565b6001600160a01b038216600090815260186020908152604091829020805483518184028101840190945280845290918301828280156135f857602002820191906000526020600020905b8154815260200190600101908083116135e4575b505050505092915050565b6001600160a01b03831660009081526011602052604081205460010b61362a846064615857565b61363491906157c0565b90506000613643836064615857565b905060008160010b8360010b1361366f578160010b8360010b12613668576000613672565b6002613672565b60015b60055460405163b91f5e3560e01b81526001600160a01b0389811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b1580156136c257600080fd5b505af11580156136d6573d6000803e3d6000fd5b5050506001600160a01b03808816600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b69350613735928a92869291169061ffff808c1691908b1690615465565b60405180910390a1505050505050565b6001600160a01b03831660009081526012602052604081205462ffffff16908161376f8486615804565b61377a9060646158de565b62ffffff16116137b75762ffffff82166137948486615804565b61379f9060646158de565b62ffffff16106137b05760006137ba565b60026137ba565b60015b60055460405163b91f5e3560e01b81526001600160a01b0388811660048301526024820184905292935091169063b91f5e3590604401600060405180830381600087803b15801561380a57600080fd5b505af115801561381e573d6000803e3d6000fd5b5050506001600160a01b03808716600090815260106020526040908190205490517f83ceafeb39bed691550da26fa66ed80c145831e22e374c627a71f30479ae59b69350613876928992869291169089908990615465565b60405180910390a15050505050565b60048054610100830151610120840151610140850151610160860151604051634e3a53b760e11b815262ffffff94851696810196909652600292830b6024870152921660448501520b60648301526000916001600160a01b0390911690639c74a76e906084015b60206040518083038186803b15801561390457600080fd5b505afa158015613918573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d19190614d60565b600354604051631c2ab73160e21b81526004810187905260009182916139ca9161010090046001600160a01b0316906370aadcc49060240160206040518083038186803b15801561398c57600080fd5b505afa1580156139a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c4919061507f565b866142cc565b6005549091506001600160a01b0316634cde32ce886139eb8189898961436e565b60035460405163c48e62f160e01b8152600481018d90526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b158015613a3357600080fd5b505afa158015613a47573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a6f9190810190614fac565b60200151600060028760018e6040518963ffffffff1660e01b8152600401613a9e989796959493929190615633565b602060405180830381600087803b158015613ab857600080fd5b505af1158015613acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af09190614a45565b5060055460408051622610c560e41b815290516001600160a01b039092169163dd5adfa39160019184916302610c50916004808301926020929190829003018186803b158015613b3f57600080fd5b505afa158015613b53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b77919061507f565b613b819190615909565b6040518263ffffffff1660e01b8152600401613b9f91815260200190565b60206040518083038186803b158015613bb757600080fd5b505afa158015613bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bef9190614a45565b9150613c2887878488888887600181518110613c1b57634e487b7160e01b600052603260045260246000fd5b60200260200101516144fe565b5095945050505050565b8015613c6757506001600160a01b03918216600090815260146020526040902080546001600160a01b03191691909216179055565b506001600160a01b03918216600090815260136020526040902080546001600160a01b03191691909216179055565b60048054608083015160a084015160c085015160e0860151604051630df2ba2560e41b8152600194850b96810196909652600292830b6024870152920b60448501520b60648301526000916001600160a01b039091169063df2ba250906084016138ec565b60408051600380825260808201909252606091600091906020820184803683375050506000848152600660205260408120600101548251929350600290810b900b91839190613d5a57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160039054906101000a900460020b60020b81600181518110613dae57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506006600084815260200190815260200160002060010160069054906101000a900460020b60020b81600281518110613e0257634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d97491613e3c918591016154ea565b60006040518083038186803b158015613e5457600080fd5b505afa158015613e68573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ff89190810190614cb1565b6001600160a01b0381166000908152600a602052604080822054815160028082526060828101909452929391928160200160208202803683375050506001600160a01b03851660009081526015602052604090205490915060ff16613f1057600082815260066020526040902060010154600160b01b900460020b613f2d565b600082815260066020526040902060010154600160581b900460020b5b60020b81600081518110613f5157634e487b7160e01b600052603260045260246000fd5b6020908102919091018101919091526001600160a01b03851660009081526015909152604090205460ff16613fa157600082815260066020526040902060010154600160e01b900460020b613fbe565b600082815260066020526040902060010154600160801b900460020b5b60020b81600181518110613fe257634e487b7160e01b600052603260045260246000fd5b602090810291909101015260048054604051632c85b65d60e21b81526001600160a01b039091169163b216d9749161401c918591016154ea565b60006040518083038186803b15801561403457600080fd5b505afa158015614048573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed29190810190614cb1565b6001600160a01b0382166000908152600d60205260408120541590826140b0576001600160a01b03808516600090815260136020526040902054166140cc565b6001600160a01b03808516600090815260146020526040902054165b905060008361410a576001600160a01b038086166000908152600f602090815260408083206101008b015162ffffff1684529091529020541661413c565b6001600160a01b038086166000908152600e6020908152604080832060808b0151600190810b900b8452909152902054165b9050828061415157506001600160a01b038116155b156141af576000614172876000015187878a608001518b610100015161393c565b905061417f868287613c32565b6001600160a01b0383161561419957614199836001612f0e565b6141a981886000015160006132dd565b50612089565b816001600160a01b0316816001600160a01b0316146141fe576141d3816000612f0e565b6141de826001612f0e565b6141e9858286613c32565b6141f981876000015160006132dd565b612089565b614209826000612f0e565b61208982876000015160006132dd565b600061422883600001516134e7565b6001600160a01b0381166000908152600d602052604090205490915015610cd55760005b6001600160a01b0382166000908152600d60205260409020548110156131b5576001600160a01b038083166000908152600c6020908152604080832085845282528083205490931680835260159091529190205460ff16151584151514156142b9576142b9816001612f0e565b50806142c48161594c565b91505061424c565b604080516002808252606080830184529260009291906020830190803683370190505090506142fd8461232861582b565b8160008151811061431e57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050826143375761271261433b565b6127115b8160018151811061435c57634e487b7160e01b600052603260045260246000fd5b60209081029190910101529392505050565b60035460405163c48e62f160e01b8152600481018690526060916000916101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b1580156143bc57600080fd5b505afa1580156143d0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526143f89190810190614fac565b60a0015160035460405163c48e62f160e01b8152600481018990526101009091046001600160a01b03169063c48e62f19060240160006040518083038186803b15801561444457600080fd5b505afa158015614458573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526144809190810190614fac565b60c0015160405160200161449592919061536f565b604051602081830303815290604052905084156144de57806144b685614794565b6040516020016144c79291906152e7565b604051602081830303815290604052915050610ed2565b806144ed8462ffffff166147e6565b6040516020016144c7929190615331565b600354604051624dc46d60e41b8152600481018990526001600160a01b038781166024830152610100909204909116906304dc46d090604401600060405180830381600087803b15801561455157600080fd5b505af1158015614565573d6000803e3d6000fd5b5050506001600160a01b038087166000818152600a602090815260408083208d905560168252808320805460ff19166001908117909155601083528184208054968e166001600160a01b03199788168117909155808552600c8452828520600d8086528487208054885291865293862080549098169096179096559490925252546145f192509061582b565b6001600160a01b0387166000908152600d602052604090205583156146e8576001600160a01b038681166000818152600e60209081526040808320600189810b80820b865291845282852080546001600160a01b0319908116988e1698891790915587865260118552838620805461ffff191661ffff90941693909317909255948452601483528184208054909116861790559382526015905291909120805460ff191690911790557f41525405a5e10a7f61a75ce8fb247811dadc00a10ad9bd82d09ddab453a686d3868689866146c883613569565b866040516146db969594939291906153d7565b60405180910390a1611eff565b6001600160a01b038087166000818152600f6020908152604080832062ffffff88168085529083528184208054968c166001600160a01b0319978816811790915580855260128452828520805462ffffff19169092179091559383526013909152902080549092161790557f2fb9c2a6ac1646a705c03b0657053182a32ea93c368b719a84e352ab42dcb8f88686898561478183613569565b86604051611ef696959493929190615427565b606060008260010b136147dd576147b96147b083600019615857565b61ffff166147e6565b6040516020016147c991906153ae565b6040516020818303038152906040526127d1565b6127d18261ffff165b60608161480a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614834578061481e8161594c565b915061482d9050600a83615843565b915061480e565b60008167ffffffffffffffff81111561485d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614887576020820181803683370190505b5090505b8415610ed25761489c600183615909565b91506148a9600a86615967565b6148b490603061582b565b60f81b8183815181106148d757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506148f9600a86615843565b945061488b565b82805482825590600052602060002090810192821561493b579160200282015b8281111561493b578251825591602001919060010190614920565b5061494792915061494b565b5090565b5b80821115614947576000815560010161494c565b803561496b816159bd565b919050565b803561496b816159d2565b8035600181900b811461496b57600080fd5b803561496b816159e0565b805161496b816159e0565b600082601f8301126149b3578081fd5b815167ffffffffffffffff8111156149cd576149cd6159a7565b6149e0601f8201601f191660200161576b565b8181528460208386010111156149f4578283fd5b610ed2826020830160208701615920565b803562ffffff8116811461496b57600080fd5b803560ff8116811461496b57600080fd5b600060208284031215614a3a578081fd5b8135612ff8816159bd565b600060208284031215614a56578081fd5b8151612ff8816159bd565b60008060008060808587031215614a76578283fd5b8435614a81816159bd565b93506020850135614a91816159bd565b92506040850135614aa1816159bd565b91506060850135614ab1816159bd565b939692955090935050565b600080600080600060a08688031215614ad3578283fd5b8535614ade816159bd565b9450602086810135614aef816159bd565b94506040870135614aff816159bd565b93506060870135614b0f816159bd565b9250608087013567ffffffffffffffff811115614b2a578283fd5b8701601f81018913614b3a578283fd5b8035614b4d614b488261579c565b61576b565b8082825284820191508484018c868560051b8701011115614b6c578687fd5b8694505b83851015614b8e578035835260019490940193918501918501614b70565b5080955050505050509295509295909350565b60008060408385031215614bb3578182fd5b8235614bbe816159bd565b91506020830135614bce816159d2565b809150509250929050565b60008060408385031215614beb578182fd5b8235614bf6816159bd565b9150614c046020840161497b565b90509250929050565b60008060408385031215614c1f578182fd5b8235614c2a816159bd565b9150614c0460208401614a05565b60008060408385031215614c4a578182fd5b8235614c55816159bd565b946020939093013593505050565b60008060008060808587031215614c78578182fd5b8435614c83816159bd565b935060208501359250614c9860408601614a18565b9150614ca660608601614a18565b905092959194509250565b60006020808385031215614cc3578182fd5b825167ffffffffffffffff811115614cd9578283fd5b8301601f81018513614ce9578283fd5b8051614cf7614b488261579c565b80828252848201915084840188868560051b8701011115614d16578687fd5b8694505b83851015614d38578051835260019490940193918501918501614d1a565b50979650505050505050565b600060208284031215614d55578081fd5b8135612ff8816159d2565b600060208284031215614d71578081fd5b8151612ff8816159d2565b600060208284031215614d8d578081fd5b5035919050565b60008060408385031215614da6578182fd5b823591506020830135614bce816159bd565b600080600060608486031215614dcc578081fd5b833592506020840135614dde816159bd565b91506040840135614dee816159d2565b809150509250925092565b600080600060608486031215614e0d578081fd5b833592506020840135614dde816159d2565b60008060008060808587031215614e34578182fd5b843593506020850135614e46816159e0565b92506040850135614e56816159e0565b91506060850135614ab1816159e0565b600080600080600080868803610220811215614e80578485fd5b8735965061018080601f1983011215614e97578586fd5b614e9f61571e565b915060208901358252614eb460408a0161498d565b6020830152614ec560608a0161498d565b6040830152614ed660808a0161498d565b6060830152614ee760a08a0161497b565b6080830152614ef860c08a0161498d565b60a0830152614f0960e08a0161497b565b60c0830152610100614f1c818b0161498d565b60e0840152610120614f2f818c01614a05565b828501526101409150614f43828c0161498d565b90840152610160614f558b8201614a05565b82850152614f64838c0161498d565b9084015250909550506101a08701359350614f826101c08801614960565b9250614f916101e08801614970565b9150614fa06102008801614970565b90509295509295509295565b600060208284031215614fbd578081fd5b815167ffffffffffffffff80821115614fd4578283fd5b9083019060e08286031215614fe7578283fd5b614fef615748565b825181526020830151602082015261500960408401614998565b604082015261501a60608401614998565b606082015261502b60808401614998565b608082015260a083015182811115615041578485fd5b61504d878286016149a3565b60a08301525060c083015182811115615064578485fd5b615070878286016149a3565b60c08301525095945050505050565b600060208284031215615090578081fd5b5051919050565b600080604083850312156150a9578182fd5b823591506020830135614bce816159d2565b6000815180845260208085019450808401835b838110156150ea578151875295820195908201906001016150ce565b509495945050505050565b6000815480845260208085019450838352808320835b838110156150ea5781548752958201956001918201910161510b565b80518252602081015161513f602084018260020b9052565b506040810151615154604084018260020b9052565b506060810151615169606084018260020b9052565b50608081015161517e608084018260010b9052565b5060a081015161519360a084018260020b9052565b5060c08101516151a860c084018260010b9052565b5060e08101516151bd60e084018260020b9052565b506101008181015162ffffff169083015261012080820151600281900b8285015250506101408181015162ffffff169083015261016080820151600281900b828501526131b5565b805482526001810154600281810b810b602085015261522e604085018360181c830b60020b9052565b615242606085018360301c830b60020b9052565b615257608085018360481c60010b60010b9052565b61526b60a085018360581c830b60020b9052565b61528060c085018360701c60010b60010b9052565b61529460e085018360801c830b60020b9052565b62ffffff609883901c81166101008601526152ba61012086018460b01c840b60020b9052565b6152d16101408601828560c81c1662ffffff169052565b506131b561016085018360e01c830b60020b9052565b600083516152f9818460208801615920565b600560fb1b9083019081528351615317816001840160208801615920565b602960f81b60019290910191820152600201949350505050565b60008351615343818460208801615920565b6201016960ed1b9083019081528351615363816003840160208801615920565b01600301949350505050565b60008351615381818460208801615920565b630103b39960e51b90830190815283516153a2816004840160208801615920565b01600401949350505050565b602d60f81b8152600082516153ca816001850160208701615920565b9190910160010192915050565b6001600160a01b0387811682528616602082015260408101859052600184900b606082015260c060808201819052600090615414908301856150bb565b90508260a0830152979650505050505050565b6001600160a01b038781168252861660208201526040810185905262ffffff8416606082015260c060808201819052600090615414908301856150bb565b6001600160a01b039586168152602081019490945291909316604083015262ffffff9283166060830152909116608082015260a00190565b6020808252825182820181905260009190848201906040850190845b818110156154de5783516001600160a01b0316835292840192918401916001016154b9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156154de57835183529284019291840191600101615506565b602081526000612ff860208301846150bb565b8481526001600160a01b0384166020820152604081018390526101e081016155606060830184615127565b95945050505050565b8481526001600160a01b0384166020820152604081018390526101e081016155606060830184615205565b8581526001600160a01b038516602082015260006102006155b86040840187615127565b806101c08401526155cb818401866150bb565b915050826101e08301529695505050505050565b60006101e08683528560208401526155fa6040840186615127565b806101c084015261560d818401856150f5565b979650505050505050565b60006101e08683528560208401526155fa6040840186615205565b60006101008a835280602084015289518082850152610120915061565d8183860160208e01615920565b604084018a90526060840189905260808401889052601f01601f19168301838103820160a0850152615691828201886150bb565b95151560c08501525050506001600160a01b039190911660e0909101529695505050505050565b6020808252600d908201526c27b7363c9031b7b739bab6b2b960991b604082015260600190565b8481526080602082015260006156f860808301866150bb565b828103604084015261570a81866150f5565b915050821515606083015295945050505050565b604051610180810167ffffffffffffffff81118282101715615742576157426159a7565b60405290565b60405160e0810167ffffffffffffffff81118282101715615742576157426159a7565b604051601f8201601f1916810167ffffffffffffffff81118282101715615794576157946159a7565b604052919050565b600067ffffffffffffffff8211156157b6576157b66159a7565b5060051b60200190565b60008160010b8360010b82821282617fff038213811516156157e4576157e461597b565b82617fff190382128116156157fb576157fb61597b565b50019392505050565b600062ffffff8083168185168083038211156158225761582261597b565b01949350505050565b6000821982111561583e5761583e61597b565b500190565b60008261585257615852615991565b500490565b60008160010b8360010b617fff838213848413838304851182821616156158805761588061597b565b617fff198685128281168783058712161561589d5761589d61597b565b8787129250858205871284841616156158b8576158b861597b565b858505871281841616156158ce576158ce61597b565b5050509290910295945050505050565b600062ffffff808316818516818304811182151516156159005761590061597b565b02949350505050565b60008282101561591b5761591b61597b565b500390565b60005b8381101561593b578181015183820152602001615923565b838111156131b55750506000910152565b60006000198214156159605761596061597b565b5060010190565b60008261597657615976615991565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461120757600080fd5b801515811461120757600080fd5b8060020b811461120757600080fdfea2646970667358221220b0fc4f8db6f34f4598842dd294869a0a414e61768861a4697a8c574f6fa944fd64736f6c63430008040033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.