Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SportsAMMV2Manager
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 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";
// internal
import "../../utils/libraries/AddressSetLib.sol";
import "../../utils/proxy/ProxyOwned.sol";
import "../../utils/proxy/ProxyPausable.sol";
import "../../interfaces/ISportsAMMV2Manager.sol";
import "../../interfaces/ISportsAMMV2RiskManager.sol";
import "../../interfaces/ITicket.sol";
contract SportsAMMV2Manager is Initializable, ProxyOwned, ProxyPausable {
using AddressSetLib for AddressSetLib.AddressSet;
uint private constant COLLATERAL_DEFAULT_DECIMALS = 18;
address public sportsAMM;
mapping(address => mapping(ISportsAMMV2Manager.Role => bool)) public whitelistedAddresses;
// stores active tickets
AddressSetLib.AddressSet internal knownTickets;
// stores active tickets per user
mapping(address => AddressSetLib.AddressSet) internal activeTicketsPerUser;
// stores resolved tickets per user
mapping(address => AddressSetLib.AddressSet) internal resolvedTicketsPerUser;
// stores tickets per game
mapping(bytes32 => AddressSetLib.AddressSet) internal ticketsPerGame;
mapping(bytes32 => mapping(uint => mapping(uint => AddressSetLib.AddressSet))) internal ticketsPerMarket;
// stores whether a given ticket address is a system bet
mapping(address => bool) public isSystemTicket;
// stores whether a given ticket address is a SGP bet
mapping(address => bool) public isSGPTicket;
/* ========== CONSTRUCTOR ========== */
function initialize(address _owner) external initializer {
setOwner(_owner);
}
/* ========== EXTERNAL FUNCTIONS ========== */
/// @notice add new ticket to known and active per user, add tickets per game and add tickets per market
/// @param _tradeData list of games
/// @param _ticket ticket address
/// @param _user to update the ticket for
function addNewKnownTicket(
ISportsAMMV2.TradeData[] memory _tradeData,
address _ticket,
address _user
) external onlySportAMMV2 {
knownTickets.add(_ticket);
activeTicketsPerUser[_user].add(_ticket);
for (uint i = 0; i < _tradeData.length; i++) {
ticketsPerGame[_tradeData[i].gameId].add(_ticket);
ticketsPerMarket[_tradeData[i].gameId][_tradeData[i].typeId][_tradeData[i].playerId].add(_ticket);
}
isSystemTicket[_ticket] = ITicket(_ticket).isSystem();
isSGPTicket[_ticket] = ITicket(_ticket).isSGP();
}
/// @notice remove known ticket from active and add as resolved
/// @param _ticket ticket address
/// @param _user to update the ticket for
function resolveKnownTicket(address _ticket, address _user) external onlySportAMMV2 {
knownTickets.remove(_ticket);
activeTicketsPerUser[_user].remove(_ticket);
resolvedTicketsPerUser[_user].add(_ticket);
}
/// @notice remove known ticket from active
/// @param _ticket ticket address
/// @param _user to update the ticket for
function expireKnownTicket(address _ticket, address _user) external onlySportAMMV2 {
knownTickets.remove(_ticket);
activeTicketsPerUser[_user].remove(_ticket);
}
/* ========== EXTERNAL READ FUNCTIONS ========== */
/// @notice check whether a ticket is known
/// @param _ticket ticket address
function isKnownTicket(address _ticket) external view returns (bool) {
return knownTickets.contains(_ticket);
}
/// @notice is provided ticket active
/// @param _ticket ticket address
/// @return isActiveTicket true/false
function isActiveTicket(address _ticket) external view returns (bool) {
return knownTickets.contains(_ticket);
}
/// @notice gets batch of active tickets
/// @param _index start index
/// @param _pageSize batch size
/// @return activeTickets
function getActiveTickets(uint _index, uint _pageSize) external view returns (address[] memory) {
return knownTickets.getPage(_index, _pageSize);
}
/// @notice gets number of active tickets
/// @return numOfActiveTickets
function numOfActiveTickets() external view returns (uint) {
return knownTickets.elements.length;
}
/// @notice gets batch of tickets per market
/// @param _index start index
/// @param _pageSize batch size
/// @param _gameId to get tickets for
/// @param _typeId to get tickets for
/// @param _playerId to get tickets for
/// @return tickets
function getTicketsPerMarket(
uint _index,
uint _pageSize,
bytes32 _gameId,
uint _typeId,
uint _playerId
) external view returns (address[] memory) {
return ticketsPerMarket[_gameId][_typeId][_playerId].getPage(_index, _pageSize);
}
/// @notice gets number of tickets per market
/// @param _gameId to get number of tickets for
/// @param _typeId to get number of tickets for
/// @param _playerId to get number of tickets for
/// @return numOfTickets
function numOfTicketsPerMarket(bytes32 _gameId, uint _typeId, uint _playerId) external view returns (uint) {
return ticketsPerMarket[_gameId][_typeId][_playerId].elements.length;
}
/// @notice gets batch of active tickets per user
/// @param _index start index
/// @param _pageSize batch size
/// @param _user to get active tickets for
/// @return activeTickets
function getActiveTicketsPerUser(uint _index, uint _pageSize, address _user) external view returns (address[] memory) {
return activeTicketsPerUser[_user].getPage(_index, _pageSize);
}
/// @notice gets number of active tickets per user
/// @param _user to get number of active tickets for
/// @return numOfActiveTickets
function numOfActiveTicketsPerUser(address _user) external view returns (uint) {
return activeTicketsPerUser[_user].elements.length;
}
/// @notice gets batch of resolved tickets per user
/// @param _index start index
/// @param _pageSize batch size
/// @param _user to get resolved tickets for
/// @return resolvedTickets
function getResolvedTicketsPerUser(uint _index, uint _pageSize, address _user) external view returns (address[] memory) {
return resolvedTicketsPerUser[_user].getPage(_index, _pageSize);
}
/// @notice gets number of resolved tickets per user
/// @param _user to get number of resolved tickets for
/// @return numOfResolvedTickets
function numOfResolvedTicketsPerUser(address _user) external view returns (uint) {
return resolvedTicketsPerUser[_user].elements.length;
}
/// @notice gets batch of tickets per game
/// @param _index start index
/// @param _pageSize batch size
/// @param _gameId to get tickets for
/// @return resolvedTickets
function getTicketsPerGame(uint _index, uint _pageSize, bytes32 _gameId) external view returns (address[] memory) {
return ticketsPerGame[_gameId].getPage(_index, _pageSize);
}
/// @notice gets number of tickets per game
/// @param _gameId to get number of tickets for
/// @return numOfTickets
function numOfTicketsPerGame(bytes32 _gameId) external view returns (uint) {
return ticketsPerGame[_gameId].elements.length;
}
/// @notice checks if address is whitelisted
/// @param _address address to be checked
/// @return bool
function isWhitelistedAddress(address _address, ISportsAMMV2Manager.Role _role) external view returns (bool) {
return whitelistedAddresses[_address][_role];
}
/* ========== EXTERNAL READ FUNCTIONS ========== */
/// @notice pause/unapause provided tickets
/// @param _tickets array of tickets to be paused/unpaused
/// @param _paused pause/unpause
function setPausedTickets(address[] calldata _tickets, bool _paused) external {
require(
msg.sender == owner || whitelistedAddresses[msg.sender][ISportsAMMV2Manager.Role.TICKET_PAUSER],
"Invalid pauser"
);
for (uint i = 0; i < _tickets.length; i++) {
ITicket(_tickets[i]).setPaused(_paused);
}
}
/* ========== SETTERS ========== */
/// @notice enables whitelist addresses of given array
/// @param _whitelistedAddresses array of whitelisted addresses
/// @param _role for which whitelisting is assign/unassigned
/// @param _flag adding or removing from whitelist (true: add, false: remove)
function setWhitelistedAddresses(
address[] calldata _whitelistedAddresses,
ISportsAMMV2Manager.Role _role,
bool _flag
) external onlyOwner {
require(_whitelistedAddresses.length > 0, "Whitelisted addresses cannot be empty");
for (uint256 index = 0; index < _whitelistedAddresses.length; index++) {
if (whitelistedAddresses[_whitelistedAddresses[index]][_role] != _flag) {
whitelistedAddresses[_whitelistedAddresses[index]][_role] = _flag;
emit WhitelistStatusChanged(_whitelistedAddresses[index], _role, _flag);
}
}
}
/// @notice set the address of SportsAMM
function setSportsAMM(address _sportsAMM) external onlyOwner {
sportsAMM = _sportsAMM;
emit SportAMMChanged(address(_sportsAMM));
}
/* ========== MODIFIERS ========== */
modifier onlySportAMMV2() {
require(msg.sender == sportsAMM, "Invalid sportsAMM");
_;
}
/* ========== EVENTS ========== */
event SportAMMChanged(address sportsAMM);
event WhitelistStatusChanged(address whitelistedAddresses, ISportsAMMV2Manager.Role role, bool flag);
}// 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/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
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;
}// 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 {
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 exerciseTicket(address _ticket) 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 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 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 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;
interface ITicket {
function setPaused(bool _paused) external;
function isSystem() external view returns (bool);
function isSGP() external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library AddressSetLib {
struct AddressSet {
address[] elements;
mapping(address => uint) indices;
}
function contains(AddressSet storage set, address candidate) internal view returns (bool) {
if (set.elements.length == 0) {
return false;
}
uint index = set.indices[candidate];
return index != 0 || set.elements[0] == candidate;
}
function getPage(AddressSet storage set, uint index, uint pageSize) internal view returns (address[] memory) {
// NOTE: This implementation should be converted to slice operators if the compiler is updated to v0.6.0+
uint endIndex = index + pageSize; // The check below that endIndex <= index handles overflow.
// If the page extends past the end of the list, truncate it.
if (endIndex > set.elements.length) {
endIndex = set.elements.length;
}
if (endIndex <= index) {
return new address[](0);
}
uint n = endIndex - index; // We already checked for negative overflow.
address[] memory page = new address[](n);
for (uint i; i < n; i++) {
page[i] = set.elements[i + index];
}
return page;
}
function add(AddressSet storage set, address element) internal {
// Adding to a set is an idempotent operation.
if (!contains(set, element)) {
set.indices[element] = set.elements.length;
set.elements.push(element);
}
}
function remove(AddressSet storage set, address element) internal {
require(contains(set, element), "Element not in set.");
// Replace the removed element with the last element of the list.
uint index = set.indices[element];
uint lastIndex = set.elements.length - 1; // We required that element is in the list, so it is not empty.
if (index != lastIndex) {
// No need to shift the last element if it is the one we want to delete.
address shiftedElement = set.elements[lastIndex];
set.elements[index] = shiftedElement;
set.indices[shiftedElement] = index;
}
set.elements.pop();
delete set.indices[element];
}
}// 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": 200
},
"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":"sportsAMM","type":"address"}],"name":"SportAMMChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"whitelistedAddresses","type":"address"},{"indexed":false,"internalType":"enum ISportsAMMV2Manager.Role","name":"role","type":"uint8"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"WhitelistStatusChanged","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":"uint8","name":"status","type":"uint8"},{"internalType":"int24","name":"line","type":"int24"},{"internalType":"uint24","name":"playerId","type":"uint24"},{"internalType":"uint256[]","name":"odds","type":"uint256[]"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint8","name":"position","type":"uint8"},{"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 ISportsAMMV2.TradeData[]","name":"_tradeData","type":"tuple[]"},{"internalType":"address","name":"_ticket","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"addNewKnownTicket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ticket","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"expireKnownTicket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"}],"name":"getActiveTickets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getActiveTicketsPerUser","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getResolvedTicketsPerUser","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"},{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"getTicketsPerGame","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_pageSize","type":"uint256"},{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"uint256","name":"_typeId","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"getTicketsPerMarket","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ticket","type":"address"}],"name":"isActiveTicket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_ticket","type":"address"}],"name":"isKnownTicket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSGPTicket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSystemTicket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"enum ISportsAMMV2Manager.Role","name":"_role","type":"uint8"}],"name":"isWhitelistedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_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":"numOfActiveTickets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"numOfActiveTicketsPerUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"numOfResolvedTicketsPerUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"}],"name":"numOfTicketsPerGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_gameId","type":"bytes32"},{"internalType":"uint256","name":"_typeId","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"numOfTicketsPerMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_ticket","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"resolveKnownTicket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tickets","type":"address[]"},{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPausedTickets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sportsAMM","type":"address"}],"name":"setSportsAMM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whitelistedAddresses","type":"address[]"},{"internalType":"enum ISportsAMMV2Manager.Role","name":"_role","type":"uint8"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setWhitelistedAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sportsAMM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"transferOwnershipAtInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum ISportsAMMV2Manager.Role","name":"","type":"uint8"}],"name":"whitelistedAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50611e59806100206000396000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638da5cb5b1161011a578063c4d66de8116100ad578063e760c3951161007c578063e760c39514610492578063e81e52ee146104a5578063f033d0f9146104b8578063f4b943cc146104cb578063f99d0cd0146104ee57600080fd5b8063c4d66de814610422578063c992528814610435578063d0972c171461044d578063dd37861d1461047f57600080fd5b80639a920a8b116100e95780639a920a8b146103e1578063a29ba83a146103e9578063bf457694146103fc578063c3b83f5f1461040f57600080fd5b80638da5cb5b146103895780639168fdd11461039c57806391b4ded9146103c557806391bf5be0146103ce57600080fd5b80634271f321116101925780635c975abb116101615780635c975abb1461034e57806368b350561461035b57806374606ede1461036e57806379ba50971461038157600080fd5b80634271f321146102d0578063485b23bf146102e357806353a47bb7146103035780635c3aa11b1461032e57600080fd5b806316c38b3c116101ce57806316c38b3c146102775780631f939b2d1461028a57806320dcb233146102ad57806321875b571461028a57600080fd5b806306ef03671461020057806313af4035146102155780631590a4a4146102285780631627540c14610264575b600080fd5b61021361020e3660046115e1565b61051c565b005b610213610223366004611614565b6105a7565b610251610236366004611614565b6001600160a01b031660009081526007602052604090205490565b6040519081526020015b60405180910390f35b610213610272366004611614565b6106d8565b61021361028536600461163d565b61072e565b61029d610298366004611614565b6107a0565b604051901515815260200161025b565b61029d6102bb366004611614565b600b6020526000908152604090205460ff1681565b6102136102de3660046116b5565b6107b3565b6102f66102f136600461171c565b6109ba565b60405161025b9190611751565b600154610316906001600160a01b031681565b6040516001600160a01b03909116815260200161025b565b61025161033c36600461179e565b60009081526009602052604090205490565b60035461029d9060ff1681565b6102f66103693660046117b7565b6109ea565b6102f661037c3660046117d9565b6109f8565b610213610a14565b600054610316906001600160a01b031681565b6102516103aa366004611614565b6001600160a01b031660009081526008602052604090205490565b61025160025481565b6102f66103dc366004611805565b610afe565b600554610251565b6102136103f7366004611ab7565b610b37565b61021361040a366004611c7f565b610db0565b61021361041d366004611614565b610ec9565b610213610430366004611614565b610fd2565b6003546103169061010090046001600160a01b031681565b61025161045b3660046117d9565b6000928352600a602090815260408085209385529281528284209184525290205490565b6102f661048d36600461171c565b6110e2565b61029d6104a0366004611cd6565b611108565b6102136104b3366004611614565b61115f565b6102136104c63660046115e1565b6111bd565b61029d6104d9366004611614565b600c6020526000908152604090205460ff1681565b61029d6104fc366004611cd6565b600460209081526000928352604080842090915290825290205460ff1681565b60035461010090046001600160a01b031633146105545760405162461bcd60e51b815260040161054b90611d00565b60405180910390fd5b61055f600583611215565b6001600160a01b03811660009081526007602052604090206105819083611215565b6001600160a01b03811660009081526008602052604090206105a3908361136e565b5050565b6001600160a01b0381166105fd5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640161054b565b600154600160a01b900460ff16156106695760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b606482015260840161054b565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b0383166001600160a01b0319909116811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6106e06113c0565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016106cd565b6107366113c0565b60035460ff1615158115151461079d576003805460ff191682151590811790915560ff161561076457426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5906020016106cd565b50565b60006107ad600583611434565b92915050565b6107bb6113c0565b826108165760405162461bcd60e51b815260206004820152602560248201527f57686974656c6973746564206164647265737365732063616e6e6f7420626520604482015264656d70747960d81b606482015260840161054b565b60005b838110156109b3578115156004600087878581811061083a5761083a611d2b565b905060200201602081019061084f9190611614565b6001600160a01b03166001600160a01b03168152602001908152602001600020600085600381111561088357610883611d41565b600381111561089457610894611d41565b815260208101919091526040016000205460ff161515146109a15781600460008787858181106108c6576108c6611d2b565b90506020020160208101906108db9190611614565b6001600160a01b03166001600160a01b03168152602001908152602001600020600085600381111561090f5761090f611d41565b600381111561092057610920611d41565b81526020810191909152604001600020805460ff19169115159190911790557fdc4a00a0a7cce3b3f28b2988c80953b51cf6219d7335a63fe2262ff0de6c3a3285858381811061097257610972611d2b565b90506020020160208101906109879190611614565b848460405161099893929190611d57565b60405180910390a15b806109ab81611db1565b915050610819565b5050505050565b6001600160a01b03811660009081526008602052604090206060906109e09085856114aa565b90505b9392505050565b60606109e3600584846114aa565b60008181526009602052604090206060906109e09085856114aa565b6001546001600160a01b03163314610a8c5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b606482015260840161054b565b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000838152600a6020908152604080832085845282528083208484529091529020606090610b2d9087876114aa565b9695505050505050565b60035461010090046001600160a01b03163314610b665760405162461bcd60e51b815260040161054b90611d00565b610b7160058361136e565b6001600160a01b0381166000908152600760205260409020610b93908361136e565b60005b8351811015610c9a57610be18360096000878581518110610bb957610bb9611d2b565b602002602001015160000151815260200190815260200160002061136e90919063ffffffff16565b610c8883600a6000878581518110610bfb57610bfb611d2b565b60200260200101516000015181526020019081526020016000206000878581518110610c2957610c29611d2b565b60200260200101516040015161ffff1681526020019081526020016000206000878581518110610c5b57610c5b611d2b565b602002602001015160c0015162ffffff16815260200190815260200160002061136e90919063ffffffff16565b80610c9281611db1565b915050610b96565b50816001600160a01b0316634652e3306040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfd9190611dca565b6001600160a01b0383166000818152600b6020908152604091829020805460ff1916941515949094179093558051631c98697960e01b815290519192631c986979926004808401938290030181865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d829190611dca565b6001600160a01b03929092166000908152600c60205260409020805460ff1916921515929092179091555050565b6000546001600160a01b0316331480610de457503360009081526004602090815260408083206003845290915290205460ff165b610e215760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103830bab9b2b960911b604482015260640161054b565b60005b82811015610ec357838382818110610e3e57610e3e611d2b565b9050602002016020810190610e539190611614565b6040516305b0e2cf60e21b815283151560048201526001600160a01b0391909116906316c38b3c90602401600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050508080610ebb90611db1565b915050610e24565b50505050565b610ed16113c0565b6001600160a01b038116610f195760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161054b565b600154600160a81b900460ff1615610f695760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b604482015260640161054b565b600080546001600160a01b0383166001600160a01b031990911681179091556001805460ff60a81b1916600160a81b1790556040805182815260208101929092527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016106cd565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff166000811580156110185750825b905060008267ffffffffffffffff1660011480156110355750303b155b905081158015611043575080155b156110615760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561108b57845460ff60401b1916600160401b1785555b611094866105a7565b83156110da57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b6001600160a01b03811660009081526007602052604090206060906109e09085856114aa565b6001600160a01b03821660009081526004602052604081208183600381111561113357611133611d41565b600381111561114457611144611d41565b815260208101919091526040016000205460ff169392505050565b6111676113c0565b60038054610100600160a81b0319166101006001600160a01b038416908102919091179091556040519081527f576297e5fcc8cd907ee80b240284865eb3d821bdc5232e6ee9e4d78a12531c09906020016106cd565b60035461010090046001600160a01b031633146111ec5760405162461bcd60e51b815260040161054b90611d00565b6111f7600583611215565b6001600160a01b03811660009081526007602052604090206105a390835b61121f8282611434565b6112615760405162461bcd60e51b815260206004820152601360248201527222b632b6b2b73a103737ba1034b71039b2ba1760691b604482015260640161054b565b6001600160a01b038116600090815260018084016020526040822054845490929161128b91611de7565b90508082146113175760008460000182815481106112ab576112ab611d2b565b60009182526020909120015485546001600160a01b03909116915081908690859081106112da576112da611d2b565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815260018601909152604090208290555b835484908061132857611328611dfa565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0394909416815260019490940190925250506040812055565b6113788282611434565b6105a35781546001600160a01b038216600081815260018086016020908152604083208590559084018655858252902090910180546001600160a01b03191690911790555050565b6000546001600160a01b031633146114325760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b606482015260840161054b565b565b81546000908103611447575060006107ad565b6001600160a01b0382166000908152600184016020526040902054801515806114a25750826001600160a01b03168460000160008154811061148b5761148b611d2b565b6000918252602090912001546001600160a01b0316145b949350505050565b606060006114b88385611e10565b85549091508111156114c8575083545b8381116114e55750506040805160008152602081019091526109e3565b60006114f18583611de7565b905060008167ffffffffffffffff81111561150e5761150e611840565b604051908082528060200260200182016040528015611537578160200160208202803683370190505b50905060005b828110156115ba57876115508883611e10565b8154811061156057611560611d2b565b9060005260206000200160009054906101000a90046001600160a01b031682828151811061159057611590611d2b565b6001600160a01b0390921660209283029190910190910152806115b281611db1565b91505061153d565b509695505050505050565b80356001600160a01b03811681146115dc57600080fd5b919050565b600080604083850312156115f457600080fd5b6115fd836115c5565b915061160b602084016115c5565b90509250929050565b60006020828403121561162657600080fd5b6109e3826115c5565b801515811461079d57600080fd5b60006020828403121561164f57600080fd5b81356109e38161162f565b60008083601f84011261166c57600080fd5b50813567ffffffffffffffff81111561168457600080fd5b6020830191508360208260051b850101111561169f57600080fd5b9250929050565b8035600481106115dc57600080fd5b600080600080606085870312156116cb57600080fd5b843567ffffffffffffffff8111156116e257600080fd5b6116ee8782880161165a565b90955093506117019050602086016116a6565b915060408501356117118161162f565b939692955090935050565b60008060006060848603121561173157600080fd5b8335925060208401359150611748604085016115c5565b90509250925092565b6020808252825182820181905260009190848201906040850190845b818110156117925783516001600160a01b03168352928401929184019160010161176d565b50909695505050505050565b6000602082840312156117b057600080fd5b5035919050565b600080604083850312156117ca57600080fd5b50508035926020909101359150565b6000806000606084860312156117ee57600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561181d57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561187957611879611840565b60405290565b604051610160810167ffffffffffffffff8111828210171561187957611879611840565b604051601f8201601f1916810167ffffffffffffffff811182821017156118cc576118cc611840565b604052919050565b600067ffffffffffffffff8211156118ee576118ee611840565b5060051b60200190565b803561ffff811681146115dc57600080fd5b803560ff811681146115dc57600080fd5b8035600281900b81146115dc57600080fd5b803562ffffff811681146115dc57600080fd5b600082601f83011261195157600080fd5b81356020611966611961836118d4565b6118a3565b82815260059290921b8401810191818101908684111561198557600080fd5b8286015b848110156115ba5780358352918301918301611989565b600082601f8301126119b157600080fd5b813560206119c1611961836118d4565b82815260059290921b840181019181810190868411156119e057600080fd5b8286015b848110156115ba57803567ffffffffffffffff811115611a045760008081fd5b8701603f81018913611a165760008081fd5b848101356040611a28611961836118d4565b8281526060928302840182019288820191908d851115611a485760008081fd5b948301945b84861015611aa55780868f031215611a655760008081fd5b611a6d611856565b611a76876118f8565b8152611a838b880161190a565b8b820152611a9285880161191b565b8186015283529485019491890191611a4d565b508752505050928401925083016119e4565b600080600060608486031215611acc57600080fd5b833567ffffffffffffffff80821115611ae457600080fd5b818601915086601f830112611af857600080fd5b81356020611b08611961836118d4565b82815260059290921b8401810191818101908a841115611b2757600080fd5b8286015b84811015611c5d57803586811115611b4257600080fd5b8701610160818e03601f19011215611b5957600080fd5b611b6161187f565b858201358152611b73604083016118f8565b86820152611b83606083016118f8565b604082015260808201356060820152611b9e60a0830161190a565b6080820152611baf60c0830161191b565b60a0820152611bc060e0830161192d565b60c082015261010082013588811115611bd857600080fd5b611be68f8883860101611940565b60e08301525061012082013588811115611bff57600080fd5b611c0d8f8883860101611940565b61010083015250611c21610140830161190a565b61012082015261016082013588811115611c3a57600080fd5b611c488f88838601016119a0565b61014083015250845250918301918301611b2b565b509750611c6d90508882016115c5565b955050505050611748604085016115c5565b600080600060408486031215611c9457600080fd5b833567ffffffffffffffff811115611cab57600080fd5b611cb78682870161165a565b9094509250506020840135611ccb8161162f565b809150509250925092565b60008060408385031215611ce957600080fd5b611cf2836115c5565b915061160b602084016116a6565b602080825260119082015270496e76616c69642073706f727473414d4d60781b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03841681526060810160048410611d8557634e487b7160e01b600052602160045260246000fd5b8360208301528215156040830152949350505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611dc357611dc3611d9b565b5060010190565b600060208284031215611ddc57600080fd5b81516109e38161162f565b818103818111156107ad576107ad611d9b565b634e487b7160e01b600052603160045260246000fd5b808201808211156107ad576107ad611d9b56fea2646970667358221220b23fe562e3a3b7e88bdd29fec22718b29679035117a75c46049af17ae5e22c0564736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638da5cb5b1161011a578063c4d66de8116100ad578063e760c3951161007c578063e760c39514610492578063e81e52ee146104a5578063f033d0f9146104b8578063f4b943cc146104cb578063f99d0cd0146104ee57600080fd5b8063c4d66de814610422578063c992528814610435578063d0972c171461044d578063dd37861d1461047f57600080fd5b80639a920a8b116100e95780639a920a8b146103e1578063a29ba83a146103e9578063bf457694146103fc578063c3b83f5f1461040f57600080fd5b80638da5cb5b146103895780639168fdd11461039c57806391b4ded9146103c557806391bf5be0146103ce57600080fd5b80634271f321116101925780635c975abb116101615780635c975abb1461034e57806368b350561461035b57806374606ede1461036e57806379ba50971461038157600080fd5b80634271f321146102d0578063485b23bf146102e357806353a47bb7146103035780635c3aa11b1461032e57600080fd5b806316c38b3c116101ce57806316c38b3c146102775780631f939b2d1461028a57806320dcb233146102ad57806321875b571461028a57600080fd5b806306ef03671461020057806313af4035146102155780631590a4a4146102285780631627540c14610264575b600080fd5b61021361020e3660046115e1565b61051c565b005b610213610223366004611614565b6105a7565b610251610236366004611614565b6001600160a01b031660009081526007602052604090205490565b6040519081526020015b60405180910390f35b610213610272366004611614565b6106d8565b61021361028536600461163d565b61072e565b61029d610298366004611614565b6107a0565b604051901515815260200161025b565b61029d6102bb366004611614565b600b6020526000908152604090205460ff1681565b6102136102de3660046116b5565b6107b3565b6102f66102f136600461171c565b6109ba565b60405161025b9190611751565b600154610316906001600160a01b031681565b6040516001600160a01b03909116815260200161025b565b61025161033c36600461179e565b60009081526009602052604090205490565b60035461029d9060ff1681565b6102f66103693660046117b7565b6109ea565b6102f661037c3660046117d9565b6109f8565b610213610a14565b600054610316906001600160a01b031681565b6102516103aa366004611614565b6001600160a01b031660009081526008602052604090205490565b61025160025481565b6102f66103dc366004611805565b610afe565b600554610251565b6102136103f7366004611ab7565b610b37565b61021361040a366004611c7f565b610db0565b61021361041d366004611614565b610ec9565b610213610430366004611614565b610fd2565b6003546103169061010090046001600160a01b031681565b61025161045b3660046117d9565b6000928352600a602090815260408085209385529281528284209184525290205490565b6102f661048d36600461171c565b6110e2565b61029d6104a0366004611cd6565b611108565b6102136104b3366004611614565b61115f565b6102136104c63660046115e1565b6111bd565b61029d6104d9366004611614565b600c6020526000908152604090205460ff1681565b61029d6104fc366004611cd6565b600460209081526000928352604080842090915290825290205460ff1681565b60035461010090046001600160a01b031633146105545760405162461bcd60e51b815260040161054b90611d00565b60405180910390fd5b61055f600583611215565b6001600160a01b03811660009081526007602052604090206105819083611215565b6001600160a01b03811660009081526008602052604090206105a3908361136e565b5050565b6001600160a01b0381166105fd5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640161054b565b600154600160a01b900460ff16156106695760405162461bcd60e51b815260206004820152602960248201527f416c726561647920696e697469616c697a65642c20757365206e6f6d696e617460448201526832a732bba7bbb732b960b91b606482015260840161054b565b6001805460ff60a01b1916600160a01b179055600080546001600160a01b0383166001600160a01b0319909116811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91015b60405180910390a150565b6106e06113c0565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016106cd565b6107366113c0565b60035460ff1615158115151461079d576003805460ff191682151590811790915560ff161561076457426002555b60035460405160ff909116151581527f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5906020016106cd565b50565b60006107ad600583611434565b92915050565b6107bb6113c0565b826108165760405162461bcd60e51b815260206004820152602560248201527f57686974656c6973746564206164647265737365732063616e6e6f7420626520604482015264656d70747960d81b606482015260840161054b565b60005b838110156109b3578115156004600087878581811061083a5761083a611d2b565b905060200201602081019061084f9190611614565b6001600160a01b03166001600160a01b03168152602001908152602001600020600085600381111561088357610883611d41565b600381111561089457610894611d41565b815260208101919091526040016000205460ff161515146109a15781600460008787858181106108c6576108c6611d2b565b90506020020160208101906108db9190611614565b6001600160a01b03166001600160a01b03168152602001908152602001600020600085600381111561090f5761090f611d41565b600381111561092057610920611d41565b81526020810191909152604001600020805460ff19169115159190911790557fdc4a00a0a7cce3b3f28b2988c80953b51cf6219d7335a63fe2262ff0de6c3a3285858381811061097257610972611d2b565b90506020020160208101906109879190611614565b848460405161099893929190611d57565b60405180910390a15b806109ab81611db1565b915050610819565b5050505050565b6001600160a01b03811660009081526008602052604090206060906109e09085856114aa565b90505b9392505050565b60606109e3600584846114aa565b60008181526009602052604090206060906109e09085856114aa565b6001546001600160a01b03163314610a8c5760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b606482015260840161054b565b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000838152600a6020908152604080832085845282528083208484529091529020606090610b2d9087876114aa565b9695505050505050565b60035461010090046001600160a01b03163314610b665760405162461bcd60e51b815260040161054b90611d00565b610b7160058361136e565b6001600160a01b0381166000908152600760205260409020610b93908361136e565b60005b8351811015610c9a57610be18360096000878581518110610bb957610bb9611d2b565b602002602001015160000151815260200190815260200160002061136e90919063ffffffff16565b610c8883600a6000878581518110610bfb57610bfb611d2b565b60200260200101516000015181526020019081526020016000206000878581518110610c2957610c29611d2b565b60200260200101516040015161ffff1681526020019081526020016000206000878581518110610c5b57610c5b611d2b565b602002602001015160c0015162ffffff16815260200190815260200160002061136e90919063ffffffff16565b80610c9281611db1565b915050610b96565b50816001600160a01b0316634652e3306040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfd9190611dca565b6001600160a01b0383166000818152600b6020908152604091829020805460ff1916941515949094179093558051631c98697960e01b815290519192631c986979926004808401938290030181865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d829190611dca565b6001600160a01b03929092166000908152600c60205260409020805460ff1916921515929092179091555050565b6000546001600160a01b0316331480610de457503360009081526004602090815260408083206003845290915290205460ff165b610e215760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103830bab9b2b960911b604482015260640161054b565b60005b82811015610ec357838382818110610e3e57610e3e611d2b565b9050602002016020810190610e539190611614565b6040516305b0e2cf60e21b815283151560048201526001600160a01b0391909116906316c38b3c90602401600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050508080610ebb90611db1565b915050610e24565b50505050565b610ed16113c0565b6001600160a01b038116610f195760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015260640161054b565b600154600160a81b900460ff1615610f695760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481d1c985b9cd9995c9c9959606a1b604482015260640161054b565b600080546001600160a01b0383166001600160a01b031990911681179091556001805460ff60a81b1916600160a81b1790556040805182815260208101929092527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016106cd565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff166000811580156110185750825b905060008267ffffffffffffffff1660011480156110355750303b155b905081158015611043575080155b156110615760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561108b57845460ff60401b1916600160401b1785555b611094866105a7565b83156110da57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b6001600160a01b03811660009081526007602052604090206060906109e09085856114aa565b6001600160a01b03821660009081526004602052604081208183600381111561113357611133611d41565b600381111561114457611144611d41565b815260208101919091526040016000205460ff169392505050565b6111676113c0565b60038054610100600160a81b0319166101006001600160a01b038416908102919091179091556040519081527f576297e5fcc8cd907ee80b240284865eb3d821bdc5232e6ee9e4d78a12531c09906020016106cd565b60035461010090046001600160a01b031633146111ec5760405162461bcd60e51b815260040161054b90611d00565b6111f7600583611215565b6001600160a01b03811660009081526007602052604090206105a390835b61121f8282611434565b6112615760405162461bcd60e51b815260206004820152601360248201527222b632b6b2b73a103737ba1034b71039b2ba1760691b604482015260640161054b565b6001600160a01b038116600090815260018084016020526040822054845490929161128b91611de7565b90508082146113175760008460000182815481106112ab576112ab611d2b565b60009182526020909120015485546001600160a01b03909116915081908690859081106112da576112da611d2b565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815260018601909152604090208290555b835484908061132857611328611dfa565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0394909416815260019490940190925250506040812055565b6113788282611434565b6105a35781546001600160a01b038216600081815260018086016020908152604083208590559084018655858252902090910180546001600160a01b03191690911790555050565b6000546001600160a01b031633146114325760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b606482015260840161054b565b565b81546000908103611447575060006107ad565b6001600160a01b0382166000908152600184016020526040902054801515806114a25750826001600160a01b03168460000160008154811061148b5761148b611d2b565b6000918252602090912001546001600160a01b0316145b949350505050565b606060006114b88385611e10565b85549091508111156114c8575083545b8381116114e55750506040805160008152602081019091526109e3565b60006114f18583611de7565b905060008167ffffffffffffffff81111561150e5761150e611840565b604051908082528060200260200182016040528015611537578160200160208202803683370190505b50905060005b828110156115ba57876115508883611e10565b8154811061156057611560611d2b565b9060005260206000200160009054906101000a90046001600160a01b031682828151811061159057611590611d2b565b6001600160a01b0390921660209283029190910190910152806115b281611db1565b91505061153d565b509695505050505050565b80356001600160a01b03811681146115dc57600080fd5b919050565b600080604083850312156115f457600080fd5b6115fd836115c5565b915061160b602084016115c5565b90509250929050565b60006020828403121561162657600080fd5b6109e3826115c5565b801515811461079d57600080fd5b60006020828403121561164f57600080fd5b81356109e38161162f565b60008083601f84011261166c57600080fd5b50813567ffffffffffffffff81111561168457600080fd5b6020830191508360208260051b850101111561169f57600080fd5b9250929050565b8035600481106115dc57600080fd5b600080600080606085870312156116cb57600080fd5b843567ffffffffffffffff8111156116e257600080fd5b6116ee8782880161165a565b90955093506117019050602086016116a6565b915060408501356117118161162f565b939692955090935050565b60008060006060848603121561173157600080fd5b8335925060208401359150611748604085016115c5565b90509250925092565b6020808252825182820181905260009190848201906040850190845b818110156117925783516001600160a01b03168352928401929184019160010161176d565b50909695505050505050565b6000602082840312156117b057600080fd5b5035919050565b600080604083850312156117ca57600080fd5b50508035926020909101359150565b6000806000606084860312156117ee57600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561181d57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561187957611879611840565b60405290565b604051610160810167ffffffffffffffff8111828210171561187957611879611840565b604051601f8201601f1916810167ffffffffffffffff811182821017156118cc576118cc611840565b604052919050565b600067ffffffffffffffff8211156118ee576118ee611840565b5060051b60200190565b803561ffff811681146115dc57600080fd5b803560ff811681146115dc57600080fd5b8035600281900b81146115dc57600080fd5b803562ffffff811681146115dc57600080fd5b600082601f83011261195157600080fd5b81356020611966611961836118d4565b6118a3565b82815260059290921b8401810191818101908684111561198557600080fd5b8286015b848110156115ba5780358352918301918301611989565b600082601f8301126119b157600080fd5b813560206119c1611961836118d4565b82815260059290921b840181019181810190868411156119e057600080fd5b8286015b848110156115ba57803567ffffffffffffffff811115611a045760008081fd5b8701603f81018913611a165760008081fd5b848101356040611a28611961836118d4565b8281526060928302840182019288820191908d851115611a485760008081fd5b948301945b84861015611aa55780868f031215611a655760008081fd5b611a6d611856565b611a76876118f8565b8152611a838b880161190a565b8b820152611a9285880161191b565b8186015283529485019491890191611a4d565b508752505050928401925083016119e4565b600080600060608486031215611acc57600080fd5b833567ffffffffffffffff80821115611ae457600080fd5b818601915086601f830112611af857600080fd5b81356020611b08611961836118d4565b82815260059290921b8401810191818101908a841115611b2757600080fd5b8286015b84811015611c5d57803586811115611b4257600080fd5b8701610160818e03601f19011215611b5957600080fd5b611b6161187f565b858201358152611b73604083016118f8565b86820152611b83606083016118f8565b604082015260808201356060820152611b9e60a0830161190a565b6080820152611baf60c0830161191b565b60a0820152611bc060e0830161192d565b60c082015261010082013588811115611bd857600080fd5b611be68f8883860101611940565b60e08301525061012082013588811115611bff57600080fd5b611c0d8f8883860101611940565b61010083015250611c21610140830161190a565b61012082015261016082013588811115611c3a57600080fd5b611c488f88838601016119a0565b61014083015250845250918301918301611b2b565b509750611c6d90508882016115c5565b955050505050611748604085016115c5565b600080600060408486031215611c9457600080fd5b833567ffffffffffffffff811115611cab57600080fd5b611cb78682870161165a565b9094509250506020840135611ccb8161162f565b809150509250925092565b60008060408385031215611ce957600080fd5b611cf2836115c5565b915061160b602084016116a6565b602080825260119082015270496e76616c69642073706f727473414d4d60781b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03841681526060810160048410611d8557634e487b7160e01b600052602160045260246000fd5b8360208301528215156040830152949350505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611dc357611dc3611d9b565b5060010190565b600060208284031215611ddc57600080fd5b81516109e38161162f565b818103818111156107ad576107ad611d9b565b634e487b7160e01b600052603160045260246000fd5b808201808211156107ad576107ad611d9b56fea2646970667358221220b23fe562e3a3b7e88bdd29fec22718b29679035117a75c46049af17ae5e22c0564736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.