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:
ApexConsumer
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";
// internal
import "../../utils/proxy/solidity-0.8.0/ProxyOwned.sol";
import "../../utils/proxy/solidity-0.8.0/ProxyPausable.sol";
// interface
import "../../interfaces/ISportPositionalMarketManager.sol";
/// @title Consumer contract which stores all data from CL data feed (Link to docs:https://market.link/nodes/Apex146/integrations), also creates all sports markets based on that data
/// @author vladan
contract ApexConsumer is Initializable, ProxyOwned, ProxyPausable {
/* ========== CONSTANTS =========== */
uint public constant CANCELLED = 0;
uint public constant HOME_WIN = 1;
uint public constant AWAY_WIN = 2;
uint public constant STATUS_CANCELLED = 0;
uint public constant STATUS_RESOLVED = 1;
uint public constant NUMBER_OF_POSITIONS = 2;
uint public constant MIN_TAG_NUMBER = 9100;
uint public constant BET_TYPE_H2H = 0;
uint public constant BET_TYPE_TOP3 = 1;
uint public constant BET_TYPE_TOP5 = 2;
uint public constant BET_TYPE_TOP10 = 3;
/* ========== CONSUMER STATE VARIABLES ========== */
struct RaceCreate {
string raceId;
uint256 qualifyingStartTime;
uint256 startTime;
string eventId;
string eventName;
string betType;
}
struct GameCreate {
bytes32 gameId;
string raceId;
uint256 startTime;
uint256 homeOdds;
uint256 awayOdds;
uint256 drawOdds;
string homeTeam;
string awayTeam;
uint betType;
}
struct GameResolve {
bytes32 gameId;
uint8 homeScore;
uint8 awayScore;
uint8 statusId;
}
struct GameResults {
bytes32 gameId;
string result;
string resultDetails;
}
struct GameOdds {
bytes32 gameId;
uint256 homeOdds;
uint256 awayOdds;
uint256 drawOdds;
bool arePostQualifyingOddsFetched;
}
/* ========== STATE VARIABLES ========== */
// global params
address public wrapperAddress;
mapping(address => bool) public whitelistedAddresses;
// Maps <GameId, Game>
mapping(string => RaceCreate) public raceCreated;
mapping(bytes32 => GameCreate) public gameCreated;
mapping(bytes32 => GameResolve) public gameResolved;
mapping(bytes32 => GameResults) public gameResults;
mapping(bytes32 => GameOdds) public gameOdds;
mapping(bytes32 => uint) public sportsIdPerGame;
mapping(string => bool) public raceFulfilledCreated;
mapping(bytes32 => bool) public gameFulfilledCreated;
mapping(bytes32 => bool) public gameFulfilledResolved;
mapping(string => string) public latestRaceIdPerSport;
// sports props
mapping(string => bool) public supportedSport;
mapping(string => uint) public supportedSportId;
// market props
ISportPositionalMarketManager public sportsManager;
mapping(bytes32 => address) public marketPerGameId;
mapping(address => bytes32) public gameIdPerMarket;
mapping(address => bool) public marketCreated;
mapping(address => bool) public marketResolved;
mapping(address => bool) public marketCanceled;
// game
mapping(address => bool) public invalidOdds;
mapping(address => bool) public isPausedByCanceledStatus;
/* ========== CONSTRUCTOR ========== */
function initialize(
address _owner,
string[] memory _supportedSports,
address _sportsManager
) external initializer {
setOwner(_owner);
sportsManager = ISportPositionalMarketManager(_sportsManager);
whitelistedAddresses[_owner] = true;
for (uint i; i < _supportedSports.length; i++) {
supportedSport[_supportedSports[i]] = true;
supportedSportId[_supportedSports[i]] = i;
}
}
/* ========== CONSUMER FULFILL FUNCTIONS ========== */
/// @notice Fulfill all race metadata necessary to create sport markets
/// @param _requestId unique request ID form CL
/// @param _eventId event ID which is provided from CL
/// @param _betType bet type for provided event ID
/// @param _eventName event name which is provided from CL
/// @param _qualifyingStartTime timestamp on which race qualifying is started
/// @param _raceStartTime timestamp on which race is started
/// @param _sport supported sport name which is provided from CL
function fulfillMetaData(
bytes32 _requestId,
string memory _eventId,
string memory _betType,
string memory _eventName,
uint256 _qualifyingStartTime,
uint256 _raceStartTime,
string memory _sport
) external onlyWrapper {
if (_raceStartTime > block.timestamp) {
RaceCreate memory race;
race.raceId = _eventId;
race.eventId = _eventId;
race.eventName = _eventName;
race.betType = _betType;
race.qualifyingStartTime = _qualifyingStartTime;
race.startTime = _raceStartTime;
latestRaceIdPerSport[_sport] = race.raceId;
_createRaceFulfill(_requestId, race, supportedSportId[_sport]);
}
}
/// @notice Fulfill all matchup data necessary to create sport markets
/// @param _requestId unique request ID form CL
/// @param _betTypeDetail1 Team/Category/Rider A identifier, returned as string
/// @param _betTypeDetail2 Team/Category/Rider B identifier, returned as string
/// @param _probA: Probability for Team/Category/Rider A, returned as uint256
/// @param _probB: Probability for Team/Category/Rider B, returned as uint256
/// @param _gameId unique game identifier
/// @param _sport supported sport name which is provided from CL
/// @param _arePostQualifyingOdds flag which indicates are "pre" or "post" odds
/// @param _betType bet type for provided game
function fulfillMatchup(
bytes32 _requestId,
string memory _betTypeDetail1,
string memory _betTypeDetail2,
uint256 _probA,
uint256 _probB,
bytes32 _gameId,
string memory _sport,
string memory _eventId,
bool _arePostQualifyingOdds,
uint _betType
) external onlyWrapper {
if (raceFulfilledCreated[_eventId]) {
RaceCreate memory race = raceCreated[_eventId];
if (race.startTime > block.timestamp) {
GameOdds memory newGameOdds;
newGameOdds.gameId = _gameId;
newGameOdds.homeOdds = _probA;
newGameOdds.awayOdds = _probB;
newGameOdds.arePostQualifyingOddsFetched = _arePostQualifyingOdds;
if (!gameFulfilledCreated[_gameId]) {
if (_areOddsValid(newGameOdds)) {
GameCreate memory game;
game.gameId = _gameId;
game.homeOdds = _probA;
game.awayOdds = _probB;
game.homeTeam = _betTypeDetail1;
game.awayTeam = _betTypeDetail2;
game.raceId = _eventId;
game.startTime = race.startTime;
game.betType = _betType;
_createGameFulfill(_requestId, game, newGameOdds, supportedSportId[_sport]);
_oddsGameFulfill(_requestId, newGameOdds);
}
} else {
_oddsGameFulfill(_requestId, newGameOdds);
}
}
}
}
/// @notice Fulfill all data necessary to resolve sport markets
/// @param _requestId unique request ID form CL
/// @param _result win/loss for the matchup
/// @param _resultDetails ranking/timing data to elaborate on win/loss
/// @param _gameId unique game identifier
/// @param _sport supported sport name which is provided from CL
function fulfillResults(
bytes32 _requestId,
string memory _result,
string memory _resultDetails,
bytes32 _gameId,
string memory _sport
) external onlyWrapper {
GameResolve memory game;
if (keccak256(abi.encodePacked(_result)) == keccak256(abi.encodePacked("win/lose"))) {
game.gameId = _gameId;
game.homeScore = 1;
game.awayScore = 0;
game.statusId = uint8(STATUS_RESOLVED);
_resolveGameFulfill(_requestId, game, supportedSportId[_sport]);
} else if (keccak256(abi.encodePacked(_result)) == keccak256(abi.encodePacked("lose/win"))) {
game.gameId = _gameId;
game.homeScore = 0;
game.awayScore = 1;
game.statusId = uint8(STATUS_RESOLVED);
_resolveGameFulfill(_requestId, game, supportedSportId[_sport]);
} else if (keccak256(abi.encodePacked(_result)) == keccak256(abi.encodePacked("null"))) {
game.gameId = _gameId;
game.homeScore = 0;
game.awayScore = 0;
game.statusId = uint8(STATUS_CANCELLED);
_resolveGameFulfill(_requestId, game, supportedSportId[_sport]);
}
GameResults memory newGameResults;
newGameResults.gameId = _gameId;
newGameResults.result = _result;
newGameResults.resultDetails = _resultDetails;
_gameResultsFulfill(_requestId, newGameResults, supportedSportId[_sport]);
}
/// @notice Creates market for a given game ID
/// @param _gameId unique game identifier
function createMarketForGame(bytes32 _gameId) public isAddressWhitelisted {
require(marketPerGameId[_gameId] == address(0), "Market for game already exists");
require(gameFulfilledCreated[_gameId], "No such game fulfilled, created");
_createMarket(_gameId);
}
/// @notice Resolve market for a given game ID
/// @param _gameId unique game identifier
function resolveMarketForGame(bytes32 _gameId) public isAddressWhitelisted {
require(!isGameResolvedOrCanceled(_gameId), "Market resolved or canceled");
require(gameFulfilledResolved[_gameId], "No such game fulfilled, resolved");
_resolveMarket(_gameId);
}
/// @notice Resolve market for a given market address
/// @param _market market address
/// @param _outcome outcome of a game (1: home win, 2: away win, 0: cancel market)
/// @param _homeScore score of home team
/// @param _awayScore score of away team
function resolveMarketManually(
address _market,
uint _outcome,
uint8 _homeScore,
uint8 _awayScore
) external isAddressWhitelisted canGameBeResolved(gameIdPerMarket[_market], _outcome, _homeScore, _awayScore) {
_resolveMarketManually(_market, _outcome, _homeScore, _awayScore);
}
/// @notice Cancel market for a given market address
/// @param _market market address
function cancelMarketManually(address _market)
external
isAddressWhitelisted
canGameBeCanceled(gameIdPerMarket[_market])
{
_cancelMarketManually(_market);
}
/* ========== VIEW FUNCTIONS ========== */
/// @notice View function which returns odds
/// @param _gameId unique game identifier
/// @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
function getOddsForGame(bytes32 _gameId)
public
view
returns (
uint256,
uint256,
uint256
)
{
return
isGamePausedByNonExistingPostQualifyingOdds(_gameId)
? (0, 0, 0)
: (gameOdds[_gameId].homeOdds, gameOdds[_gameId].awayOdds, gameOdds[_gameId].drawOdds);
}
/// @notice View function which returns game created object based on ID of a game
/// @param _gameId unique game identifier
/// @return GameCreate game create object
function getGameCreatedById(bytes32 _gameId) public view returns (GameCreate memory) {
return gameCreated[_gameId];
}
/// @notice View function which returns game resolved object based on ID of a game
/// @param _gameId unique game identifier
/// @return GameResolve game resolve object
function getGameResolvedById(bytes32 _gameId) public view returns (GameResolve memory) {
return gameResolved[_gameId];
}
/// @notice View function which returns if game is resolved or canceled and ready for market to be resolved or canceled
/// @param _gameId unique game identifier for which game is looking
/// @return bool is it ready for resolve or cancel true/false
function isGameResolvedOrCanceled(bytes32 _gameId) public view returns (bool) {
return marketResolved[marketPerGameId[_gameId]] || marketCanceled[marketPerGameId[_gameId]];
}
/// @notice View function which returns if sport is supported or not
/// @param _sport sport for which is looking
/// @return bool is sport supported true/false
function isSupportedSport(string memory _sport) external view returns (bool) {
return supportedSport[_sport];
}
/// @notice View function which returns normalized odds up to 100 (Example: 50-40-10)
/// @param _gameId unique game identifier for which game is looking
/// @return uint[] odds array normalized
function getNormalizedOdds(bytes32 _gameId) public view returns (uint[] memory) {
uint[] memory normalizedOdds = new uint[](3);
(normalizedOdds[0], normalizedOdds[1], normalizedOdds[2]) = getOddsForGame(_gameId);
for (uint i = 0; i < normalizedOdds.length; i++) {
normalizedOdds[i] = (1e18 * normalizedOdds[i]) / 1e4;
}
return normalizedOdds;
}
/// @notice Vew function which returns if game is resolved
/// @param _gameId unique game identifier for which game is looking
/// @return bool is game resolved true/false
function isGameInResolvedStatus(bytes32 _gameId) public view returns (bool) {
return _isGameStatusResolved(getGameResolvedById(_gameId));
}
/// @notice View function which returns if game is provided by Apex
/// @param _gameId unique game identifier for which result is looking
/// @return bool is game provided by Apex
function isApexGame(bytes32 _gameId) public view returns (bool) {
return gameFulfilledCreated[_gameId];
}
/// @notice View function which returns if game is paused because there are no new odds for post qualifying phase
/// @param _gameId unique game identifier for which result is looking
/// @return bool is game paused
function isGamePausedByNonExistingPostQualifyingOdds(bytes32 _gameId) public view returns (bool) {
GameCreate memory game = gameCreated[_gameId];
RaceCreate memory race = raceCreated[game.raceId];
GameOdds memory odds = gameOdds[_gameId];
return
race.qualifyingStartTime < block.timestamp &&
game.startTime > block.timestamp &&
!odds.arePostQualifyingOddsFetched;
}
/* ========== INTERNALS ========== */
function _createRaceFulfill(
bytes32 _requestId,
RaceCreate memory _race,
uint _sportId
) internal {
raceCreated[_race.raceId] = _race;
raceFulfilledCreated[_race.raceId] = true;
emit RaceCreated(_requestId, _sportId, _race.raceId, _race);
}
function _createGameFulfill(
bytes32 _requestId,
GameCreate memory _game,
GameOdds memory _gameOdds,
uint _sportId
) internal {
gameCreated[_game.gameId] = _game;
sportsIdPerGame[_game.gameId] = _sportId;
gameFulfilledCreated[_game.gameId] = true;
gameOdds[_game.gameId] = _gameOdds;
emit GameCreated(_requestId, _sportId, _game.gameId, _game, getNormalizedOdds(_game.gameId));
}
function _resolveGameFulfill(
bytes32 _requestId,
GameResolve memory _game,
uint _sportId
) internal {
GameCreate memory singleGameCreated = getGameCreatedById(_game.gameId);
// if status is resolved OR (status is canceled AND start time has passed fulfill game to be resolved)
if (
_isGameStatusResolved(_game) || (_isGameStatusCancelled(_game) && singleGameCreated.startTime < block.timestamp)
) {
gameResolved[_game.gameId] = _game;
gameFulfilledResolved[_game.gameId] = true;
emit GameResolved(_requestId, _sportId, _game.gameId, _game);
}
// if market for the game exists AND status is canceled AND start time has not passed only pause market
else if (
marketPerGameId[_game.gameId] != address(0) &&
_isGameStatusCancelled(_game) &&
singleGameCreated.startTime >= block.timestamp
) {
isPausedByCanceledStatus[marketPerGameId[_game.gameId]] = true;
_pauseOrUnpauseMarket(marketPerGameId[_game.gameId], true);
}
}
function _gameResultsFulfill(
bytes32 _requestId,
GameResults memory _game,
uint _sportId
) internal {
gameResults[_game.gameId] = _game;
emit GameResultsSet(_requestId, _sportId, _game.gameId, _game);
}
function _oddsGameFulfill(bytes32 requestId, GameOdds memory _game) internal {
// if odds are valid store them if not pause market if created
if (_areOddsValid(_game)) {
gameOdds[_game.gameId] = _game;
// if market created and was paused (paused by invalid odds or paused by canceled status) unpause
if (marketPerGameId[_game.gameId] != address(0) && sportsManager.isMarketPaused(marketPerGameId[_game.gameId])) {
if (invalidOdds[marketPerGameId[_game.gameId]] || isPausedByCanceledStatus[marketPerGameId[_game.gameId]]) {
invalidOdds[marketPerGameId[_game.gameId]] = false;
isPausedByCanceledStatus[marketPerGameId[_game.gameId]] = false;
_pauseOrUnpauseMarket(marketPerGameId[_game.gameId], false);
}
}
emit GameOddsAdded(requestId, _game.gameId, _game, getNormalizedOdds(_game.gameId));
} else {
if (
marketPerGameId[_game.gameId] != address(0) && !sportsManager.isMarketPaused(marketPerGameId[_game.gameId])
) {
invalidOdds[marketPerGameId[_game.gameId]] = true;
_pauseOrUnpauseMarket(marketPerGameId[_game.gameId], true);
emit InvalidOddsForMarket(requestId, marketPerGameId[_game.gameId], _game.gameId, _game);
}
}
}
function _createMarket(bytes32 _gameId) internal {
GameCreate memory game = getGameCreatedById(_gameId);
uint sportId = sportsIdPerGame[_gameId];
uint[] memory tags = _calculateTags(sportId);
// create
sportsManager.createMarket(
_gameId,
_append(game.homeTeam, game.awayTeam), // gameLabel
game.startTime, //maturity
0, //initialMint
NUMBER_OF_POSITIONS,
tags //tags
);
address marketAddress = sportsManager.getActiveMarketAddress(sportsManager.numActiveMarkets() - 1);
marketPerGameId[game.gameId] = marketAddress;
gameIdPerMarket[marketAddress] = game.gameId;
marketCreated[marketAddress] = true;
emit CreateSportsMarket(marketAddress, game.gameId, game, tags, getNormalizedOdds(game.gameId));
}
function _resolveMarket(bytes32 _gameId) internal {
GameResolve memory game = getGameResolvedById(_gameId);
GameCreate memory singleGameCreated = getGameCreatedById(_gameId);
if (_isGameStatusResolved(game)) {
if (invalidOdds[marketPerGameId[game.gameId]]) {
_pauseOrUnpauseMarket(marketPerGameId[game.gameId], false);
}
uint _outcome = _calculateOutcome(game);
sportsManager.resolveMarket(marketPerGameId[game.gameId], _outcome);
marketResolved[marketPerGameId[game.gameId]] = true;
emit ResolveSportsMarket(marketPerGameId[game.gameId], game.gameId, _outcome);
// if status is canceled and start time of a game passed cancel market
} else if (_isGameStatusCancelled(game) && singleGameCreated.startTime < block.timestamp) {
_cancelMarket(game.gameId);
}
}
function _resolveMarketManually(
address _market,
uint _outcome,
uint8 _homeScore,
uint8 _awayScore
) internal {
_pauseOrUnpauseMarket(_market, false);
sportsManager.resolveMarket(_market, _outcome);
marketResolved[_market] = true;
gameResolved[gameIdPerMarket[_market]] = GameResolve(
gameIdPerMarket[_market],
_homeScore,
_awayScore,
uint8(STATUS_RESOLVED)
);
emit GameResolved(
gameIdPerMarket[_market], // no req. from CL (manual resolve) so just put gameID
sportsIdPerGame[gameIdPerMarket[_market]],
gameIdPerMarket[_market],
gameResolved[gameIdPerMarket[_market]]
);
emit ResolveSportsMarket(_market, gameIdPerMarket[_market], _outcome);
}
function _cancelMarketManually(address _market) internal {
_pauseOrUnpauseMarket(_market, false);
sportsManager.resolveMarket(_market, 0);
marketCanceled[_market] = true;
emit CancelSportsMarket(_market, gameIdPerMarket[_market]);
}
function _pauseOrUnpauseMarket(address _market, bool _pause) internal {
if (sportsManager.isMarketPaused(_market) != _pause) {
sportsManager.setMarketPaused(_market, _pause);
emit PauseSportsMarket(_market, _pause);
}
}
function _cancelMarket(bytes32 _gameId) internal {
sportsManager.resolveMarket(marketPerGameId[_gameId], 0);
marketCanceled[marketPerGameId[_gameId]] = true;
emit CancelSportsMarket(marketPerGameId[_gameId], _gameId);
}
function _append(string memory teamA, string memory teamB) internal pure returns (string memory) {
return string(abi.encodePacked(teamA, " vs ", teamB));
}
function _calculateTags(uint _sportsId) internal pure returns (uint[] memory) {
uint[] memory result = new uint[](1);
result[0] = MIN_TAG_NUMBER + _sportsId;
return result;
}
function _isGameStatusResolved(GameResolve memory _game) internal pure returns (bool) {
return _game.statusId == STATUS_RESOLVED;
}
function _isGameStatusCancelled(GameResolve memory _game) internal pure returns (bool) {
return _game.statusId == STATUS_CANCELLED;
}
function _calculateOutcome(GameResolve memory _game) internal pure returns (uint) {
return _game.homeScore > _game.awayScore ? HOME_WIN : AWAY_WIN;
}
function _areOddsValid(GameOdds memory _game) internal pure returns (bool) {
return _game.awayOdds != 0 && _game.homeOdds != 0;
}
function _isValidOutcomeForGame(uint _outcome) internal pure returns (bool) {
return _outcome == HOME_WIN || _outcome == AWAY_WIN || _outcome == CANCELLED;
}
function _isValidOutcomeWithResult(
uint _outcome,
uint _homeScore,
uint _awayScore
) internal pure returns (bool) {
if (_outcome == CANCELLED) {
return _awayScore == CANCELLED && _homeScore == CANCELLED;
} else if (_outcome == HOME_WIN) {
return _homeScore > _awayScore;
} else if (_outcome == AWAY_WIN) {
return _homeScore < _awayScore;
} else {
return _homeScore == _awayScore;
}
}
/* ========== CONTRACT MANAGEMENT ========== */
/// @notice Sets if sport is suported or not (delete from supported sport)
/// @param sport sport which needs to be supported or not
/// @param _isSupported true/false (supported or not)
function setSupportedSport(string memory sport, bool _isSupported) external onlyOwner {
require(supportedSport[sport] != _isSupported, "Already set");
supportedSport[sport] = _isSupported;
emit SupportedSportsChanged(sport, _isSupported);
}
/// @notice Sets wrapper and manager addresses
/// @param _wrapperAddress wrapper address
/// @param _sportsManager sport manager address
function setSportContracts(address _wrapperAddress, address _sportsManager) external onlyOwner {
require(_wrapperAddress != address(0) || _sportsManager != address(0), "Invalid addreses");
sportsManager = ISportPositionalMarketManager(_sportsManager);
wrapperAddress = _wrapperAddress;
emit NewSportContracts(_wrapperAddress, _sportsManager);
}
/// @notice Adding/removing whitelist address depending on a flag
/// @param _whitelistAddress address that needed to be whitelisted or removed from WL
/// @param _flag adding or removing from whitelist (true: add, false: remove)
function addToWhitelist(address _whitelistAddress, bool _flag) external onlyOwner {
require(_whitelistAddress != address(0), "Invalid address");
require(whitelistedAddresses[_whitelistAddress] != _flag, "Already set to that flag");
whitelistedAddresses[_whitelistAddress] = _flag;
emit AddedIntoWhitelist(_whitelistAddress, _flag);
}
/* ========== MODIFIERS ========== */
modifier onlyWrapper() {
require(msg.sender == wrapperAddress, "Only wrapper can call this function");
_;
}
modifier isAddressWhitelisted() {
require(whitelistedAddresses[msg.sender], "Invalid caller");
_;
}
modifier canGameBeCanceled(bytes32 _gameId) {
require(!isGameResolvedOrCanceled(_gameId), "Market resolved or canceled");
require(marketPerGameId[_gameId] != address(0), "No market created for game");
_;
}
modifier canGameBeResolved(
bytes32 _gameId,
uint _outcome,
uint8 _homeScore,
uint8 _awayScore
) {
require(!isGameResolvedOrCanceled(_gameId), "Market resolved or canceled");
require(marketPerGameId[_gameId] != address(0), "No market created for game");
require(
_isValidOutcomeForGame(_outcome) && _isValidOutcomeWithResult(_outcome, _homeScore, _awayScore),
"Bad result or outcome"
);
_;
}
/* ========== EVENTS ========== */
event RaceCreated(bytes32 _requestId, uint _sportId, string _id, RaceCreate _race);
event GameCreated(bytes32 _requestId, uint _sportId, bytes32 _id, GameCreate _game, uint[] _normalizedOdds);
event GameResolved(bytes32 _requestId, uint _sportId, bytes32 _id, GameResolve _game);
event GameResultsSet(bytes32 requestId, uint _sportId, bytes32 _id, GameResults _game);
event GameOddsAdded(bytes32 _requestId, bytes32 _id, GameOdds _game, uint[] _normalizedOdds);
event InvalidOddsForMarket(bytes32 _requestId, address _marketAddress, bytes32 _id, GameOdds _game);
event CreateSportsMarket(address _marketAddress, bytes32 _id, GameCreate _game, uint[] _tags, uint[] _normalizedOdds);
event ResolveSportsMarket(address _marketAddress, bytes32 _id, uint _outcome);
event PauseSportsMarket(address _marketAddress, bool _pause);
event CancelSportsMarket(address _marketAddress, bytes32 _id);
event SupportedSportsChanged(string _sport, bool _isSupported);
event NewSportContracts(address _wrapperAddress, address _sportsManager);
event AddedIntoWhitelist(address _whitelistAddress, bool _flag);
}// 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
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 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);
/* ========== MUTATIVE FUNCTIONS ========== */
function createMarket(
bytes32 gameId,
string memory gameLabel,
uint maturity,
uint initialMint, // initial sUSD to mint options for,
uint positionCount,
uint[] memory tags
) 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;
}// 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 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 getMaximumBurnable(address account) external view returns (uint amount);
/* ========== 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 burnOptions(uint amount) external;
function burnOptionsMaximum() 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);
}// 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":"_whitelistAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"_flag","type":"bool"}],"name":"AddedIntoWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"CancelSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"string","name":"raceId","type":"string"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"},{"internalType":"uint256","name":"betType","type":"uint256"}],"indexed":false,"internalType":"struct ApexConsumer.GameCreate","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_tags","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"CreateSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"string","name":"raceId","type":"string"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"},{"internalType":"uint256","name":"betType","type":"uint256"}],"indexed":false,"internalType":"struct ApexConsumer.GameCreate","name":"_game","type":"tuple"},{"indexed":false,"internalType":"uint256[]","name":"_normalizedOdds","type":"uint256[]"}],"name":"GameCreated","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":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"bool","name":"arePostQualifyingOddsFetched","type":"bool"}],"indexed":false,"internalType":"struct ApexConsumer.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":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint8","name":"homeScore","type":"uint8"},{"internalType":"uint8","name":"awayScore","type":"uint8"},{"internalType":"uint8","name":"statusId","type":"uint8"}],"indexed":false,"internalType":"struct ApexConsumer.GameResolve","name":"_game","type":"tuple"}],"name":"GameResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"string","name":"result","type":"string"},{"internalType":"string","name":"resultDetails","type":"string"}],"indexed":false,"internalType":"struct ApexConsumer.GameResults","name":"_game","type":"tuple"}],"name":"GameResultsSet","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":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"bool","name":"arePostQualifyingOddsFetched","type":"bool"}],"indexed":false,"internalType":"struct ApexConsumer.GameOdds","name":"_game","type":"tuple"}],"name":"InvalidOddsForMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_wrapperAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_sportsManager","type":"address"}],"name":"NewSportContracts","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":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"_pause","type":"bool"}],"name":"PauseSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_sportId","type":"uint256"},{"indexed":false,"internalType":"string","name":"_id","type":"string"},{"components":[{"internalType":"string","name":"raceId","type":"string"},{"internalType":"uint256","name":"qualifyingStartTime","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"string","name":"eventId","type":"string"},{"internalType":"string","name":"eventName","type":"string"},{"internalType":"string","name":"betType","type":"string"}],"indexed":false,"internalType":"struct ApexConsumer.RaceCreate","name":"_race","type":"tuple"}],"name":"RaceCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_marketAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"_id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_outcome","type":"uint256"}],"name":"ResolveSportsMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_sport","type":"string"},{"indexed":false,"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"SupportedSportsChanged","type":"event"},{"inputs":[],"name":"AWAY_WIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BET_TYPE_H2H","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BET_TYPE_TOP10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BET_TYPE_TOP3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BET_TYPE_TOP5","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":"NUMBER_OF_POSITIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STATUS_CANCELLED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STATUS_RESOLVED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelistAddress","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"}],"name":"cancelMarketManually","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"createMarketForGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"string","name":"_betTypeDetail1","type":"string"},{"internalType":"string","name":"_betTypeDetail2","type":"string"},{"internalType":"uint256","name":"_probA","type":"uint256"},{"internalType":"uint256","name":"_probB","type":"uint256"},{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"string","name":"_sport","type":"string"},{"internalType":"string","name":"_eventId","type":"string"},{"internalType":"bool","name":"_arePostQualifyingOdds","type":"bool"},{"internalType":"uint256","name":"_betType","type":"uint256"}],"name":"fulfillMatchup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"string","name":"_eventId","type":"string"},{"internalType":"string","name":"_betType","type":"string"},{"internalType":"string","name":"_eventName","type":"string"},{"internalType":"uint256","name":"_qualifyingStartTime","type":"uint256"},{"internalType":"uint256","name":"_raceStartTime","type":"uint256"},{"internalType":"string","name":"_sport","type":"string"}],"name":"fulfillMetaData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"string","name":"_result","type":"string"},{"internalType":"string","name":"_resultDetails","type":"string"},{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"string","name":"_sport","type":"string"}],"name":"fulfillResults","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameCreated","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"string","name":"raceId","type":"string"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"},{"internalType":"uint256","name":"betType","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameFulfilledCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameFulfilledResolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gameIdPerMarket","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":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"bool","name":"arePostQualifyingOddsFetched","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameResolved","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint8","name":"homeScore","type":"uint8"},{"internalType":"uint8","name":"awayScore","type":"uint8"},{"internalType":"uint8","name":"statusId","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"gameResults","outputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"string","name":"result","type":"string"},{"internalType":"string","name":"resultDetails","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getGameCreatedById","outputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"string","name":"raceId","type":"string"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"homeOdds","type":"uint256"},{"internalType":"uint256","name":"awayOdds","type":"uint256"},{"internalType":"uint256","name":"drawOdds","type":"uint256"},{"internalType":"string","name":"homeTeam","type":"string"},{"internalType":"string","name":"awayTeam","type":"string"},{"internalType":"uint256","name":"betType","type":"uint256"}],"internalType":"struct ApexConsumer.GameCreate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getGameResolvedById","outputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint8","name":"homeScore","type":"uint8"},{"internalType":"uint8","name":"awayScore","type":"uint8"},{"internalType":"uint8","name":"statusId","type":"uint8"}],"internalType":"struct ApexConsumer.GameResolve","name":"","type":"tuple"}],"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":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getOddsForGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string[]","name":"_supportedSports","type":"string[]"},{"internalType":"address","name":"_sportsManager","type":"address"}],"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":"bytes32","name":"_gameId","type":"bytes32"}],"name":"isApexGame","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"isGameInResolvedStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"isGamePausedByNonExistingPostQualifyingOdds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"isGameResolvedOrCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPausedByCanceledStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_sport","type":"string"}],"name":"isSupportedSport","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":"string","name":"","type":"string"}],"name":"latestRaceIdPerSport","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"marketPerGameId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketResolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"raceCreated","outputs":[{"internalType":"string","name":"raceId","type":"string"},{"internalType":"uint256","name":"qualifyingStartTime","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"string","name":"eventId","type":"string"},{"internalType":"string","name":"eventName","type":"string"},{"internalType":"string","name":"betType","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"raceFulfilledCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"resolveMarketForGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"_outcome","type":"uint256"},{"internalType":"uint8","name":"_homeScore","type":"uint8"},{"internalType":"uint8","name":"_awayScore","type":"uint8"}],"name":"resolveMarketManually","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":"address","name":"_wrapperAddress","type":"address"},{"internalType":"address","name":"_sportsManager","type":"address"}],"name":"setSportContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sport","type":"string"},{"internalType":"bool","name":"_isSupported","type":"bool"}],"name":"setSupportedSport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"sportsIdPerGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sportsManager","outputs":[{"internalType":"contract ISportPositionalMarketManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"supportedSport","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"supportedSportId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrapperAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50614ef0806100206000396000f3fe608060405234801561001057600080fd5b50600436106103ba5760003560e01c806379ba5097116101f4578063ae71dcdf1161011a578063c48e62f1116100ad578063e59aff4b1161007c578063e59aff4b146109ac578063e7015ab2146109bf578063f83aaaf8146109df578063f89c6f18146109f257600080fd5b8063c48e62f114610941578063cc61edf314610961578063d2cd9eb814610969578063dec72d631461098957600080fd5b8063b9679951116100e9578063b9679951146108f6578063bc93233f1461091b578063c0fb7e9c14610528578063c3b83f5f1461092e57600080fd5b8063ae71dcdf14610632578063b4976d7b146108b0578063b704edc4146108d0578063b91618c6146108e357600080fd5b80638c4e8cb51161019257806393f4452e1161016157806393f4452e146108135780639aceb36e1461087d578063a47a874f1461089d578063a81bda5f1461052057600080fd5b80638c4e8cb5146107bb5780638da5cb5b146107de5780638ec2c5a6146107f757806391b4ded91461080a57600080fd5b80637df8b802116101ce5780637df8b80214610762578063847ac2b514610528578063885d292a1461077a5780638980d03e146107a857600080fd5b806379ba50971461072f57806379daacd2146106325780637b041a581461073757600080fd5b80634989f9be116102e45780635b9fbe0711610277578063621da70311610246578063621da703146106ab57806367674b14146106be578063693decdc146106e157806370aadcc41461070f57600080fd5b80635b9fbe071461063a5780635c975abb1461065d57806360b4df851461066a57806361772f641461069857600080fd5b8063557db448116102b3578063557db448146105f75780635895f4881461061f5780635a4e5a15146106325780635b0aa21f1461052057600080fd5b80634989f9be1461059c5780634c70e636146105be578063523f1c8f146105d157806353a47bb7146105e457600080fd5b80631afed5cc1161035c57806336c0d8551161032b57806336c0d855146105305780633ec70ca5146105535780634156305d14610576578063489f4b971461058957600080fd5b80631afed5cc146104e65780632a4a3e7c146104fd5780632fff702014610520578063300a02981461052857600080fd5b806313af40351161039857806313af4035146104885780631627540c1461049d57806316c38b3c146104b05780631734bcd4146104c357600080fd5b806306c933d8146103bf5780630b5cde46146103f757806310063fdc1461045d575b600080fd5b6103e26103cd3660046141ea565b60046020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6104346104053660046143f4565b6007602052600090815260409020805460019091015460ff808216916101008104821691620100009091041684565b6040805194855260ff9384166020860152918316918401919091521660608201526080016103ee565b601154610470906001600160a01b031681565b6040516001600160a01b0390911681526020016103ee565b61049b6104963660046141ea565b610a1b565b005b61049b6104ab3660046141ea565b610b5b565b61049b6104be3660046143bc565b610bb1565b6103e26104d13660046143f4565b6000908152600c602052604090205460ff1690565b6104ef61238c81565b6040519081526020016103ee565b6103e261050b3660046141ea565b60186020526000908152604090205460ff1681565b6104ef600181565b6104ef600281565b6103e261053e3660046141ea565b60176020526000908152604090205460ff1681565b6103e26105613660046143f4565b600d6020526000908152604090205460ff1681565b61049b6105843660046141ea565b610c27565b6103e26105973660046143f4565b610d06565b6105af6105aa3660046143f4565b610d63565b6040516103ee93929190614969565b61049b6105cc36600461425a565b610e96565b61049b6105df3660046144a4565b611059565b600154610470906001600160a01b031681565b61060a6106053660046143f4565b611157565b6040516103ee999897969594939291906149e8565b61049b61062d36600461440c565b611336565b6104ef600081565b6103e26106483660046141ea565b60156020526000908152604090205460ff1681565b6003546103e29060ff1681565b61067d6106783660046143f4565b61158e565b604080519384526020840192909252908201526060016103ee565b6103e26106a63660046143f4565b6115d9565b6103e26106b93660046143f4565b611aed565b6103e26106cc3660046143f4565b600c6020526000908152604090205460ff1681565b6103e26106ef366004614654565b8051602081830181018051600f8252928201919093012091525460ff1681565b6104ef61071d3660046143f4565b600a6020526000908152604090205481565b61049b611b08565b6104ef610745366004614654565b805160208183018101805160108252928201919093012091525481565b6003546104709061010090046001600160a01b031681565b6103e2610788366004614654565b8051602081830181018051600b8252928201919093012091525460ff1681565b61049b6107b6366004614569565b611c05565b6103e26107c93660046141ea565b60146020526000908152604090205460ff1681565b600054610470906201000090046001600160a01b031681565b61049b6108053660046143f4565b611fd6565b6104ef60025481565b6108536108213660046143f4565b600960205260009081526040902080546001820154600283015460038401546004909401549293919290919060ff1685565b6040805195865260208601949094529284019190915260608301521515608082015260a0016103ee565b61089061088b3660046143f4565b6120d1565b6040516103ee9190614899565b61049b6108ab36600461436e565b61221b565b6108c36108be3660046143f4565b612361565b6040516103ee9190614d12565b61049b6108de36600461468f565b6123ce565b6103e26108f1366004614654565b6124a7565b610909610904366004614654565b6124d2565b6040516103ee96959493929190614c04565b61049b610929366004614341565b612731565b61049b61093c3660046141ea565b61284c565b61095461094f3660046143f4565b612965565b6040516103ee9190614cff565b6104ef600381565b61097c610977366004614654565b612b85565b6040516103ee9190614bcd565b6103e26109973660046141ea565b60166020526000908152604090205460ff1681565b61049b6109ba3660046143f4565b612c2a565b6104ef6109cd3660046141ea565b60136020526000908152604090205481565b61049b6109ed366004614222565b612ce6565b610470610a003660046143f4565b6012602052600090815260409020546001600160a01b031681565b6001600160a01b038116610a765760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f7420626520300000000000000060448201526064015b60405180910390fd5b600154600160a01b900460ff1615610ae25760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610a6d565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610b63612dbd565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610b50565b610bb9612dbd565b60035460ff1615158115151415610bcd5750565b6003805460ff191682151590811790915560ff1615610beb57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610b50565b50565b3360009081526004602052604090205460ff16610c565760405162461bcd60e51b8152600401610a6d90614c5d565b6001600160a01b038116600090815260136020526040902054610c7881610d06565b15610c955760405162461bcd60e51b8152600401610a6d90614cc8565b6000818152601260205260409020546001600160a01b0316610cf95760405162461bcd60e51b815260206004820152601a60248201527f4e6f206d61726b6574206372656174656420666f722067616d650000000000006044820152606401610a6d565b610d0282612e37565b5050565b6000818152601260209081526040808320546001600160a01b03168352601590915281205460ff1680610d5d57506000828152601260209081526040808320546001600160a01b03168352601690915290205460ff165b92915050565b60086020526000908152604090208054600182018054919291610d8590614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054610db190614e15565b8015610dfe5780601f10610dd357610100808354040283529160200191610dfe565b820191906000526020600020905b815481529060010190602001808311610de157829003601f168201915b505050505090806002018054610e1390614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3f90614e15565b8015610e8c5780601f10610e6157610100808354040283529160200191610e8c565b820191906000526020600020905b815481529060010190602001808311610e6f57829003601f168201915b5050505050905083565b600054610100900460ff16610eb15760005460ff1615610eb5565b303b155b610f185760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a6d565b600054610100900460ff16158015610f3a576000805461ffff19166101011790555b610f4384610a1b565b601180546001600160a01b0319166001600160a01b038481169190911790915584166000908152600460205260408120805460ff191660011790555b8351811015611040576001600f858381518110610fac57634e487b7160e01b600052603260045260246000fd5b6020026020010151604051610fc191906147e5565b908152602001604051809103902060006101000a81548160ff02191690831515021790555080601085838151811061100957634e487b7160e01b600052603260045260246000fd5b602002602001015160405161101e91906147e5565b908152604051908190036020019020558061103881614e50565b915050610f7f565b508015611053576000805461ff00191690555b50505050565b60035461010090046001600160a01b031633146110885760405162461bcd60e51b8152600401610a6d90614c85565b4282111561114e576110c96040518060c001604052806060815260200160008152602001600081526020016060815260200160608152602001606081525090565b868152606081018790526080810185905260a08101869052602081018490526040808201849052518790600e906111019085906147e5565b9081526020016040518091039020908051906020019061112292919061406b565b5061114c888260108560405161113891906147e5565b908152602001604051809103902054612f08565b505b50505050505050565b6006602052600090815260409020805460018201805491929161117990614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546111a590614e15565b80156111f25780601f106111c7576101008083540402835291602001916111f2565b820191906000526020600020905b8154815290600101906020018083116111d557829003601f168201915b50505050509080600201549080600301549080600401549080600501549080600601805461121f90614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461124b90614e15565b80156112985780601f1061126d57610100808354040283529160200191611298565b820191906000526020600020905b81548152906001019060200180831161127b57829003601f168201915b5050505050908060070180546112ad90614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546112d990614e15565b80156113265780601f106112fb57610100808354040283529160200191611326565b820191906000526020600020905b81548152906001019060200180831161130957829003601f168201915b5050505050908060080154905089565b60035461010090046001600160a01b031633146113655760405162461bcd60e51b8152600401610a6d90614c85565b6040805160808101825260008082526020820181905291810182905260608101919091526040516777696e2f6c6f736560c01b602082015260280160405160208183030381529060405280519060200120856040516020016113c791906147e5565b60405160208183030381529060405280519060200120141561143257828152600160208201819052600060408084019190915260608301919091525161142d90879083906010906114199087906147e5565b908152602001604051809103902054613025565b611548565b604051673637b9b297bbb4b760c11b6020820152602801604051602081830303815290604052805190602001208560405160200161147091906147e5565b6040516020818303038152906040528051906020012014156114bf57828152600060208201526001604080830182905260608301919091525161142d90879083906010906114199087906147e5565b604051631b9d5b1b60e21b602082015260240160405160208183030381529060405280519060200120856040516020016114f991906147e5565b60405160208183030381529060405280519060200120141561154857828152600060208201819052604080830182905260608301919091525161154890879083906010906114199087906147e5565b6040805160608101825284815260208101879052808201869052905161114e908890839060109061157a9088906147e5565b9081526020016040518091039020546131aa565b600080600061159c846115d9565b6115c6576000848152600960205260409020600181015460028201546003909201549091906115cc565b60008060005b9250925092509193909250565b6000818152600660209081526040808320815161012081019092528054825260018101805485948401919061160d90614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461163990614e15565b80156116865780601f1061165b57610100808354040283529160200191611686565b820191906000526020600020905b81548152906001019060200180831161166957829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820180546116c790614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546116f390614e15565b80156117405780601f1061171557610100808354040283529160200191611740565b820191906000526020600020905b81548152906001019060200180831161172357829003601f168201915b5050505050815260200160078201805461175990614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461178590614e15565b80156117d25780601f106117a7576101008083540402835291602001916117d2565b820191906000526020600020905b8154815290600101906020018083116117b557829003601f168201915b5050505050815260200160088201548152505090506000600582602001516040516117fd91906147e5565b90815260200160405180910390206040518060c001604052908160008201805461182690614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461185290614e15565b801561189f5780601f106118745761010080835404028352916020019161189f565b820191906000526020600020905b81548152906001019060200180831161188257829003601f168201915b5050505050815260200160018201548152602001600282015481526020016003820180546118cc90614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546118f890614e15565b80156119455780601f1061191a57610100808354040283529160200191611945565b820191906000526020600020905b81548152906001019060200180831161192857829003601f168201915b5050505050815260200160048201805461195e90614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461198a90614e15565b80156119d75780601f106119ac576101008083540402835291602001916119d7565b820191906000526020600020905b8154815290600101906020018083116119ba57829003601f168201915b505050505081526020016005820180546119f090614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1c90614e15565b8015611a695780601f10611a3e57610100808354040283529160200191611a69565b820191906000526020600020905b815481529060010190602001808311611a4c57829003601f168201915b50505091909252505050600085815260096020908152604091829020825160a08101845281548152600182015481840152600282015493810193909352600381015460608401526004015460ff16151560808301528201519192509042118015611ad65750428360400151115b8015611ae457508060800151155b95945050505050565b6000610d5d611afb83612361565b6060015160ff1660011490565b6001546001600160a01b03163314611b805760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610a6d565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60035461010090046001600160a01b03163314611c345760405162461bcd60e51b8152600401610a6d90614c85565b600b83604051611c4491906147e5565b9081526040519081900360200190205460ff1615611fca576000600584604051611c6e91906147e5565b90815260200160405180910390206040518060c0016040529081600082018054611c9790614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc390614e15565b8015611d105780601f10611ce557610100808354040283529160200191611d10565b820191906000526020600020905b815481529060010190602001808311611cf357829003601f168201915b505050505081526020016001820154815260200160028201548152602001600382018054611d3d90614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611d6990614e15565b8015611db65780601f10611d8b57610100808354040283529160200191611db6565b820191906000526020600020905b815481529060010190602001808311611d9957829003601f168201915b50505050508152602001600482018054611dcf90614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611dfb90614e15565b8015611e485780601f10611e1d57610100808354040283529160200191611e48565b820191906000526020600020905b815481529060010190602001808311611e2b57829003601f168201915b50505050508152602001600582018054611e6190614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8d90614e15565b8015611eda5780601f10611eaf57610100808354040283529160200191611eda565b820191906000526020600020905b815481529060010190602001808311611ebd57829003601f168201915b50505050508152505090504281604001511115611fc8576040805160a08101825260006060820181905288825260208083018c90528284018b90528615156080840152898252600c9052919091205460ff16611fbc57611f3981613230565b15611fb757611f466140ef565b878152606081018a90526080810189905260c081018c905260e081018b90526020810186905260408381015181830152610100820185905251611fab908e9083908590601090611f97908d906147e5565b90815260200160405180910390205461324c565b611fb58d836133ab565b505b611fc6565b611fc68c826133ab565b505b505b50505050505050505050565b3360009081526004602052604090205460ff166120055760405162461bcd60e51b8152600401610a6d90614c5d565b6000818152601260205260409020546001600160a01b03161561206a5760405162461bcd60e51b815260206004820152601e60248201527f4d61726b657420666f722067616d6520616c72656164792065786973747300006044820152606401610a6d565b6000818152600c602052604090205460ff166120c85760405162461bcd60e51b815260206004820152601f60248201527f4e6f20737563682067616d652066756c66696c6c65642c2063726561746564006044820152606401610a6d565b610c2481613715565b60408051600380825260808201909252606091600091906020820184803683370190505090506121008361158e565b8360008151811061212157634e487b7160e01b600052603260045260246000fd5b602002602001018460018151811061214957634e487b7160e01b600052603260045260246000fd5b602002602001018560028151811061217157634e487b7160e01b600052603260045260246000fd5b60209081029190910101929092529190525260005b8151811015612214576127108282815181106121b257634e487b7160e01b600052603260045260246000fd5b6020026020010151670de0b6b3a76400006121cd9190614db3565b6121d79190614d93565b8282815181106121f757634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061220c81614e50565b915050612186565b5092915050565b3360009081526004602052604090205460ff1661224a5760405162461bcd60e51b8152600401610a6d90614c5d565b6001600160a01b03841660009081526013602052604090205483838361226f84610d06565b1561228c5760405162461bcd60e51b8152600401610a6d90614cc8565b6000848152601260205260409020546001600160a01b03166122f05760405162461bcd60e51b815260206004820152601a60248201527f4e6f206d61726b6574206372656174656420666f722067616d650000000000006044820152606401610a6d565b6122f983613989565b80156123115750612311838360ff168360ff166139a5565b6123555760405162461bcd60e51b815260206004820152601560248201527442616420726573756c74206f72206f7574636f6d6560581b6044820152606401610a6d565b61114c888888886139ef565b60408051608080820183526000808352602080840182905283850182905260609384018290529481526007855283902083519182018452805482526001015460ff808216958301959095526101008104851693820193909352620100009092049092169181019190915290565b6123d6612dbd565b801515600f836040516123e991906147e5565b9081526040519081900360200190205460ff161515141561243a5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b6044820152606401610a6d565b80600f8360405161244b91906147e5565b908152604051908190036020018120805492151560ff19909316929092179091557fe92e7e4ed0d02d467abd7819bc8d193838230815969e3c5395cb296aa831b9349061249b9084908490614be0565b60405180910390a15050565b6000600f826040516124b991906147e5565b9081526040519081900360200190205460ff1692915050565b80516020818301810180516005825292820191909301209152805481906124f890614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461252490614e15565b80156125715780601f1061254657610100808354040283529160200191612571565b820191906000526020600020905b81548152906001019060200180831161255457829003601f168201915b50505050509080600101549080600201549080600301805461259290614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546125be90614e15565b801561260b5780601f106125e05761010080835404028352916020019161260b565b820191906000526020600020905b8154815290600101906020018083116125ee57829003601f168201915b50505050509080600401805461262090614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461264c90614e15565b80156126995780601f1061266e57610100808354040283529160200191612699565b820191906000526020600020905b81548152906001019060200180831161267c57829003601f168201915b5050505050908060050180546126ae90614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546126da90614e15565b80156127275780601f106126fc57610100808354040283529160200191612727565b820191906000526020600020905b81548152906001019060200180831161270a57829003601f168201915b5050505050905086565b612739612dbd565b6001600160a01b0382166127815760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610a6d565b6001600160a01b03821660009081526004602052604090205460ff16151581151514156127f05760405162461bcd60e51b815260206004820152601860248201527f416c72656164792073657420746f207468617420666c616700000000000000006044820152606401610a6d565b6001600160a01b038216600081815260046020908152604091829020805460ff19168515159081179091558251938452908301527f58d7a3ccc34541e162fcfc87b84be7b78c34d1e1e7f15de6e4dd67d0fe70aecd910161249b565b612854612dbd565b6001600160a01b03811661289c5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610a6d565b600154600160a81b900460ff16156128ec5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610a6d565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610b50565b61296d6140ef565b6006600083815260200190815260200160002060405180610120016040529081600082015481526020016001820180546129a690614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546129d290614e15565b8015612a1f5780601f106129f457610100808354040283529160200191612a1f565b820191906000526020600020905b815481529060010190602001808311612a0257829003601f168201915b5050505050815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682018054612a6090614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054612a8c90614e15565b8015612ad95780601f10612aae57610100808354040283529160200191612ad9565b820191906000526020600020905b815481529060010190602001808311612abc57829003601f168201915b50505050508152602001600782018054612af290614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054612b1e90614e15565b8015612b6b5780601f10612b4057610100808354040283529160200191612b6b565b820191906000526020600020905b815481529060010190602001808311612b4e57829003601f168201915b505050505081526020016008820154815250509050919050565b8051602081830181018051600e8252928201919093012091528054612ba990614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054612bd590614e15565b8015612c225780601f10612bf757610100808354040283529160200191612c22565b820191906000526020600020905b815481529060010190602001808311612c0557829003601f168201915b505050505081565b3360009081526004602052604090205460ff16612c595760405162461bcd60e51b8152600401610a6d90614c5d565b612c6281610d06565b15612c7f5760405162461bcd60e51b8152600401610a6d90614cc8565b6000818152600d602052604090205460ff16612cdd5760405162461bcd60e51b815260206004820181905260248201527f4e6f20737563682067616d652066756c66696c6c65642c207265736f6c7665646044820152606401610a6d565b610c2481613be3565b612cee612dbd565b6001600160a01b038216151580612d0d57506001600160a01b03811615155b612d4c5760405162461bcd60e51b815260206004820152601060248201526f496e76616c696420616464726573657360801b6044820152606401610a6d565b601180546001600160a01b0319166001600160a01b0383811691821790925560038054610100600160a81b0319166101009386169384021790556040805192835260208301919091527fccefc88c0e3817483ffaef8936e4a4973ae9d1e9acdb8a5367e9c73d2a133b96910161249b565b6000546201000090046001600160a01b03163314612e355760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610a6d565b565b612e42816000613da3565b60115460405163b91f5e3560e01b81526001600160a01b038381166004830152600060248301529091169063b91f5e3590604401600060405180830381600087803b158015612e9057600080fd5b505af1158015612ea4573d6000803e3d6000fd5b505050506001600160a01b0381166000818152601660209081526040808320805460ff191660011790556013825291829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc9101610b50565b8160058360000151604051612f1d91906147e5565b90815260200160405180910390206000820151816000019080519060200190612f4792919061406b565b5060208281015160018301556040830151600283015560608301518051612f74926003850192019061406b565b5060808201518051612f9091600484019160209091019061406b565b5060a08201518051612fac91600584019160209091019061406b565b5050825160405160019250600b91612fc3916147e5565b908152604051908190036020018120805492151560ff199093169290921790915582517f2e6bf47bc9ee9350735385cfd1f22060bb7b79c788896e02a6912024aa237cf3916130189186918591908790614b32565b60405180910390a1505050565b60006130348360000151612965565b9050613047836060015160ff1660011490565b806130655750606083015160ff161580156130655750428160400151105b1561311b578251600090815260076020908152604080832086518082558388015160019283018054858b015160608c015160ff908116620100000262ff0000199282166101000261ffff19909416919095161791909117169190911790558452600d90925291829020805460ff19169091179055835190517f7e80b69d2801f3f66d0f9f2fc3094877a0342f02f4ca250452ff3c31d3c9e25b9161310e91879186918890614a91565b60405180910390a1611053565b82516000908152601260205260409020546001600160a01b0316158015906131485750606083015160ff16155b8015613158575042816040015110155b156110535782516000908152601260208181526040808420546001600160a01b03908116855260188352818520805460ff19166001908117909155885186529390925290922054611053921690613da3565b815160009081526008602090815260409091208351815581840151805185936131da92600185019291019061406b565b50604082015180516131f691600284019160209091019061406b565b505082516040517fe86cb442443fcb5c124a534e34acf54c1969dc8fbb2690898ad55a6c974de39792506130189186918591908790614add565b60008160400151600014158015610d5d57505060200151151590565b8251600090815260066020908152604090912084518155818501518051869361327c92600185019291019061406b565b5060408201516002820155606082015160038201556080820151600482015560a0820151600582015560c082015180516132c091600684019160209091019061406b565b5060e082015180516132dc91600784019160209091019061406b565b50610100919091015160089091015582516000908152600a6020908152604080832084905585518352600c82528083208054600160ff19918216811790925587518552600984529382902086518155928601519083015584015160028201556060840151600382015560808401516004909101805490921690151517905582517f5e470733e5dfe041554967f793631241b21e86eb6786cbc263446b604007f17e90859083908661338c826120d1565b60405161339d959493929190614a5a565b60405180910390a150505050565b6133b481613230565b156135bd578051600090815260096020908152604080832084518082558386015160018301558286015160028301556060860151600383015560808601516004909201805460ff191692151592909217909155835260129091529020546001600160a01b0316158015906134b157506011548151600090815260126020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b15801561347957600080fd5b505afa15801561348d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b191906143d8565b1561357d5780516000908152601260209081526040808320546001600160a01b03168352601790915290205460ff1680613511575080516000908152601260209081526040808320546001600160a01b03168352601890915290205460ff165b1561357d5780516000908152601260208181526040808420546001600160a01b03908116855260178352818520805460ff199081169091558651865284845282862054821686526018845282862080549091169055855185529290915282205461357d92911690613da3565b80517f2ba31ae73d6b31e8f74548d44dc71cfb954366366b1cc5ff24bdde61e685bd92908390836135ad826120d1565b60405161249b9493929190614904565b80516000908152601260205260409020546001600160a01b03161580159061367057506011548151600090815260126020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b15801561363657600080fd5b505afa15801561364a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061366e91906143d8565b155b15610d025780516000908152601260208181526040808420546001600160a01b03908116855260178352818520805460ff191660019081179091558651865293909252909220546136c2921690613da3565b80516000908152601260205260409081902054825191517fdd18d3730051e2f6fc7c02567eb2b4cdaf7d5bc0005317c844909f334c0fec569261249b9286926001600160a01b03909116919086906148ac565b600061372082612965565b6000838152600a602052604081205491925061373b82613ed1565b60115460c085015160e08601519293506001600160a01b039091169163e3eb40d99187916137699190613f35565b866040015160006002876040518763ffffffff1660e01b81526004016137949695949392919061499e565b602060405180830381600087803b1580156137ae57600080fd5b505af11580156137c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e69190614206565b5060115460408051622610c560e41b815290516000926001600160a01b03169163dd5adfa39160019184916302610c5091600480820192602092909190829003018186803b15801561383757600080fd5b505afa15801561384b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061386f91906146d4565b6138799190614dd2565b6040518263ffffffff1660e01b815260040161389791815260200190565b60206040518083038186803b1580156138af57600080fd5b505afa1580156138c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e79190614206565b8451600090815260126020908152604080832080546001600160a01b0319166001600160a01b0386169081179091558851908452601383528184205560149091529020805460ff1916600117905584519091507f58feac78a45168e6741403b1b4df633765f301bfcb8b8956272f673de847c5f39082908685613969836120d1565b60405161397a959493929190614840565b60405180910390a15050505050565b6000600182148061399a5750600282145b80610d5d5750501590565b6000836139bf57811580156139b8575082155b90506139e8565b60018414156139d157508082116139e8565b60028414156139e357508082106139e8565b508181145b9392505050565b6139fa846000613da3565b60115460405163b91f5e3560e01b81526001600160a01b038681166004830152602482018690529091169063b91f5e3590604401600060405180830381600087803b158015613a4857600080fd5b505af1158015613a5c573d6000803e3d6000fd5b5050506001600160a01b0385166000908152601560209081526040808320805460ff19166001908117909155815160808101835260138452828520805480835260ff8a81168488019081528a821685880190815260608601878152938a526007808a52888b20965187559151959096018054965193518316620100000262ff0000199484166101000261ffff19909816969093169590951795909517919091161790915554808552600a845282852054818652919093529281902090517f7e80b69d2801f3f66d0f9f2fc3094877a0342f02f4ca250452ff3c31d3c9e25b9450613b869391839193845260208401929092526040830152805460608301526001015460ff8082166080840152600882901c811660a084015260109190911c1660c082015260e00190565b60405180910390a16001600160a01b0384166000818152601360209081526040918290205482519384529083015281018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449060600161339d565b6000613bee82612361565b90506000613bfb83612965565b9050613c0e826060015160ff1660011490565b15613d765781516000908152601260209081526040808320546001600160a01b03168352601790915290205460ff1615613c68578151600090815260126020526040812054613c68916001600160a01b0390911690613da3565b6000613c7383613f61565b60115484516000908152601260205260409081902054905163b91f5e3560e01b81526001600160a01b03918216600482015260248101849052929350169063b91f5e3590604401600060405180830381600087803b158015613cd457600080fd5b505af1158015613ce8573d6000803e3d6000fd5b505084516000908152601260208181526040808420546001600160a01b03908116855260158352818520805460ff1916600117905589518552928252928390205488518451919093168152908101919091529081018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449250606001905060405180910390a150505050565b606082015160ff16158015613d8e5750428160400151105b15613d9e578151613d9e90613f87565b505050565b6011546040516333dfec9960e21b81526001600160a01b03848116600483015283151592169063cf7fb2649060240160206040518083038186803b158015613dea57600080fd5b505afa158015613dfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e2291906143d8565b151514610d0257601154604051637f8c2d6160e01b81526001600160a01b038481166004830152831515602483015290911690637f8c2d6190604401600060405180830381600087803b158015613e7857600080fd5b505af1158015613e8c573d6000803e3d6000fd5b5050604080516001600160a01b038616815284151560208201527f2b8992e59f9813c2f92be2374e9bdd5384146ff8f719b038fbaf7d3dbfa78fde935001905061249b565b6040805160018082528183019092526060916000919060208083019080368337019050509050613f038361238c614d7b565b81600081518110613f2457634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b60608282604051602001613f4a929190614801565b604051602081830303815290604052905092915050565b6000816040015160ff16826020015160ff1611613f7f576002610d5d565b600192915050565b60115460008281526012602052604080822054905163b91f5e3560e01b81526001600160a01b03918216600482015260248101929092529091169063b91f5e3590604401600060405180830381600087803b158015613fe557600080fd5b505af1158015613ff9573d6000803e3d6000fd5b505050600082815260126020818152604080842080546001600160a01b03908116865260168452828620805460ff1916600117905594879052928252915482519316835282018490527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc925001610b50565b82805461407790614e15565b90600052602060002090601f01602090048101928261409957600085556140df565b82601f106140b257805160ff19168380011785556140df565b828001600101855582156140df579182015b828111156140df5782518255916020019190600101906140c4565b506140eb92915061413e565b5090565b6040518061012001604052806000801916815260200160608152602001600081526020016000815260200160008152602001600081526020016060815260200160608152602001600081525090565b5b808211156140eb576000815560010161413f565b803561415e81614e97565b919050565b803561415e81614eac565b600082601f83011261417e578081fd5b813567ffffffffffffffff81111561419857614198614e81565b6141ab601f8201601f1916602001614d4a565b8181528460208386010111156141bf578283fd5b816020850160208301379081016020019190915292915050565b803560ff8116811461415e57600080fd5b6000602082840312156141fb578081fd5b81356139e881614e97565b600060208284031215614217578081fd5b81516139e881614e97565b60008060408385031215614234578081fd5b823561423f81614e97565b9150602083013561424f81614e97565b809150509250929050565b60008060006060848603121561426e578081fd5b833561427981614e97565b925060208481013567ffffffffffffffff80821115614296578384fd5b818701915087601f8301126142a9578384fd5b8135818111156142bb576142bb614e81565b8060051b6142ca858201614d4a565b8281528581019085870183870188018d10156142e4578889fd5b8893505b84841015614321578035868111156142fe57898afd5b61430c8e8a838b010161416e565b845250600193909301929187019187016142e8565b508098505050505050505061433860408501614153565b90509250925092565b60008060408385031215614353578182fd5b823561435e81614e97565b9150602083013561424f81614eac565b60008060008060808587031215614383578081fd5b843561438e81614e97565b9350602085013592506143a3604086016141d9565b91506143b1606086016141d9565b905092959194509250565b6000602082840312156143cd578081fd5b81356139e881614eac565b6000602082840312156143e9578081fd5b81516139e881614eac565b600060208284031215614405578081fd5b5035919050565b600080600080600060a08688031215614423578081fd5b85359450602086013567ffffffffffffffff80821115614441578283fd5b61444d89838a0161416e565b95506040880135915080821115614462578283fd5b61446e89838a0161416e565b945060608801359350608088013591508082111561448a578283fd5b506144978882890161416e565b9150509295509295909350565b600080600080600080600060e0888a0312156144be578182fd5b87359650602088013567ffffffffffffffff808211156144dc578384fd5b6144e88b838c0161416e565b975060408a01359150808211156144fd578384fd5b6145098b838c0161416e565b965060608a013591508082111561451e578384fd5b61452a8b838c0161416e565b955060808a0135945060a08a0135935060c08a013591508082111561454d578283fd5b5061455a8a828b0161416e565b91505092959891949750929550565b6000806000806000806000806000806101408b8d031215614588578384fd5b8a35995060208b013567ffffffffffffffff808211156145a6578586fd5b6145b28e838f0161416e565b9a5060408d01359150808211156145c7578586fd5b6145d38e838f0161416e565b995060608d0135985060808d0135975060a08d0135965060c08d01359150808211156145fd578586fd5b6146098e838f0161416e565b955060e08d013591508082111561461e578485fd5b5061462b8d828e0161416e565b93505061463b6101008c01614163565b91506101208b013590509295989b9194979a5092959850565b600060208284031215614665578081fd5b813567ffffffffffffffff81111561467b578182fd5b6146878482850161416e565b949350505050565b600080604083850312156146a1578182fd5b823567ffffffffffffffff8111156146b7578283fd5b6146c38582860161416e565b925050602083013561424f81614eac565b6000602082840312156146e5578081fd5b5051919050565b6000815180845260208085019450808401835b8381101561471b578151875295820195908201906001016146ff565b509495945050505050565b6000815180845261473e816020860160208601614de9565b601f01601f19169290920160200192915050565b600061012082518452602083015181602086015261477282860182614726565b91505060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015184820360c08601526147b48282614726565b91505060e083015184820360e08601526147ce8282614726565b610100948501519590940194909452509092915050565b600082516147f7818460208701614de9565b9190910192915050565b60008351614813818460208801614de9565b630103b39960e51b9083019081528351614834816004840160208801614de9565b01600401949350505050565b60018060a01b038616815284602082015260a06040820152600061486760a0830186614752565b828103606084015261487981866146ec565b9050828103608084015261488d81856146ec565b98975050505050505050565b6020815260006139e860208301846146ec565b8481526001600160a01b0384166020820152604081018390526101008101611ae46060830184805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b600061010086835285602084015261494c6040840186805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b8060e084015261495e818401856146ec565b979650505050505050565b8381526060602082015260006149826060830185614726565b82810360408401526149948185614726565b9695505050505050565b86815260c0602082015260006149b760c0830188614726565b86604084015285606084015284608084015282810360a08401526149db81856146ec565b9998505050505050505050565b60006101208b8352806020840152614a028184018c614726565b90508960408401528860608401528760808401528660a084015282810360c0840152614a2e8187614726565b905082810360e0840152614a428186614726565b915050826101008301529a9950505050505050505050565b85815284602082015283604082015260a060608201526000614a7f60a0830185614752565b828103608084015261488d81856146ec565b848152602081018490526040810183905260e08101611ae460608301848051825260ff602082015116602083015260ff604082015116604083015260ff60608201511660608301525050565b848152836020820152826040820152608060608201528151608082015260006020830151606060a0840152614b1560e0840182614726565b90506040840151607f198483030160c085015261488d8282614726565b848152836020820152608060408201526000614b516080830185614726565b8281036060840152835160c08252614b6c60c0830182614726565b9050602085015160208301526040850151604083015260608501518282036060840152614b998282614726565b91505060808501518282036080840152614bb38282614726565b91505060a085015182820360a08401526149db8282614726565b6020815260006139e86020830184614726565b604081526000614bf36040830185614726565b905082151560208301529392505050565b60c081526000614c1760c0830189614726565b8760208401528660408401528281036060840152614c358187614726565b90508281036080840152614c498186614726565b905082810360a08401526149db8185614726565b6020808252600e908201526d24b73b30b634b21031b0b63632b960911b604082015260600190565b60208082526023908201527f4f6e6c7920777261707065722063616e2063616c6c20746869732066756e637460408201526234b7b760e91b606082015260800190565b6020808252601b908201527f4d61726b6574207265736f6c766564206f722063616e63656c65640000000000604082015260600190565b6020815260006139e86020830184614752565b60808101610d5d82848051825260ff602082015116602083015260ff604082015116604083015260ff60608201511660608301525050565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d7357614d73614e81565b604052919050565b60008219821115614d8e57614d8e614e6b565b500190565b600082614dae57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615614dcd57614dcd614e6b565b500290565b600082821015614de457614de4614e6b565b500390565b60005b83811015614e04578181015183820152602001614dec565b838111156110535750506000910152565b600181811c90821680614e2957607f821691505b60208210811415614e4a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415614e6457614e64614e6b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c2457600080fd5b8015158114610c2457600080fdfea264697066735822122039f147c6dc05f94aa74b62a345baa572f9dc1d3ec7470021f6899fb0d032b8b664736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103ba5760003560e01c806379ba5097116101f4578063ae71dcdf1161011a578063c48e62f1116100ad578063e59aff4b1161007c578063e59aff4b146109ac578063e7015ab2146109bf578063f83aaaf8146109df578063f89c6f18146109f257600080fd5b8063c48e62f114610941578063cc61edf314610961578063d2cd9eb814610969578063dec72d631461098957600080fd5b8063b9679951116100e9578063b9679951146108f6578063bc93233f1461091b578063c0fb7e9c14610528578063c3b83f5f1461092e57600080fd5b8063ae71dcdf14610632578063b4976d7b146108b0578063b704edc4146108d0578063b91618c6146108e357600080fd5b80638c4e8cb51161019257806393f4452e1161016157806393f4452e146108135780639aceb36e1461087d578063a47a874f1461089d578063a81bda5f1461052057600080fd5b80638c4e8cb5146107bb5780638da5cb5b146107de5780638ec2c5a6146107f757806391b4ded91461080a57600080fd5b80637df8b802116101ce5780637df8b80214610762578063847ac2b514610528578063885d292a1461077a5780638980d03e146107a857600080fd5b806379ba50971461072f57806379daacd2146106325780637b041a581461073757600080fd5b80634989f9be116102e45780635b9fbe0711610277578063621da70311610246578063621da703146106ab57806367674b14146106be578063693decdc146106e157806370aadcc41461070f57600080fd5b80635b9fbe071461063a5780635c975abb1461065d57806360b4df851461066a57806361772f641461069857600080fd5b8063557db448116102b3578063557db448146105f75780635895f4881461061f5780635a4e5a15146106325780635b0aa21f1461052057600080fd5b80634989f9be1461059c5780634c70e636146105be578063523f1c8f146105d157806353a47bb7146105e457600080fd5b80631afed5cc1161035c57806336c0d8551161032b57806336c0d855146105305780633ec70ca5146105535780634156305d14610576578063489f4b971461058957600080fd5b80631afed5cc146104e65780632a4a3e7c146104fd5780632fff702014610520578063300a02981461052857600080fd5b806313af40351161039857806313af4035146104885780631627540c1461049d57806316c38b3c146104b05780631734bcd4146104c357600080fd5b806306c933d8146103bf5780630b5cde46146103f757806310063fdc1461045d575b600080fd5b6103e26103cd3660046141ea565b60046020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6104346104053660046143f4565b6007602052600090815260409020805460019091015460ff808216916101008104821691620100009091041684565b6040805194855260ff9384166020860152918316918401919091521660608201526080016103ee565b601154610470906001600160a01b031681565b6040516001600160a01b0390911681526020016103ee565b61049b6104963660046141ea565b610a1b565b005b61049b6104ab3660046141ea565b610b5b565b61049b6104be3660046143bc565b610bb1565b6103e26104d13660046143f4565b6000908152600c602052604090205460ff1690565b6104ef61238c81565b6040519081526020016103ee565b6103e261050b3660046141ea565b60186020526000908152604090205460ff1681565b6104ef600181565b6104ef600281565b6103e261053e3660046141ea565b60176020526000908152604090205460ff1681565b6103e26105613660046143f4565b600d6020526000908152604090205460ff1681565b61049b6105843660046141ea565b610c27565b6103e26105973660046143f4565b610d06565b6105af6105aa3660046143f4565b610d63565b6040516103ee93929190614969565b61049b6105cc36600461425a565b610e96565b61049b6105df3660046144a4565b611059565b600154610470906001600160a01b031681565b61060a6106053660046143f4565b611157565b6040516103ee999897969594939291906149e8565b61049b61062d36600461440c565b611336565b6104ef600081565b6103e26106483660046141ea565b60156020526000908152604090205460ff1681565b6003546103e29060ff1681565b61067d6106783660046143f4565b61158e565b604080519384526020840192909252908201526060016103ee565b6103e26106a63660046143f4565b6115d9565b6103e26106b93660046143f4565b611aed565b6103e26106cc3660046143f4565b600c6020526000908152604090205460ff1681565b6103e26106ef366004614654565b8051602081830181018051600f8252928201919093012091525460ff1681565b6104ef61071d3660046143f4565b600a6020526000908152604090205481565b61049b611b08565b6104ef610745366004614654565b805160208183018101805160108252928201919093012091525481565b6003546104709061010090046001600160a01b031681565b6103e2610788366004614654565b8051602081830181018051600b8252928201919093012091525460ff1681565b61049b6107b6366004614569565b611c05565b6103e26107c93660046141ea565b60146020526000908152604090205460ff1681565b600054610470906201000090046001600160a01b031681565b61049b6108053660046143f4565b611fd6565b6104ef60025481565b6108536108213660046143f4565b600960205260009081526040902080546001820154600283015460038401546004909401549293919290919060ff1685565b6040805195865260208601949094529284019190915260608301521515608082015260a0016103ee565b61089061088b3660046143f4565b6120d1565b6040516103ee9190614899565b61049b6108ab36600461436e565b61221b565b6108c36108be3660046143f4565b612361565b6040516103ee9190614d12565b61049b6108de36600461468f565b6123ce565b6103e26108f1366004614654565b6124a7565b610909610904366004614654565b6124d2565b6040516103ee96959493929190614c04565b61049b610929366004614341565b612731565b61049b61093c3660046141ea565b61284c565b61095461094f3660046143f4565b612965565b6040516103ee9190614cff565b6104ef600381565b61097c610977366004614654565b612b85565b6040516103ee9190614bcd565b6103e26109973660046141ea565b60166020526000908152604090205460ff1681565b61049b6109ba3660046143f4565b612c2a565b6104ef6109cd3660046141ea565b60136020526000908152604090205481565b61049b6109ed366004614222565b612ce6565b610470610a003660046143f4565b6012602052600090815260409020546001600160a01b031681565b6001600160a01b038116610a765760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f7420626520300000000000000060448201526064015b60405180910390fd5b600154600160a01b900460ff1615610ae25760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b6064820152608401610a6d565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b03831662010000810262010000600160b01b03199092169190911782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b610b63612dbd565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610b50565b610bb9612dbd565b60035460ff1615158115151415610bcd5750565b6003805460ff191682151590811790915560ff1615610beb57426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610b50565b50565b3360009081526004602052604090205460ff16610c565760405162461bcd60e51b8152600401610a6d90614c5d565b6001600160a01b038116600090815260136020526040902054610c7881610d06565b15610c955760405162461bcd60e51b8152600401610a6d90614cc8565b6000818152601260205260409020546001600160a01b0316610cf95760405162461bcd60e51b815260206004820152601a60248201527f4e6f206d61726b6574206372656174656420666f722067616d650000000000006044820152606401610a6d565b610d0282612e37565b5050565b6000818152601260209081526040808320546001600160a01b03168352601590915281205460ff1680610d5d57506000828152601260209081526040808320546001600160a01b03168352601690915290205460ff165b92915050565b60086020526000908152604090208054600182018054919291610d8590614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054610db190614e15565b8015610dfe5780601f10610dd357610100808354040283529160200191610dfe565b820191906000526020600020905b815481529060010190602001808311610de157829003601f168201915b505050505090806002018054610e1390614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3f90614e15565b8015610e8c5780601f10610e6157610100808354040283529160200191610e8c565b820191906000526020600020905b815481529060010190602001808311610e6f57829003601f168201915b5050505050905083565b600054610100900460ff16610eb15760005460ff1615610eb5565b303b155b610f185760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a6d565b600054610100900460ff16158015610f3a576000805461ffff19166101011790555b610f4384610a1b565b601180546001600160a01b0319166001600160a01b038481169190911790915584166000908152600460205260408120805460ff191660011790555b8351811015611040576001600f858381518110610fac57634e487b7160e01b600052603260045260246000fd5b6020026020010151604051610fc191906147e5565b908152602001604051809103902060006101000a81548160ff02191690831515021790555080601085838151811061100957634e487b7160e01b600052603260045260246000fd5b602002602001015160405161101e91906147e5565b908152604051908190036020019020558061103881614e50565b915050610f7f565b508015611053576000805461ff00191690555b50505050565b60035461010090046001600160a01b031633146110885760405162461bcd60e51b8152600401610a6d90614c85565b4282111561114e576110c96040518060c001604052806060815260200160008152602001600081526020016060815260200160608152602001606081525090565b868152606081018790526080810185905260a08101869052602081018490526040808201849052518790600e906111019085906147e5565b9081526020016040518091039020908051906020019061112292919061406b565b5061114c888260108560405161113891906147e5565b908152602001604051809103902054612f08565b505b50505050505050565b6006602052600090815260409020805460018201805491929161117990614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546111a590614e15565b80156111f25780601f106111c7576101008083540402835291602001916111f2565b820191906000526020600020905b8154815290600101906020018083116111d557829003601f168201915b50505050509080600201549080600301549080600401549080600501549080600601805461121f90614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461124b90614e15565b80156112985780601f1061126d57610100808354040283529160200191611298565b820191906000526020600020905b81548152906001019060200180831161127b57829003601f168201915b5050505050908060070180546112ad90614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546112d990614e15565b80156113265780601f106112fb57610100808354040283529160200191611326565b820191906000526020600020905b81548152906001019060200180831161130957829003601f168201915b5050505050908060080154905089565b60035461010090046001600160a01b031633146113655760405162461bcd60e51b8152600401610a6d90614c85565b6040805160808101825260008082526020820181905291810182905260608101919091526040516777696e2f6c6f736560c01b602082015260280160405160208183030381529060405280519060200120856040516020016113c791906147e5565b60405160208183030381529060405280519060200120141561143257828152600160208201819052600060408084019190915260608301919091525161142d90879083906010906114199087906147e5565b908152602001604051809103902054613025565b611548565b604051673637b9b297bbb4b760c11b6020820152602801604051602081830303815290604052805190602001208560405160200161147091906147e5565b6040516020818303038152906040528051906020012014156114bf57828152600060208201526001604080830182905260608301919091525161142d90879083906010906114199087906147e5565b604051631b9d5b1b60e21b602082015260240160405160208183030381529060405280519060200120856040516020016114f991906147e5565b60405160208183030381529060405280519060200120141561154857828152600060208201819052604080830182905260608301919091525161154890879083906010906114199087906147e5565b6040805160608101825284815260208101879052808201869052905161114e908890839060109061157a9088906147e5565b9081526020016040518091039020546131aa565b600080600061159c846115d9565b6115c6576000848152600960205260409020600181015460028201546003909201549091906115cc565b60008060005b9250925092509193909250565b6000818152600660209081526040808320815161012081019092528054825260018101805485948401919061160d90614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461163990614e15565b80156116865780601f1061165b57610100808354040283529160200191611686565b820191906000526020600020905b81548152906001019060200180831161166957829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820180546116c790614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546116f390614e15565b80156117405780601f1061171557610100808354040283529160200191611740565b820191906000526020600020905b81548152906001019060200180831161172357829003601f168201915b5050505050815260200160078201805461175990614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461178590614e15565b80156117d25780601f106117a7576101008083540402835291602001916117d2565b820191906000526020600020905b8154815290600101906020018083116117b557829003601f168201915b5050505050815260200160088201548152505090506000600582602001516040516117fd91906147e5565b90815260200160405180910390206040518060c001604052908160008201805461182690614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461185290614e15565b801561189f5780601f106118745761010080835404028352916020019161189f565b820191906000526020600020905b81548152906001019060200180831161188257829003601f168201915b5050505050815260200160018201548152602001600282015481526020016003820180546118cc90614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546118f890614e15565b80156119455780601f1061191a57610100808354040283529160200191611945565b820191906000526020600020905b81548152906001019060200180831161192857829003601f168201915b5050505050815260200160048201805461195e90614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461198a90614e15565b80156119d75780601f106119ac576101008083540402835291602001916119d7565b820191906000526020600020905b8154815290600101906020018083116119ba57829003601f168201915b505050505081526020016005820180546119f090614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1c90614e15565b8015611a695780601f10611a3e57610100808354040283529160200191611a69565b820191906000526020600020905b815481529060010190602001808311611a4c57829003601f168201915b50505091909252505050600085815260096020908152604091829020825160a08101845281548152600182015481840152600282015493810193909352600381015460608401526004015460ff16151560808301528201519192509042118015611ad65750428360400151115b8015611ae457508060800151155b95945050505050565b6000610d5d611afb83612361565b6060015160ff1660011490565b6001546001600160a01b03163314611b805760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b6064820152608401610a6d565b60005460015460408051620100009093046001600160a01b03908116845290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805462010000600160b01b0319166001600160a01b03831662010000021790556001600160a01b0319169055565b60035461010090046001600160a01b03163314611c345760405162461bcd60e51b8152600401610a6d90614c85565b600b83604051611c4491906147e5565b9081526040519081900360200190205460ff1615611fca576000600584604051611c6e91906147e5565b90815260200160405180910390206040518060c0016040529081600082018054611c9790614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc390614e15565b8015611d105780601f10611ce557610100808354040283529160200191611d10565b820191906000526020600020905b815481529060010190602001808311611cf357829003601f168201915b505050505081526020016001820154815260200160028201548152602001600382018054611d3d90614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611d6990614e15565b8015611db65780601f10611d8b57610100808354040283529160200191611db6565b820191906000526020600020905b815481529060010190602001808311611d9957829003601f168201915b50505050508152602001600482018054611dcf90614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611dfb90614e15565b8015611e485780601f10611e1d57610100808354040283529160200191611e48565b820191906000526020600020905b815481529060010190602001808311611e2b57829003601f168201915b50505050508152602001600582018054611e6190614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8d90614e15565b8015611eda5780601f10611eaf57610100808354040283529160200191611eda565b820191906000526020600020905b815481529060010190602001808311611ebd57829003601f168201915b50505050508152505090504281604001511115611fc8576040805160a08101825260006060820181905288825260208083018c90528284018b90528615156080840152898252600c9052919091205460ff16611fbc57611f3981613230565b15611fb757611f466140ef565b878152606081018a90526080810189905260c081018c905260e081018b90526020810186905260408381015181830152610100820185905251611fab908e9083908590601090611f97908d906147e5565b90815260200160405180910390205461324c565b611fb58d836133ab565b505b611fc6565b611fc68c826133ab565b505b505b50505050505050505050565b3360009081526004602052604090205460ff166120055760405162461bcd60e51b8152600401610a6d90614c5d565b6000818152601260205260409020546001600160a01b03161561206a5760405162461bcd60e51b815260206004820152601e60248201527f4d61726b657420666f722067616d6520616c72656164792065786973747300006044820152606401610a6d565b6000818152600c602052604090205460ff166120c85760405162461bcd60e51b815260206004820152601f60248201527f4e6f20737563682067616d652066756c66696c6c65642c2063726561746564006044820152606401610a6d565b610c2481613715565b60408051600380825260808201909252606091600091906020820184803683370190505090506121008361158e565b8360008151811061212157634e487b7160e01b600052603260045260246000fd5b602002602001018460018151811061214957634e487b7160e01b600052603260045260246000fd5b602002602001018560028151811061217157634e487b7160e01b600052603260045260246000fd5b60209081029190910101929092529190525260005b8151811015612214576127108282815181106121b257634e487b7160e01b600052603260045260246000fd5b6020026020010151670de0b6b3a76400006121cd9190614db3565b6121d79190614d93565b8282815181106121f757634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061220c81614e50565b915050612186565b5092915050565b3360009081526004602052604090205460ff1661224a5760405162461bcd60e51b8152600401610a6d90614c5d565b6001600160a01b03841660009081526013602052604090205483838361226f84610d06565b1561228c5760405162461bcd60e51b8152600401610a6d90614cc8565b6000848152601260205260409020546001600160a01b03166122f05760405162461bcd60e51b815260206004820152601a60248201527f4e6f206d61726b6574206372656174656420666f722067616d650000000000006044820152606401610a6d565b6122f983613989565b80156123115750612311838360ff168360ff166139a5565b6123555760405162461bcd60e51b815260206004820152601560248201527442616420726573756c74206f72206f7574636f6d6560581b6044820152606401610a6d565b61114c888888886139ef565b60408051608080820183526000808352602080840182905283850182905260609384018290529481526007855283902083519182018452805482526001015460ff808216958301959095526101008104851693820193909352620100009092049092169181019190915290565b6123d6612dbd565b801515600f836040516123e991906147e5565b9081526040519081900360200190205460ff161515141561243a5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b6044820152606401610a6d565b80600f8360405161244b91906147e5565b908152604051908190036020018120805492151560ff19909316929092179091557fe92e7e4ed0d02d467abd7819bc8d193838230815969e3c5395cb296aa831b9349061249b9084908490614be0565b60405180910390a15050565b6000600f826040516124b991906147e5565b9081526040519081900360200190205460ff1692915050565b80516020818301810180516005825292820191909301209152805481906124f890614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461252490614e15565b80156125715780601f1061254657610100808354040283529160200191612571565b820191906000526020600020905b81548152906001019060200180831161255457829003601f168201915b50505050509080600101549080600201549080600301805461259290614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546125be90614e15565b801561260b5780601f106125e05761010080835404028352916020019161260b565b820191906000526020600020905b8154815290600101906020018083116125ee57829003601f168201915b50505050509080600401805461262090614e15565b80601f016020809104026020016040519081016040528092919081815260200182805461264c90614e15565b80156126995780601f1061266e57610100808354040283529160200191612699565b820191906000526020600020905b81548152906001019060200180831161267c57829003601f168201915b5050505050908060050180546126ae90614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546126da90614e15565b80156127275780601f106126fc57610100808354040283529160200191612727565b820191906000526020600020905b81548152906001019060200180831161270a57829003601f168201915b5050505050905086565b612739612dbd565b6001600160a01b0382166127815760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610a6d565b6001600160a01b03821660009081526004602052604090205460ff16151581151514156127f05760405162461bcd60e51b815260206004820152601860248201527f416c72656164792073657420746f207468617420666c616700000000000000006044820152606401610a6d565b6001600160a01b038216600081815260046020908152604091829020805460ff19168515159081179091558251938452908301527f58d7a3ccc34541e162fcfc87b84be7b78c34d1e1e7f15de6e4dd67d0fe70aecd910161249b565b612854612dbd565b6001600160a01b03811661289c5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610a6d565b600154600160a81b900460ff16156128ec5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b6044820152606401610a6d565b600080546001600160a01b038381166201000081810262010000600160b01b031990941693909317938490556001805460ff60a81b1916600160a81b1790556040805193909404909116825260208201527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9101610b50565b61296d6140ef565b6006600083815260200190815260200160002060405180610120016040529081600082015481526020016001820180546129a690614e15565b80601f01602080910402602001604051908101604052809291908181526020018280546129d290614e15565b8015612a1f5780601f106129f457610100808354040283529160200191612a1f565b820191906000526020600020905b815481529060010190602001808311612a0257829003601f168201915b5050505050815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682018054612a6090614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054612a8c90614e15565b8015612ad95780601f10612aae57610100808354040283529160200191612ad9565b820191906000526020600020905b815481529060010190602001808311612abc57829003601f168201915b50505050508152602001600782018054612af290614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054612b1e90614e15565b8015612b6b5780601f10612b4057610100808354040283529160200191612b6b565b820191906000526020600020905b815481529060010190602001808311612b4e57829003601f168201915b505050505081526020016008820154815250509050919050565b8051602081830181018051600e8252928201919093012091528054612ba990614e15565b80601f0160208091040260200160405190810160405280929190818152602001828054612bd590614e15565b8015612c225780601f10612bf757610100808354040283529160200191612c22565b820191906000526020600020905b815481529060010190602001808311612c0557829003601f168201915b505050505081565b3360009081526004602052604090205460ff16612c595760405162461bcd60e51b8152600401610a6d90614c5d565b612c6281610d06565b15612c7f5760405162461bcd60e51b8152600401610a6d90614cc8565b6000818152600d602052604090205460ff16612cdd5760405162461bcd60e51b815260206004820181905260248201527f4e6f20737563682067616d652066756c66696c6c65642c207265736f6c7665646044820152606401610a6d565b610c2481613be3565b612cee612dbd565b6001600160a01b038216151580612d0d57506001600160a01b03811615155b612d4c5760405162461bcd60e51b815260206004820152601060248201526f496e76616c696420616464726573657360801b6044820152606401610a6d565b601180546001600160a01b0319166001600160a01b0383811691821790925560038054610100600160a81b0319166101009386169384021790556040805192835260208301919091527fccefc88c0e3817483ffaef8936e4a4973ae9d1e9acdb8a5367e9c73d2a133b96910161249b565b6000546201000090046001600160a01b03163314612e355760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610a6d565b565b612e42816000613da3565b60115460405163b91f5e3560e01b81526001600160a01b038381166004830152600060248301529091169063b91f5e3590604401600060405180830381600087803b158015612e9057600080fd5b505af1158015612ea4573d6000803e3d6000fd5b505050506001600160a01b0381166000818152601660209081526040808320805460ff191660011790556013825291829020548251938452908301527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc9101610b50565b8160058360000151604051612f1d91906147e5565b90815260200160405180910390206000820151816000019080519060200190612f4792919061406b565b5060208281015160018301556040830151600283015560608301518051612f74926003850192019061406b565b5060808201518051612f9091600484019160209091019061406b565b5060a08201518051612fac91600584019160209091019061406b565b5050825160405160019250600b91612fc3916147e5565b908152604051908190036020018120805492151560ff199093169290921790915582517f2e6bf47bc9ee9350735385cfd1f22060bb7b79c788896e02a6912024aa237cf3916130189186918591908790614b32565b60405180910390a1505050565b60006130348360000151612965565b9050613047836060015160ff1660011490565b806130655750606083015160ff161580156130655750428160400151105b1561311b578251600090815260076020908152604080832086518082558388015160019283018054858b015160608c015160ff908116620100000262ff0000199282166101000261ffff19909416919095161791909117169190911790558452600d90925291829020805460ff19169091179055835190517f7e80b69d2801f3f66d0f9f2fc3094877a0342f02f4ca250452ff3c31d3c9e25b9161310e91879186918890614a91565b60405180910390a1611053565b82516000908152601260205260409020546001600160a01b0316158015906131485750606083015160ff16155b8015613158575042816040015110155b156110535782516000908152601260208181526040808420546001600160a01b03908116855260188352818520805460ff19166001908117909155885186529390925290922054611053921690613da3565b815160009081526008602090815260409091208351815581840151805185936131da92600185019291019061406b565b50604082015180516131f691600284019160209091019061406b565b505082516040517fe86cb442443fcb5c124a534e34acf54c1969dc8fbb2690898ad55a6c974de39792506130189186918591908790614add565b60008160400151600014158015610d5d57505060200151151590565b8251600090815260066020908152604090912084518155818501518051869361327c92600185019291019061406b565b5060408201516002820155606082015160038201556080820151600482015560a0820151600582015560c082015180516132c091600684019160209091019061406b565b5060e082015180516132dc91600784019160209091019061406b565b50610100919091015160089091015582516000908152600a6020908152604080832084905585518352600c82528083208054600160ff19918216811790925587518552600984529382902086518155928601519083015584015160028201556060840151600382015560808401516004909101805490921690151517905582517f5e470733e5dfe041554967f793631241b21e86eb6786cbc263446b604007f17e90859083908661338c826120d1565b60405161339d959493929190614a5a565b60405180910390a150505050565b6133b481613230565b156135bd578051600090815260096020908152604080832084518082558386015160018301558286015160028301556060860151600383015560808601516004909201805460ff191692151592909217909155835260129091529020546001600160a01b0316158015906134b157506011548151600090815260126020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b15801561347957600080fd5b505afa15801561348d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b191906143d8565b1561357d5780516000908152601260209081526040808320546001600160a01b03168352601790915290205460ff1680613511575080516000908152601260209081526040808320546001600160a01b03168352601890915290205460ff165b1561357d5780516000908152601260208181526040808420546001600160a01b03908116855260178352818520805460ff199081169091558651865284845282862054821686526018845282862080549091169055855185529290915282205461357d92911690613da3565b80517f2ba31ae73d6b31e8f74548d44dc71cfb954366366b1cc5ff24bdde61e685bd92908390836135ad826120d1565b60405161249b9493929190614904565b80516000908152601260205260409020546001600160a01b03161580159061367057506011548151600090815260126020526040908190205490516333dfec9960e21b81526001600160a01b03918216600482015291169063cf7fb2649060240160206040518083038186803b15801561363657600080fd5b505afa15801561364a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061366e91906143d8565b155b15610d025780516000908152601260208181526040808420546001600160a01b03908116855260178352818520805460ff191660019081179091558651865293909252909220546136c2921690613da3565b80516000908152601260205260409081902054825191517fdd18d3730051e2f6fc7c02567eb2b4cdaf7d5bc0005317c844909f334c0fec569261249b9286926001600160a01b03909116919086906148ac565b600061372082612965565b6000838152600a602052604081205491925061373b82613ed1565b60115460c085015160e08601519293506001600160a01b039091169163e3eb40d99187916137699190613f35565b866040015160006002876040518763ffffffff1660e01b81526004016137949695949392919061499e565b602060405180830381600087803b1580156137ae57600080fd5b505af11580156137c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e69190614206565b5060115460408051622610c560e41b815290516000926001600160a01b03169163dd5adfa39160019184916302610c5091600480820192602092909190829003018186803b15801561383757600080fd5b505afa15801561384b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061386f91906146d4565b6138799190614dd2565b6040518263ffffffff1660e01b815260040161389791815260200190565b60206040518083038186803b1580156138af57600080fd5b505afa1580156138c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e79190614206565b8451600090815260126020908152604080832080546001600160a01b0319166001600160a01b0386169081179091558851908452601383528184205560149091529020805460ff1916600117905584519091507f58feac78a45168e6741403b1b4df633765f301bfcb8b8956272f673de847c5f39082908685613969836120d1565b60405161397a959493929190614840565b60405180910390a15050505050565b6000600182148061399a5750600282145b80610d5d5750501590565b6000836139bf57811580156139b8575082155b90506139e8565b60018414156139d157508082116139e8565b60028414156139e357508082106139e8565b508181145b9392505050565b6139fa846000613da3565b60115460405163b91f5e3560e01b81526001600160a01b038681166004830152602482018690529091169063b91f5e3590604401600060405180830381600087803b158015613a4857600080fd5b505af1158015613a5c573d6000803e3d6000fd5b5050506001600160a01b0385166000908152601560209081526040808320805460ff19166001908117909155815160808101835260138452828520805480835260ff8a81168488019081528a821685880190815260608601878152938a526007808a52888b20965187559151959096018054965193518316620100000262ff0000199484166101000261ffff19909816969093169590951795909517919091161790915554808552600a845282852054818652919093529281902090517f7e80b69d2801f3f66d0f9f2fc3094877a0342f02f4ca250452ff3c31d3c9e25b9450613b869391839193845260208401929092526040830152805460608301526001015460ff8082166080840152600882901c811660a084015260109190911c1660c082015260e00190565b60405180910390a16001600160a01b0384166000818152601360209081526040918290205482519384529083015281018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449060600161339d565b6000613bee82612361565b90506000613bfb83612965565b9050613c0e826060015160ff1660011490565b15613d765781516000908152601260209081526040808320546001600160a01b03168352601790915290205460ff1615613c68578151600090815260126020526040812054613c68916001600160a01b0390911690613da3565b6000613c7383613f61565b60115484516000908152601260205260409081902054905163b91f5e3560e01b81526001600160a01b03918216600482015260248101849052929350169063b91f5e3590604401600060405180830381600087803b158015613cd457600080fd5b505af1158015613ce8573d6000803e3d6000fd5b505084516000908152601260208181526040808420546001600160a01b03908116855260158352818520805460ff1916600117905589518552928252928390205488518451919093168152908101919091529081018490527f1bf3a61a401436c0f119e17875fafabde9c95fbb6787cef2850d2d4a8f31e4449250606001905060405180910390a150505050565b606082015160ff16158015613d8e5750428160400151105b15613d9e578151613d9e90613f87565b505050565b6011546040516333dfec9960e21b81526001600160a01b03848116600483015283151592169063cf7fb2649060240160206040518083038186803b158015613dea57600080fd5b505afa158015613dfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e2291906143d8565b151514610d0257601154604051637f8c2d6160e01b81526001600160a01b038481166004830152831515602483015290911690637f8c2d6190604401600060405180830381600087803b158015613e7857600080fd5b505af1158015613e8c573d6000803e3d6000fd5b5050604080516001600160a01b038616815284151560208201527f2b8992e59f9813c2f92be2374e9bdd5384146ff8f719b038fbaf7d3dbfa78fde935001905061249b565b6040805160018082528183019092526060916000919060208083019080368337019050509050613f038361238c614d7b565b81600081518110613f2457634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b60608282604051602001613f4a929190614801565b604051602081830303815290604052905092915050565b6000816040015160ff16826020015160ff1611613f7f576002610d5d565b600192915050565b60115460008281526012602052604080822054905163b91f5e3560e01b81526001600160a01b03918216600482015260248101929092529091169063b91f5e3590604401600060405180830381600087803b158015613fe557600080fd5b505af1158015613ff9573d6000803e3d6000fd5b505050600082815260126020818152604080842080546001600160a01b03908116865260168452828620805460ff1916600117905594879052928252915482519316835282018490527fb71d01900104b9abac3b5fb2ce8418fe7a6cdacf50d1f3cd0f9e4497961f4fdc925001610b50565b82805461407790614e15565b90600052602060002090601f01602090048101928261409957600085556140df565b82601f106140b257805160ff19168380011785556140df565b828001600101855582156140df579182015b828111156140df5782518255916020019190600101906140c4565b506140eb92915061413e565b5090565b6040518061012001604052806000801916815260200160608152602001600081526020016000815260200160008152602001600081526020016060815260200160608152602001600081525090565b5b808211156140eb576000815560010161413f565b803561415e81614e97565b919050565b803561415e81614eac565b600082601f83011261417e578081fd5b813567ffffffffffffffff81111561419857614198614e81565b6141ab601f8201601f1916602001614d4a565b8181528460208386010111156141bf578283fd5b816020850160208301379081016020019190915292915050565b803560ff8116811461415e57600080fd5b6000602082840312156141fb578081fd5b81356139e881614e97565b600060208284031215614217578081fd5b81516139e881614e97565b60008060408385031215614234578081fd5b823561423f81614e97565b9150602083013561424f81614e97565b809150509250929050565b60008060006060848603121561426e578081fd5b833561427981614e97565b925060208481013567ffffffffffffffff80821115614296578384fd5b818701915087601f8301126142a9578384fd5b8135818111156142bb576142bb614e81565b8060051b6142ca858201614d4a565b8281528581019085870183870188018d10156142e4578889fd5b8893505b84841015614321578035868111156142fe57898afd5b61430c8e8a838b010161416e565b845250600193909301929187019187016142e8565b508098505050505050505061433860408501614153565b90509250925092565b60008060408385031215614353578182fd5b823561435e81614e97565b9150602083013561424f81614eac565b60008060008060808587031215614383578081fd5b843561438e81614e97565b9350602085013592506143a3604086016141d9565b91506143b1606086016141d9565b905092959194509250565b6000602082840312156143cd578081fd5b81356139e881614eac565b6000602082840312156143e9578081fd5b81516139e881614eac565b600060208284031215614405578081fd5b5035919050565b600080600080600060a08688031215614423578081fd5b85359450602086013567ffffffffffffffff80821115614441578283fd5b61444d89838a0161416e565b95506040880135915080821115614462578283fd5b61446e89838a0161416e565b945060608801359350608088013591508082111561448a578283fd5b506144978882890161416e565b9150509295509295909350565b600080600080600080600060e0888a0312156144be578182fd5b87359650602088013567ffffffffffffffff808211156144dc578384fd5b6144e88b838c0161416e565b975060408a01359150808211156144fd578384fd5b6145098b838c0161416e565b965060608a013591508082111561451e578384fd5b61452a8b838c0161416e565b955060808a0135945060a08a0135935060c08a013591508082111561454d578283fd5b5061455a8a828b0161416e565b91505092959891949750929550565b6000806000806000806000806000806101408b8d031215614588578384fd5b8a35995060208b013567ffffffffffffffff808211156145a6578586fd5b6145b28e838f0161416e565b9a5060408d01359150808211156145c7578586fd5b6145d38e838f0161416e565b995060608d0135985060808d0135975060a08d0135965060c08d01359150808211156145fd578586fd5b6146098e838f0161416e565b955060e08d013591508082111561461e578485fd5b5061462b8d828e0161416e565b93505061463b6101008c01614163565b91506101208b013590509295989b9194979a5092959850565b600060208284031215614665578081fd5b813567ffffffffffffffff81111561467b578182fd5b6146878482850161416e565b949350505050565b600080604083850312156146a1578182fd5b823567ffffffffffffffff8111156146b7578283fd5b6146c38582860161416e565b925050602083013561424f81614eac565b6000602082840312156146e5578081fd5b5051919050565b6000815180845260208085019450808401835b8381101561471b578151875295820195908201906001016146ff565b509495945050505050565b6000815180845261473e816020860160208601614de9565b601f01601f19169290920160200192915050565b600061012082518452602083015181602086015261477282860182614726565b91505060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015184820360c08601526147b48282614726565b91505060e083015184820360e08601526147ce8282614726565b610100948501519590940194909452509092915050565b600082516147f7818460208701614de9565b9190910192915050565b60008351614813818460208801614de9565b630103b39960e51b9083019081528351614834816004840160208801614de9565b01600401949350505050565b60018060a01b038616815284602082015260a06040820152600061486760a0830186614752565b828103606084015261487981866146ec565b9050828103608084015261488d81856146ec565b98975050505050505050565b6020815260006139e860208301846146ec565b8481526001600160a01b0384166020820152604081018390526101008101611ae46060830184805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b600061010086835285602084015261494c6040840186805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b8060e084015261495e818401856146ec565b979650505050505050565b8381526060602082015260006149826060830185614726565b82810360408401526149948185614726565b9695505050505050565b86815260c0602082015260006149b760c0830188614726565b86604084015285606084015284608084015282810360a08401526149db81856146ec565b9998505050505050505050565b60006101208b8352806020840152614a028184018c614726565b90508960408401528860608401528760808401528660a084015282810360c0840152614a2e8187614726565b905082810360e0840152614a428186614726565b915050826101008301529a9950505050505050505050565b85815284602082015283604082015260a060608201526000614a7f60a0830185614752565b828103608084015261488d81856146ec565b848152602081018490526040810183905260e08101611ae460608301848051825260ff602082015116602083015260ff604082015116604083015260ff60608201511660608301525050565b848152836020820152826040820152608060608201528151608082015260006020830151606060a0840152614b1560e0840182614726565b90506040840151607f198483030160c085015261488d8282614726565b848152836020820152608060408201526000614b516080830185614726565b8281036060840152835160c08252614b6c60c0830182614726565b9050602085015160208301526040850151604083015260608501518282036060840152614b998282614726565b91505060808501518282036080840152614bb38282614726565b91505060a085015182820360a08401526149db8282614726565b6020815260006139e86020830184614726565b604081526000614bf36040830185614726565b905082151560208301529392505050565b60c081526000614c1760c0830189614726565b8760208401528660408401528281036060840152614c358187614726565b90508281036080840152614c498186614726565b905082810360a08401526149db8185614726565b6020808252600e908201526d24b73b30b634b21031b0b63632b960911b604082015260600190565b60208082526023908201527f4f6e6c7920777261707065722063616e2063616c6c20746869732066756e637460408201526234b7b760e91b606082015260800190565b6020808252601b908201527f4d61726b6574207265736f6c766564206f722063616e63656c65640000000000604082015260600190565b6020815260006139e86020830184614752565b60808101610d5d82848051825260ff602082015116602083015260ff604082015116604083015260ff60608201511660608301525050565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d7357614d73614e81565b604052919050565b60008219821115614d8e57614d8e614e6b565b500190565b600082614dae57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615614dcd57614dcd614e6b565b500290565b600082821015614de457614de4614e6b565b500390565b60005b83811015614e04578181015183820152602001614dec565b838111156110535750506000910152565b600181811c90821680614e2957607f821691505b60208210811415614e4a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415614e6457614e64614e6b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c2457600080fd5b8015158114610c2457600080fdfea264697066735822122039f147c6dc05f94aa74b62a345baa572f9dc1d3ec7470021f6899fb0d032b8b664736f6c63430008040033
Loading...
Loading
Loading...
Loading
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.