Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SportsAMMV2Data
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 100 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../../utils/proxy/ProxyOwned.sol";
import "../../utils/proxy/ProxyPausable.sol";
import "../../interfaces/ISportsAMMV2.sol";
import "../../interfaces/ISportsAMMV2RiskManager.sol";
import "../../interfaces/ISportsAMMV2ResultManager.sol";
import "../../interfaces/IFreeBetsHolder.sol";
import "./../AMM/Ticket.sol";
contract SportsAMMV2Data is Initializable, ProxyOwned, ProxyPausable {
/* ========== STRUCT VARIABLES ========== */
struct SportsAMMParameters {
uint minBuyInAmount;
uint maxTicketSize;
uint maxSupportedAmount;
uint maxSupportedOdds;
uint safeBoxFee;
bool paused;
uint maxAllowedSystemCombinations;
}
struct MarketData {
bytes32 gameId;
uint16 sportId;
uint16 typeId;
uint maturity;
int24 line;
uint24 playerId;
uint8 position;
uint odd;
ISportsAMMV2.CombinedPosition[] combinedPositions;
}
struct MarketResult {
ISportsAMMV2ResultManager.MarketPositionStatus status;
int24[] results;
}
struct TicketData {
address id;
MarketData[] marketsData;
MarketResult[] marketsResult;
address collateral;
address ticketOwner;
uint buyInAmount;
uint fees;
uint totalQuote;
uint numOfMarkets;
uint expiry;
uint createdAt;
bool resolved;
bool paused;
bool cancelled;
bool isLost;
bool isUserTheWinner;
bool isExercisable;
uint finalPayout;
bool isLive;
bool isSystem;
uint8 systemBetDenominator;
bool isSGP;
}
struct TicketMarketInfo {
bytes32 gameId;
uint16 typeId;
uint24 playerId;
int24 line;
}
struct MarketStakeCalculationInput {
bytes32 gameId;
uint16 sportId;
uint16 typeId;
uint24 playerId;
int24 line;
uint maturity;
bool isLive;
uint8 position;
uint odds; // implied odds in 18 decimals
}
enum ResultType {
Unassigned,
ExactPosition,
OverUnder,
CombinedPositions
}
/* ========== STATE VARIABLES ========== */
ISportsAMMV2 public sportsAMM;
ISportsAMMV2RiskManager public riskManager;
function initialize(address _owner, ISportsAMMV2 _sportsAMM, ISportsAMMV2RiskManager _riskManager) external initializer {
setOwner(_owner);
sportsAMM = _sportsAMM;
riskManager = _riskManager;
}
/**
* @notice Retrieves the parameters used by the SportsAMM contract.
* @dev Returns a struct containing various configurable parameters for the SportsAMM.
* @return A `SportsAMMParameters` struct containing:
* - `minBuyInAmount`: Minimum buy-in amount.
* - `maxTicketSize`: Maximum size of a single ticket.
* - `maxSupportedAmount`: Maximum amount supported by the AMM.
* - `maxSupportedOdds`: Maximum odds supported by the AMM.
* - `safeBoxFee`: Fee for the safe box.
* - `paused`: Whether the SportsAMM is currently paused.
* - `maxAllowedSystemCombinations`: Maximum allowed system combinations.
*/
function getSportsAMMParameters() external view returns (SportsAMMParameters memory) {
return
SportsAMMParameters(
riskManager.minBuyInAmount(),
riskManager.maxTicketSize(),
riskManager.maxSupportedAmount(),
riskManager.maxSupportedOdds(),
sportsAMM.safeBoxFee(),
sportsAMM.paused(),
riskManager.maxAllowedSystemCombinations()
);
}
/**
* @notice Retrieves data for the specified tickets.
* @dev Fetches ticket information for a given array of ticket addresses.
* @param ticketsArray An array of ticket addresses to retrieve data for.
* @return An array of `TicketData` containing details for each ticket.
*/
function getTicketsData(address[] calldata ticketsArray) external view returns (TicketData[] memory) {
return _getTicketsData(ticketsArray);
}
/**
* @notice Retrieves active ticket data for a specific user within a paginated range.
* @dev Fetches data for active tickets, free bets, and staking proxy tickets.
* @param user The address of the user.
* @param _startIndex The starting index for pagination.
* @param _pageSize The number of entries to fetch in the current page.
* @return ticketsData Active tickets data.
* @return freeBetsData Free bets data.
* @return stakingBettingProxyData Staking proxy tickets data.
*/
function getActiveTicketsDataPerUser(
address user,
uint _startIndex,
uint _pageSize
)
external
view
returns (
TicketData[] memory ticketsData,
TicketData[] memory freeBetsData,
TicketData[] memory stakingBettingProxyData
)
{
address[] memory freeBetsArray = sportsAMM.freeBetsHolder().getActiveTicketsPerUser(_startIndex, _pageSize, user);
address[] memory ticketsArray = sportsAMM.manager().getActiveTicketsPerUser(_startIndex, _pageSize, user);
ticketsData = _getTicketsData(ticketsArray);
freeBetsData = _getTicketsData(freeBetsArray);
if (address(sportsAMM.stakingThalesBettingProxy()) != address(0)) {
address[] memory stakingBettingProxyArray = sportsAMM.stakingThalesBettingProxy().getActiveTicketsPerUser(
_startIndex,
_pageSize,
user
);
stakingBettingProxyData = _getTicketsData(stakingBettingProxyArray);
}
}
/**
* @notice Retrieves free bets data for a specific user.
* @dev Fetches free bets data for a given user and collateral addresses.
* @param user The address of the user.
* @param collateralAddresses An array of collateral addresses to retrieve free bets data for.
* @return freeBetsAmountPerCollateral An array of free bets amounts for each collateral address.
* @return freeBetsExpiryPerCollateral An array of free bets expiries for each collateral address.
*/
function getFreeBetsDataPerUser(
address user,
address[] memory collateralAddresses
) external view returns (uint[] memory freeBetsAmountPerCollateral, uint[] memory freeBetsExpiryPerCollateral) {
freeBetsAmountPerCollateral = new uint[](collateralAddresses.length);
freeBetsExpiryPerCollateral = new uint[](collateralAddresses.length);
IFreeBetsHolder freeBetsHolder = sportsAMM.freeBetsHolder();
uint freeBetExpirationUpgrade = freeBetsHolder.freeBetExpirationUpgrade();
uint freeBetExpirationPeriod = freeBetsHolder.freeBetExpirationPeriod();
for (uint i = 0; i < collateralAddresses.length; i++) {
freeBetsAmountPerCollateral[i] = freeBetsHolder.balancePerUserAndCollateral(user, collateralAddresses[i]);
uint userFreeBetExpiration = freeBetsHolder.freeBetExpiration(user, collateralAddresses[i]);
if (userFreeBetExpiration == 0) {
userFreeBetExpiration = freeBetExpirationUpgrade + freeBetExpirationPeriod > block.timestamp
? freeBetExpirationUpgrade + freeBetExpirationPeriod - block.timestamp
: 0;
} else {
userFreeBetExpiration = userFreeBetExpiration > block.timestamp
? userFreeBetExpiration - block.timestamp
: 0;
}
freeBetsExpiryPerCollateral[i] = userFreeBetExpiration;
}
}
/**
* @notice Retrieves resolved ticket data for a specific user within a paginated range.
* @dev Fetches data for resolved tickets, free bets, and staking proxy tickets.
* @param user The address of the user.
* @param _startIndex The starting index for pagination.
* @param _pageSize The number of entries to fetch in the current page.
* @return ticketsData Resolved tickets data.
* @return freeBetsData Free bets data.
* @return stakingBettingProxyData Staking proxy tickets data.
*/
function getResolvedTicketsDataPerUser(
address user,
uint _startIndex,
uint _pageSize
)
external
view
returns (
TicketData[] memory ticketsData,
TicketData[] memory freeBetsData,
TicketData[] memory stakingBettingProxyData
)
{
address[] memory freeBetsArray = sportsAMM.freeBetsHolder().getResolvedTicketsPerUser(_startIndex, _pageSize, user);
address[] memory ticketsArray = sportsAMM.manager().getResolvedTicketsPerUser(_startIndex, _pageSize, user);
ticketsData = _getTicketsData(ticketsArray);
freeBetsData = _getTicketsData(freeBetsArray);
if (address(sportsAMM.stakingThalesBettingProxy()) != address(0)) {
address[] memory stakingBettingProxyArray = sportsAMM.stakingThalesBettingProxy().getResolvedTicketsPerUser(
_startIndex,
_pageSize,
user
);
stakingBettingProxyData = _getTicketsData(stakingBettingProxyArray);
}
}
/**
* @notice Retrieves ticket data for a specific game within a paginated range.
* @dev Fetches ticket information for tickets associated with the given game ID.
* @param gameId The ID of the game to retrieve tickets for.
* @param _startIndex The starting index for pagination.
* @param _pageSize The number of entries to fetch in the current page.
* @return An array of `TicketData` containing details for the tickets of the specified game.
*/
function getTicketsDataPerGame(
bytes32 gameId,
uint _startIndex,
uint _pageSize
) external view returns (TicketData[] memory) {
uint numOfTicketsPerGame = sportsAMM.manager().numOfTicketsPerGame(gameId);
_pageSize = _pageSize > numOfTicketsPerGame ? numOfTicketsPerGame : _pageSize;
address[] memory ticketsArray = sportsAMM.manager().getTicketsPerGame(_startIndex, _pageSize, gameId);
return _getTicketsData(ticketsArray);
}
/**
* @notice Retrieves active game IDs and their associated tickets within a paginated range.
* @dev Filters only active game IDs and retrieves tickets for each game ID.
* @param _gameIds An array of game IDs to filter and process.
* @param _startIndex The starting index for pagination.
* @param _pageSize The number of entries to fetch in the current page.
* @return activeGameIds An array of active game IDs.
* @return numOfTicketsPerGameId An array of ticket counts for each active game ID.
* @return ticketsPerGameId A 2D array of ticket addresses for each active game ID.
*/
function getOnlyActiveGameIdsAndTicketsOf(
bytes32[] memory _gameIds,
uint _startIndex,
uint _pageSize
)
external
view
returns (bytes32[] memory activeGameIds, uint[] memory numOfTicketsPerGameId, address[][] memory ticketsPerGameId)
{
(activeGameIds, numOfTicketsPerGameId, ticketsPerGameId) = _getOnlyActiveGameIdsAndTicketsOf(
_gameIds,
_startIndex,
_pageSize
);
}
/**
* @notice Retrieves all active game IDs, type IDs, player IDs, and lines for the specified game IDs within a paginated range.
* @dev Processes active game IDs and tickets, retrieving unique type IDs, player IDs, and market lines.
* @param _gameIds An array of game IDs to filter and process.
* @param _startIndex The starting index for pagination.
* @param _pageSize The number of game IDs to process in the current page.
* @return finalTicketsInfo An array of TicketMarketInfo containing active market details for the specified game IDs.
*/
function getAllActiveGameIdsTypeIdsPlayerIdsLinesForGameIds(
bytes32[] memory _gameIds,
uint _startIndex,
uint _pageSize
) external view returns (TicketMarketInfo[] memory finalTicketsInfo) {
bytes32[] memory activeGameIds;
uint[] memory numOfTicketsPerGameId;
address[][] memory ticketsPerGameId;
(activeGameIds, numOfTicketsPerGameId, ticketsPerGameId) = _getOnlyActiveGameIdsAndTicketsOf(
_gameIds,
_startIndex,
_pageSize
);
// Get number of matches
uint matchCounter;
for (uint i = 0; i < activeGameIds.length; i++) {
for (uint j = 0; j < numOfTicketsPerGameId[i]; j++) {
matchCounter += Ticket(ticketsPerGameId[i][j]).numOfMarkets();
}
}
TicketMarketInfo[] memory ticketsMarkets = new TicketMarketInfo[](matchCounter);
matchCounter = 0;
MarketData memory marketData;
for (uint i = 0; i < activeGameIds.length; i++) {
for (uint j = 0; j < numOfTicketsPerGameId[i]; j++) {
Ticket ticket = Ticket(ticketsPerGameId[i][j]);
for (uint t = 0; t < ticket.numOfMarkets(); t++) {
marketData = _getMarketData(ticket, t);
ticketsMarkets[matchCounter].gameId = marketData.gameId;
ticketsMarkets[matchCounter].typeId = marketData.typeId;
ticketsMarkets[matchCounter].playerId = marketData.playerId;
ticketsMarkets[matchCounter].line = marketData.line;
matchCounter++;
}
}
}
(matchCounter, numOfTicketsPerGameId) = _getUniqueTypeIdsPlayerIds(ticketsMarkets);
finalTicketsInfo = new TicketMarketInfo[](matchCounter);
matchCounter = 0;
for (uint i = 0; i < ticketsMarkets.length; i++) {
if (numOfTicketsPerGameId[i] == 1) {
finalTicketsInfo[matchCounter] = ticketsMarkets[i];
++matchCounter;
}
}
}
/**
* @notice Checks if specified markets are resolved.
* @dev Determines the resolution status of markets by querying the result manager.
* @param _gameIds An array of game IDs representing the markets.
* @param _typeIds An array of type IDs associated with the markets.
* @param _playerIds An array of player IDs associated with the markets.
* @param _lines An array of market lines for the specified markets.
* @return resolvedMarkets An array of booleans indicating whether each market is resolved.
*/
function areMarketsResolved(
bytes32[] memory _gameIds,
uint16[] memory _typeIds,
uint24[] memory _playerIds,
int24[] memory _lines
) external view returns (bool[] memory resolvedMarkets) {
if (_gameIds.length == _typeIds.length && _typeIds.length == _playerIds.length) {
resolvedMarkets = new bool[](_gameIds.length);
for (uint i = 0; i < _gameIds.length; i++) {
uint8 resultType = sportsAMM.resultManager().resultTypePerMarketType(_typeIds[i]);
if (resultType != uint8(ResultType.CombinedPositions)) {
ISportsAMMV2.CombinedPosition[] memory combinedPositions = new ISportsAMMV2.CombinedPosition[](0);
resolvedMarkets[i] = sportsAMM.resultManager().isMarketResolved(
_gameIds[i],
_typeIds[i],
_playerIds[i],
_lines[i],
combinedPositions
);
}
}
}
}
/**
* @notice Retrieves the results for the specified markets.
* @dev Queries the result manager for results based on game, type, and player IDs.
* @param _gameIds An array of game IDs representing the markets.
* @param _typeIds An array of type IDs associated with the markets.
* @param _playerIds An array of player IDs associated with the markets.
* @return resultsForMarkets A 2D array containing market results for each specified market.
*/
function getResultsForMarkets(
bytes32[] memory _gameIds,
uint16[] memory _typeIds,
uint24[] memory _playerIds
) external view returns (int24[][] memory resultsForMarkets) {
if (_gameIds.length == _typeIds.length && _typeIds.length == _playerIds.length) {
resultsForMarkets = new int24[][](_gameIds.length);
for (uint i = 0; i < _gameIds.length; i++) {
resultsForMarkets[i] = sportsAMM.resultManager().getResultsPerMarket(
_gameIds[i],
_typeIds[i],
_playerIds[i]
);
}
}
}
/**
* @notice Retrieves the amount spent on specified games.
* @dev Queries the risk manager for the spent amounts for each game ID.
* @param _gameIds An array of game IDs to calculate the spent amounts for.
* @return spentAmounts An array of spent amounts corresponding to each game ID.
*/
function getSpentOnGames(bytes32[] calldata _gameIds) external view returns (uint[] memory spentAmounts) {
spentAmounts = new uint[](_gameIds.length);
for (uint i = 0; i < _gameIds.length; i++) {
spentAmounts[i] = riskManager.spentOnGame(_gameIds[i]);
}
}
/**
* @notice Retrieves the risk amounts for specific market positions.
* @dev This function queries the risk manager to get the risk per market type and position.
* @param _gameIds An array of game IDs representing the markets.
* @param _typeIds An array of type IDs representing the types of the markets.
* @param _playerIds An array of player IDs associated with the markets.
* @param _positions An array of positions in the markets.
* @return riskAmounts An array of risk amounts corresponding to the provided market details.
*/
function getRiskOnMarkets(
bytes32[] calldata _gameIds,
uint[] calldata _typeIds,
uint[] calldata _playerIds,
uint[] calldata _positions
) external view returns (int[] memory riskAmounts) {
riskAmounts = new int[](_gameIds.length);
for (uint i = 0; i < _gameIds.length; i++) {
riskAmounts[i] = riskManager.riskPerMarketTypeAndPosition(
_gameIds[i],
_typeIds[i],
_playerIds[i],
_positions[i]
);
}
}
/**
* @notice Calculates max stake and available liquidity for each market+position input.
* @dev Returns two arrays: maxStake and availableLiquidity, both on decimals matching the default collateral.
* @param inputs Array of market definitions and odds.
* @return maxStakes Array of maximum stake values.
* @return availableLiquidity Array of available risk the house is willing to take.
*/
function getMaxStakeAndLiquidityBatch(
MarketStakeCalculationInput[] calldata inputs
) external view returns (uint[] memory maxStakes, uint[] memory availableLiquidity) {
uint len = inputs.length;
maxStakes = new uint[](len);
availableLiquidity = new uint[](len);
for (uint i = 0; i < len; i++) {
maxStakes[i] = _calculateMaxStakeAndLiquidity(inputs[i], availableLiquidity, i);
}
}
function _calculateMaxStakeAndLiquidity(
MarketStakeCalculationInput calldata input,
uint[] memory availableLiquidity,
uint index
) internal view returns (uint) {
// Fetch position-level cap and risk
uint cap = riskManager.calculateCapToBeUsed(
input.gameId,
input.sportId,
input.typeId,
input.playerId,
input.line,
input.maturity,
input.isLive
);
int positionRisk = riskManager.riskPerMarketTypeAndPosition(
input.gameId,
input.typeId,
input.playerId,
input.position
);
int availablePosRisk = int(cap) - positionRisk;
uint availablePerPosition = availablePosRisk > 0 ? uint(availablePosRisk) : 0;
availableLiquidity[index] = availablePerPosition;
// Fetch game-level cap and spent
uint totalGameCap = riskManager.calculateTotalRiskOnGame(input.gameId, input.sportId, input.maturity);
uint spent = riskManager.spentOnGame(input.gameId);
uint availablePerGame = totalGameCap > spent ? totalGameCap - spent : 0;
if (input.odds > 0 && input.odds < 1e18) {
uint denominator = 1e18 - input.odds;
uint maxStakePos = (availablePerPosition * input.odds) / denominator;
uint maxStakeGame = (availablePerGame * input.odds) / denominator;
return maxStakePos < maxStakeGame ? maxStakePos : maxStakeGame;
} else {
return 0;
}
}
/**
* @notice Calculates the caps for specific markets based on their details.
* @dev This function queries the risk manager to determine the cap to be used for each market.
* @param _gameIds An array of game IDs representing the markets.
* @param _sportIds An array of sport IDs associated with the markets.
* @param _typeIds An array of type IDs representing the types of the markets.
* @param _maturities An array of maturities (timestamps) for the markets.
* @return caps An array of cap values corresponding to the provided market details.
*/
function getCapsPerMarkets(
bytes32[] calldata _gameIds,
uint16[] calldata _sportIds,
uint16[] calldata _typeIds,
uint[] calldata _maturities
) external view returns (uint[] memory caps) {
caps = new uint[](_gameIds.length);
for (uint i = 0; i < _gameIds.length; i++) {
caps[i] = riskManager.calculateCapToBeUsed(_gameIds[i], _sportIds[i], _typeIds[i], 0, 0, _maturities[i], false);
}
}
function _getTicketsData(address[] memory ticketsArray) internal view returns (TicketData[] memory) {
TicketData[] memory tickets = new TicketData[](ticketsArray.length);
for (uint i = 0; i < ticketsArray.length; i++) {
Ticket ticket = Ticket(ticketsArray[i]);
MarketData[] memory marketsData = new MarketData[](ticket.numOfMarkets());
MarketResult[] memory marketsResult = new MarketResult[](ticket.numOfMarkets());
for (uint j = 0; j < ticket.numOfMarkets(); j++) {
marketsData[j] = _getMarketData(ticket, j);
marketsResult[j] = _getMarketResult(ticket, j);
}
bool isSystem = sportsAMM.manager().isSystemTicket(address(ticket));
bool isSGP = sportsAMM.manager().isSGPTicket(address(ticket));
tickets[i] = TicketData(
ticketsArray[i],
marketsData,
marketsResult,
address(ticket.collateral()),
ticket.ticketOwner(),
ticket.buyInAmount(),
ticket.fees(),
ticket.totalQuote(),
ticket.numOfMarkets(),
ticket.expiry(),
ticket.createdAt(),
ticket.resolved(),
ticket.paused(),
ticket.cancelled(),
ticket.isTicketLost(),
ticket.isUserTheWinner(),
ticket.isTicketExercisable(),
ticket.finalPayout(),
ticket.isLive(),
isSystem,
isSystem ? ticket.systemBetDenominator() : 0,
isSGP
);
}
return tickets;
}
function _getMarketData(Ticket ticket, uint marketIndex) internal view returns (MarketData memory) {
(
bytes32 gameId,
uint16 sportId,
uint16 typeId,
uint maturity,
,
int24 line,
uint24 playerId,
uint8 position,
uint odd
) = ticket.markets(marketIndex);
ISportsAMMV2.CombinedPosition[] memory combinedPositions = ticket.getCombinedPositions(marketIndex);
return MarketData(gameId, sportId, typeId, maturity, line, playerId, position, odd, combinedPositions);
}
function _getMarketResult(Ticket ticket, uint marketIndex) internal view returns (MarketResult memory) {
(bytes32 gameId, , uint16 typeId, , , int24 line, uint24 playerId, uint8 position, ) = ticket.markets(marketIndex);
ISportsAMMV2.CombinedPosition[] memory combinedPositions = ticket.getCombinedPositions(marketIndex);
ISportsAMMV2ResultManager.MarketPositionStatus status = sportsAMM.resultManager().getMarketPositionStatus(
gameId,
typeId,
playerId,
line,
position,
combinedPositions
);
int24[] memory results = sportsAMM.resultManager().getResultsPerMarket(gameId, typeId, playerId);
return MarketResult(status, results);
}
function _getOnlyActiveGameIdsAndTicketsOf(
bytes32[] memory _gameIds,
uint _startIndex,
uint _pageSize
)
internal
view
returns (bytes32[] memory activeGameIds, uint[] memory numOfTicketsPerGameId, address[][] memory ticketsPerGameId)
{
_pageSize = _pageSize > _gameIds.length ? _gameIds.length : _pageSize;
uint[] memory ticketsPerGame = new uint[](_pageSize);
uint counter;
for (uint i = _startIndex; i < _pageSize; i++) {
uint numOfTicketsPerGame = sportsAMM.manager().numOfTicketsPerGame(_gameIds[i]);
if (numOfTicketsPerGame > 0) {
counter++;
ticketsPerGame[i] = numOfTicketsPerGame;
}
}
activeGameIds = new bytes32[](counter);
numOfTicketsPerGameId = new uint[](counter);
ticketsPerGameId = new address[][](counter);
counter = 0;
for (uint i = 0; i < _gameIds.length; i++) {
if (ticketsPerGame[i] > 0) {
activeGameIds[counter] = _gameIds[i];
numOfTicketsPerGameId[counter] = ticketsPerGame[i];
ticketsPerGameId[counter] = sportsAMM.manager().getTicketsPerGame(0, ticketsPerGame[i], _gameIds[i]);
counter++;
}
}
}
function _getUniqueTypeIdsPlayerIds(
TicketMarketInfo[] memory ticketsMarkets
) internal pure returns (uint numOfUniqueMatches, uint[] memory uniqueIndexes) {
bytes32[] memory uniqueHashes = new bytes32[](ticketsMarkets.length);
uniqueIndexes = new uint[](ticketsMarkets.length);
bytes32 currentHash;
bool isUnique;
for (uint i = 0; i < ticketsMarkets.length; i++) {
currentHash = keccak256(abi.encode(ticketsMarkets[i]));
isUnique = true;
for (uint j = 0; j < numOfUniqueMatches; j++) {
if (currentHash == uniqueHashes[j]) {
isUnique = false;
break;
}
}
if (isUnique) {
uniqueHashes[numOfUniqueMatches] = currentHash;
uniqueIndexes[i] = 1;
numOfUniqueMatches++;
}
}
}
function setSportsAMM(ISportsAMMV2 _sportsAMM) external onlyOwner {
sportsAMM = _sportsAMM;
emit SportAMMChanged(address(_sportsAMM));
}
function setRiskManager(ISportsAMMV2RiskManager _riskManager) external onlyOwner {
riskManager = _riskManager;
emit RiskManagerChanged(address(_riskManager));
}
event SportAMMChanged(address sportsAMM);
event RiskManagerChanged(address riskManager);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @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 proxied contracts do not make use of 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.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* 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 prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
// internal
import "../../interfaces/ISportsAMMV2Manager.sol";
import "../../interfaces/ISportsAMMV2.sol";
contract Ticket {
using SafeERC20 for IERC20;
uint private constant ONE = 1e18;
enum Phase {
Trading,
Maturity,
Expiry
}
struct MarketData {
bytes32 gameId;
uint16 sportId;
uint16 typeId;
uint maturity;
uint8 status;
int24 line;
uint24 playerId;
uint8 position;
uint odd;
ISportsAMMV2.CombinedPosition[] combinedPositions;
}
struct TicketInit {
MarketData[] _markets;
uint _buyInAmount;
uint _fees;
uint _totalQuote;
address _sportsAMM;
address _ticketOwner;
IERC20 _collateral;
uint _expiry;
bool _isLive;
uint8 _systemBetDenominator;
bool _isSGP;
}
ISportsAMMV2 public sportsAMM;
address public ticketOwner;
IERC20 public collateral;
uint public buyInAmount;
uint public fees;
uint public totalQuote;
uint public numOfMarkets;
uint public expiry;
uint public createdAt;
bool public resolved;
bool public paused;
bool public initialized;
bool public cancelled;
bool public isLive;
mapping(uint => MarketData) public markets;
uint public finalPayout;
bool public isSystem;
uint8 public systemBetDenominator;
bool public isSGP;
bool public isMarkedAsLost;
/* ========== CONSTRUCTOR ========== */
/// @notice initialize the ticket contract
/// @param params all parameters for Init
function initialize(TicketInit calldata params) external {
require(!initialized, "Ticket already initialized");
initialized = true;
sportsAMM = ISportsAMMV2(params._sportsAMM);
numOfMarkets = params._markets.length;
for (uint i = 0; i < numOfMarkets; i++) {
markets[i] = params._markets[i];
}
buyInAmount = params._buyInAmount;
fees = params._fees;
totalQuote = params._totalQuote;
ticketOwner = params._ticketOwner;
collateral = params._collateral;
expiry = params._expiry;
isLive = params._isLive;
createdAt = block.timestamp;
systemBetDenominator = params._systemBetDenominator;
isSystem = systemBetDenominator > 0;
isSGP = params._isSGP;
}
/* ========== EXTERNAL READ FUNCTIONS ========== */
/// @notice checks if the user lost the ticket
/// @return isTicketLost true/false
function isTicketLost() public view returns (bool) {
if (isMarkedAsLost) {
return true;
} else {
uint lostMarketsCount = 0;
for (uint i = 0; i < numOfMarkets; i++) {
(bool isMarketResolved, bool isWinningMarketPosition) = sportsAMM
.resultManager()
.isMarketResolvedAndPositionWinning(
markets[i].gameId,
markets[i].typeId,
markets[i].playerId,
markets[i].line,
markets[i].position,
markets[i].combinedPositions
);
if (isMarketResolved && !isWinningMarketPosition) {
if (!isSystem) {
return true;
} else {
lostMarketsCount++;
if (lostMarketsCount > (numOfMarkets - systemBetDenominator)) {
return true;
}
}
}
}
return false;
}
}
/// @notice checks are all markets of the ticket resolved
/// @return areAllMarketsResolved true/false
function areAllMarketsResolved() public view returns (bool) {
for (uint i = 0; i < numOfMarkets; i++) {
if (
!sportsAMM.resultManager().isMarketResolved(
markets[i].gameId,
markets[i].typeId,
markets[i].playerId,
markets[i].line,
markets[i].combinedPositions
)
) {
return false;
}
}
return true;
}
/// @notice checks if the user won the ticket
/// @return hasUserWon true/false
function isUserTheWinner() external view returns (bool hasUserWon) {
hasUserWon = _isUserTheWinner();
}
/// @notice checks if the ticket ready to be exercised
/// @return isExercisable true/false
function isTicketExercisable() public view returns (bool isExercisable) {
isExercisable = !resolved && (areAllMarketsResolved() || isTicketLost());
}
/// @notice gets current phase of the ticket
/// @return phase ticket phase
function phase() public view returns (Phase) {
return
isTicketExercisable() || resolved ? ((expiry < block.timestamp) ? Phase.Expiry : Phase.Maturity) : Phase.Trading;
}
/// @notice gets combined positions of the game
/// @return combinedPositions game combined positions
function getCombinedPositions(
uint _marketIndex
) public view returns (ISportsAMMV2.CombinedPosition[] memory combinedPositions) {
return markets[_marketIndex].combinedPositions;
}
/// @notice return the payout for this ticket
/// @return systemBetPayout the payout for this ticket
function getSystemBetPayout() external view returns (uint systemBetPayout) {
systemBetPayout = _getSystemBetPayout();
}
/* ========== EXTERNAL WRITE FUNCTIONS ========== */
/// @notice exercise ticket
function exercise(address _exerciseCollateral) external onlyAMM notPaused returns (uint) {
bool isExercisable = isTicketExercisable();
require(isExercisable, "Ticket not exercisable yet");
uint payoutWithFees = collateral.balanceOf(address(this));
uint payout = payoutWithFees - fees;
bool isCancelled = false;
if (_isUserTheWinner()) {
finalPayout = payout;
isCancelled = true;
for (uint i = 0; i < numOfMarkets; i++) {
bool isCancelledMarketPosition = sportsAMM.resultManager().isCancelledMarketPosition(
markets[i].gameId,
markets[i].typeId,
markets[i].playerId,
markets[i].line,
markets[i].position,
markets[i].combinedPositions
);
if (isCancelledMarketPosition) {
if (isSGP) {
isCancelled = true;
break;
}
finalPayout = (finalPayout * markets[i].odd) / ONE;
} else {
isCancelled = false;
}
}
finalPayout = isCancelled ? buyInAmount : (isSystem ? _getSystemBetPayout() : finalPayout);
collateral.safeTransfer(
_exerciseCollateral == address(0) || _exerciseCollateral == address(collateral)
? address(ticketOwner)
: address(sportsAMM),
finalPayout
);
}
// if user is lost or if the user payout was less than anticipated due to cancelled games, send the remainder to AMM
uint balance = collateral.balanceOf(address(this));
if (balance != 0) {
collateral.safeTransfer(address(sportsAMM), balance);
}
_resolve(!isTicketLost(), isCancelled);
return finalPayout;
}
/// @notice expire ticket
function expire(address _beneficiary) external onlyAMM {
require(phase() == Phase.Expiry, "Ticket not in expiry phase");
require(!resolved, "Can't expire resolved ticket");
emit Expired(_beneficiary);
_selfDestruct(_beneficiary);
}
/// @notice cancel the ticket
function cancel() external onlyAMM notPaused returns (uint) {
finalPayout = buyInAmount;
collateral.safeTransfer(address(ticketOwner), finalPayout);
uint balance = collateral.balanceOf(address(this));
if (balance != 0) {
collateral.safeTransfer(address(sportsAMM), balance);
}
_resolve(true, true);
return finalPayout;
}
/// @notice mark the ticket as lost
function markAsLost() external onlyAMM notPaused returns (uint) {
uint balance = collateral.balanceOf(address(this));
if (balance != 0) {
collateral.safeTransfer(address(sportsAMM), balance);
}
_resolve(false, false);
isMarkedAsLost = true;
return 0;
}
/// @notice withdraw collateral from the ticket
function withdrawCollateral(address recipient) external onlyAMM {
collateral.safeTransfer(recipient, collateral.balanceOf(address(this)));
}
/* ========== INTERNAL FUNCTIONS ========== */
function _resolve(bool _hasUserWon, bool _cancelled) internal {
resolved = true;
cancelled = _cancelled;
emit Resolved(_hasUserWon, _cancelled);
}
function _selfDestruct(address beneficiary) internal {
uint balance = collateral.balanceOf(address(this));
if (balance != 0) {
collateral.safeTransfer(beneficiary, balance);
}
}
function _isUserTheWinner() internal view returns (bool hasUserWon) {
if (areAllMarketsResolved()) {
hasUserWon = !isTicketLost();
}
}
/* ========== SETTERS ========== */
function setPaused(bool _paused) external {
require(msg.sender == address(sportsAMM.manager()), "Invalid sender");
if (paused == _paused) return;
paused = _paused;
emit PauseUpdated(_paused);
}
/* ========== SYSTEM BET UTILS ========== */
function _getSystemBetPayout() internal view returns (uint systemBetPayout) {
if (isSystem) {
uint8[][] memory systemCombinations = sportsAMM.riskManager().generateCombinations(
uint8(numOfMarkets),
systemBetDenominator
);
uint totalCombinations = systemCombinations.length;
uint buyinPerCombination = ((buyInAmount * ONE) / totalCombinations) / ONE;
bool[] memory winningMarkets = new bool[](numOfMarkets);
bool[] memory cancelledMarkets = new bool[](numOfMarkets);
for (uint i = 0; i < numOfMarkets; i++) {
if (
!sportsAMM.resultManager().isMarketResolved(
markets[i].gameId,
markets[i].typeId,
markets[i].playerId,
markets[i].line,
markets[i].combinedPositions
)
) {
return 0;
}
winningMarkets[i] = sportsAMM.resultManager().isWinningMarketPosition(
markets[i].gameId,
markets[i].typeId,
markets[i].playerId,
markets[i].line,
markets[i].position,
markets[i].combinedPositions
);
cancelledMarkets[i] = sportsAMM.resultManager().isCancelledMarketPosition(
markets[i].gameId,
markets[i].typeId,
markets[i].playerId,
markets[i].line,
markets[i].position,
markets[i].combinedPositions
);
}
// Loop through each stored combination
for (uint i = 0; i < totalCombinations; i++) {
uint8[] memory currentCombination = systemCombinations[i];
uint combinationQuote = ONE;
for (uint j = 0; j < currentCombination.length; j++) {
uint8 marketIndex = currentCombination[j];
if (winningMarkets[marketIndex]) {
if (!cancelledMarkets[marketIndex]) {
combinationQuote = (combinationQuote * markets[marketIndex].odd) / ONE;
}
} else {
combinationQuote = 0;
break;
}
}
if (combinationQuote > 0) {
uint combinationPayout = (buyinPerCombination * ONE) / combinationQuote;
systemBetPayout += combinationPayout;
}
}
uint maxPayout = (buyInAmount * ONE) / totalQuote;
if (systemBetPayout > maxPayout) {
systemBetPayout = maxPayout;
}
}
}
/* ========== MODIFIERS ========== */
modifier onlyAMM() {
require(msg.sender == address(sportsAMM), "Only the AMM may perform these methods");
_;
}
modifier notPaused() {
require(!paused, "Market paused");
_;
}
/* ========== EVENTS ========== */
event Resolved(bool isUserTheWinner, bool cancelled);
event Expired(address beneficiary);
event PauseUpdated(bool paused);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./IProxyBetting.sol";
interface IFreeBetsHolder is IProxyBetting {
function confirmLiveTrade(bytes32 requestId, address _createdTicket, uint _buyInAmount, address _collateral) external;
function confirmSGPTrade(bytes32 requestId, address _createdTicket, uint _buyInAmount, address _collateral) external;
function balancePerUserAndCollateral(address user, address collateral) external view returns (uint);
function freeBetExpiration(address user, address collateral) external view returns (uint);
function freeBetExpirationUpgrade() external view returns (uint);
function freeBetExpirationPeriod() external view returns (uint);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IProxyBetting {
function getActiveTicketsPerUser(uint _index, uint _pageSize, address _user) external view returns (address[] memory);
function numOfActiveTicketsPerUser(address _user) external view returns (uint);
function getResolvedTicketsPerUser(uint _index, uint _pageSize, address _user) external view returns (address[] memory);
function numOfResolvedTicketsPerUser(address _user) external view returns (uint);
function confirmTicketResolved(address _resolvedTicket) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/ISportsAMMV2Manager.sol";
import "../interfaces/ISportsAMMV2ResultManager.sol";
import "../interfaces/ISportsAMMV2RiskManager.sol";
import "../interfaces/ISportsAMMV2Manager.sol";
import "../interfaces/IFreeBetsHolder.sol";
import "../interfaces/IStakingThalesBettingProxy.sol";
interface ISportsAMMV2 {
enum TicketAction {
Exercise,
Cancel,
MarkLost
}
struct CombinedPosition {
uint16 typeId;
uint8 position;
int24 line;
}
struct TradeData {
bytes32 gameId;
uint16 sportId;
uint16 typeId;
uint maturity;
uint8 status;
int24 line;
uint24 playerId;
uint[] odds;
bytes32[] merkleProof;
uint8 position;
CombinedPosition[][] combinedPositions;
}
function defaultCollateral() external view returns (IERC20);
function manager() external view returns (ISportsAMMV2Manager);
function resultManager() external view returns (ISportsAMMV2ResultManager);
function safeBoxFee() external view returns (uint);
function handleTicketResolving(address _ticket, ISportsAMMV2.TicketAction action) external;
function riskManager() external view returns (ISportsAMMV2RiskManager);
function freeBetsHolder() external view returns (IFreeBetsHolder);
function stakingThalesBettingProxy() external view returns (IStakingThalesBettingProxy);
function tradeLive(
TradeData[] calldata _tradeData,
uint _buyInAmount,
uint _expectedQuote,
address _recipient,
address _referrer,
address _collateral
) external returns (address _createdTicket);
function trade(
TradeData[] calldata _tradeData,
uint _buyInAmount,
uint _expectedQuote,
uint _additionalSlippage,
address _referrer,
address _collateral,
bool _isEth
) external returns (address _createdTicket);
function tradeSystemBet(
TradeData[] calldata _tradeData,
uint _buyInAmount,
uint _expectedQuote,
uint _additionalSlippage,
address _referrer,
address _collateral,
bool _isEth,
uint8 _systemBetDenominator
) external returns (address _createdTicket);
function tradeSGP(
ISportsAMMV2.TradeData[] calldata _tradeData,
uint _buyInAmount,
uint _approvedQuote,
address _recipient,
address _referrer,
address _collateral
) external returns (address _createdTicket);
function rootPerGame(bytes32 game) external view returns (bytes32);
function getRootsPerGames(bytes32[] calldata _games) external view returns (bytes32[] memory _roots);
function paused() external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./ISportsAMMV2.sol";
interface ISportsAMMV2Manager {
enum Role {
ROOT_SETTING,
RISK_MANAGING,
MARKET_RESOLVING,
TICKET_PAUSER
}
function isWhitelistedAddress(address _address, Role role) external view returns (bool);
function decimals() external view returns (uint);
function feeToken() external view returns (address);
function isActiveTicket(address _ticket) external view returns (bool);
function getActiveTickets(uint _index, uint _pageSize) external view returns (address[] memory);
function numOfActiveTickets() external view returns (uint);
function getActiveTicketsPerUser(uint _index, uint _pageSize, address _user) external view returns (address[] memory);
function numOfActiveTicketsPerUser(address _user) external view returns (uint);
function getResolvedTicketsPerUser(uint _index, uint _pageSize, address _user) external view returns (address[] memory);
function numOfResolvedTicketsPerUser(address _user) external view returns (uint);
function getTicketsPerGame(uint _index, uint _pageSize, bytes32 _gameId) external view returns (address[] memory);
function numOfTicketsPerGame(bytes32 _gameId) external view returns (uint);
function isKnownTicket(address _ticket) external view returns (bool);
function sportsAMM() external view returns (address);
function getTicketsPerMarket(
uint _index,
uint _pageSize,
bytes32 _gameId,
uint _typeId,
uint _playerId
) external view returns (address[] memory);
function numOfTicketsPerMarket(bytes32 _gameId, uint _typeId, uint _playerId) external view returns (uint);
function addNewKnownTicket(ISportsAMMV2.TradeData[] memory _tradeData, address ticket, address user) external;
function resolveKnownTicket(address ticket, address ticketOwner) external;
function expireKnownTicket(address ticket, address ticketOwner) external;
function isSystemTicket(address _ticket) external view returns (bool);
function isSGPTicket(address _ticket) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./ISportsAMMV2.sol";
interface ISportsAMMV2ResultManager {
enum MarketPositionStatus {
Open,
Cancelled,
Winning,
Losing
}
function isMarketResolved(
bytes32 _gameId,
uint16 _typeId,
uint24 _playerId,
int24 _line,
ISportsAMMV2.CombinedPosition[] memory combinedPositions
) external view returns (bool isResolved);
function getMarketPositionStatus(
bytes32 _gameId,
uint16 _typeId,
uint24 _playerId,
int24 _line,
uint _position,
ISportsAMMV2.CombinedPosition[] memory _combinedPositions
) external view returns (MarketPositionStatus status);
function isWinningMarketPosition(
bytes32 _gameId,
uint16 _typeId,
uint24 _playerId,
int24 _line,
uint _position,
ISportsAMMV2.CombinedPosition[] memory _combinedPositions
) external view returns (bool isWinning);
function isCancelledMarketPosition(
bytes32 _gameId,
uint16 _typeId,
uint24 _playerId,
int24 _line,
uint _position,
ISportsAMMV2.CombinedPosition[] memory _combinedPositions
) external view returns (bool isCancelled);
function getResultsPerMarket(
bytes32 _gameId,
uint16 _typeId,
uint24 _playerId
) external view returns (int24[] memory results);
function resultTypePerMarketType(uint _typeId) external view returns (uint8 marketType);
function isMarketResolvedAndPositionWinning(
bytes32 _gameId,
uint16 _typeId,
uint24 _playerId,
int24 _line,
uint _position,
ISportsAMMV2.CombinedPosition[] memory _combinedPositions
) external view returns (bool isResolved, bool isWinning);
function setResultsPerMarkets(
bytes32[] memory _gameIds,
uint16[] memory _typeIds,
uint24[] memory _playerIds,
int24[][] memory _results
) external;
function isGameCancelled(bytes32 _gameId) external view returns (bool);
function cancelGames(bytes32[] memory _gameIds) external;
function cancelMarkets(
bytes32[] memory _gameIds,
uint16[] memory _typeIds,
uint24[] memory _playerIds,
int24[] memory _lines
) external;
function cancelMarket(bytes32 _gameId, uint16 _typeId, uint24 _playerId, int24 _line) external;
function cancelGame(bytes32 _gameId) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./ISportsAMMV2.sol";
interface ISportsAMMV2RiskManager {
struct TypeCap {
uint typeId;
uint cap;
}
struct CapData {
uint capPerSport;
uint capPerChild;
TypeCap[] capPerType;
}
struct DynamicLiquidityData {
uint cutoffTimePerSport;
uint cutoffDividerPerSport;
}
struct RiskData {
uint sportId;
CapData capData;
uint riskMultiplierPerSport;
DynamicLiquidityData dynamicLiquidityData;
}
enum RiskStatus {
NoRisk,
OutOfLiquidity,
InvalidCombination
}
function minBuyInAmount() external view returns (uint);
function maxTicketSize() external view returns (uint);
function maxSupportedAmount() external view returns (uint);
function maxSupportedOdds() external view returns (uint);
function maxAllowedSystemCombinations() external view returns (uint);
function expiryDuration() external view returns (uint);
function liveTradingPerSportAndTypeEnabled(uint _sportId, uint _typeId) external view returns (bool _enabled);
function calculateCapToBeUsed(
bytes32 _gameId,
uint16 _sportId,
uint16 _typeId,
uint24 _playerId,
int24 _line,
uint _maturity,
bool _isLive
) external view returns (uint cap);
function calculateTotalRiskOnGame(
bytes32 _gameId,
uint16 _sportId,
uint _maturity
) external view returns (uint totalRisk);
function checkRisks(
ISportsAMMV2.TradeData[] memory _tradeData,
uint _buyInAmount,
bool _isLive,
uint8 _systemBetDenominator
) external view returns (ISportsAMMV2RiskManager.RiskStatus riskStatus, bool[] memory isMarketOutOfLiquidity);
function checkLimits(
uint _buyInAmount,
uint _totalQuote,
uint _payout,
uint _expectedPayout,
uint _additionalSlippage,
uint _ticketSize
) external view;
function spentOnGame(bytes32 _gameId) external view returns (uint);
function riskPerMarketTypeAndPosition(
bytes32 _gameId,
uint _typeId,
uint _playerId,
uint _position
) external view returns (int);
function checkAndUpdateRisks(
ISportsAMMV2.TradeData[] memory _tradeData,
uint _buyInAmount,
uint _payout,
bool _isLive,
uint8 _systemBetDenominator,
bool _isSGP
) external;
function verifyMerkleTree(ISportsAMMV2.TradeData memory _marketTradeData, bytes32 _rootPerGame) external pure;
function batchVerifyMerkleTree(
ISportsAMMV2.TradeData[] memory _marketTradeData,
bytes32[] memory _rootPerGame
) external pure;
function isSportIdFuture(uint16 _sportsId) external view returns (bool);
function sgpOnSportIdEnabled(uint16 _sportsId) external view returns (bool);
function getMaxSystemBetPayout(
ISportsAMMV2.TradeData[] memory _tradeData,
uint8 _systemBetDenominator,
uint _buyInAmount,
uint _addedPayoutPercentage
) external view returns (uint systemBetPayout, uint systemBetQuote);
function generateCombinations(uint8 n, uint8 k) external pure returns (uint8[][] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./IProxyBetting.sol";
interface IStakingThalesBettingProxy is IProxyBetting {
function preConfirmLiveTrade(bytes32 requestId, uint _buyInAmount) external;
function confirmLiveTrade(bytes32 requestId, address _createdTicket, uint _buyInAmount) external;
function preConfirmSGPTrade(bytes32 requestId, uint _buyInAmount) external;
function confirmSGPTrade(bytes32 requestId, address _createdTicket, uint _buyInAmount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// 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.20;
// 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");
_;
}
}{
"optimizer": {
"enabled": true,
"runs": 100
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","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":"riskManager","type":"address"}],"name":"RiskManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sportsAMM","type":"address"}],"name":"SportAMMChanged","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"},{"internalType":"uint16[]","name":"_typeIds","type":"uint16[]"},{"internalType":"uint24[]","name":"_playerIds","type":"uint24[]"},{"internalType":"int24[]","name":"_lines","type":"int24[]"}],"name":"areMarketsResolved","outputs":[{"internalType":"bool[]","name":"resolvedMarkets","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"}],"name":"getActiveTicketsDataPerUser","outputs":[{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"ticketsData","type":"tuple[]"},{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"freeBetsData","type":"tuple[]"},{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"stakingBettingProxyData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"}],"name":"getAllActiveGameIdsTypeIdsPlayerIdsLinesForGameIds","outputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct SportsAMMV2Data.TicketMarketInfo[]","name":"finalTicketsInfo","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"},{"internalType":"uint16[]","name":"_sportIds","type":"uint16[]"},{"internalType":"uint16[]","name":"_typeIds","type":"uint16[]"},{"internalType":"uint256[]","name":"_maturities","type":"uint256[]"}],"name":"getCapsPerMarkets","outputs":[{"internalType":"uint256[]","name":"caps","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address[]","name":"collateralAddresses","type":"address[]"}],"name":"getFreeBetsDataPerUser","outputs":[{"internalType":"uint256[]","name":"freeBetsAmountPerCollateral","type":"uint256[]"},{"internalType":"uint256[]","name":"freeBetsExpiryPerCollateral","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odds","type":"uint256"}],"internalType":"struct SportsAMMV2Data.MarketStakeCalculationInput[]","name":"inputs","type":"tuple[]"}],"name":"getMaxStakeAndLiquidityBatch","outputs":[{"internalType":"uint256[]","name":"maxStakes","type":"uint256[]"},{"internalType":"uint256[]","name":"availableLiquidity","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"}],"name":"getOnlyActiveGameIdsAndTicketsOf","outputs":[{"internalType":"bytes32[]","name":"activeGameIds","type":"bytes32[]"},{"internalType":"uint256[]","name":"numOfTicketsPerGameId","type":"uint256[]"},{"internalType":"address[][]","name":"ticketsPerGameId","type":"address[][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"}],"name":"getResolvedTicketsDataPerUser","outputs":[{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"ticketsData","type":"tuple[]"},{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"freeBetsData","type":"tuple[]"},{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"stakingBettingProxyData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"},{"internalType":"uint16[]","name":"_typeIds","type":"uint16[]"},{"internalType":"uint24[]","name":"_playerIds","type":"uint24[]"}],"name":"getResultsForMarkets","outputs":[{"internalType":"int24[][]","name":"resultsForMarkets","type":"int24[][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"},{"internalType":"uint256[]","name":"_typeIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_playerIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_positions","type":"uint256[]"}],"name":"getRiskOnMarkets","outputs":[{"internalType":"int256[]","name":"riskAmounts","type":"int256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_gameIds","type":"bytes32[]"}],"name":"getSpentOnGames","outputs":[{"internalType":"uint256[]","name":"spentAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSportsAMMParameters","outputs":[{"components":[{"internalType":"uint256","name":"minBuyInAmount","type":"uint256"},{"internalType":"uint256","name":"maxTicketSize","type":"uint256"},{"internalType":"uint256","name":"maxSupportedAmount","type":"uint256"},{"internalType":"uint256","name":"maxSupportedOdds","type":"uint256"},{"internalType":"uint256","name":"safeBoxFee","type":"uint256"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"maxAllowedSystemCombinations","type":"uint256"}],"internalType":"struct SportsAMMV2Data.SportsAMMParameters","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"ticketsArray","type":"address[]"}],"name":"getTicketsData","outputs":[{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"}],"name":"getTicketsDataPerGame","outputs":[{"components":[{"internalType":"address","name":"id","type":"address"},{"components":[{"internalType":"bytes32","name":"gameId","type":"bytes32"},{"internalType":"uint16","name":"sportId","type":"uint16"},{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"uint256","name":"odd","type":"uint256"},{"components":[{"internalType":"uint16","name":"typeId","type":"uint16"},{"internalType":"uint8","name":"position","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"}],"internalType":"struct ISportsAMMV2.CombinedPosition[]","name":"combinedPositions","type":"tuple[]"}],"internalType":"struct SportsAMMV2Data.MarketData[]","name":"marketsData","type":"tuple[]"},{"components":[{"internalType":"enum ISportsAMMV2ResultManager.MarketPositionStatus","name":"status","type":"uint8"},{"internalType":"int24[]","name":"results","type":"int24[]"}],"internalType":"struct SportsAMMV2Data.MarketResult[]","name":"marketsResult","type":"tuple[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"ticketOwner","type":"address"},{"internalType":"uint256","name":"buyInAmount","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"},{"internalType":"uint256","name":"totalQuote","type":"uint256"},{"internalType":"uint256","name":"numOfMarkets","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"bool","name":"resolved","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"isLost","type":"bool"},{"internalType":"bool","name":"isUserTheWinner","type":"bool"},{"internalType":"bool","name":"isExercisable","type":"bool"},{"internalType":"uint256","name":"finalPayout","type":"uint256"},{"internalType":"bool","name":"isLive","type":"bool"},{"internalType":"bool","name":"isSystem","type":"bool"},{"internalType":"uint8","name":"systemBetDenominator","type":"uint8"},{"internalType":"bool","name":"isSGP","type":"bool"}],"internalType":"struct SportsAMMV2Data.TicketData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract ISportsAMMV2","name":"_sportsAMM","type":"address"},{"internalType":"contract ISportsAMMV2RiskManager","name":"_riskManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"riskManager","outputs":[{"internalType":"contract ISportsAMMV2RiskManager","name":"","type":"address"}],"stateMutability":"view","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":"contract ISportsAMMV2RiskManager","name":"_riskManager","type":"address"}],"name":"setRiskManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISportsAMMV2","name":"_sportsAMM","type":"address"}],"name":"setSportsAMM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sportsAMM","outputs":[{"internalType":"contract ISportsAMMV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061593180620000216000396000f3fe608060405234801561001057600080fd5b50600436106101845760003560e01c806379ba5097116100d9578063c3b83f5f11610087578063c3b83f5f14610391578063c9925288146103a4578063ddd57607146103bc578063e2110884146103de578063e81e52ee146103f1578063f39d03b814610404578063f518a5cf1461046457600080fd5b806379ba5097146103065780638da5cb5b1461030e57806391b4ded914610321578063b60d370714610338578063b71a6cf91461034b578063b7dab9301461036b578063c0c53b8b1461037e57600080fd5b8063563b27c411610136578063563b27c4146102435780635b615b2c146102635780635c975abb146102765780635fb1162d14610293578063604ab8b4146102b357806362ca8460146102d35780636b43bc82146102e657600080fd5b806313af4035146101895780631627540c1461019e57806316c38b3c146101b157806345e94eb8146101c457806347842663146101ef578063500ff14b1461020f57806353a47bb714610230575b600080fd5b61019c6101973660046145a3565b610484565b005b61019c6101ac3660046145a3565b6105a0565b61019c6101bf3660046145ce565b6105f3565b6101d76101d23660046146e7565b610665565b6040516101e69392919061476f565b60405180910390f35b600454610202906001600160a01b031681565b6040516101e6919061484c565b61022261021d366004614860565b610684565b6040516101e69291906148d5565b600154610202906001600160a01b031681565b61025661025136600461494e565b610776565b6040516101e69190614cfc565b610222610271366004614d0f565b6107bd565b6003546102839060ff1681565b60405190151581526020016101e6565b6102a66102a1366004614dbd565b610b61565b6040516101e69190614e80565b6102c66102c13660046146e7565b610cd9565b6040516101e69190614ef6565b61019c6102e13660046145a3565b611155565b6102f96102f4366004615021565b6111a8565b6040516101e691906150a8565b61019c6113a5565b600054610202906001600160a01b031681565b61032a60025481565b6040519081526020016101e6565b61025661034636600461510a565b61147d565b61035e61035936600461494e565b611684565b6040516101e69190615136565b61035e610379366004614dbd565b611794565b61019c61038c366004615149565b61190d565b61019c61039f3660046145a3565b611a5c565b6003546102029061010090046001600160a01b031681565b6103cf6103ca366004615194565b611b4c565b6040516101e6939291906151c9565b6103cf6103ec366004615194565b611edc565b61019c6103ff3660046145a3565b61220d565b61040c612265565b6040516101e69190600060e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015260c083015160c083015292915050565b610477610472366004615211565b61261a565b6040516101e69190615319565b6001600160a01b0381166104db5760405162461bcd60e51b815260206004820152601960248201527804f776e657220616464726573732063616e6e6f74206265203603c1b60448201526064015b60405180910390fd5b600154600160a01b900460ff16156105475760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b60648201526084016104d2565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b0383166001600160a01b03199091161781556040516000805160206158dc83398151915291610595918490615353565b60405180910390a150565b6105a861296f565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229061059590839061484c565b6105fb61296f565b60035460ff16151581151514610662576003805460ff191682151590811790915560ff161561062957426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610595565b50565b60608060606106758686866129e3565b91989097509095509350505050565b60608082806001600160401b038111156106a0576106a06145eb565b6040519080825280602002602001820160405280156106c9578160200160208202803683370190505b509250806001600160401b038111156106e4576106e46145eb565b60405190808252806020026020018201604052801561070d578160200160208202803683370190505b50915060005b8181101561076d5761073e8686838181106107305761073061536d565b905061012002018483612e87565b8482815181106107505761075061536d565b60209081029190910101528061076581615399565b915050610713565b50509250929050565b60606107b483838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061324392505050565b90505b92915050565b60608082516001600160401b038111156107d9576107d96145eb565b604051908082528060200260200182016040528015610802578160200160208202803683370190505b50915082516001600160401b0381111561081e5761081e6145eb565b604051908082528060200260200182016040528015610847578160200160208202803683370190505b5090506000600360019054906101000a90046001600160a01b03166001600160a01b031663ce18a8376040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c391906153b2565b90506000816001600160a01b031663b1b5823b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610905573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092991906153cf565b90506000826001600160a01b031663edc5de8e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f91906153cf565b905060005b8651811015610b5657836001600160a01b031663cab7bf56898984815181106109bf576109bf61536d565b60200260200101516040518363ffffffff1660e01b81526004016109e4929190615353565b602060405180830381865afa158015610a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2591906153cf565b868281518110610a3757610a3761536d565b6020026020010181815250506000846001600160a01b031663e74e33e08a8a8581518110610a6757610a6761536d565b60200260200101516040518363ffffffff1660e01b8152600401610a8c929190615353565b602060405180830381865afa158015610aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acd91906153cf565b905080600003610b0a5742610ae284866153e8565b11610aee576000610b03565b42610af984866153e8565b610b0391906153fb565b9050610b25565b428111610b18576000610b22565b610b2242826153fb565b90505b80868381518110610b3857610b3861536d565b60209081029190910101525080610b4e81615399565b915050610994565b505050509250929050565b6060876001600160401b03811115610b7b57610b7b6145eb565b604051908082528060200260200182016040528015610ba4578160200160208202803683370190505b50905060005b88811015610ccc576004546001600160a01b031663ca9ef2e68b8b84818110610bd557610bd561536d565b905060200201358a8a85818110610bee57610bee61536d565b90506020020135898986818110610c0757610c0761536d565b90506020020135888887818110610c2057610c2061536d565b905060200201356040518563ffffffff1660e01b8152600401610c5c949392919093845260208401929092526040830152606082015260800190565b602060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d91906153cf565b828281518110610caf57610caf61536d565b602090810291909101015280610cc481615399565b915050610baa565b5098975050505050505050565b606080606080610cea8787876129e3565b919450925090506000805b8451811015610de75760005b848281518110610d1357610d1361536d565b6020026020010151811015610dd457838281518110610d3457610d3461536d565b60200260200101518181518110610d4d57610d4d61536d565b60200260200101516001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db691906153cf565b610dc090846153e8565b925080610dcc81615399565b915050610d01565b5080610ddf81615399565b915050610cf5565b506000816001600160401b03811115610e0257610e026145eb565b604051908082528060200260200182016040528015610e5457816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610e205790505b50905060009150610e63614540565b60005b86518110156110455760005b868281518110610e8457610e8461536d565b6020026020010151811015611032576000868381518110610ea757610ea761536d565b60200260200101518281518110610ec057610ec061536d565b6020026020010151905060005b816001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2f91906153cf565b81101561101d57610f408282613f0b565b94508460000151868881518110610f5957610f5961536d565b602002602001015160000181815250508460400151868881518110610f8057610f8061536d565b60200260200101516020019061ffff16908161ffff16815250508460a00151868881518110610fb157610fb161536d565b60200260200101516040019062ffffff16908162ffffff16815250508460800151868881518110610fe457610fe461536d565b60200260200101516060019060020b908160020b81525050868061100790615399565b975050808061101590615399565b915050610ecd565b5050808061102a90615399565b915050610e72565b508061103d81615399565b915050610e66565b5061104f82614071565b95509250826001600160401b0381111561106b5761106b6145eb565b6040519080825280602002602001820160405280156110bd57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816110895790505b5096506000925060005b8251811015611147578581815181106110e2576110e261536d565b6020026020010151600103611135578281815181106111035761110361536d565b602002602001015188858151811061111d5761111d61536d565b60200260200101819052508361113290615399565b93505b8061113f81615399565b9150506110c7565b505050505050509392505050565b61115d61296f565b600480546001600160a01b0319166001600160a01b0383161790556040517fde93646733d5d7f1fb776a284cd4a3d76db86799b2789f91c07cdb2b45dc6d4c9061059590839061484c565b6060825184511480156111bc575081518351145b1561139e5783516001600160401b038111156111da576111da6145eb565b60405190808252806020026020018201604052801561120d57816020015b60608152602001906001900390816111f85790505b50905060005b845181101561139c57600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129391906153b2565b6001600160a01b031663514b75638683815181106112b3576112b361536d565b60200260200101518684815181106112cd576112cd61536d565b60200260200101518685815181106112e7576112e761536d565b60200260200101516040518463ffffffff1660e01b81526004016113279392919092835261ffff91909116602083015262ffffff16604082015260600190565b600060405180830381865afa158015611344573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261136c919081019061540e565b82828151811061137e5761137e61536d565b6020026020010181905250808061139490615399565b915050611213565b505b9392505050565b6001546001600160a01b0316331461141d5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b60648201526084016104d2565b6000546001546040516000805160206158dc8339815191529261144e926001600160a01b0391821692911690615353565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60606000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f891906153b2565b6001600160a01b0316635c3aa11b866040518263ffffffff1660e01b815260040161152591815260200190565b602060405180830381865afa158015611542573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156691906153cf565b90508083116115755782611577565b805b92506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f291906153b2565b604051633a30376f60e11b81526004810187905260248101869052604481018890526001600160a01b0391909116906374606ede90606401600060405180830381865afa158015611647573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261166f91908101906154a7565b905061167a81613243565b9695505050505050565b6060816001600160401b0381111561169e5761169e6145eb565b6040519080825280602002602001820160405280156116c7578160200160208202803683370190505b50905060005b8281101561178d576004546001600160a01b03166305954ad48585848181106116f8576116f861536d565b905060200201356040518263ffffffff1660e01b815260040161171d91815260200190565b602060405180830381865afa15801561173a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175e91906153cf565b8282815181106117705761177061536d565b60209081029190910101528061178581615399565b9150506116cd565b5092915050565b6060876001600160401b038111156117ae576117ae6145eb565b6040519080825280602002602001820160405280156117d7578160200160208202803683370190505b50905060005b88811015610ccc576004546001600160a01b03166359dc82578b8b848181106118085761180861536d565b905060200201358a8a858181106118215761182161536d565b90506020020160208101906118369190615535565b8989868181106118485761184861536d565b905060200201602081019061185d9190615535565b6000808a8a898181106118725761187261536d565b9050602002013560006040518863ffffffff1660e01b815260040161189d9796959493929190615552565b602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de91906153cf565b8282815181106118f0576118f061536d565b60209081029190910101528061190581615399565b9150506117dd565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03166000811580156119525750825b90506000826001600160401b0316600114801561196e5750303b155b90508115801561197c575080155b1561199a5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156119c457845460ff60401b1916600160401b1785555b6119cd88610484565b60038054610100600160a81b0319166101006001600160a01b038a81169190910291909117909155600480546001600160a01b0319169188169190911790558315611a5257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b611a6461296f565b6001600160a01b038116611aac5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016104d2565b600154600160a81b900460ff1615611afc5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b60448201526064016104d2565b600080546001600160a01b0383166001600160a01b031990911681179091556001805460ff60a81b1916600160a81b1790556040516000805160206158dc83398151915291610595918490615353565b60608060606000600360019054906101000a90046001600160a01b03166001600160a01b031663ce18a8376040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bca91906153b2565b6001600160a01b031663485b23bf87878a6040518463ffffffff1660e01b8152600401611bf993929190615593565b600060405180830381865afa158015611c16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c3e91908101906154a7565b90506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb991906153b2565b6001600160a01b031663485b23bf88888b6040518463ffffffff1660e01b8152600401611ce893929190615593565b600060405180830381865afa158015611d05573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d2d91908101906154a7565b9050611d3881613243565b9450611d4382613243565b935060006001600160a01b0316600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa158015611da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc791906153b2565b6001600160a01b031614611ed1576000600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4e91906153b2565b6001600160a01b031663485b23bf89898c6040518463ffffffff1660e01b8152600401611e7d93929190615593565b600060405180830381865afa158015611e9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ec291908101906154a7565b9050611ecd81613243565b9350505b505093509350939050565b60608060606000600360019054906101000a90046001600160a01b03166001600160a01b031663ce18a8376040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5a91906153b2565b6001600160a01b031663dd37861d87878a6040518463ffffffff1660e01b8152600401611f8993929190615593565b600060405180830381865afa158015611fa6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fce91908101906154a7565b90506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612025573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204991906153b2565b6001600160a01b031663dd37861d88888b6040518463ffffffff1660e01b815260040161207893929190615593565b600060405180830381865afa158015612095573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120bd91908101906154a7565b90506120c881613243565b94506120d382613243565b935060006001600160a01b0316600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa158015612133573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215791906153b2565b6001600160a01b031614611ed1576000600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121de91906153b2565b6001600160a01b031663dd37861d89898c6040518463ffffffff1660e01b8152600401611e7d93929190615593565b61221561296f565b60038054610100600160a81b0319166101006001600160a01b038416021790556040517f576297e5fcc8cd907ee80b240284865eb3d821bdc5232e6ee9e4d78a12531c099061059590839061484c565b6122a76040518060e001604052806000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600081525090565b6040518060e00160405280600460009054906101000a90046001600160a01b03166001600160a01b031663c6334f9f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612305573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232991906153cf565b8152602001600460009054906101000a90046001600160a01b03166001600160a01b03166341dcd5fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a591906153cf565b8152602001600460009054906101000a90046001600160a01b03166001600160a01b031663422f96bf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242191906153cf565b8152602001600460009054906101000a90046001600160a01b03166001600160a01b031663e88698bf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249d91906153cf565b8152602001600360019054906101000a90046001600160a01b03166001600160a01b03166338ea71036040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251991906153cf565b8152602001600360019054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612571573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259591906155b2565b15158152602001600460009054906101000a90046001600160a01b03166001600160a01b031663e20222136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261391906153cf565b9052919050565b60608351855114801561262e575082518451145b156129675784516001600160401b0381111561264c5761264c6145eb565b604051908082528060200260200182016040528015612675578160200160208202803683370190505b50905060005b8551811015612965576000600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd91906153b2565b6001600160a01b031663914008bc87848151811061271d5761271d61536d565b60200260200101516040518263ffffffff1660e01b815260040161274b919061ffff91909116815260200190565b602060405180830381865afa158015612768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278c91906155de565b905060ff81166003146129525760408051600080825260208201909252816127dc565b60408051606081018252600080825260208083018290529282015282526000199092019101816127af5790505b509050600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612832573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285691906153b2565b6001600160a01b031663397f78238985815181106128765761287661536d565b60200260200101518986815181106128905761289061536d565b60200260200101518987815181106128aa576128aa61536d565b60200260200101518988815181106128c4576128c461536d565b6020026020010151866040518663ffffffff1660e01b81526004016128ed9594939291906155fb565b602060405180830381865afa15801561290a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292e91906155b2565b8484815181106129405761294061536d565b91151560209283029190910190910152505b508061295d81615399565b91505061267b565b505b949350505050565b6000546001600160a01b031633146129e15760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b60648201526084016104d2565b565b6060806060855184116129f657836129f9565b85515b93506000846001600160401b03811115612a1557612a156145eb565b604051908082528060200260200182016040528015612a3e578160200160208202803683370190505b5090506000865b86811015612b95576000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac691906153b2565b6001600160a01b0316635c3aa11b8b8481518110612ae657612ae661536d565b60200260200101516040518263ffffffff1660e01b8152600401612b0c91815260200190565b602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d91906153cf565b90508015612b825782612b5f81615399565b93505080848381518110612b7557612b7561536d565b6020026020010181815250505b5080612b8d81615399565b915050612a45565b50806001600160401b03811115612bae57612bae6145eb565b604051908082528060200260200182016040528015612bd7578160200160208202803683370190505b509450806001600160401b03811115612bf257612bf26145eb565b604051908082528060200260200182016040528015612c1b578160200160208202803683370190505b509350806001600160401b03811115612c3657612c366145eb565b604051908082528060200260200182016040528015612c6957816020015b6060815260200190600190039081612c545790505b5092506000905060005b8851811015612e7b576000838281518110612c9057612c9061536d565b60200260200101511115612e6957888181518110612cb057612cb061536d565b6020026020010151868381518110612cca57612cca61536d565b602002602001018181525050828181518110612ce857612ce861536d565b6020026020010151858381518110612d0257612d0261536d565b602002602001018181525050600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8591906153b2565b6001600160a01b03166374606ede6000858481518110612da757612da761536d565b60200260200101518c8581518110612dc157612dc161536d565b60200260200101516040518463ffffffff1660e01b8152600401612df8939291909283526020830191909152604082015260600190565b600060405180830381865afa158015612e15573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e3d91908101906154a7565b848381518110612e4f57612e4f61536d565b60200260200101819052508180612e6590615399565b9250505b80612e7381615399565b915050612c73565b50505093509350939050565b60045460009081906001600160a01b03166359dc82578635612eaf6040890160208a01615535565b612ebf60608a0160408b01615535565b612ecf60808b0160608c01615632565b612edf60a08c0160808d0161564f565b60a08c0135612ef460e08e0160c08f016145ce565b6040518863ffffffff1660e01b8152600401612f169796959493929190615552565b602060405180830381865afa158015612f33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5791906153cf565b6004549091506000906001600160a01b031663ca9ef2e68735612f8060608a0160408b01615535565b612f9060808b0160608c01615632565b612fa16101008c0160e08d0161566c565b6040516001600160e01b031960e087901b168152600481019490945261ffff909216602484015262ffffff16604483015260ff166064820152608401602060405180830381865afa158015612ffa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301e91906153cf565b9050600061302c8284615689565b9050600080821361303e576000613040565b815b9050808787815181106130555761305561536d565b6020908102919091018101919091526004546000916001600160a01b03909116906399182a82908b359061308f9060408e01908e01615535565b6040516001600160e01b031960e085901b168152600481019290925261ffff16602482015260a08c01356044820152606401602060405180830381865afa1580156130de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310291906153cf565b6004805460405163016552b560e21b81528c35928101929092529192506000916001600160a01b0316906305954ad490602401602060405180830381865afa158015613152573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317691906153cf565b90506000818311613188576000613192565b61319282846153fb565b905060008b61010001351180156131b55750670de0b6b3a76400008b6101000135105b156132335760006131d36101008d0135670de0b6b3a76400006153fb565b90506000816131e76101008f0135886156a9565b6131f191906156c0565b90506000828e61010001358561320791906156a9565b61321191906156c0565b90508082106132205780613222565b815b9a505050505050505050505061139e565b600097505050505050505061139e565b6060600082516001600160401b03811115613260576132606145eb565b60405190808252806020026020018201604052801561333f57816020015b604080516102c08101825260008082526060602080840182905293830181905282018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a0820152825260001990920191018161327e5790505b50905060005b835181101561178d5760008482815181106133625761336261536d565b602002602001015190506000816001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d091906153cf565b6001600160401b038111156133e7576133e76145eb565b60405190808252806020026020018201604052801561342057816020015b61340d614540565b8152602001906001900390816134055790505b5090506000826001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015613463573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348791906153cf565b6001600160401b0381111561349e5761349e6145eb565b6040519080825280602002602001820160405280156134e457816020015b6040805180820190915260008152606060208201528152602001906001900390816134bc5790505b50905060005b836001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015613528573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354c91906153cf565b8110156135b45761355d8482613f0b565b83828151811061356f5761356f61536d565b6020026020010181905250613584848261420a565b8282815181106135965761359661536d565b602002602001018190525080806135ac90615399565b9150506134ea565b506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa15801561360a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362e91906153b2565b6001600160a01b03166320dcb233856040518263ffffffff1660e01b8152600401613659919061484c565b602060405180830381865afa158015613676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061369a91906155b2565b90506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156136f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371591906153b2565b6001600160a01b031663f4b943cc866040518263ffffffff1660e01b8152600401613740919061484c565b602060405180830381865afa15801561375d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061378191906155b2565b9050604051806102c001604052808a88815181106137a1576137a161536d565b60200260200101516001600160a01b03168152602001858152602001848152602001866001600160a01b031663d8dfeb456040518163ffffffff1660e01b8152600401602060405180830381865afa158015613801573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382591906153b2565b6001600160a01b03168152602001866001600160a01b031662641e8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613870573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389491906153b2565b6001600160a01b03168152602001866001600160a01b031663d165dac26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390491906153cf565b8152602001866001600160a01b0316639af1d35a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061396b91906153cf565b8152602001866001600160a01b031663400e69ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156139ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139d291906153cf565b8152602001866001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3991906153cf565b8152602001866001600160a01b031663e184c9be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aa091906153cf565b8152602001866001600160a01b031663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0791906153cf565b8152602001866001600160a01b0316633f6fa6556040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b6e91906155b2565b15158152602001866001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bd791906155b2565b15158152602001866001600160a01b0316639a82a09a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4091906155b2565b15158152602001866001600160a01b031663085d03ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca991906155b2565b15158152602001866001600160a01b0316633356a35a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613cee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d1291906155b2565b15158152602001866001600160a01b031663e74d3c476040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d7b91906155b2565b15158152602001866001600160a01b031663242a8a6b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613dc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de491906153cf565b8152602001866001600160a01b031663b8f7a6656040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e4b91906155b2565b15158152602001831515815260200183613e66576000613ec8565b866001600160a01b031663eef8889b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ec891906155de565b60ff168152602001821515815250878781518110613ee857613ee861536d565b602002602001018190525050505050508080613f0390615399565b915050613345565b613f13614540565b6000806000806000806000808a6001600160a01b031663b1283e778b6040518263ffffffff1660e01b8152600401613f4d91815260200190565b61012060405180830381865afa158015613f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f8f91906156e2565b985098509850985050975097509750975060008b6001600160a01b031663c358c6968c6040518263ffffffff1660e01b8152600401613fd091815260200190565b600060405180830381865afa158015613fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140159190810190615788565b60408051610120810182529a8b5261ffff998a1660208c01529790981696890196909652606088019490945260029290920b608087015262ffffff1660a086015260ff1660c085015260e0840152506101008201529392505050565b60006060600083516001600160401b03811115614090576140906145eb565b6040519080825280602002602001820160405280156140b9578160200160208202803683370190505b50905083516001600160401b038111156140d5576140d56145eb565b6040519080825280602002602001820160405280156140fe578160200160208202803683370190505b50915060008060005b8651811015614201578681815181106141225761412261536d565b602002602001015160405160200161413a9190615860565b6040516020818303038152906040528051906020012092506001915060005b8681101561419c578481815181106141735761417361536d565b6020026020010151840361418a576000925061419c565b8061419481615399565b915050614159565b5081156141ef57828487815181106141b6576141b661536d565b60200260200101818152505060018582815181106141d6576141d661536d565b6020908102919091010152856141eb81615399565b9650505b806141f981615399565b915050614107565b50505050915091565b6040805180820190915260008152606060208201526000806000806000876001600160a01b031663b1283e77886040518263ffffffff1660e01b815260040161425591815260200190565b61012060405180830381865afa158015614273573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061429791906156e2565b50975097509750505095505094506000886001600160a01b031663c358c696896040518263ffffffff1660e01b81526004016142d591815260200190565b600060405180830381865afa1580156142f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261431a9190810190615788565b90506000600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614371573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061439591906153b2565b6001600160a01b031663aa0cc0968888878988886040518763ffffffff1660e01b81526004016143ca9695949392919061586e565b602060405180830381865afa1580156143e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061440b91906158ba565b90506000600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614462573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061448691906153b2565b60405163514b756360e01b8152600481018a905261ffff8916602482015262ffffff871660448201526001600160a01b03919091169063514b756390606401600060405180830381865afa1580156144e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261450a919081019061540e565b9050604051806040016040528083600381111561452957614529614aac565b8152602001919091529a9950505050505050505050565b604080516101208101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e082019290925261010081019190915290565b6001600160a01b038116811461066257600080fd5b6000602082840312156145b557600080fd5b813561139e8161458e565b801515811461066257600080fd5b6000602082840312156145e057600080fd5b813561139e816145c0565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715614623576146236145eb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614651576146516145eb565b604052919050565b60006001600160401b03821115614672576146726145eb565b5060051b60200190565b600082601f83011261468d57600080fd5b813560206146a261469d83614659565b614629565b82815260059290921b840181019181810190868411156146c157600080fd5b8286015b848110156146dc57803583529183019183016146c5565b509695505050505050565b6000806000606084860312156146fc57600080fd5b83356001600160401b0381111561471257600080fd5b61471e8682870161467c565b9660208601359650604090950135949350505050565b600081518084526020808501945080840160005b8381101561476457815187529582019590820190600101614748565b509495945050505050565b606080825284519082018190526000906020906080840190828801845b828110156147a85781518452928401929084019060010161478c565b505050838103828501526147bc8187614734565b905083810360408501528085518083528383019150838160051b84010184880160005b8381101561483c57858303601f1901855281518051808552908801908885019060005b818110156148275783516001600160a01b03168352928a0192918a0191600101614802565b505095880195935050908601906001016147df565b50909a9950505050505050505050565b6001600160a01b0391909116815260200190565b6000806020838503121561487357600080fd5b82356001600160401b038082111561488a57600080fd5b818501915085601f83011261489e57600080fd5b8135818111156148ad57600080fd5b866020610120830285010111156148c357600080fd5b60209290920196919550909350505050565b6040815260006148e86040830185614734565b82810360208401526148fa8185614734565b95945050505050565b60008083601f84011261491557600080fd5b5081356001600160401b0381111561492c57600080fd5b6020830191508360208260051b850101111561494757600080fd5b9250929050565b6000806020838503121561496157600080fd5b82356001600160401b0381111561497757600080fd5b61498385828601614903565b90969095509350505050565b600081518084526020808501945080840160005b83811015614764578151805161ffff1688528381015160ff168489015260409081015160020b90880152606090960195908201906001016149a3565b600081518084526020808501808196508360051b8101915082860160005b85811015614a9f57828403895281516101208151865286820151614a268888018261ffff169052565b5060408281015161ffff16908701526060808301519087015260808083015160020b9087015260a08083015162ffffff169087015260c08083015160ff169087015260e0808301519087015261010091820151918601819052614a8b8187018361498f565b9a87019a95505050908401906001016149fd565b5091979650505050505050565b634e487b7160e01b600052602160045260246000fd5b600081518084526020808501945080840160005b8381101561476457815160020b87529582019590820190600101614ad6565b600081518084526020808501808196508360051b810191508286016000805b86811015614b71578385038a528251604081516004808210614b4357634e487b7160e01b865260218152602486fd5b5087529087015187870182905290614b5d81880183614ac2565b9b88019b9650505091850191600101614b14565b509298975050505050505050565b600081518084526020808501808196508360051b8101915082860160005b85811015614a9f578284038952815180516001600160a01b031685526102c0868201518188880152614bd1828801826149df565b91505060408083015187830382890152614beb8382614af5565b92505050606080830151614c09828901826001600160a01b03169052565b50506080828101516001600160a01b03169087015260a0808301519087015260c0808301519087015260e0808301519087015261010080830151908701526101208083015190870152610140808301519087015261016080830151151590870152610180808301511515908701526101a0808301511515908701526101c0808301511515908701526101e08083015115159087015261020080830151151590870152610220808301519087015261024080830151151590870152610260808301511515908701526102808083015160ff16908701526102a091820151151591909501529784019790840190600101614b9d565b6020815260006107b46020830184614b7f565b60008060408385031215614d2257600080fd5b8235614d2d8161458e565b91506020838101356001600160401b03811115614d4957600080fd5b8401601f81018613614d5a57600080fd5b8035614d6861469d82614659565b81815260059190911b82018301908381019088831115614d8757600080fd5b928401925b82841015614dae578335614d9f8161458e565b82529284019290840190614d8c565b80955050505050509250929050565b6000806000806000806000806080898b031215614dd957600080fd5b88356001600160401b0380821115614df057600080fd5b614dfc8c838d01614903565b909a50985060208b0135915080821115614e1557600080fd5b614e218c838d01614903565b909850965060408b0135915080821115614e3a57600080fd5b614e468c838d01614903565b909650945060608b0135915080821115614e5f57600080fd5b50614e6c8b828c01614903565b999c989b5096995094979396929594505050565b6020808252825182820181905260009190848201906040850190845b81811015614eb857835183529284019291840191600101614e9c565b50909695505050505050565b8051825261ffff602082015116602083015262ffffff6040820151166040830152606081015160020b60608301525050565b6020808252825182820181905260009190848201906040850190845b81811015614eb857614f25838551614ec4565b9284019260809290920191600101614f12565b61ffff8116811461066257600080fd5b600082601f830112614f5957600080fd5b81356020614f6961469d83614659565b82815260059290921b84018101918181019086841115614f8857600080fd5b8286015b848110156146dc578035614f9f81614f38565b8352918301918301614f8c565b62ffffff8116811461066257600080fd5b600082601f830112614fce57600080fd5b81356020614fde61469d83614659565b82815260059290921b84018101918181019086841115614ffd57600080fd5b8286015b848110156146dc57803561501481614fac565b8352918301918301615001565b60008060006060848603121561503657600080fd5b83356001600160401b038082111561504d57600080fd5b6150598783880161467c565b9450602086013591508082111561506f57600080fd5b61507b87838801614f48565b9350604086013591508082111561509157600080fd5b5061509e86828701614fbd565b9150509250925092565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156150fd57603f198886030184526150eb858351614ac2565b945092850192908501906001016150cf565b5092979650505050505050565b60008060006060848603121561511f57600080fd5b505081359360208301359350604090920135919050565b6020815260006107b46020830184614734565b60008060006060848603121561515e57600080fd5b83356151698161458e565b925060208401356151798161458e565b915060408401356151898161458e565b809150509250925092565b6000806000606084860312156151a957600080fd5b83356151b48161458e565b95602085013595506040909401359392505050565b6060815260006151dc6060830186614b7f565b82810360208401526151ee8186614b7f565b9050828103604084015261167a8185614b7f565b8060020b811461066257600080fd5b6000806000806080858703121561522757600080fd5b84356001600160401b038082111561523e57600080fd5b61524a8883890161467c565b955060209150818701358181111561526157600080fd5b61526d89828a01614f48565b95505060408701358181111561528257600080fd5b61528e89828a01614fbd565b9450506060870135818111156152a357600080fd5b87019050601f810188136152b657600080fd5b80356152c461469d82614659565b81815260059190911b8201830190838101908a8311156152e357600080fd5b928401925b8284101561530a5783356152fb81615202565b825292840192908401906152e8565b979a9699509497505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614eb8578351151583529284019291840191600101615335565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016153ab576153ab615383565b5060010190565b6000602082840312156153c457600080fd5b815161139e8161458e565b6000602082840312156153e157600080fd5b5051919050565b808201808211156107b7576107b7615383565b818103818111156107b7576107b7615383565b6000602080838503121561542157600080fd5b82516001600160401b0381111561543757600080fd5b8301601f8101851361544857600080fd5b805161545661469d82614659565b81815260059190911b8201830190838101908783111561547557600080fd5b928401925b8284101561549c57835161548d81615202565b8252928401929084019061547a565b979650505050505050565b600060208083850312156154ba57600080fd5b82516001600160401b038111156154d057600080fd5b8301601f810185136154e157600080fd5b80516154ef61469d82614659565b81815260059190911b8201830190838101908783111561550e57600080fd5b928401925b8284101561549c5783516155268161458e565b82529284019290840190615513565b60006020828403121561554757600080fd5b813561139e81614f38565b96875261ffff958616602088015293909416604086015262ffffff91909116606085015260020b608084015260a0830191909152151560c082015260e00190565b92835260208301919091526001600160a01b0316604082015260600190565b6000602082840312156155c457600080fd5b815161139e816145c0565b60ff8116811461066257600080fd5b6000602082840312156155f057600080fd5b815161139e816155cf565b85815261ffff8516602082015262ffffff841660408201528260020b606082015260a06080820152600061549c60a083018461498f565b60006020828403121561564457600080fd5b813561139e81614fac565b60006020828403121561566157600080fd5b813561139e81615202565b60006020828403121561567e57600080fd5b813561139e816155cf565b818103600083128015838313168383128216171561178d5761178d615383565b80820281158282048414176107b7576107b7615383565b6000826156dd57634e487b7160e01b600052601260045260246000fd5b500490565b60008060008060008060008060006101208a8c03121561570157600080fd5b8951985060208a015161571381614f38565b60408b015190985061572481614f38565b60608b015160808c0151919850965061573c816155cf565b60a08b015190955061574d81615202565b60c08b015190945061575e81614fac565b60e08b015190935061576f816155cf565b809250506101008a015190509295985092959850929598565b6000602080838503121561579b57600080fd5b82516001600160401b038111156157b157600080fd5b8301601f810185136157c257600080fd5b80516157d061469d82614659565b818152606091820283018401918482019190888411156157ef57600080fd5b938501935b838510156158545780858a03121561580c5760008081fd5b615814614601565b855161581f81614f38565b81528587015161582e816155cf565b8188015260408681015161584181615202565b90820152835293840193918501916157f4565b50979650505050505050565b608081016107b78284614ec4565b86815261ffff8616602082015262ffffff851660408201528360020b606082015260ff8316608082015260c060a082015260006158ae60c083018461498f565b98975050505050505050565b6000602082840312156158cc57600080fd5b81516004811061139e57600080fdfeb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159ca2646970667358221220e54ad3475e1ceb96218e63e29e1694441f67d637bac036726cbb2448b21799a864736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101845760003560e01c806379ba5097116100d9578063c3b83f5f11610087578063c3b83f5f14610391578063c9925288146103a4578063ddd57607146103bc578063e2110884146103de578063e81e52ee146103f1578063f39d03b814610404578063f518a5cf1461046457600080fd5b806379ba5097146103065780638da5cb5b1461030e57806391b4ded914610321578063b60d370714610338578063b71a6cf91461034b578063b7dab9301461036b578063c0c53b8b1461037e57600080fd5b8063563b27c411610136578063563b27c4146102435780635b615b2c146102635780635c975abb146102765780635fb1162d14610293578063604ab8b4146102b357806362ca8460146102d35780636b43bc82146102e657600080fd5b806313af4035146101895780631627540c1461019e57806316c38b3c146101b157806345e94eb8146101c457806347842663146101ef578063500ff14b1461020f57806353a47bb714610230575b600080fd5b61019c6101973660046145a3565b610484565b005b61019c6101ac3660046145a3565b6105a0565b61019c6101bf3660046145ce565b6105f3565b6101d76101d23660046146e7565b610665565b6040516101e69392919061476f565b60405180910390f35b600454610202906001600160a01b031681565b6040516101e6919061484c565b61022261021d366004614860565b610684565b6040516101e69291906148d5565b600154610202906001600160a01b031681565b61025661025136600461494e565b610776565b6040516101e69190614cfc565b610222610271366004614d0f565b6107bd565b6003546102839060ff1681565b60405190151581526020016101e6565b6102a66102a1366004614dbd565b610b61565b6040516101e69190614e80565b6102c66102c13660046146e7565b610cd9565b6040516101e69190614ef6565b61019c6102e13660046145a3565b611155565b6102f96102f4366004615021565b6111a8565b6040516101e691906150a8565b61019c6113a5565b600054610202906001600160a01b031681565b61032a60025481565b6040519081526020016101e6565b61025661034636600461510a565b61147d565b61035e61035936600461494e565b611684565b6040516101e69190615136565b61035e610379366004614dbd565b611794565b61019c61038c366004615149565b61190d565b61019c61039f3660046145a3565b611a5c565b6003546102029061010090046001600160a01b031681565b6103cf6103ca366004615194565b611b4c565b6040516101e6939291906151c9565b6103cf6103ec366004615194565b611edc565b61019c6103ff3660046145a3565b61220d565b61040c612265565b6040516101e69190600060e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015260c083015160c083015292915050565b610477610472366004615211565b61261a565b6040516101e69190615319565b6001600160a01b0381166104db5760405162461bcd60e51b815260206004820152601960248201527804f776e657220616464726573732063616e6e6f74206265203603c1b60448201526064015b60405180910390fd5b600154600160a01b900460ff16156105475760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b60648201526084016104d2565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b0383166001600160a01b03199091161781556040516000805160206158dc83398151915291610595918490615353565b60405180910390a150565b6105a861296f565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229061059590839061484c565b6105fb61296f565b60035460ff16151581151514610662576003805460ff191682151590811790915560ff161561062957426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec590602001610595565b50565b60608060606106758686866129e3565b91989097509095509350505050565b60608082806001600160401b038111156106a0576106a06145eb565b6040519080825280602002602001820160405280156106c9578160200160208202803683370190505b509250806001600160401b038111156106e4576106e46145eb565b60405190808252806020026020018201604052801561070d578160200160208202803683370190505b50915060005b8181101561076d5761073e8686838181106107305761073061536d565b905061012002018483612e87565b8482815181106107505761075061536d565b60209081029190910101528061076581615399565b915050610713565b50509250929050565b60606107b483838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061324392505050565b90505b92915050565b60608082516001600160401b038111156107d9576107d96145eb565b604051908082528060200260200182016040528015610802578160200160208202803683370190505b50915082516001600160401b0381111561081e5761081e6145eb565b604051908082528060200260200182016040528015610847578160200160208202803683370190505b5090506000600360019054906101000a90046001600160a01b03166001600160a01b031663ce18a8376040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c391906153b2565b90506000816001600160a01b031663b1b5823b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610905573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092991906153cf565b90506000826001600160a01b031663edc5de8e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f91906153cf565b905060005b8651811015610b5657836001600160a01b031663cab7bf56898984815181106109bf576109bf61536d565b60200260200101516040518363ffffffff1660e01b81526004016109e4929190615353565b602060405180830381865afa158015610a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2591906153cf565b868281518110610a3757610a3761536d565b6020026020010181815250506000846001600160a01b031663e74e33e08a8a8581518110610a6757610a6761536d565b60200260200101516040518363ffffffff1660e01b8152600401610a8c929190615353565b602060405180830381865afa158015610aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acd91906153cf565b905080600003610b0a5742610ae284866153e8565b11610aee576000610b03565b42610af984866153e8565b610b0391906153fb565b9050610b25565b428111610b18576000610b22565b610b2242826153fb565b90505b80868381518110610b3857610b3861536d565b60209081029190910101525080610b4e81615399565b915050610994565b505050509250929050565b6060876001600160401b03811115610b7b57610b7b6145eb565b604051908082528060200260200182016040528015610ba4578160200160208202803683370190505b50905060005b88811015610ccc576004546001600160a01b031663ca9ef2e68b8b84818110610bd557610bd561536d565b905060200201358a8a85818110610bee57610bee61536d565b90506020020135898986818110610c0757610c0761536d565b90506020020135888887818110610c2057610c2061536d565b905060200201356040518563ffffffff1660e01b8152600401610c5c949392919093845260208401929092526040830152606082015260800190565b602060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d91906153cf565b828281518110610caf57610caf61536d565b602090810291909101015280610cc481615399565b915050610baa565b5098975050505050505050565b606080606080610cea8787876129e3565b919450925090506000805b8451811015610de75760005b848281518110610d1357610d1361536d565b6020026020010151811015610dd457838281518110610d3457610d3461536d565b60200260200101518181518110610d4d57610d4d61536d565b60200260200101516001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db691906153cf565b610dc090846153e8565b925080610dcc81615399565b915050610d01565b5080610ddf81615399565b915050610cf5565b506000816001600160401b03811115610e0257610e026145eb565b604051908082528060200260200182016040528015610e5457816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610e205790505b50905060009150610e63614540565b60005b86518110156110455760005b868281518110610e8457610e8461536d565b6020026020010151811015611032576000868381518110610ea757610ea761536d565b60200260200101518281518110610ec057610ec061536d565b6020026020010151905060005b816001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2f91906153cf565b81101561101d57610f408282613f0b565b94508460000151868881518110610f5957610f5961536d565b602002602001015160000181815250508460400151868881518110610f8057610f8061536d565b60200260200101516020019061ffff16908161ffff16815250508460a00151868881518110610fb157610fb161536d565b60200260200101516040019062ffffff16908162ffffff16815250508460800151868881518110610fe457610fe461536d565b60200260200101516060019060020b908160020b81525050868061100790615399565b975050808061101590615399565b915050610ecd565b5050808061102a90615399565b915050610e72565b508061103d81615399565b915050610e66565b5061104f82614071565b95509250826001600160401b0381111561106b5761106b6145eb565b6040519080825280602002602001820160405280156110bd57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816110895790505b5096506000925060005b8251811015611147578581815181106110e2576110e261536d565b6020026020010151600103611135578281815181106111035761110361536d565b602002602001015188858151811061111d5761111d61536d565b60200260200101819052508361113290615399565b93505b8061113f81615399565b9150506110c7565b505050505050509392505050565b61115d61296f565b600480546001600160a01b0319166001600160a01b0383161790556040517fde93646733d5d7f1fb776a284cd4a3d76db86799b2789f91c07cdb2b45dc6d4c9061059590839061484c565b6060825184511480156111bc575081518351145b1561139e5783516001600160401b038111156111da576111da6145eb565b60405190808252806020026020018201604052801561120d57816020015b60608152602001906001900390816111f85790505b50905060005b845181101561139c57600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129391906153b2565b6001600160a01b031663514b75638683815181106112b3576112b361536d565b60200260200101518684815181106112cd576112cd61536d565b60200260200101518685815181106112e7576112e761536d565b60200260200101516040518463ffffffff1660e01b81526004016113279392919092835261ffff91909116602083015262ffffff16604082015260600190565b600060405180830381865afa158015611344573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261136c919081019061540e565b82828151811061137e5761137e61536d565b6020026020010181905250808061139490615399565b915050611213565b505b9392505050565b6001546001600160a01b0316331461141d5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b60648201526084016104d2565b6000546001546040516000805160206158dc8339815191529261144e926001600160a01b0391821692911690615353565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60606000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f891906153b2565b6001600160a01b0316635c3aa11b866040518263ffffffff1660e01b815260040161152591815260200190565b602060405180830381865afa158015611542573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156691906153cf565b90508083116115755782611577565b805b92506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f291906153b2565b604051633a30376f60e11b81526004810187905260248101869052604481018890526001600160a01b0391909116906374606ede90606401600060405180830381865afa158015611647573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261166f91908101906154a7565b905061167a81613243565b9695505050505050565b6060816001600160401b0381111561169e5761169e6145eb565b6040519080825280602002602001820160405280156116c7578160200160208202803683370190505b50905060005b8281101561178d576004546001600160a01b03166305954ad48585848181106116f8576116f861536d565b905060200201356040518263ffffffff1660e01b815260040161171d91815260200190565b602060405180830381865afa15801561173a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175e91906153cf565b8282815181106117705761177061536d565b60209081029190910101528061178581615399565b9150506116cd565b5092915050565b6060876001600160401b038111156117ae576117ae6145eb565b6040519080825280602002602001820160405280156117d7578160200160208202803683370190505b50905060005b88811015610ccc576004546001600160a01b03166359dc82578b8b848181106118085761180861536d565b905060200201358a8a858181106118215761182161536d565b90506020020160208101906118369190615535565b8989868181106118485761184861536d565b905060200201602081019061185d9190615535565b6000808a8a898181106118725761187261536d565b9050602002013560006040518863ffffffff1660e01b815260040161189d9796959493929190615552565b602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de91906153cf565b8282815181106118f0576118f061536d565b60209081029190910101528061190581615399565b9150506117dd565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03166000811580156119525750825b90506000826001600160401b0316600114801561196e5750303b155b90508115801561197c575080155b1561199a5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156119c457845460ff60401b1916600160401b1785555b6119cd88610484565b60038054610100600160a81b0319166101006001600160a01b038a81169190910291909117909155600480546001600160a01b0319169188169190911790558315611a5257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b611a6461296f565b6001600160a01b038116611aac5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016104d2565b600154600160a81b900460ff1615611afc5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b60448201526064016104d2565b600080546001600160a01b0383166001600160a01b031990911681179091556001805460ff60a81b1916600160a81b1790556040516000805160206158dc83398151915291610595918490615353565b60608060606000600360019054906101000a90046001600160a01b03166001600160a01b031663ce18a8376040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bca91906153b2565b6001600160a01b031663485b23bf87878a6040518463ffffffff1660e01b8152600401611bf993929190615593565b600060405180830381865afa158015611c16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c3e91908101906154a7565b90506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb991906153b2565b6001600160a01b031663485b23bf88888b6040518463ffffffff1660e01b8152600401611ce893929190615593565b600060405180830381865afa158015611d05573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d2d91908101906154a7565b9050611d3881613243565b9450611d4382613243565b935060006001600160a01b0316600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa158015611da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc791906153b2565b6001600160a01b031614611ed1576000600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4e91906153b2565b6001600160a01b031663485b23bf89898c6040518463ffffffff1660e01b8152600401611e7d93929190615593565b600060405180830381865afa158015611e9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ec291908101906154a7565b9050611ecd81613243565b9350505b505093509350939050565b60608060606000600360019054906101000a90046001600160a01b03166001600160a01b031663ce18a8376040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5a91906153b2565b6001600160a01b031663dd37861d87878a6040518463ffffffff1660e01b8152600401611f8993929190615593565b600060405180830381865afa158015611fa6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fce91908101906154a7565b90506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612025573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204991906153b2565b6001600160a01b031663dd37861d88888b6040518463ffffffff1660e01b815260040161207893929190615593565b600060405180830381865afa158015612095573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120bd91908101906154a7565b90506120c881613243565b94506120d382613243565b935060006001600160a01b0316600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa158015612133573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215791906153b2565b6001600160a01b031614611ed1576000600360019054906101000a90046001600160a01b03166001600160a01b0316630fe621906040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121de91906153b2565b6001600160a01b031663dd37861d89898c6040518463ffffffff1660e01b8152600401611e7d93929190615593565b61221561296f565b60038054610100600160a81b0319166101006001600160a01b038416021790556040517f576297e5fcc8cd907ee80b240284865eb3d821bdc5232e6ee9e4d78a12531c099061059590839061484c565b6122a76040518060e001604052806000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600081525090565b6040518060e00160405280600460009054906101000a90046001600160a01b03166001600160a01b031663c6334f9f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612305573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232991906153cf565b8152602001600460009054906101000a90046001600160a01b03166001600160a01b03166341dcd5fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a591906153cf565b8152602001600460009054906101000a90046001600160a01b03166001600160a01b031663422f96bf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242191906153cf565b8152602001600460009054906101000a90046001600160a01b03166001600160a01b031663e88698bf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249d91906153cf565b8152602001600360019054906101000a90046001600160a01b03166001600160a01b03166338ea71036040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251991906153cf565b8152602001600360019054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612571573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259591906155b2565b15158152602001600460009054906101000a90046001600160a01b03166001600160a01b031663e20222136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261391906153cf565b9052919050565b60608351855114801561262e575082518451145b156129675784516001600160401b0381111561264c5761264c6145eb565b604051908082528060200260200182016040528015612675578160200160208202803683370190505b50905060005b8551811015612965576000600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd91906153b2565b6001600160a01b031663914008bc87848151811061271d5761271d61536d565b60200260200101516040518263ffffffff1660e01b815260040161274b919061ffff91909116815260200190565b602060405180830381865afa158015612768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278c91906155de565b905060ff81166003146129525760408051600080825260208201909252816127dc565b60408051606081018252600080825260208083018290529282015282526000199092019101816127af5790505b509050600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612832573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285691906153b2565b6001600160a01b031663397f78238985815181106128765761287661536d565b60200260200101518986815181106128905761289061536d565b60200260200101518987815181106128aa576128aa61536d565b60200260200101518988815181106128c4576128c461536d565b6020026020010151866040518663ffffffff1660e01b81526004016128ed9594939291906155fb565b602060405180830381865afa15801561290a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292e91906155b2565b8484815181106129405761294061536d565b91151560209283029190910190910152505b508061295d81615399565b91505061267b565b505b949350505050565b6000546001600160a01b031633146129e15760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b60648201526084016104d2565b565b6060806060855184116129f657836129f9565b85515b93506000846001600160401b03811115612a1557612a156145eb565b604051908082528060200260200182016040528015612a3e578160200160208202803683370190505b5090506000865b86811015612b95576000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac691906153b2565b6001600160a01b0316635c3aa11b8b8481518110612ae657612ae661536d565b60200260200101516040518263ffffffff1660e01b8152600401612b0c91815260200190565b602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d91906153cf565b90508015612b825782612b5f81615399565b93505080848381518110612b7557612b7561536d565b6020026020010181815250505b5080612b8d81615399565b915050612a45565b50806001600160401b03811115612bae57612bae6145eb565b604051908082528060200260200182016040528015612bd7578160200160208202803683370190505b509450806001600160401b03811115612bf257612bf26145eb565b604051908082528060200260200182016040528015612c1b578160200160208202803683370190505b509350806001600160401b03811115612c3657612c366145eb565b604051908082528060200260200182016040528015612c6957816020015b6060815260200190600190039081612c545790505b5092506000905060005b8851811015612e7b576000838281518110612c9057612c9061536d565b60200260200101511115612e6957888181518110612cb057612cb061536d565b6020026020010151868381518110612cca57612cca61536d565b602002602001018181525050828181518110612ce857612ce861536d565b6020026020010151858381518110612d0257612d0261536d565b602002602001018181525050600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8591906153b2565b6001600160a01b03166374606ede6000858481518110612da757612da761536d565b60200260200101518c8581518110612dc157612dc161536d565b60200260200101516040518463ffffffff1660e01b8152600401612df8939291909283526020830191909152604082015260600190565b600060405180830381865afa158015612e15573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e3d91908101906154a7565b848381518110612e4f57612e4f61536d565b60200260200101819052508180612e6590615399565b9250505b80612e7381615399565b915050612c73565b50505093509350939050565b60045460009081906001600160a01b03166359dc82578635612eaf6040890160208a01615535565b612ebf60608a0160408b01615535565b612ecf60808b0160608c01615632565b612edf60a08c0160808d0161564f565b60a08c0135612ef460e08e0160c08f016145ce565b6040518863ffffffff1660e01b8152600401612f169796959493929190615552565b602060405180830381865afa158015612f33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5791906153cf565b6004549091506000906001600160a01b031663ca9ef2e68735612f8060608a0160408b01615535565b612f9060808b0160608c01615632565b612fa16101008c0160e08d0161566c565b6040516001600160e01b031960e087901b168152600481019490945261ffff909216602484015262ffffff16604483015260ff166064820152608401602060405180830381865afa158015612ffa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301e91906153cf565b9050600061302c8284615689565b9050600080821361303e576000613040565b815b9050808787815181106130555761305561536d565b6020908102919091018101919091526004546000916001600160a01b03909116906399182a82908b359061308f9060408e01908e01615535565b6040516001600160e01b031960e085901b168152600481019290925261ffff16602482015260a08c01356044820152606401602060405180830381865afa1580156130de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310291906153cf565b6004805460405163016552b560e21b81528c35928101929092529192506000916001600160a01b0316906305954ad490602401602060405180830381865afa158015613152573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317691906153cf565b90506000818311613188576000613192565b61319282846153fb565b905060008b61010001351180156131b55750670de0b6b3a76400008b6101000135105b156132335760006131d36101008d0135670de0b6b3a76400006153fb565b90506000816131e76101008f0135886156a9565b6131f191906156c0565b90506000828e61010001358561320791906156a9565b61321191906156c0565b90508082106132205780613222565b815b9a505050505050505050505061139e565b600097505050505050505061139e565b6060600082516001600160401b03811115613260576132606145eb565b60405190808252806020026020018201604052801561333f57816020015b604080516102c08101825260008082526060602080840182905293830181905282018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e08201819052610200820181905261022082018190526102408201819052610260820181905261028082018190526102a0820152825260001990920191018161327e5790505b50905060005b835181101561178d5760008482815181106133625761336261536d565b602002602001015190506000816001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d091906153cf565b6001600160401b038111156133e7576133e76145eb565b60405190808252806020026020018201604052801561342057816020015b61340d614540565b8152602001906001900390816134055790505b5090506000826001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015613463573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348791906153cf565b6001600160401b0381111561349e5761349e6145eb565b6040519080825280602002602001820160405280156134e457816020015b6040805180820190915260008152606060208201528152602001906001900390816134bc5790505b50905060005b836001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015613528573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354c91906153cf565b8110156135b45761355d8482613f0b565b83828151811061356f5761356f61536d565b6020026020010181905250613584848261420a565b8282815181106135965761359661536d565b602002602001018190525080806135ac90615399565b9150506134ea565b506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa15801561360a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362e91906153b2565b6001600160a01b03166320dcb233856040518263ffffffff1660e01b8152600401613659919061484c565b602060405180830381865afa158015613676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061369a91906155b2565b90506000600360019054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156136f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371591906153b2565b6001600160a01b031663f4b943cc866040518263ffffffff1660e01b8152600401613740919061484c565b602060405180830381865afa15801561375d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061378191906155b2565b9050604051806102c001604052808a88815181106137a1576137a161536d565b60200260200101516001600160a01b03168152602001858152602001848152602001866001600160a01b031663d8dfeb456040518163ffffffff1660e01b8152600401602060405180830381865afa158015613801573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382591906153b2565b6001600160a01b03168152602001866001600160a01b031662641e8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613870573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389491906153b2565b6001600160a01b03168152602001866001600160a01b031663d165dac26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390491906153cf565b8152602001866001600160a01b0316639af1d35a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061396b91906153cf565b8152602001866001600160a01b031663400e69ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156139ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139d291906153cf565b8152602001866001600160a01b03166362e5c8196040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3991906153cf565b8152602001866001600160a01b031663e184c9be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aa091906153cf565b8152602001866001600160a01b031663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0791906153cf565b8152602001866001600160a01b0316633f6fa6556040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b6e91906155b2565b15158152602001866001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bd791906155b2565b15158152602001866001600160a01b0316639a82a09a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4091906155b2565b15158152602001866001600160a01b031663085d03ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca991906155b2565b15158152602001866001600160a01b0316633356a35a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613cee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d1291906155b2565b15158152602001866001600160a01b031663e74d3c476040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d7b91906155b2565b15158152602001866001600160a01b031663242a8a6b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613dc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de491906153cf565b8152602001866001600160a01b031663b8f7a6656040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e4b91906155b2565b15158152602001831515815260200183613e66576000613ec8565b866001600160a01b031663eef8889b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ea4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ec891906155de565b60ff168152602001821515815250878781518110613ee857613ee861536d565b602002602001018190525050505050508080613f0390615399565b915050613345565b613f13614540565b6000806000806000806000808a6001600160a01b031663b1283e778b6040518263ffffffff1660e01b8152600401613f4d91815260200190565b61012060405180830381865afa158015613f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f8f91906156e2565b985098509850985050975097509750975060008b6001600160a01b031663c358c6968c6040518263ffffffff1660e01b8152600401613fd091815260200190565b600060405180830381865afa158015613fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140159190810190615788565b60408051610120810182529a8b5261ffff998a1660208c01529790981696890196909652606088019490945260029290920b608087015262ffffff1660a086015260ff1660c085015260e0840152506101008201529392505050565b60006060600083516001600160401b03811115614090576140906145eb565b6040519080825280602002602001820160405280156140b9578160200160208202803683370190505b50905083516001600160401b038111156140d5576140d56145eb565b6040519080825280602002602001820160405280156140fe578160200160208202803683370190505b50915060008060005b8651811015614201578681815181106141225761412261536d565b602002602001015160405160200161413a9190615860565b6040516020818303038152906040528051906020012092506001915060005b8681101561419c578481815181106141735761417361536d565b6020026020010151840361418a576000925061419c565b8061419481615399565b915050614159565b5081156141ef57828487815181106141b6576141b661536d565b60200260200101818152505060018582815181106141d6576141d661536d565b6020908102919091010152856141eb81615399565b9650505b806141f981615399565b915050614107565b50505050915091565b6040805180820190915260008152606060208201526000806000806000876001600160a01b031663b1283e77886040518263ffffffff1660e01b815260040161425591815260200190565b61012060405180830381865afa158015614273573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061429791906156e2565b50975097509750505095505094506000886001600160a01b031663c358c696896040518263ffffffff1660e01b81526004016142d591815260200190565b600060405180830381865afa1580156142f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261431a9190810190615788565b90506000600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614371573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061439591906153b2565b6001600160a01b031663aa0cc0968888878988886040518763ffffffff1660e01b81526004016143ca9695949392919061586e565b602060405180830381865afa1580156143e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061440b91906158ba565b90506000600360019054906101000a90046001600160a01b03166001600160a01b0316638ff9d5cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614462573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061448691906153b2565b60405163514b756360e01b8152600481018a905261ffff8916602482015262ffffff871660448201526001600160a01b03919091169063514b756390606401600060405180830381865afa1580156144e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261450a919081019061540e565b9050604051806040016040528083600381111561452957614529614aac565b8152602001919091529a9950505050505050505050565b604080516101208101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e082019290925261010081019190915290565b6001600160a01b038116811461066257600080fd5b6000602082840312156145b557600080fd5b813561139e8161458e565b801515811461066257600080fd5b6000602082840312156145e057600080fd5b813561139e816145c0565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715614623576146236145eb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614651576146516145eb565b604052919050565b60006001600160401b03821115614672576146726145eb565b5060051b60200190565b600082601f83011261468d57600080fd5b813560206146a261469d83614659565b614629565b82815260059290921b840181019181810190868411156146c157600080fd5b8286015b848110156146dc57803583529183019183016146c5565b509695505050505050565b6000806000606084860312156146fc57600080fd5b83356001600160401b0381111561471257600080fd5b61471e8682870161467c565b9660208601359650604090950135949350505050565b600081518084526020808501945080840160005b8381101561476457815187529582019590820190600101614748565b509495945050505050565b606080825284519082018190526000906020906080840190828801845b828110156147a85781518452928401929084019060010161478c565b505050838103828501526147bc8187614734565b905083810360408501528085518083528383019150838160051b84010184880160005b8381101561483c57858303601f1901855281518051808552908801908885019060005b818110156148275783516001600160a01b03168352928a0192918a0191600101614802565b505095880195935050908601906001016147df565b50909a9950505050505050505050565b6001600160a01b0391909116815260200190565b6000806020838503121561487357600080fd5b82356001600160401b038082111561488a57600080fd5b818501915085601f83011261489e57600080fd5b8135818111156148ad57600080fd5b866020610120830285010111156148c357600080fd5b60209290920196919550909350505050565b6040815260006148e86040830185614734565b82810360208401526148fa8185614734565b95945050505050565b60008083601f84011261491557600080fd5b5081356001600160401b0381111561492c57600080fd5b6020830191508360208260051b850101111561494757600080fd5b9250929050565b6000806020838503121561496157600080fd5b82356001600160401b0381111561497757600080fd5b61498385828601614903565b90969095509350505050565b600081518084526020808501945080840160005b83811015614764578151805161ffff1688528381015160ff168489015260409081015160020b90880152606090960195908201906001016149a3565b600081518084526020808501808196508360051b8101915082860160005b85811015614a9f57828403895281516101208151865286820151614a268888018261ffff169052565b5060408281015161ffff16908701526060808301519087015260808083015160020b9087015260a08083015162ffffff169087015260c08083015160ff169087015260e0808301519087015261010091820151918601819052614a8b8187018361498f565b9a87019a95505050908401906001016149fd565b5091979650505050505050565b634e487b7160e01b600052602160045260246000fd5b600081518084526020808501945080840160005b8381101561476457815160020b87529582019590820190600101614ad6565b600081518084526020808501808196508360051b810191508286016000805b86811015614b71578385038a528251604081516004808210614b4357634e487b7160e01b865260218152602486fd5b5087529087015187870182905290614b5d81880183614ac2565b9b88019b9650505091850191600101614b14565b509298975050505050505050565b600081518084526020808501808196508360051b8101915082860160005b85811015614a9f578284038952815180516001600160a01b031685526102c0868201518188880152614bd1828801826149df565b91505060408083015187830382890152614beb8382614af5565b92505050606080830151614c09828901826001600160a01b03169052565b50506080828101516001600160a01b03169087015260a0808301519087015260c0808301519087015260e0808301519087015261010080830151908701526101208083015190870152610140808301519087015261016080830151151590870152610180808301511515908701526101a0808301511515908701526101c0808301511515908701526101e08083015115159087015261020080830151151590870152610220808301519087015261024080830151151590870152610260808301511515908701526102808083015160ff16908701526102a091820151151591909501529784019790840190600101614b9d565b6020815260006107b46020830184614b7f565b60008060408385031215614d2257600080fd5b8235614d2d8161458e565b91506020838101356001600160401b03811115614d4957600080fd5b8401601f81018613614d5a57600080fd5b8035614d6861469d82614659565b81815260059190911b82018301908381019088831115614d8757600080fd5b928401925b82841015614dae578335614d9f8161458e565b82529284019290840190614d8c565b80955050505050509250929050565b6000806000806000806000806080898b031215614dd957600080fd5b88356001600160401b0380821115614df057600080fd5b614dfc8c838d01614903565b909a50985060208b0135915080821115614e1557600080fd5b614e218c838d01614903565b909850965060408b0135915080821115614e3a57600080fd5b614e468c838d01614903565b909650945060608b0135915080821115614e5f57600080fd5b50614e6c8b828c01614903565b999c989b5096995094979396929594505050565b6020808252825182820181905260009190848201906040850190845b81811015614eb857835183529284019291840191600101614e9c565b50909695505050505050565b8051825261ffff602082015116602083015262ffffff6040820151166040830152606081015160020b60608301525050565b6020808252825182820181905260009190848201906040850190845b81811015614eb857614f25838551614ec4565b9284019260809290920191600101614f12565b61ffff8116811461066257600080fd5b600082601f830112614f5957600080fd5b81356020614f6961469d83614659565b82815260059290921b84018101918181019086841115614f8857600080fd5b8286015b848110156146dc578035614f9f81614f38565b8352918301918301614f8c565b62ffffff8116811461066257600080fd5b600082601f830112614fce57600080fd5b81356020614fde61469d83614659565b82815260059290921b84018101918181019086841115614ffd57600080fd5b8286015b848110156146dc57803561501481614fac565b8352918301918301615001565b60008060006060848603121561503657600080fd5b83356001600160401b038082111561504d57600080fd5b6150598783880161467c565b9450602086013591508082111561506f57600080fd5b61507b87838801614f48565b9350604086013591508082111561509157600080fd5b5061509e86828701614fbd565b9150509250925092565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156150fd57603f198886030184526150eb858351614ac2565b945092850192908501906001016150cf565b5092979650505050505050565b60008060006060848603121561511f57600080fd5b505081359360208301359350604090920135919050565b6020815260006107b46020830184614734565b60008060006060848603121561515e57600080fd5b83356151698161458e565b925060208401356151798161458e565b915060408401356151898161458e565b809150509250925092565b6000806000606084860312156151a957600080fd5b83356151b48161458e565b95602085013595506040909401359392505050565b6060815260006151dc6060830186614b7f565b82810360208401526151ee8186614b7f565b9050828103604084015261167a8185614b7f565b8060020b811461066257600080fd5b6000806000806080858703121561522757600080fd5b84356001600160401b038082111561523e57600080fd5b61524a8883890161467c565b955060209150818701358181111561526157600080fd5b61526d89828a01614f48565b95505060408701358181111561528257600080fd5b61528e89828a01614fbd565b9450506060870135818111156152a357600080fd5b87019050601f810188136152b657600080fd5b80356152c461469d82614659565b81815260059190911b8201830190838101908a8311156152e357600080fd5b928401925b8284101561530a5783356152fb81615202565b825292840192908401906152e8565b979a9699509497505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614eb8578351151583529284019291840191600101615335565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016153ab576153ab615383565b5060010190565b6000602082840312156153c457600080fd5b815161139e8161458e565b6000602082840312156153e157600080fd5b5051919050565b808201808211156107b7576107b7615383565b818103818111156107b7576107b7615383565b6000602080838503121561542157600080fd5b82516001600160401b0381111561543757600080fd5b8301601f8101851361544857600080fd5b805161545661469d82614659565b81815260059190911b8201830190838101908783111561547557600080fd5b928401925b8284101561549c57835161548d81615202565b8252928401929084019061547a565b979650505050505050565b600060208083850312156154ba57600080fd5b82516001600160401b038111156154d057600080fd5b8301601f810185136154e157600080fd5b80516154ef61469d82614659565b81815260059190911b8201830190838101908783111561550e57600080fd5b928401925b8284101561549c5783516155268161458e565b82529284019290840190615513565b60006020828403121561554757600080fd5b813561139e81614f38565b96875261ffff958616602088015293909416604086015262ffffff91909116606085015260020b608084015260a0830191909152151560c082015260e00190565b92835260208301919091526001600160a01b0316604082015260600190565b6000602082840312156155c457600080fd5b815161139e816145c0565b60ff8116811461066257600080fd5b6000602082840312156155f057600080fd5b815161139e816155cf565b85815261ffff8516602082015262ffffff841660408201528260020b606082015260a06080820152600061549c60a083018461498f565b60006020828403121561564457600080fd5b813561139e81614fac565b60006020828403121561566157600080fd5b813561139e81615202565b60006020828403121561567e57600080fd5b813561139e816155cf565b818103600083128015838313168383128216171561178d5761178d615383565b80820281158282048414176107b7576107b7615383565b6000826156dd57634e487b7160e01b600052601260045260246000fd5b500490565b60008060008060008060008060006101208a8c03121561570157600080fd5b8951985060208a015161571381614f38565b60408b015190985061572481614f38565b60608b015160808c0151919850965061573c816155cf565b60a08b015190955061574d81615202565b60c08b015190945061575e81614fac565b60e08b015190935061576f816155cf565b809250506101008a015190509295985092959850929598565b6000602080838503121561579b57600080fd5b82516001600160401b038111156157b157600080fd5b8301601f810185136157c257600080fd5b80516157d061469d82614659565b818152606091820283018401918482019190888411156157ef57600080fd5b938501935b838510156158545780858a03121561580c5760008081fd5b615814614601565b855161581f81614f38565b81528587015161582e816155cf565b8188015260408681015161584181615202565b90820152835293840193918501916157f4565b50979650505050505050565b608081016107b78284614ec4565b86815261ffff8616602082015262ffffff851660408201528360020b606082015260ff8316608082015260c060a082015260006158ae60c083018461498f565b98975050505050505050565b6000602082840312156158cc57600080fd5b81516004811061139e57600080fdfeb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159ca2646970667358221220e54ad3475e1ceb96218e63e29e1694441f67d637bac036726cbb2448b21799a864736f6c63430008140033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 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.