ERC-20
Overview
Max Total Supply
1,483,132,095,919,655,982,101,730,053
Holders
887
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Balance
17,238,070,868,741,735,221,515Value
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
MorpherState
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity Multiple files format)
pragma solidity 0.5.16; import "./Ownable.sol"; import "./SafeMath.sol"; import "./IMorpherToken.sol"; // ---------------------------------------------------------------------------------- // Data and token balance storage of the Morpher platform // Writing access is only granted to platform contracts. The contract can be paused // by an elected platform administrator (see MorpherGovernance) to perform protocol updates. // ---------------------------------------------------------------------------------- contract MorpherState is Ownable { using SafeMath for uint256; bool public mainChain; uint256 public totalSupply; uint256 public totalToken; uint256 public totalInPositions; uint256 public totalOnOtherChain; uint256 public maximumLeverage = 10**9; // Leverage precision is 1e8, maximum leverage set to 10 initially uint256 constant PRECISION = 10**8; uint256 constant DECIMALS = 18; uint256 constant REWARDPERIOD = 1 days; bool public paused = false; address public morpherGovernance; address public morpherRewards; address public administrator; address public oracleContract; address public sideChainOperator; address public morpherBridge; address public morpherToken; uint256 public rewardBasisPoints; uint256 public lastRewardTime; bytes32 public sideChainMerkleRoot; uint256 public sideChainMerkleRootWrittenAtTime; // Set initial withdraw limit from sidechain to 20m token or 2% of initial supply uint256 public mainChainWithdrawLimit24 = 2 * 10**25; mapping(address => bool) private stateAccess; mapping(address => bool) private transferAllowed; mapping(address => uint256) private balances; mapping(address => mapping(address => uint256)) private allowed; mapping(bytes32 => bool) private marketActive; // ---------------------------------------------------------------------------- // Position struct records virtual futures // ---------------------------------------------------------------------------- struct position { uint256 lastUpdated; uint256 longShares; uint256 shortShares; uint256 meanEntryPrice; uint256 meanEntrySpread; uint256 meanEntryLeverage; uint256 liquidationPrice; bytes32 positionHash; } // ---------------------------------------------------------------------------- // A portfolio is an address specific collection of postions // ---------------------------------------------------------------------------- mapping(address => mapping(bytes32 => position)) private portfolio; // ---------------------------------------------------------------------------- // Record all addresses that hold a position of a market, needed for clean stock splits // ---------------------------------------------------------------------------- struct hasExposure { uint256 maxMappingIndex; mapping(address => uint256) index; mapping(uint256 => address) addy; } mapping(bytes32 => hasExposure) private exposureByMarket; // ---------------------------------------------------------------------------- // Bridge Variables // ---------------------------------------------------------------------------- mapping (address => uint256) private tokenClaimedOnThisChain; mapping (address => uint256) private tokenSentToLinkedChain; mapping (address => uint256) private tokenSentToLinkedChainTime; mapping (bytes32 => bool) private positionClaimedOnMainChain; uint256 public lastWithdrawLimitReductionTime; uint256 public last24HoursAmountWithdrawn; uint256 public withdrawLimit24Hours; uint256 public inactivityPeriod = 3 days; uint256 public transferNonce; bool public fastTransfersEnabled; // ---------------------------------------------------------------------------- // Sidechain spam protection // ---------------------------------------------------------------------------- mapping(address => uint256) private lastRequestBlock; mapping(address => uint256) private numberOfRequests; uint256 public numberOfRequestsLimit; // ---------------------------------------------------------------------------- // Events // ---------------------------------------------------------------------------- event StateAccessGranted(address indexed whiteList, uint256 indexed blockNumber); event StateAccessDenied(address indexed blackList, uint256 indexed blockNumber); event TransfersEnabled(address indexed whiteList); event TransfersDisabled(address indexed blackList); event Transfer(address indexed sender, address indexed recipient, uint256 amount); event Mint(address indexed recipient, uint256 amount, uint256 totalToken); event Burn(address indexed recipient, uint256 amount, uint256 totalToken); event NewTotalSupply(uint256 newTotalSupply); event NewTotalOnOtherChain(uint256 newTotalOnOtherChain); event NewTotalInPositions(uint256 newTotalOnOtherChain); event OperatingRewardMinted(address indexed recipient, uint256 amount); event RewardsChange(address indexed rewardsAddress, uint256 indexed rewardsBasisPoints); event LastRewardTime(uint256 indexed rewardsTime); event GovernanceChange(address indexed governanceAddress); event TokenChange(address indexed tokenAddress); event AdministratorChange(address indexed administratorAddress); event OracleChange(address indexed oracleContract); event MaximumLeverageChange(uint256 maxLeverage); event MarketActivated(bytes32 indexed activateMarket); event MarketDeActivated(bytes32 indexed deActivateMarket); event BridgeChange(address _bridgeAddress); event SideChainMerkleRootUpdate(bytes32 indexed sideChainMerkleRoot); event NewSideChainOperator(address indexed sideChainOperator); event NumberOfRequestsLimitUpdate(uint256 _numberOfRequests); event MainChainWithdrawLimitUpdate(uint256 indexed mainChainWithdrawLimit24); event TokenSentToLinkedChain(address _address, uint256 _token, uint256 _totalTokenSent, bytes32 indexed _tokenSentToLinkedChainHash); event TransferredTokenClaimed(address _address, uint256 _token); event LastWithdrawAt(); event RollingWithdrawnAmountUpdated(uint256 _last24HoursAmountWithdrawn, uint256 _lastWithdrawLimitReductionTime); event WithdrawLimitUpdated(uint256 _amount); event InactivityPeriodUpdated(uint256 _periodLength); event FastWithdrawsDisabled(); event NewBridgeNonce(uint256 _transferNonce); event Last24HoursAmountWithdrawnReset(); event StatePaused(address administrator, bool _paused); event SetAllowance(address indexed sender, address indexed spender, uint256 tokens); event SetPosition(bytes32 indexed positionHash, address indexed sender, bytes32 indexed marketId, uint256 timeStamp, uint256 longShares, uint256 shortShares, uint256 meanEntryPrice, uint256 meanEntrySpread, uint256 meanEntryLeverage, uint256 liquidationPrice ); event SetBalance(address indexed account, uint256 balance, bytes32 indexed balanceHash); event TokenTransferredToOtherChain(address indexed account, uint256 tokenTransferredToOtherChain, bytes32 indexed transferHash); modifier notPaused { require(paused == false, "MorpherState: Contract paused, aborting"); _; } modifier onlyPlatform { require(stateAccess[msg.sender] == true, "MorpherState: Only Platform is allowed to execute operation."); _; } modifier onlyGovernance { require(msg.sender == getGovernance(), "MorpherState: Calling contract not the Governance Contract. Aborting."); _; } modifier onlyAdministrator { require(msg.sender == getAdministrator(), "MorpherState: Caller is not the Administrator. Aborting."); _; } modifier onlySideChainOperator { require(msg.sender == sideChainOperator, "MorpherState: Caller is not the Sidechain Operator. Aborting."); _; } modifier canTransfer { require(getCanTransfer(msg.sender), "MorpherState: Caller may not transfer token. Aborting."); _; } modifier onlyBridge { require(msg.sender == getMorpherBridge(), "MorpherState: Caller is not the Bridge. Aborting."); _; } modifier onlyMainChain { require(mainChain == true, "MorpherState: Can only be called on mainchain."); _; } modifier onlySideChain { require(mainChain == false, "MorpherState: Can only be called on mainchain."); _; } constructor(bool _mainChain, address _sideChainOperator, address _morpherTreasury) public { // @Deployer: Transfer State Ownership to cold storage address after deploying protocol mainChain = _mainChain; // true for Ethereum, false for Morpher PoA sidechain setLastRewardTime(now); uint256 _sideChainMint = 575000000 * 10**(DECIMALS); uint256 _mainChainMint = 425000000 * 10**(DECIMALS); grantAccess(owner()); setSideChainOperator(owner()); if (mainChain == false) { // Create token only on sidechain balances[owner()] = _sideChainMint; // Create airdrop and team token on sidechain totalToken = _sideChainMint; emit Mint(owner(), balanceOf(owner()), _sideChainMint); setRewardBasisPoints(0); // Reward is minted on mainchain setRewardAddress(address(0)); setTotalOnOtherChain(_mainChainMint); } else { balances[owner()] = _mainChainMint; // Create treasury and investor token on mainchain totalToken = _mainChainMint; emit Mint(owner(), balanceOf(owner()), _mainChainMint); setRewardBasisPoints(15000); // 15000 / PRECISION = 0.00015 setRewardAddress(_morpherTreasury); setTotalOnOtherChain(_sideChainMint); } fastTransfersEnabled = true; setNumberOfRequestsLimit(3); setMainChainWithdrawLimit(totalSupply / 50); setSideChainOperator(_sideChainOperator); denyAccess(owner()); } // ---------------------------------------------------------------------------- // Setter/Getter functions for market wise exposure // ---------------------------------------------------------------------------- function getMaxMappingIndex(bytes32 _marketId) public view returns(uint256 _maxMappingIndex) { return exposureByMarket[_marketId].maxMappingIndex; } function getExposureMappingIndex(bytes32 _marketId, address _address) public view returns(uint256 _mappingIndex) { return exposureByMarket[_marketId].index[_address]; } function getExposureMappingAddress(bytes32 _marketId, uint256 _mappingIndex) public view returns(address _address) { return exposureByMarket[_marketId].addy[_mappingIndex]; } function setMaxMappingIndex(bytes32 _marketId, uint256 _maxMappingIndex) public onlyPlatform { exposureByMarket[_marketId].maxMappingIndex = _maxMappingIndex; } function setExposureMapping(bytes32 _marketId, address _address, uint256 _index) public onlyPlatform { setExposureMappingIndex(_marketId, _address, _index); setExposureMappingAddress(_marketId, _address, _index); } function setExposureMappingIndex(bytes32 _marketId, address _address, uint256 _index) public onlyPlatform { exposureByMarket[_marketId].index[_address] = _index; } function setExposureMappingAddress(bytes32 _marketId, address _address, uint256 _index) public onlyPlatform { exposureByMarket[_marketId].addy[_index] = _address; } // ---------------------------------------------------------------------------- // Setter/Getter functions for bridge variables // ---------------------------------------------------------------------------- function setTokenClaimedOnThisChain(address _address, uint256 _token) public onlyBridge { tokenClaimedOnThisChain[_address] = _token; emit TransferredTokenClaimed(_address, _token); } function getTokenClaimedOnThisChain(address _address) public view returns (uint256 _token) { return tokenClaimedOnThisChain[_address]; } function setTokenSentToLinkedChain(address _address, uint256 _token) public onlyBridge { tokenSentToLinkedChain[_address] = _token; tokenSentToLinkedChainTime[_address] = now; emit TokenSentToLinkedChain(_address, _token, tokenSentToLinkedChain[_address], getBalanceHash(_address, tokenSentToLinkedChain[_address])); } function getTokenSentToLinkedChain(address _address) public view returns (uint256 _token) { return tokenSentToLinkedChain[_address]; } function getTokenSentToLinkedChainTime(address _address) public view returns (uint256 _timeStamp) { return tokenSentToLinkedChainTime[_address]; } function add24HoursWithdrawn(uint256 _amount) public onlyBridge { last24HoursAmountWithdrawn = last24HoursAmountWithdrawn.add(_amount); emit RollingWithdrawnAmountUpdated(last24HoursAmountWithdrawn, lastWithdrawLimitReductionTime); } function update24HoursWithdrawLimit(uint256 _amount) public onlyBridge { if (last24HoursAmountWithdrawn > _amount) { last24HoursAmountWithdrawn = last24HoursAmountWithdrawn.sub(_amount); } else { last24HoursAmountWithdrawn = 0; } lastWithdrawLimitReductionTime = now; emit RollingWithdrawnAmountUpdated(last24HoursAmountWithdrawn, lastWithdrawLimitReductionTime); } function set24HourWithdrawLimit(uint256 _limit) public onlyBridge { withdrawLimit24Hours = _limit; emit WithdrawLimitUpdated(_limit); } function resetLast24HoursAmountWithdrawn() public onlyBridge { last24HoursAmountWithdrawn = 0; emit Last24HoursAmountWithdrawnReset(); } function setInactivityPeriod(uint256 _periodLength) public onlyBridge { inactivityPeriod = _periodLength; emit InactivityPeriodUpdated(_periodLength); } function getBridgeNonce() public onlyBridge returns (uint256 _nonce) { transferNonce++; emit NewBridgeNonce(transferNonce); return transferNonce; } function disableFastWithdraws() public onlyBridge { fastTransfersEnabled = false; emit FastWithdrawsDisabled(); } function setPositionClaimedOnMainChain(bytes32 _positionHash) public onlyBridge { positionClaimedOnMainChain[_positionHash] = true; } function getPositionClaimedOnMainChain(bytes32 _positionHash) public view returns (bool _alreadyClaimed) { return positionClaimedOnMainChain[_positionHash]; } // ---------------------------------------------------------------------------- // Setter/Getter functions for spam protection // ---------------------------------------------------------------------------- function setLastRequestBlock(address _address) public onlyPlatform { lastRequestBlock[_address] = block.number; } function getLastRequestBlock(address _address) public view returns(uint256 _lastRequestBlock) { return lastRequestBlock[_address]; } function setNumberOfRequests(address _address, uint256 _numberOfRequests) public onlyPlatform { numberOfRequests[_address] = _numberOfRequests; } function increaseNumberOfRequests(address _address) public onlyPlatform{ numberOfRequests[_address]++; } function getNumberOfRequests(address _address) public view returns(uint256 _numberOfRequests) { return numberOfRequests[_address]; } function setNumberOfRequestsLimit(uint256 _numberOfRequestsLimit) public onlyPlatform { numberOfRequestsLimit = _numberOfRequestsLimit; emit NumberOfRequestsLimitUpdate(_numberOfRequestsLimit); } function getNumberOfRequestsLimit() public view returns (uint256 _numberOfRequestsLimit) { return numberOfRequestsLimit; } function setMainChainWithdrawLimit(uint256 _mainChainWithdrawLimit24) public onlyOwner { mainChainWithdrawLimit24 = _mainChainWithdrawLimit24; emit MainChainWithdrawLimitUpdate(_mainChainWithdrawLimit24); } function getMainChainWithdrawLimit() public view returns (uint256 _mainChainWithdrawLimit24) { return mainChainWithdrawLimit24; } // ---------------------------------------------------------------------------- // Setter/Getter functions for state access // ---------------------------------------------------------------------------- function grantAccess(address _address) public onlyOwner { stateAccess[_address] = true; emit StateAccessGranted(_address, block.number); } function denyAccess(address _address) public onlyOwner { stateAccess[_address] = false; emit StateAccessDenied(_address, block.number); } function getStateAccess(address _address) public view returns(bool _hasAccess) { return stateAccess[_address]; } // ---------------------------------------------------------------------------- // Setter/Getter functions for addresses that can transfer tokens (sidechain only) // ---------------------------------------------------------------------------- function enableTransfers(address _address) public onlyOwner { transferAllowed[_address] = true; emit TransfersEnabled(_address); } function disableTransfers(address _address) public onlyOwner { transferAllowed[_address] = false; emit TransfersDisabled(_address); } function getCanTransfer(address _address) public view returns(bool _hasAccess) { return transferAllowed[_address]; } // ---------------------------------------------------------------------------- // Minting/burning/transfer of token // ---------------------------------------------------------------------------- function transfer(address _from, address _to, uint256 _token) public onlyPlatform notPaused { require(balances[_from] >= _token, "MorpherState: Not enough token."); balances[_from] = balances[_from].sub(_token); balances[_to] = balances[_to].add(_token); IMorpherToken(morpherToken).emitTransfer(_from, _to, _token); emit Transfer(_from, _to, _token); emit SetBalance(_from, balances[_from], getBalanceHash(_from, balances[_from])); emit SetBalance(_to, balances[_to], getBalanceHash(_to, balances[_to])); } function mint(address _address, uint256 _token) public onlyPlatform notPaused { balances[_address] = balances[_address].add(_token); totalToken = totalToken.add(_token); updateTotalSupply(); IMorpherToken(morpherToken).emitTransfer(address(0), _address, _token); emit Mint(_address, _token, totalToken); emit SetBalance(_address, balances[_address], getBalanceHash(_address, balances[_address])); } function burn(address _address, uint256 _token) public onlyPlatform notPaused { require(balances[_address] >= _token, "MorpherState: Not enough token."); balances[_address] = balances[_address].sub(_token); totalToken = totalToken.sub(_token); updateTotalSupply(); IMorpherToken(morpherToken).emitTransfer(_address, address(0), _token); emit Burn(_address, _token, totalToken); emit SetBalance(_address, balances[_address], getBalanceHash(_address, balances[_address])); } // ---------------------------------------------------------------------------- // Setter/Getter functions for balance and token functions (ERC20) // ---------------------------------------------------------------------------- function updateTotalSupply() private { totalSupply = totalToken.add(totalInPositions).add(totalOnOtherChain); emit NewTotalSupply(totalSupply); } function setTotalInPositions(uint256 _totalInPositions) public onlyAdministrator { totalInPositions = _totalInPositions; updateTotalSupply(); emit NewTotalInPositions(_totalInPositions); } function setTotalOnOtherChain(uint256 _newTotalOnOtherChain) public onlySideChainOperator { totalOnOtherChain = _newTotalOnOtherChain; updateTotalSupply(); emit NewTotalOnOtherChain(_newTotalOnOtherChain); } function balanceOf(address _tokenOwner) public view returns (uint256 balance) { return balances[_tokenOwner]; } function setAllowance(address _from, address _spender, uint256 _tokens) public onlyPlatform { allowed[_from][_spender] = _tokens; emit SetAllowance(_from, _spender, _tokens); } function getAllowance(address _tokenOwner, address spender) public view returns (uint256 remaining) { return allowed[_tokenOwner][spender]; } // ---------------------------------------------------------------------------- // Setter/Getter functions for platform roles // ---------------------------------------------------------------------------- function setGovernanceContract(address _newGovernanceContractAddress) public onlyOwner { morpherGovernance = _newGovernanceContractAddress; emit GovernanceChange(_newGovernanceContractAddress); } function getGovernance() public view returns (address _governanceContract) { return morpherGovernance; } function setMorpherBridge(address _newBridge) public onlyOwner { morpherBridge = _newBridge; emit BridgeChange(_newBridge); } function getMorpherBridge() public view returns (address _currentBridge) { return morpherBridge; } function setOracleContract(address _newOracleContract) public onlyGovernance { oracleContract = _newOracleContract; emit OracleChange(_newOracleContract); } function getOracleContract() public view returns(address) { return oracleContract; } function setTokenContract(address _newTokenContract) public onlyOwner { morpherToken = _newTokenContract; emit TokenChange(_newTokenContract); } function getTokenContract() public view returns(address) { return morpherToken; } function setAdministrator(address _newAdministrator) public onlyGovernance { administrator = _newAdministrator; emit AdministratorChange(_newAdministrator); } function getAdministrator() public view returns(address) { return administrator; } // ---------------------------------------------------------------------------- // Setter/Getter functions for platform operating rewards // ---------------------------------------------------------------------------- function setRewardAddress(address _newRewardsAddress) public onlyOwner { morpherRewards = _newRewardsAddress; emit RewardsChange(_newRewardsAddress, rewardBasisPoints); } function setRewardBasisPoints(uint256 _newRewardBasisPoints) public onlyOwner { if (mainChain == true) { require(_newRewardBasisPoints <= 15000, "MorpherState: Reward basis points need to be less or equal to 15000."); } else { require(_newRewardBasisPoints == 0, "MorpherState: Reward basis points can only be set on Ethereum."); } rewardBasisPoints = _newRewardBasisPoints; emit RewardsChange(morpherRewards, _newRewardBasisPoints); } function setLastRewardTime(uint256 _lastRewardTime) private { lastRewardTime = _lastRewardTime; emit LastRewardTime(_lastRewardTime); } // ---------------------------------------------------------------------------- // Setter/Getter functions for platform administration // ---------------------------------------------------------------------------- function activateMarket(bytes32 _activateMarket) public onlyAdministrator { marketActive[_activateMarket] = true; emit MarketActivated(_activateMarket); } function deActivateMarket(bytes32 _deActivateMarket) public onlyAdministrator { marketActive[_deActivateMarket] = false; emit MarketDeActivated(_deActivateMarket); } function getMarketActive(bytes32 _marketId) public view returns(bool _active) { return marketActive[_marketId]; } function setMaximumLeverage(uint256 _newMaximumLeverage) public onlyAdministrator { require(_newMaximumLeverage > PRECISION, "MorpherState: Leverage precision is 1e8"); maximumLeverage = _newMaximumLeverage; emit MaximumLeverageChange(_newMaximumLeverage); } function getMaximumLeverage() public view returns(uint256 _maxLeverage) { return maximumLeverage; } function pauseState() public onlyAdministrator { paused = true; emit StatePaused(msg.sender, true); } function unPauseState() public onlyAdministrator { paused = false; emit StatePaused(msg.sender, false); } // ---------------------------------------------------------------------------- // Setter/Getter for side chain state // ---------------------------------------------------------------------------- function setSideChainMerkleRoot(bytes32 _sideChainMerkleRoot) public onlyBridge { sideChainMerkleRoot = _sideChainMerkleRoot; sideChainMerkleRootWrittenAtTime = now; payOperatingReward; emit SideChainMerkleRootUpdate(_sideChainMerkleRoot); } function getSideChainMerkleRoot() public view returns(bytes32 _sideChainMerkleRoot) { return sideChainMerkleRoot; } function setSideChainOperator(address _address) public onlyOwner { sideChainOperator = _address; emit NewSideChainOperator(_address); } function getSideChainOperator() public view returns (address _address) { return sideChainOperator; } function getSideChainMerkleRootWrittenAtTime() public view returns(uint256 _sideChainMerkleRoot) { return sideChainMerkleRootWrittenAtTime; } // ---------------------------------------------------------------------------- // Setter/Getter functions for portfolio // ---------------------------------------------------------------------------- function setPosition( address _address, bytes32 _marketId, uint256 _timeStamp, uint256 _longShares, uint256 _shortShares, uint256 _meanEntryPrice, uint256 _meanEntrySpread, uint256 _meanEntryLeverage, uint256 _liquidationPrice ) public onlyPlatform { portfolio[_address][_marketId].lastUpdated = _timeStamp; portfolio[_address][_marketId].longShares = _longShares; portfolio[_address][_marketId].shortShares = _shortShares; portfolio[_address][_marketId].meanEntryPrice = _meanEntryPrice; portfolio[_address][_marketId].meanEntrySpread = _meanEntrySpread; portfolio[_address][_marketId].meanEntryLeverage = _meanEntryLeverage; portfolio[_address][_marketId].liquidationPrice = _liquidationPrice; portfolio[_address][_marketId].positionHash = getPositionHash( _address, _marketId, _timeStamp, _longShares, _shortShares, _meanEntryPrice, _meanEntrySpread, _meanEntryLeverage, _liquidationPrice ); if (_longShares > 0 || _shortShares > 0) { addExposureByMarket(_marketId, _address); } else { deleteExposureByMarket(_marketId, _address); } emit SetPosition( portfolio[_address][_marketId].positionHash, _address, _marketId, _timeStamp, _longShares, _shortShares, _meanEntryPrice, _meanEntrySpread, _meanEntryLeverage, _liquidationPrice ); } function getPosition( address _address, bytes32 _marketId ) public view returns ( uint256 _longShares, uint256 _shortShares, uint256 _meanEntryPrice, uint256 _meanEntrySpread, uint256 _meanEntryLeverage, uint256 _liquidationPrice ) { return( portfolio[_address][_marketId].longShares, portfolio[_address][_marketId].shortShares, portfolio[_address][_marketId].meanEntryPrice, portfolio[_address][_marketId].meanEntrySpread, portfolio[_address][_marketId].meanEntryLeverage, portfolio[_address][_marketId].liquidationPrice ); } function getPositionHash( address _address, bytes32 _marketId, uint256 _timeStamp, uint256 _longShares, uint256 _shortShares, uint256 _meanEntryPrice, uint256 _meanEntrySpread, uint256 _meanEntryLeverage, uint256 _liquidationPrice ) public pure returns (bytes32 _hash) { return keccak256( abi.encodePacked( _address, _marketId, _timeStamp, _longShares, _shortShares, _meanEntryPrice, _meanEntrySpread, _meanEntryLeverage, _liquidationPrice ) ); } function getBalanceHash(address _address, uint256 _balance) public pure returns (bytes32 _hash) { return keccak256(abi.encodePacked(_address, _balance)); } function getLastUpdated(address _address, bytes32 _marketId) public view returns (uint256 _lastUpdated) { return(portfolio[_address][_marketId].lastUpdated); } function getLongShares(address _address, bytes32 _marketId) public view returns (uint256 _longShares) { return(portfolio[_address][_marketId].longShares); } function getShortShares(address _address, bytes32 _marketId) public view returns (uint256 _shortShares) { return(portfolio[_address][_marketId].shortShares); } function getMeanEntryPrice(address _address, bytes32 _marketId) public view returns (uint256 _meanEntryPrice) { return(portfolio[_address][_marketId].meanEntryPrice); } function getMeanEntrySpread(address _address, bytes32 _marketId) public view returns (uint256 _meanEntrySpread) { return(portfolio[_address][_marketId].meanEntrySpread); } function getMeanEntryLeverage(address _address, bytes32 _marketId) public view returns (uint256 _meanEntryLeverage) { return(portfolio[_address][_marketId].meanEntryLeverage); } function getLiquidationPrice(address _address, bytes32 _marketId) public view returns (uint256 _liquidationPrice) { return(portfolio[_address][_marketId].liquidationPrice); } // ---------------------------------------------------------------------------- // Record positions by market by address. Needed for exposure aggregations // and spits and dividends. // ---------------------------------------------------------------------------- function addExposureByMarket(bytes32 _symbol, address _address) private { // Address must not be already recored uint256 _myExposureIndex = getExposureMappingIndex(_symbol, _address); if (_myExposureIndex == 0) { uint256 _maxMappingIndex = getMaxMappingIndex(_symbol).add(1); setMaxMappingIndex(_symbol, _maxMappingIndex); setExposureMapping(_symbol, _address, _maxMappingIndex); } } function deleteExposureByMarket(bytes32 _symbol, address _address) private { // Get my index in mapping uint256 _myExposureIndex = getExposureMappingIndex(_symbol, _address); // Get last element of mapping uint256 _lastIndex = getMaxMappingIndex(_symbol); address _lastAddress = getExposureMappingAddress(_symbol, _lastIndex); // If _myExposureIndex is greater than 0 (i.e. there is an exposure of that address on that market) delete it if (_myExposureIndex > 0) { // If _myExposureIndex is less than _lastIndex overwrite element at _myExposureIndex with element at _lastIndex in // deleted elements position. if (_myExposureIndex < _lastIndex) { setExposureMappingAddress(_symbol, _lastAddress, _myExposureIndex); setExposureMappingIndex(_symbol, _lastAddress, _myExposureIndex); } // Delete _lastIndex and _lastAddress element and reduce maxExposureIndex setExposureMappingAddress(_symbol, address(0), _lastIndex); setExposureMappingIndex(_symbol, _address, 0); // Shouldn't happen, but check that not empty if (_lastIndex > 0) { setMaxMappingIndex(_symbol, _lastIndex.sub(1)); } } } // ---------------------------------------------------------------------------- // Calculate and send operating reward // Every 24 hours the protocol mints rewardBasisPoints/(PRECISION) percent of the total // supply as reward for the protocol operator. The amount can not exceed 0.015% per // day. // ---------------------------------------------------------------------------- function payOperatingReward() public onlyMainChain { if (now > lastRewardTime.add(REWARDPERIOD)) { uint256 _reward = totalSupply.mul(rewardBasisPoints).div(PRECISION); setLastRewardTime(lastRewardTime.add(REWARDPERIOD)); mint(morpherRewards, _reward); emit OperatingRewardMinted(morpherRewards, _reward); } } }
pragma solidity 0.5.16; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
pragma solidity 0.5.16; interface IMorpherToken { /** * Emits a {Transfer} event in ERC-20 token contract. */ function emitTransfer(address _from, address _to, uint256 _amount) external; }
pragma solidity 0.5.16; /** * @dev These functions deal with verification of Merkle trees (hash trees), */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { require(proof.length < 100, "MerkleProof: proof too long. Use only sibling hashes."); bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash < proofElement) { // Hash(current computed hash + current element of the proof) computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { // Hash(current element of the proof + current computed hash) computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } } // Check if the computed hash (root) is equal to the provided root return computedHash == root; } }
pragma solidity 0.5.16; contract Migrations { address public owner; uint public last_completed_migration; modifier restricted() { if (msg.sender == owner) _; } constructor() public { owner = msg.sender; } function setCompleted(uint completed) public restricted { last_completed_migration = completed; } function upgrade(address new_address) public restricted { Migrations upgraded = Migrations(new_address); upgraded.setCompleted(last_completed_migration); } }
pragma solidity 0.5.16; import "./SafeMath.sol"; import "./MorpherState.sol"; import "./MorpherTradeEngine.sol"; // ---------------------------------------------------------------------------------- // Administrator of the Morpher platform // ---------------------------------------------------------------------------------- contract MorpherAdmin { MorpherState state; MorpherTradeEngine tradeEngine; using SafeMath for uint256; // ---------------------------------------------------------------------------- // Precision of prices and leverage // ---------------------------------------------------------------------------- modifier onlyAdministrator { require(msg.sender == state.getAdministrator(), "Function can only be called by the Administrator."); _; } constructor(address _stateAddress, address _tradeEngine) public { state = MorpherState(_stateAddress); tradeEngine = MorpherTradeEngine(_tradeEngine); } // ---------------------------------------------------------------------------- // Administrative functions // Set state address and maximum permitted leverage on platform // ---------------------------------------------------------------------------- function setMorpherState(address _stateAddress) public onlyAdministrator { state = MorpherState(_stateAddress); } function setMorpherTradeEngine(address _tradeEngine) public onlyAdministrator { tradeEngine = MorpherTradeEngine(_tradeEngine); } // ---------------------------------------------------------------------------------- // stockSplits(bytes32 _marketId, uint256 _fromIx, uint256 _toIx, uint256 _nominator, uint256 _denominator) // Experimental and untested // ---------------------------------------------------------------------------------- function stockSplits(bytes32 _marketId, uint256 _fromIx, uint256 _toIx, uint256 _nominator, uint256 _denominator) public onlyAdministrator { require(state.getMarketActive(_marketId) == false, "Market must be paused to process stock splits."); // If no _fromIx and _toIx specified, do entire _list if (_fromIx == 0) { _fromIx = 1; } if (_toIx == 0) { _toIx = state.getMaxMappingIndex(_marketId); } uint256 _positionLongShares; uint256 _positionShortShares; uint256 _positionAveragePrice; uint256 _positionAverageSpread; uint256 _positionAverageLeverage; uint256 _liquidationPrice; address _address; for (uint256 i = _fromIx; i <= _toIx; i++) { // GET position from state // multiply with nominator, divide by denominator (longShares/shortShares/meanEntry/meanSpread) // Write back to state _address = state.getExposureMappingAddress(_marketId, i); (_positionLongShares, _positionShortShares, _positionAveragePrice, _positionAverageSpread, _positionAverageLeverage, _liquidationPrice) = state.getPosition(_address, _marketId); _positionLongShares = _positionLongShares.mul(_denominator).div(_nominator); _positionShortShares = _positionShortShares.mul(_denominator).div(_nominator); _positionAveragePrice = _positionAveragePrice.mul(_nominator).div(_denominator); _positionAverageSpread = _positionAverageSpread.mul(_nominator).div(_denominator); if (_positionShortShares > 0) { _liquidationPrice = tradeEngine.getLiquidationPrice(_positionAveragePrice, _positionAverageLeverage, false); } else { _liquidationPrice = tradeEngine.getLiquidationPrice(_positionAveragePrice, _positionAverageLeverage, true); } state.setPosition(_address, _marketId, now, _positionLongShares, _positionShortShares, _positionAveragePrice, _positionAverageSpread, _positionAverageLeverage, _liquidationPrice); } } // ---------------------------------------------------------------------------------- // contractRolls(bytes32 _marketId, uint256 _fromIx, uint256 _toIx, uint256 _rollUp, uint256 _rollDown) // Experimental and untested // ---------------------------------------------------------------------------------- function contractRolls(bytes32 _marketId, uint256 _fromIx, uint256 _toIx, uint256 _rollUp, uint256 _rollDown) public onlyAdministrator { // If no _fromIx and _toIx specified, do entire _list // dividends set meanEntry down, rolls either up or down require(state.getMarketActive(_marketId) == false, "Market must be paused to process rolls."); // If no _fromIx and _toIx specified, do entire _list if (_fromIx == 0) { _fromIx = 1; } if (_toIx == 0) { _toIx = state.getMaxMappingIndex(_marketId); } uint256 _positionLongShares; uint256 _positionShortShares; uint256 _positionAveragePrice; uint256 _positionAverageSpread; uint256 _positionAverageLeverage; uint256 _liquidationPrice; address _address; for (uint256 i = _fromIx; i <= _toIx; i++) { // GET position from state // shift by _upMove and _downMove (one of them is supposed to be zero) // Write back to state _address = state.getExposureMappingAddress(_marketId, i); (_positionLongShares, _positionShortShares, _positionAveragePrice, _positionAverageSpread, _positionAverageLeverage, _liquidationPrice) = state.getPosition(_address, _marketId); _positionAveragePrice = _positionAveragePrice.add(_rollUp).sub(_rollDown); if (_positionShortShares > 0) { _liquidationPrice = tradeEngine.getLiquidationPrice(_positionAveragePrice, _positionAverageLeverage, false); } else { _liquidationPrice = tradeEngine.getLiquidationPrice(_positionAveragePrice, _positionAverageLeverage, true); } state.setPosition(_address, _marketId, now, _positionLongShares, _positionShortShares, _positionAveragePrice, _positionAverageSpread, _positionAverageLeverage, _liquidationPrice); } } // ---------------------------------------------------------------------------------- // stockDividends() // May want to add support for dividends later // ---------------------------------------------------------------------------------- /* function stockDividends(bytes32 _marketId, uint256 _fromIx, uint256 _toIx, uint256 _meanEntryUp, uint256 _meanEntryDown) public onlyOracle returns (bool _success){ } */ }
pragma solidity 0.5.16; import "./Ownable.sol"; import "./SafeMath.sol"; import "./IERC20.sol"; // ---------------------------------------------------------------------------------- // Holds the Airdrop Token balance on contract address // AirdropAdmin can authorize addresses to receive airdrop. // Users have to claim their airdrop actively or Admin initiates transfer. // ---------------------------------------------------------------------------------- contract MorpherAirdrop is Ownable { using SafeMath for uint256; // ---------------------------------------------------------------------------- // Mappings for authorized / claimed airdrop // ---------------------------------------------------------------------------- mapping(address => uint256) private airdropClaimed; mapping(address => uint256) private airdropAuthorized; uint256 public totalAirdropAuthorized; uint256 public totalAirdropClaimed; address public airdropAdmin; address public morpherToken; // ---------------------------------------------------------------------------- // Events // ---------------------------------------------------------------------------- event AirdropSent(address indexed _operator, address indexed _recipient, uint256 _amountClaimed, uint256 _amountAuthorized); event SetAirdropAuthorized(address indexed _recipient, uint256 _amountClaimed, uint256 _amountAuthorized); constructor(address _airdropAdminAddress, address _morpherToken, address _coldStorageOwnerAddress) public { setAirdropAdmin(_airdropAdminAddress); setMorpherTokenAddress(_morpherToken); transferOwnership(_coldStorageOwnerAddress); } modifier onlyAirdropAdmin { require(msg.sender == airdropAdmin, "MorpherAirdrop: can only be called by Airdrop Administrator."); _; } // ---------------------------------------------------------------------------- // Administrative functions // ---------------------------------------------------------------------------- function setAirdropAdmin(address _address) public onlyOwner { airdropAdmin = _address; } function setMorpherTokenAddress(address _address) public onlyOwner { morpherToken = _address; } // ---------------------------------------------------------------------------- // Get airdrop amount authorized for or claimed by address // ---------------------------------------------------------------------------- function getAirdropClaimed(address _userAddress) public view returns (uint256 _amount) { return airdropClaimed[_userAddress]; } function getAirdropAuthorized(address _userAddress) public view returns (uint256 _balance) { return airdropAuthorized[_userAddress]; } function getAirdrop(address _userAddress) public view returns(uint256 _claimed, uint256 _authorized) { return (airdropClaimed[_userAddress], airdropAuthorized[_userAddress]); } // ---------------------------------------------------------------------------- // Airdrop Administrator can authorize airdrop amount per address // ---------------------------------------------------------------------------- function setAirdropAuthorized(address _userAddress, uint256 _authorized) public onlyAirdropAdmin { // Can only set authorized amount to be higher than claimed require(_authorized >= airdropClaimed[_userAddress], "MorpherAirdrop: airdrop authorized must be larger than claimed."); // Authorized amount can be higher or lower than previously authorized amount, adjust accordingly totalAirdropAuthorized = totalAirdropAuthorized.sub(getAirdropAuthorized(_userAddress)).add(_authorized); airdropAuthorized[_userAddress] = _authorized; emit SetAirdropAuthorized(_userAddress, airdropClaimed[_userAddress], _authorized); } // ---------------------------------------------------------------------------- // User claims their entire airdrop // ---------------------------------------------------------------------------- function claimAirdrop() public { uint256 _amount = airdropAuthorized[msg.sender].sub(airdropClaimed[msg.sender]); _sendAirdrop(msg.sender, _amount); } // ---------------------------------------------------------------------------- // User claims part of their airdrop // ---------------------------------------------------------------------------- function claimSomeAirdrop(uint256 _amount) public { _sendAirdrop(msg.sender, _amount); } // ---------------------------------------------------------------------------- // Administrator sends user their entire airdrop // ---------------------------------------------------------------------------- function adminSendAirdrop(address _recipient) public onlyAirdropAdmin { uint256 _amount = airdropAuthorized[_recipient].sub(airdropClaimed[_recipient]); _sendAirdrop(_recipient, _amount); } // ---------------------------------------------------------------------------- // Administrator sends user part of their airdrop // ---------------------------------------------------------------------------- function adminSendSomeAirdrop(address _recipient, uint256 _amount) public onlyAirdropAdmin { _sendAirdrop(_recipient, _amount); } // ---------------------------------------------------------------------------- // Administrator sends user entire airdrop // ---------------------------------------------------------------------------- function _sendAirdrop(address _recipient, uint256 _amount) private { require(airdropAuthorized[_recipient] >= airdropClaimed[_recipient].add(_amount), "MorpherAirdrop: amount exceeds authorized airdrop amount."); airdropClaimed[_recipient] = airdropClaimed[_recipient].add(_amount); totalAirdropClaimed = totalAirdropClaimed.add(_amount); IERC20(morpherToken).transfer(_recipient, _amount); emit AirdropSent(msg.sender, _recipient, airdropClaimed[_recipient], airdropAuthorized[_recipient]); } // ---------------------------------------------------------------------------- // Administrator sends user part of their airdrop // ---------------------------------------------------------------------------- function adminAuthorizeAndSend(address _recipient, uint256 _amount) public onlyAirdropAdmin { setAirdropAuthorized(_recipient, getAirdropAuthorized(_recipient).add(_amount)); _sendAirdrop(_recipient, _amount); } // ------------------------------------------------------------------------ // Don't accept ETH // ------------------------------------------------------------------------ function () external payable { revert("MorpherAirdrop: you can't deposit Ether here"); } }
// ------------------------------------------------------------------------ // MorpherBridge // Handles deposit to and withdraws from the side chain, writing of the merkle // root to the main chain by the side chain operator, and enforces a rolling 24 hours // token withdraw limit from side chain to main chain. // If side chain operator doesn't write a merkle root hash to main chain for more than // 72 hours positions and balaces from side chain can be transferred to main chain. // ------------------------------------------------------------------------ pragma solidity 0.5.16; import "./Ownable.sol"; import "./SafeMath.sol"; import "./MorpherState.sol"; import "./MerkleProof.sol"; contract MorpherBridge is Ownable { MorpherState state; using SafeMath for uint256; event TransferToLinkedChain( address indexed from, uint256 tokens, uint256 totalTokenSent, uint256 timeStamp, uint256 transferNonce, bytes32 indexed transferHash ); event TrustlessWithdrawFromSideChain(address indexed from, uint256 tokens); event OperatorChainTransfer(address indexed from, uint256 tokens, bytes32 sidechainTransactionHash); event ClaimFailedTransferToSidechain(address indexed from, uint256 tokens); event PositionRecoveryFromSideChain(address indexed from, bytes32 positionHash); event TokenRecoveryFromSideChain(address indexed from, bytes32 positionHash); event SideChainMerkleRootUpdated(bytes32 _rootHash); event WithdrawLimitReset(); event WithdrawLimitChanged(uint256 _withdrawLimit); event LinkState(address _address); constructor(address _stateAddress, address _coldStorageOwnerAddress) public { setMorpherState(_stateAddress); transferOwnership(_coldStorageOwnerAddress); } modifier onlySideChainOperator { require(msg.sender == state.getSideChainOperator(), "MorpherBridge: Function can only be called by Sidechain Operator."); _; } modifier sideChainInactive { require(now - state.inactivityPeriod() > state.getSideChainMerkleRootWrittenAtTime(), "MorpherBridge: Function can only be called if sidechain is inactive."); _; } modifier fastTransfers { require(state.fastTransfersEnabled() == true, "MorpherBridge: Fast transfers have been disabled permanently."); _; } modifier onlyMainchain { require(state.mainChain() == true, "MorpherBridge: Function can only be executed on Ethereum." ); _; } // ------------------------------------------------------------------------ // Links Token Contract with State // ------------------------------------------------------------------------ function setMorpherState(address _stateAddress) public onlyOwner { state = MorpherState(_stateAddress); emit LinkState(_stateAddress); } function setInactivityPeriod(uint256 _periodInSeconds) private { state.setInactivityPeriod(_periodInSeconds); } function disableFastTransfers() public onlyOwner { state.disableFastWithdraws(); } function updateSideChainMerkleRoot(bytes32 _rootHash) public onlySideChainOperator { state.setSideChainMerkleRoot(_rootHash); emit SideChainMerkleRootUpdated(_rootHash); } function resetLast24HoursAmountWithdrawn() public onlySideChainOperator { state.resetLast24HoursAmountWithdrawn(); emit WithdrawLimitReset(); } function set24HourWithdrawLimit(uint256 _withdrawLimit) public onlySideChainOperator { state.set24HourWithdrawLimit(_withdrawLimit); emit WithdrawLimitChanged(_withdrawLimit); } function getTokenSentToLinkedChain(address _address) public view returns (uint256 _token) { return state.getTokenSentToLinkedChain(_address); } function getTokenClaimedOnThisChain(address _address) public view returns (uint256 _token) { return state.getTokenClaimedOnThisChain(_address); } function getTokenSentToLinkedChainTime(address _address) public view returns (uint256 _time) { return state.getTokenSentToLinkedChainTime(_address); } // ------------------------------------------------------------------------ // verifyWithdrawOk(uint256 _amount) // Checks if creating _amount token on main chain does not violate the 24 hour transfer limit // ------------------------------------------------------------------------ function verifyWithdrawOk(uint256 _amount) public returns (bool _authorized) { uint256 _lastWithdrawLimitReductionTime = state.lastWithdrawLimitReductionTime(); uint256 _withdrawLimit24Hours = state.withdrawLimit24Hours(); if (now > _lastWithdrawLimitReductionTime) { uint256 _timePassed = now.sub(_lastWithdrawLimitReductionTime); state.update24HoursWithdrawLimit(_timePassed.mul(_withdrawLimit24Hours).div(1 days)); } if (state.last24HoursAmountWithdrawn().add(_amount) <= _withdrawLimit24Hours) { return true; } else { return false; } } // ------------------------------------------------------------------------ // transferToSideChain(uint256 _tokens) // Transfer token to Morpher's side chain to trade without fees and near instant // settlement. // - Owner's account must have sufficient balance to transfer // - 0 value transfers are not supported // Token are burned on the main chain and are created and credited to msg.sender // on the side chain // ------------------------------------------------------------------------ function transferToSideChain(uint256 _tokens) public { require(_tokens >= 0, "MorpherBridge: Amount of tokens must be positive."); require(state.balanceOf(msg.sender) >= _tokens, "MorpherBridge: Insufficient balance."); state.burn(msg.sender, _tokens); uint256 _newTokenSentToLinkedChain = getTokenSentToLinkedChain(msg.sender).add(_tokens); uint256 _transferNonce = state.getBridgeNonce(); uint256 _timeStamp = now; bytes32 _transferHash = keccak256( abi.encodePacked( msg.sender, _tokens, _newTokenSentToLinkedChain, _timeStamp, _transferNonce ) ); state.setTokenSentToLinkedChain(msg.sender, _newTokenSentToLinkedChain); emit TransferToLinkedChain(msg.sender, _tokens, _newTokenSentToLinkedChain, _timeStamp, _transferNonce, _transferHash); } // ------------------------------------------------------------------------ // fastTransferFromSideChain(uint256 _numOfToken, uint256 _tokenBurnedOnLinkedChain, bytes32[] memory _proof) // The sidechain operator can credit users with token they burend on the sidechain. Transfers // happen immediately. To be removed after Beta. // ------------------------------------------------------------------------ function fastTransferFromSideChain(address _address, uint256 _numOfToken, uint256 _tokenBurnedOnLinkedChain, bytes32 _sidechainTransactionHash) public onlySideChainOperator fastTransfers { uint256 _tokenClaimed = state.getTokenClaimedOnThisChain(_address); require(verifyWithdrawOk(_numOfToken), "MorpherBridge: Withdraw amount exceeds permitted 24 hour limit. Please try again in a few hours."); require(_tokenClaimed.add(_numOfToken) <= _tokenBurnedOnLinkedChain, "MorpherBridge: Token amount exceeds token deleted on linked chain."); _chainTransfer(_address, _tokenClaimed, _numOfToken); emit OperatorChainTransfer(_address, _numOfToken, _sidechainTransactionHash); } // ------------------------------------------------------------------------ // trustlessTransferFromSideChain(uint256 _numOfToken, uint256 _claimLimit, bytes32[] memory _proof) // Performs a merkle proof on the number of token that have been burned by the user on the side chain. // If the number of token claimed on the main chain is less than the number of burned token on the side chain // the difference (or less) can be claimed on the main chain. // ------------------------------------------------------------------------ function trustlessTransferFromLinkedChain(uint256 _numOfToken, uint256 _claimLimit, bytes32[] memory _proof) public { bytes32 leaf = keccak256(abi.encodePacked(msg.sender, _claimLimit)); uint256 _tokenClaimed = state.getTokenClaimedOnThisChain(msg.sender); require(mProof(_proof, leaf), "MorpherBridge: Merkle Proof failed. Please make sure you entered the correct claim limit."); require(verifyWithdrawOk(_numOfToken), "MorpherBridge: Withdraw amount exceeds permitted 24 hour limit. Please try again in a few hours."); require(_tokenClaimed.add(_numOfToken) <= _claimLimit, "MorpherBridge: Token amount exceeds token deleted on linked chain."); _chainTransfer(msg.sender, _tokenClaimed, _numOfToken); emit TrustlessWithdrawFromSideChain(msg.sender, _numOfToken); } // ------------------------------------------------------------------------ // _chainTransfer(address _address, uint256 _tokenClaimed, uint256 _numOfToken) // Creates token on the chain for the user after proving their distruction on the // linked chain has been proven before // ------------------------------------------------------------------------ function _chainTransfer(address _address, uint256 _tokenClaimed, uint256 _numOfToken) private { state.setTokenClaimedOnThisChain(_address, _tokenClaimed.add(_numOfToken)); state.add24HoursWithdrawn(_numOfToken); state.mint(_address, _numOfToken); } // ------------------------------------------------------------------------ // claimFailedTransferToSidechain(uint256 _wrongSideChainBalance, bytes32[] memory _proof) // If token sent to side chain were not credited to the user on the side chain within inactivityPeriod // they can reclaim the token on the main chain by submitting the proof that their // side chain balance is less than the number of token sent from main chain. // ------------------------------------------------------------------------ function claimFailedTransferToSidechain(uint256 _wrongSideChainBalance, bytes32[] memory _proof) public { bytes32 leaf = keccak256(abi.encodePacked(msg.sender, _wrongSideChainBalance)); uint256 _tokenSentToLinkedChain = getTokenSentToLinkedChain(msg.sender); uint256 _tokenSentToLinkedChainTime = getTokenSentToLinkedChainTime(msg.sender); uint256 _inactivityPeriod = state.inactivityPeriod(); require(now > _tokenSentToLinkedChainTime.add(_inactivityPeriod), "MorpherBridge: Failed deposits can only be claimed after inactivity period."); require(_wrongSideChainBalance < _tokenSentToLinkedChain, "MorpherBridge: Other chain credit is greater equal to wrongSideChainBalance."); require(verifyWithdrawOk(_tokenSentToLinkedChain.sub(_wrongSideChainBalance)), "MorpherBridge: Claim amount exceeds permitted 24 hour limit."); require(mProof(_proof, leaf), "MorpherBridge: Merkle Proof failed. Enter total amount of deposits on side chain."); uint256 _claimAmount = _tokenSentToLinkedChain.sub(_wrongSideChainBalance); state.setTokenSentToLinkedChain(msg.sender, _tokenSentToLinkedChain.sub(_claimAmount)); state.add24HoursWithdrawn(_claimAmount); state.mint(msg.sender, _claimAmount); emit ClaimFailedTransferToSidechain(msg.sender, _claimAmount); } // ------------------------------------------------------------------------ // recoverPositionFromSideChain(bytes32[] memory _proof, bytes32 _leaf, bytes32 _marketId, uint256 _timeStamp, uint256 _longShares, uint256 _shortShares, uint256 _meanEntryPrice, uint256 _meanEntrySpread, uint256 _meanEntryLeverage) // Failsafe against side chain operator becoming inactive or withholding Times (Time withhold attack). // After 72 hours of no update of the side chain merkle root users can withdraw their last recorded // positions from side chain to main chain. Overwrites eventually existing position on main chain. // ------------------------------------------------------------------------ function recoverPositionFromSideChain( bytes32[] memory _proof, bytes32 _leaf, bytes32 _marketId, uint256 _timeStamp, uint256 _longShares, uint256 _shortShares, uint256 _meanEntryPrice, uint256 _meanEntrySpread, uint256 _meanEntryLeverage, uint256 _liquidationPrice ) public sideChainInactive onlyMainchain { require(_leaf == state.getPositionHash(msg.sender, _marketId, _timeStamp, _longShares, _shortShares, _meanEntryPrice, _meanEntrySpread, _meanEntryLeverage, _liquidationPrice), "MorpherBridge: leaf does not equal position hash."); require(state.getPositionClaimedOnMainChain(_leaf) == false, "MorpherBridge: Position already transferred."); require(mProof(_proof,_leaf) == true, "MorpherBridge: Merkle proof failed."); state.setPositionClaimedOnMainChain(_leaf); state.setPosition(msg.sender, _marketId, _timeStamp, _longShares, _shortShares, _meanEntryPrice, _meanEntrySpread, _meanEntryLeverage, _liquidationPrice); emit PositionRecoveryFromSideChain(msg.sender, _leaf); // Remark: After resuming operations side chain operator has 72 hours to sync and eliminate transferred positions on side chain to avoid double spend } // ------------------------------------------------------------------------ // recoverTokenFromSideChain(bytes32[] memory _proof, bytes32 _leaf, bytes32 _marketId, uint256 _timeStamp, uint256 _longShares, uint256 _shortShares, uint256 _meanEntryPrice, uint256 _meanEntrySpread, uint256 _meanEntryLeverage) // Failsafe against side chain operator becoming inactive or withholding times (time withhold attack). // After 72 hours of no update of the side chain merkle root users can withdraw their last recorded // token balance from side chain to main chain. // ------------------------------------------------------------------------ function recoverTokenFromSideChain(bytes32[] memory _proof, bytes32 _leaf, uint256 _balance) public sideChainInactive onlyMainchain { // Require side chain root hash not set on Mainchain for more than 72 hours (=3 days) require(_leaf == state.getBalanceHash(msg.sender, _balance), "MorpherBridge: Wrong balance."); require(state.getPositionClaimedOnMainChain(_leaf) == false, "MorpherBridge: Token already transferred."); require(mProof(_proof,_leaf) == true, "MorpherBridge: Merkle proof failed."); require(verifyWithdrawOk(_balance), "MorpherBridge: Withdraw amount exceeds permitted 24 hour limit."); state.setPositionClaimedOnMainChain(_leaf); _chainTransfer(msg.sender, state.getTokenClaimedOnThisChain(msg.sender), _balance); emit TokenRecoveryFromSideChain(msg.sender, _leaf); // Remark: Side chain operator must adjust side chain balances for token recoveries before restarting operations to avoid double spend } // ------------------------------------------------------------------------ // mProof(bytes32[] memory _proof, bytes32 _leaf) // Computes merkle proof against the root hash of the sidechain stored in Morpher state // ------------------------------------------------------------------------ function mProof(bytes32[] memory _proof, bytes32 _leaf) public view returns(bool _isTrue) { return MerkleProof.verify(_proof, state.getSideChainMerkleRoot(), _leaf); } }
pragma solidity 0.5.16; import "./Ownable.sol"; import "./SafeMath.sol"; import "./IERC20.sol"; // ---------------------------------------------------------------------------------- // Escrow contract to safely store and release the token allocated to Morpher at // protocol inception // ---------------------------------------------------------------------------------- contract MorpherEscrow is Ownable{ using SafeMath for uint256; uint256 public lastEscrowTransferTime; address public recipient; address public morpherToken; uint256 public constant RELEASEAMOUNT = 10**25; uint256 public constant RELEASEPERIOD = 30 days; event EscrowReleased(uint256 _released, uint256 _leftInEscrow); constructor(address _recipientAddress, address _morpherToken, address _coldStorageOwnerAddress) public { setRecipientAddress(_recipientAddress); setMorpherTokenAddress(_morpherToken); lastEscrowTransferTime = now; transferOwnership(_coldStorageOwnerAddress); } // ---------------------------------------------------------------------------------- // Owner can modify recipient address and update morpherToken adddress // ---------------------------------------------------------------------------------- function setRecipientAddress(address _recipientAddress) public onlyOwner { recipient = _recipientAddress; } function setMorpherTokenAddress(address _address) public onlyOwner { morpherToken = _address; } // ---------------------------------------------------------------------------------- // Anyone can release funds from escrow if enough time has elapsed // Every 30 days 1% of the total initial supply or 10m token are released to Morpher // ---------------------------------------------------------------------------------- function releaseFromEscrow() public { require(IERC20(morpherToken).balanceOf(address(this)) > 0, "No funds left in escrow."); uint256 _releasedAmount; if (now > lastEscrowTransferTime.add(RELEASEPERIOD)) { if (IERC20(morpherToken).balanceOf(address(this)) > RELEASEAMOUNT) { _releasedAmount = RELEASEAMOUNT; } else { _releasedAmount = IERC20(morpherToken).balanceOf(address(this)); } IERC20(morpherToken).transfer(recipient, _releasedAmount); lastEscrowTransferTime = lastEscrowTransferTime.add(RELEASEPERIOD); emit EscrowReleased(_releasedAmount, IERC20(morpherToken).balanceOf(address(this))); } } }
pragma solidity 0.5.16; // ------------------------------------------------------------------------ // Morpher Governance (MAIN CHAIN ONLY) // // Every user able and willig to lock up sufficient token can become a validator // of the Morpher protocol. Validators function similiar to a board of directors // and vote on the protocol Administrator and the Oracle contract. // The Administrator (=Protocol CEO) has the power to add/delete markets and to // pause the contracts to allow for updates. // The Oracle contract is the address of the contract allowed to fetch prices // from outside the smart contract. // // It becomes progressively harder to become a valdiator. Each new validator // has to lock up (numberOfValidators + 1) * 10m Morpher token. Upon stepping // down as validator only 99% of the locked up token are returned, the other 1% // are burned. // // Governance is expected to become more sophisticated in the future // ------------------------------------------------------------------------ import "./Ownable.sol"; import "./SafeMath.sol"; import "./MorpherState.sol"; contract MorpherGovernance is Ownable { using SafeMath for uint256; MorpherState state; event BecomeValidator(address indexed _sender, uint256 indexed _myValidatorIndex); event StepDownAsValidator(address indexed _sender, uint256 indexed _myValidatorIndex); event ElectedAdministrator(address indexed _administratorAddress, uint256 _votes); event ElectedOracle(address indexed _oracleAddress, uint256 _votes); uint256 public constant MINVALIDATORLOCKUP = 10**25; uint256 public constant MAXVALIDATORS = 21; uint256 public constant VALIDATORWARMUPPERIOD = 7 days; uint256 public numberOfValidators; uint256 public lastValidatorJoined; uint256 public rewardBasisPoints; address public morpherToken; mapping(address => uint256) private validatorIndex; mapping(address => uint256) private validatorJoinedAtTime; mapping(uint256 => address) private validatorAddress; mapping(address => address) private oracleVote; mapping(address => address) private administratorVote; mapping(address => uint256) private countVotes; constructor(address _stateAddress, address _coldStorageOwnerAddress) public { setMorpherState(_stateAddress); transferOwnership(_coldStorageOwnerAddress); } modifier onlyValidator() { require(isValidator(msg.sender), "MorpherGovernance: Only Validators can invoke that function."); _; } function setMorpherState(address _stateAddress) private { state = MorpherState(_stateAddress); } function setMorpherTokenAddress(address _address) public onlyOwner { morpherToken = _address; } function getValidatorAddress(uint256 _index) public view returns (address _address) { return validatorAddress[_index]; } function getValidatorIndex(address _address) public view returns (uint256 _index) { return validatorIndex[_address]; } function isValidator(address _address) public view returns (bool) { return validatorIndex[_address] > 0; } function setOracle(address _oracleAddress) private { state.setOracleContract(_oracleAddress); } function setAdministrator(address _administratorAddress) private { state.setAdministrator(_administratorAddress); } function getMorpherAdministrator() public view returns (address _address) { return state.getAdministrator(); } function getMorpherOracle() public view returns (address _address) { return state.getOracleContract(); } function getOracleVote(address _address) public view returns (address _votedOracleAddress) { return oracleVote[_address]; } function becomeValidator() public { // To become a validator you have to lock up 10m * (number of validators + 1) Morpher Token in escrow // After a warmup period of 7 days the new validator can vote on Oracle contract and protocol Administrator uint256 _requiredAmount = MINVALIDATORLOCKUP.mul(numberOfValidators.add(1)); require(state.balanceOf(msg.sender) >= _requiredAmount, "MorpherGovernance: Insufficient balance to become Validator."); require(isValidator(msg.sender) == false, "MorpherGovernance: Address is already Validator."); require(numberOfValidators <= MAXVALIDATORS, "MorpherGovernance: number of Validators can not exceed Max Validators."); state.transfer(msg.sender, address(this), _requiredAmount); numberOfValidators = numberOfValidators.add(1); validatorIndex[msg.sender] = numberOfValidators; validatorJoinedAtTime[msg.sender] = now; lastValidatorJoined = now; validatorAddress[numberOfValidators] = msg.sender; emit BecomeValidator(msg.sender, numberOfValidators); } function stepDownValidator() public onlyValidator { // Stepping down as validator nullifies the validator's votes and releases his token // from escrow. If the validator stepping down is not the validator that joined last, // all validators who joined after the validator stepping down receive 10^7 * 0.99 token from // escrow, and their validator ordinal number is reduced by one. E.g. if validator 3 of 5 steps down // validator 4 becomes validator 3, and validator 5 becomes validator 4. Both receive 10^7 * 0.99 token // from escrow, as their new position requires fewer token in lockup. 1% of the token released from escrow // are burned for every validator receiving a payout. // Burning prevents vote delay attacks: validators stepping down and re-joining could // delay votes for VALIDATORWARMUPPERIOD. uint256 _myValidatorIndex = validatorIndex[msg.sender]; require(state.balanceOf(address(this)) >= MINVALIDATORLOCKUP.mul(numberOfValidators), "MorpherGovernance: Escrow does not have enough funds. Should not happen."); // Stepping down as validator potentially releases token to the other validatorAddresses for (uint256 i = _myValidatorIndex; i < numberOfValidators; i++) { validatorAddress[i] = validatorAddress[i+1]; validatorIndex[validatorAddress[i]] = i; // Release 9.9m of token to every validator moving up, burn 0.1m token state.transfer(address(this), validatorAddress[i], MINVALIDATORLOCKUP.div(100).mul(99)); state.burn(address(this), MINVALIDATORLOCKUP.div(100)); } // Release 99% of escrow token of validator dropping out, burn 1% validatorAddress[numberOfValidators] = address(0); validatorIndex[msg.sender] = 0; validatorJoinedAtTime[msg.sender] = 0; oracleVote[msg.sender] = address(0); administratorVote[msg.sender] = address(0); numberOfValidators = numberOfValidators.sub(1); countOracleVote(); countAdministratorVote(); state.transfer(address(this), msg.sender, MINVALIDATORLOCKUP.mul(_myValidatorIndex).div(100).mul(99)); state.burn(address(this), MINVALIDATORLOCKUP.mul(_myValidatorIndex).div(100)); emit StepDownAsValidator(msg.sender, validatorIndex[msg.sender]); } function voteOracle(address _oracleAddress) public onlyValidator { require(validatorJoinedAtTime[msg.sender].add(VALIDATORWARMUPPERIOD) < now, "MorpherGovernance: Validator was just appointed and is not eligible to vote yet."); require(lastValidatorJoined.add(VALIDATORWARMUPPERIOD) < now, "MorpherGovernance: New validator joined the board recently, please wait for the end of the warm up period."); oracleVote[msg.sender] = _oracleAddress; // Count Oracle Votes (address _votedOracleAddress, uint256 _votes) = countOracleVote(); emit ElectedOracle(_votedOracleAddress, _votes); } function voteAdministrator(address _administratorAddress) public onlyValidator { require(validatorJoinedAtTime[msg.sender].add(VALIDATORWARMUPPERIOD) < now, "MorpherGovernance: Validator was just appointed and is not eligible to vote yet."); require(lastValidatorJoined.add(VALIDATORWARMUPPERIOD) < now, "MorpherGovernance: New validator joined the board recently, please wait for the end of the warm up period."); administratorVote[msg.sender] = _administratorAddress; // Count Administrator Votes (address _appointedAdministrator, uint256 _votes) = countAdministratorVote(); emit ElectedAdministrator(_appointedAdministrator, _votes); } function countOracleVote() public returns (address _votedOracleAddress, uint256 _votes) { // Count oracle votes for (uint256 i = 1; i <= numberOfValidators; i++) { countVotes[oracleVote[validatorAddress[i]]]++; if (countVotes[oracleVote[validatorAddress[i]]] > _votes) { _votes = countVotes[oracleVote[validatorAddress[i]]]; _votedOracleAddress = oracleVote[validatorAddress[i]]; } } // Evaluate: Simple majority of Validators resets oracleAddress if (_votes > numberOfValidators.div(2)) { setOracle(_votedOracleAddress); } for (uint256 i = 1; i <= numberOfValidators; i++) { countVotes[administratorVote[validatorAddress[i]]] = 0; } return(_votedOracleAddress, _votes); } function countAdministratorVote() public returns (address _appointedAdministrator, uint256 _votes) { // Count Administrator votes for (uint256 i=1; i<=numberOfValidators; i++) { countVotes[administratorVote[validatorAddress[i]]]++; if (countVotes[administratorVote[validatorAddress[i]]] > _votes) { _votes = countVotes[administratorVote[validatorAddress[i]]]; _appointedAdministrator = administratorVote[validatorAddress[i]]; } } // Evaluate: Simple majority of Validators resets administratorAddress if (_votes > numberOfValidators / 2) { setAdministrator(_appointedAdministrator); } for (uint256 i = 1; i <= numberOfValidators; i++) { countVotes[administratorVote[validatorAddress[i]]] = 0; } return(_appointedAdministrator, _votes); } }
pragma solidity 0.5.16; import "./Ownable.sol"; import "./MorpherTradeEngine.sol"; // ---------------------------------------------------------------------------------- // Morpher Oracle contract // The oracle initates a new trade by calling trade engine and requesting a new orderId. // An event is fired by the contract notifying the oracle operator to query a price/liquidation unchecked // for a market/user and return the information via the callback function. Since calling // the callback function requires gas, the user must send a fixed amount of Ether when // creating their order. // ---------------------------------------------------------------------------------- contract MorpherOracle is Ownable { MorpherTradeEngine tradeEngine; bool public paused; uint256 public gasForCallback; address payable public callBackCollectionAddress; mapping(address => bool) public callBackAddress; // ---------------------------------------------------------------------------------- // Events // ---------------------------------------------------------------------------------- event OrderCreated( bytes32 indexed _orderId, address indexed _address, bytes32 indexed _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage ); event LiquidationOrderCreated( bytes32 indexed _orderId, address _sender, address indexed _address, bytes32 indexed _marketId ); event OrderProcessed( bytes32 indexed _orderId, uint256 _price, uint256 _spread, uint256 _positionLiquidationTimestamp, uint256 _timeStamp, uint256 _newLongShares, uint256 _newShortShares, uint256 _newMeanEntry, uint256 _newMeanSprad, uint256 _newMeanLeverage, uint256 _liquidationPrice ); event OrderFailed( bytes32 indexed _orderId, address indexed _address, bytes32 indexed _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage ); event OrderCancelled( bytes32 indexed _orderId, address indexed _sender ); event CallbackAddressEnabled( address indexed _address ); event CallbackAddressDisabled( address indexed _address ); event OraclePaused( bool _paused ); event CallBackCollectionAddressChange( address _address ); event SetGasForCallback( uint256 _gasForCallback ); event LinkTradeEngine( address _address ); modifier onlyOracleOperator { require(isCallbackAddress(msg.sender), "MorpherOracle: Only the oracle operator can call this function."); _; } modifier notPaused { require(paused == false, "MorpherOracle: Oracle paused, aborting"); _; } constructor(address _tradeEngineAddress, address _callBackAddress, address payable _gasCollectionAddress, uint256 _gasForCallback, address _coldStorageOwnerAddress) public { setTradeEngineAddress(_tradeEngineAddress); enableCallbackAddress(_callBackAddress); setCallbackCollectionAddress(_gasCollectionAddress); setGasForCallback(_gasForCallback); transferOwnership(_coldStorageOwnerAddress); } // ---------------------------------------------------------------------------------- // Setter/getter functions for trade engine address, oracle operator (callback) address, // and prepaid gas limit for callback function // ---------------------------------------------------------------------------------- function setTradeEngineAddress(address _address) public onlyOwner { tradeEngine = MorpherTradeEngine(_address); emit LinkTradeEngine(_address); } function setGasForCallback(uint256 _gasForCallback) public onlyOwner { gasForCallback = _gasForCallback; emit SetGasForCallback(_gasForCallback); } function enableCallbackAddress(address _address) public onlyOwner { callBackAddress[_address] = true; emit CallbackAddressEnabled(_address); } function disableCallbackAddress(address _address) public onlyOwner { callBackAddress[_address] = false; emit CallbackAddressDisabled(_address); } function isCallbackAddress(address _address) public view returns (bool _isCallBackAddress) { return callBackAddress[_address]; } function setCallbackCollectionAddress(address payable _address) public onlyOwner { callBackCollectionAddress = _address; emit CallBackCollectionAddressChange(_address); } // ---------------------------------------------------------------------------------- // emitOrderFailed // Can be called by Oracle Operator to notifiy user of failed order // ---------------------------------------------------------------------------------- function emitOrderFailed( bytes32 _orderId, address _address, bytes32 _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage ) public onlyOracleOperator { emit OrderFailed( _orderId, _address, _marketId, _tradeAmountGivenInShares, _tradeAmount, _tradeDirection, _orderLeverage); } // ---------------------------------------------------------------------------------- // createOrder(bytes32 _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage) // Request a new orderId from trade engine and fires event for price/liquidation check request. // ---------------------------------------------------------------------------------- function createOrder( bytes32 _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage ) public payable notPaused returns (bytes32 _orderId) { if (gasForCallback > 0) { require(msg.value >= gasForCallback, "MorpherOracle: Must transfer gas costs for Oracle Callback function."); callBackCollectionAddress.transfer(msg.value); } _orderId = tradeEngine.requestOrderId(msg.sender, _marketId, _tradeAmountGivenInShares, _tradeAmount, _tradeDirection, _orderLeverage); emit OrderCreated( _orderId, msg.sender, _marketId, _tradeAmountGivenInShares, _tradeAmount, _tradeDirection, _orderLeverage ); return _orderId; } // ---------------------------------------------------------------------------------- // cancelOrder(bytes32 _orderId) // Users can cancel their own orders before the _callback has been executed // ---------------------------------------------------------------------------------- function cancelOrder(bytes32 _orderId) public { tradeEngine.cancelOrder(_orderId, msg.sender); emit OrderCancelled( _orderId, msg.sender ); } // ---------------------------------------------------------------------------------- // Setter/getter functions for pausing the Oracle contract // ---------------------------------------------------------------------------------- function pauseOracle() public onlyOwner { paused = true; emit OraclePaused(true); } function unpauseOracle() public onlyOwner { paused = false; emit OraclePaused(false); } // ---------------------------------------------------------------------------------- // createLiquidationOrder(address _address, bytes32 _marketId) // Checks if position has been liquidated since last check. Requires gas for callback // function. Anyone can issue a liquidation order for any other address and market. // ---------------------------------------------------------------------------------- function createLiquidationOrder( address _address, bytes32 _marketId ) public notPaused payable returns (bytes32 _orderId) { if (gasForCallback > 0) { require(msg.value >= gasForCallback, "MorpherOracle: Must transfer gas costs for Oracle Callback function."); callBackCollectionAddress.transfer(msg.value); } _orderId = tradeEngine.requestOrderId(_address, _marketId, true, 0, true, 10**8); emit LiquidationOrderCreated(_orderId, msg.sender, _address, _marketId); return _orderId; } // ---------------------------------------------------------------------------------- // __callback(bytes32 _orderId, uint256 _price, uint256 _spread, uint256 _liquidationTimestamp, uint256 _timeStamp) // Called by the oracle operator. Writes price/spread/liquidiation check to the blockchain. // Trade engine processes the order and updates the portfolio in state if successful. // ---------------------------------------------------------------------------------- function __callback( bytes32 _orderId, uint256 _price, uint256 _spread, uint256 _liquidationTimestamp, uint256 _timeStamp ) public onlyOracleOperator notPaused returns (uint256 _newLongShares, uint256 _newShortShares, uint256 _newMeanEntry, uint256 _newMeanSpread, uint256 _newMeanLeverage, uint256 _liquidationPrice) { ( _newLongShares, _newShortShares, _newMeanEntry, _newMeanSpread, _newMeanLeverage, _liquidationPrice ) = tradeEngine.processOrder(_orderId, _price, _spread, _liquidationTimestamp, _timeStamp); emit OrderProcessed( _orderId, _price, _spread, _liquidationTimestamp, _timeStamp, _newLongShares, _newShortShares, _newMeanEntry, _newMeanSpread, _newMeanLeverage, _liquidationPrice ); return (_newLongShares, _newShortShares, _newMeanEntry, _newMeanSpread, _newMeanLeverage, _liquidationPrice); } // ---------------------------------------------------------------------------------- // Auxiliary function to hash a string market name i.e. // "CRYPTO_BTC" => 0x0bc89e95f9fdaab7e8a11719155f2fd638cb0f665623f3d12aab71d1a125daf9; // ---------------------------------------------------------------------------------- function stringToHash(string memory _source) public pure returns (bytes32 _result) { return keccak256(abi.encodePacked(_source)); } }
pragma solidity 0.5.16; import "./IERC20.sol"; import "./Ownable.sol"; import "./SafeMath.sol"; import "./MorpherState.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20Mintable}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract MorpherToken is IERC20, Ownable { MorpherState state; using SafeMath for uint256; string public constant name = "Morpher"; string public constant symbol = "MPH"; uint8 public constant decimals = 18; modifier onlyState { require(msg.sender == address(state), "ERC20: caller must be MorpherState contract."); _; } modifier canTransfer { require(state.mainChain() == true || state.getCanTransfer(msg.sender), "ERC20: token transfers disabled on sidechain."); _; } event LinkState(address _address); // ------------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------------ constructor(address _stateAddress, address _coldStorageOwnerAddress) public { setMorpherState(_stateAddress); transferOwnership(_coldStorageOwnerAddress); } // ------------------------------------------------------------------------ // Links Token Contract with State // ------------------------------------------------------------------------ function setMorpherState(address _stateAddress) public onlyOwner { state = MorpherState(_stateAddress); emit LinkState(_stateAddress); } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return state.totalSupply(); } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address _account) public view returns (uint256) { return state.balanceOf(_account); } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. * * Emits a {Transfer} event via emitTransfer called by MorpherState */ function transfer(address _recipient, uint256 _amount) public returns (bool) { _transfer(msg.sender, _recipient, _amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address _owner, address _spender) public view returns (uint256) { return state.getAllowance(_owner, _spender); } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address _spender, uint256 _amount) public returns (bool) { _approve(msg.sender, _spender, _amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `_sender` and `_recipient` cannot be the zero address. * - `_sender` must have a balance of at least `amount`. * - the caller must have allowance for `_sender`'s tokens of at least * `amount`. */ function transferFrom(address _sender, address _recipient, uint256 amount) public returns (bool) { _transfer(_sender, _recipient, amount); _approve(_sender, msg.sender, state.getAllowance(_sender, msg.sender).sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `_spender` cannot be the zero address. */ function increaseAllowance(address _spender, uint256 _addedValue) public returns (bool) { _approve(msg.sender, _spender, state.getAllowance(msg.sender, _spender).add(_addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address _spender, uint256 _subtractedValue) public returns (bool) { _approve(msg.sender, _spender, state.getAllowance(msg.sender, _spender).sub(_subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Caller destroys `_amount` tokens permanently * * Emits a {Transfer} event to zero address called by MorpherState via emitTransfer. * * Requirements: * * - Caller must have token balance of at least `_amount` * */ function burn(uint256 _amount) public returns (bool) { state.burn(msg.sender, _amount); return true; } /** * @dev Emits a {Transfer} event * * MorpherState emits a {Transfer} event. * * Requirements: * * - Caller must be MorpherState * */ function emitTransfer(address _from, address _to, uint256 _amount) public onlyState { emit Transfer(_from, _to, _amount); } /** * @dev Moves tokens `_amount` from `sender` to `_recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event via emitTransfer called by MorpherState * * Requirements: * * - `_sender` cannot be the zero address. * - `_recipient` cannot be the zero address. * - `_sender` must have a balance of at least `_amount`. */ function _transfer(address _sender, address _recipient, uint256 _amount) canTransfer internal { require(_sender != address(0), "ERC20: transfer from the zero address"); require(_recipient != address(0), "ERC20: transfer to the zero address"); require(state.balanceOf(_sender) >= _amount, "ERC20: transfer amount exceeds balance"); state.transfer(_sender, _recipient, _amount); } /** * @dev Sets `_amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address _owner, address _spender, uint256 _amount) internal { require(_owner != address(0), "ERC20: approve from the zero address"); require(_spender != address(0), "ERC20: approve to the zero address"); state.setAllowance(_owner, _spender, _amount); emit Approval(_owner, _spender, _amount); } // ------------------------------------------------------------------------ // Don't accept ETH // ------------------------------------------------------------------------ function () external payable { revert("ERC20: You can't deposit Ether here"); } }
pragma solidity 0.5.16; import "./Ownable.sol"; import "./SafeMath.sol"; import "./MorpherState.sol"; // ---------------------------------------------------------------------------------- // Tradeengine of the Morpher platform // Creates and processes orders, and computes the state change of portfolio. // Needs writing/reading access to/from Morpher State. Order objects are stored locally, // portfolios are stored in state. // ---------------------------------------------------------------------------------- contract MorpherTradeEngine is Ownable { MorpherState state; using SafeMath for uint256; // ---------------------------------------------------------------------------- // Precision of prices and leverage // ---------------------------------------------------------------------------- uint256 constant PRECISION = 10**8; uint256 public orderNonce; bytes32 public lastOrderId; // ---------------------------------------------------------------------------- // Order struct contains all order specific varibles. Variables are completed // during processing of trade. State changes are saved in the order struct as // well, since local variables would lead to stack to deep errors *sigh*. // ---------------------------------------------------------------------------- struct order { address userId; bool tradeAmountGivenInShares; bytes32 marketId; uint256 tradeAmount; bool tradeDirection; // true = long, false = short uint256 liquidationTimestamp; uint256 marketPrice; uint256 marketSpread; uint256 orderLeverage; uint256 timeStamp; uint256 longSharesOrder; uint256 shortSharesOrder; uint256 balanceDown; uint256 balanceUp; uint256 newLongShares; uint256 newShortShares; uint256 newMeanEntryPrice; uint256 newMeanEntrySpread; uint256 newMeanEntryLeverage; uint256 newLiquidationPrice; } mapping(bytes32 => order) private orders; // ---------------------------------------------------------------------------- // Events // Order created/processed events are fired by MorpherOracle. // ---------------------------------------------------------------------------- event PositionLiquidated( address indexed _address, bytes32 indexed _marketId, bool _longPosition, uint256 _timeStamp, uint256 _marketPrice, uint256 _marketSpread ); event OrderCancelled( bytes32 indexed _orderId, address indexed _address ); event OrderIdRequested( bytes32 _orderId, address indexed _address, bytes32 indexed _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage ); event OrderProcessed( bytes32 _orderId, uint256 _marketPrice, uint256 _marketSpread, uint256 _liquidationTimestamp, uint256 _timeStamp, uint256 _newLongShares, uint256 _newShortShares, uint256 _newAverageEntry, uint256 _newAverageSpread, uint256 _newAverageLeverage, uint256 _liquidationPrice ); event PositionUpdated( address _userId, bytes32 _marketId, uint256 _timeStamp, uint256 _newLongShares, uint256 _newShortShares, uint256 _newMeanEntryPrice, uint256 _newMeanEntrySpread, uint256 _newMeanEntryLeverage, uint256 _newLiquidationPrice, uint256 _mint, uint256 _burn ); event LinkState(address _address); constructor(address _stateAddress, address _coldStorageOwnerAddress) public { setMorpherState(_stateAddress); transferOwnership(_coldStorageOwnerAddress); } modifier onlyOracle { require(msg.sender == state.getOracleContract(), "MorpherTradeEngine: function can only be called by Oracle Contract."); _; } modifier onlyAdministrator { require(msg.sender == getAdministrator(), "MorpherTradeEngine: function can only be called by the Administrator."); _; } // ---------------------------------------------------------------------------- // Administrative functions // Set state address, get administrator address // ---------------------------------------------------------------------------- function setMorpherState(address _stateAddress) public onlyOwner { state = MorpherState(_stateAddress); emit LinkState(_stateAddress); } function getAdministrator() public view returns(address _administrator) { return state.getAdministrator(); } // ---------------------------------------------------------------------------- // requestOrderId(address _address, bytes32 _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage) // Creates a new order object with unique orderId and assigns order information. // Must be called by MorpherOracle contract. // ---------------------------------------------------------------------------- function requestOrderId( address _address, bytes32 _marketId, bool _tradeAmountGivenInShares, uint256 _tradeAmount, bool _tradeDirection, uint256 _orderLeverage ) public onlyOracle returns (bytes32 _orderId) { require(_orderLeverage >= PRECISION, "MorpherTradeEngine: leverage too small. Leverage precision is 1e8"); require(_orderLeverage <= state.getMaximumLeverage(), "MorpherTradeEngine: leverage exceeds maximum allowed leverage."); require(state.getMarketActive(_marketId) == true, "MorpherTradeEngine: market unknown or currently not enabled for trading."); require(state.getNumberOfRequests(_address) <= state.getNumberOfRequestsLimit() || state.getLastRequestBlock(_address) < block.number, "MorpherTradeEngine: request exceeded maximum permitted requests per block." ); state.setLastRequestBlock(_address); state.increaseNumberOfRequests(_address); orderNonce++; _orderId = keccak256( abi.encodePacked( _address, block.number, _marketId, _tradeAmountGivenInShares, _tradeAmount, _tradeDirection, _orderLeverage, orderNonce ) ); lastOrderId = _orderId; orders[_orderId].userId = _address; orders[_orderId].marketId = _marketId; orders[_orderId].tradeAmountGivenInShares = _tradeAmountGivenInShares; orders[_orderId].tradeAmount = _tradeAmount; orders[_orderId].tradeDirection = _tradeDirection; orders[_orderId].orderLeverage = _orderLeverage; emit OrderIdRequested( _orderId, _address, _marketId, _tradeAmountGivenInShares, _tradeAmount, _tradeDirection, _orderLeverage ); return _orderId; } // ---------------------------------------------------------------------------- // Getter functions for orders, shares, and positions // ---------------------------------------------------------------------------- function getOrder(bytes32 _orderId) public view returns ( address _userId, bytes32 _marketId, uint256 _tradeAmount, uint256 _marketPrice, uint256 _marketSpread, uint256 _orderLeverage ) { return( orders[_orderId].userId, orders[_orderId].marketId, orders[_orderId].tradeAmount, orders[_orderId].marketPrice, orders[_orderId].marketSpread, orders[_orderId].orderLeverage ); } function getOrderShares(bytes32 _orderId) public view returns ( uint256 _longSharesOrder, uint256 _shortSharesOrder, uint256 _tradeAmount, bool _tradeDirection, uint256 _balanceUp, uint256 _balanceDown) { return( orders[_orderId].longSharesOrder, orders[_orderId].shortSharesOrder, orders[_orderId].tradeAmount, orders[_orderId].tradeDirection, orders[_orderId].balanceUp, orders[_orderId].balanceDown ); } function getPosition(address _address, bytes32 _marketId) public view returns ( uint256 _positionLongShares, uint256 _positionShortShares, uint256 _positionAveragePrice, uint256 _positionAverageSpread, uint256 _positionAverageLeverage, uint256 _liquidationPrice ) { return( state.getLongShares(_address, _marketId), state.getShortShares(_address, _marketId), state.getMeanEntryPrice(_address,_marketId), state.getMeanEntrySpread(_address,_marketId), state.getMeanEntryLeverage(_address,_marketId), state.getLiquidationPrice(_address,_marketId) ); } // ---------------------------------------------------------------------------- // liquidate(bytes32 _orderId) // Checks for bankruptcy of position between its last update and now // Time check is necessary to avoid two consecutive / unorderded liquidations // ---------------------------------------------------------------------------- function liquidate(bytes32 _orderId) private { address _address = orders[_orderId].userId; bytes32 _marketId = orders[_orderId].marketId; uint256 _liquidationTimestamp = orders[_orderId].liquidationTimestamp; if (_liquidationTimestamp > state.getLastUpdated(_address, _marketId)) { if (state.getLongShares(_address,_marketId) > 0) { state.setPosition( _address, _marketId, orders[_orderId].timeStamp, 0, state.getShortShares(_address, _marketId), 0, 0, PRECISION, 0); emit PositionLiquidated( _address, _marketId, true, orders[_orderId].timeStamp, orders[_orderId].marketPrice, orders[_orderId].marketSpread ); } if (state.getShortShares(_address,_marketId) > 0) { state.setPosition( _address, _marketId, orders[_orderId].timeStamp, state.getLongShares(_address, _marketId), 0, 0, 0, PRECISION, 0 ); emit PositionLiquidated( _address, _marketId, false, orders[_orderId].timeStamp, orders[_orderId].marketPrice, orders[_orderId].marketSpread ); } } } // ---------------------------------------------------------------------------- // processOrder(bytes32 _orderId, uint256 _marketPrice, uint256 _marketSpread, uint256 _liquidationTimestamp, uint256 _timeStamp) // ProcessOrder receives the price/spread/liqidation information from the Oracle and // triggers the processing of the order. If successful, processOrder updates the portfolio state. // Liquidation time check is necessary to avoid two consecutive / unorderded liquidations // ---------------------------------------------------------------------------- function processOrder( bytes32 _orderId, uint256 _marketPrice, uint256 _marketSpread, uint256 _liquidationTimestamp, uint256 _timeStamp ) public onlyOracle returns ( uint256 _newLongShares, uint256 _newShortShares, uint256 _newAverageEntry, uint256 _newAverageSpread, uint256 _newAverageLeverage, uint256 _liquidationPrice ) { require(orders[_orderId].userId != address(0), "MorpherTradeEngine: unable to process, order has been deleted."); require(_marketPrice > 0, "MorpherTradeEngine: market priced at zero. Buy order cannot be processed."); require(_marketPrice >= _marketSpread, "MorpherTradeEngine: market price lower then market spread. Order cannot be processed."); address _address = orders[_orderId].userId; bytes32 _marketId = orders[_orderId].marketId; require(state.getMarketActive(_marketId) == true, "MorpherTradeEngine: market unknown or currently not enabled for trading."); orders[_orderId].marketPrice = _marketPrice; orders[_orderId].marketSpread = _marketSpread; orders[_orderId].timeStamp = _timeStamp; orders[_orderId].liquidationTimestamp = _liquidationTimestamp; // Check if previous position on that market was liquidated if (_liquidationTimestamp > state.getLastUpdated(_address, _marketId)) { liquidate(_orderId); } if (orders[_orderId].tradeAmount > 0) { if (orders[_orderId].tradeDirection) { processBuyOrder(_orderId); } else { processSellOrder(_orderId); } } delete orders[_orderId]; emit OrderProcessed( _orderId, _marketPrice, _marketSpread, _liquidationTimestamp, _timeStamp, _newLongShares, _newShortShares, _newAverageEntry, _newAverageSpread, _newAverageLeverage, _liquidationPrice ); return ( state.getLongShares(_address, _marketId), state.getShortShares(_address, _marketId), state.getMeanEntryPrice(_address,_marketId), state.getMeanEntrySpread(_address,_marketId), state.getMeanEntryLeverage(_address,_marketId), state.getLiquidationPrice(_address,_marketId) ); } // ---------------------------------------------------------------------------- // function cancelOrder(bytes32 _orderId, address _address) // Users or Administrator can delete pending orders before the callback went through // ---------------------------------------------------------------------------- function cancelOrder(bytes32 _orderId, address _address) public onlyOracle { require(_address == orders[_orderId].userId || _address == getAdministrator(), "MorpherTradeEngine: only Administrator or user can cancel an order."); require(orders[_orderId].userId != address(0), "MorpherTradeEngine: unable to process, order does not exist."); delete orders[_orderId]; emit OrderCancelled(_orderId, _address); } // ---------------------------------------------------------------------------- // shortShareValue / longShareValue compute the value of a virtual future // given current price/spread/leverage of the market and mean price/spread/leverage // at the beginning of the trade // ---------------------------------------------------------------------------- function shortShareValue( uint256 _positionAveragePrice, uint256 _positionAverageLeverage, uint256 _liquidationPrice, uint256 _marketPrice, uint256 _marketSpread, uint256 _orderLeverage, bool _sell ) public pure returns (uint256 _shareValue) { uint256 _averagePrice = _positionAveragePrice; uint256 _averageLeverage = _positionAverageLeverage; if (_positionAverageLeverage < PRECISION) { // Leverage can never be less than 1. Fail safe for empty positions, i.e. undefined _positionAverageLeverage _averageLeverage = PRECISION; } if (_sell == false) { // New short position // It costs marketPrice + marketSpread to build up a new short position _averagePrice = _marketPrice; // This is the average Leverage _averageLeverage = _orderLeverage; } if ( _liquidationPrice <= _marketPrice ) { // Position is worthless _shareValue = 0; } else { // The regular share value is 2x the entry price minus the current price for short positions. _shareValue = _averagePrice.mul((PRECISION.add(_averageLeverage))).div(PRECISION); _shareValue = _shareValue.sub(_marketPrice.mul(_averageLeverage).div(PRECISION)); if (_sell == true) { // We have to reduce the share value by the average spread (i.e. the average expense to build up the position) // and reduce the value further by the spread for selling. _shareValue = _shareValue.sub(_marketSpread.mul(_averageLeverage).div(PRECISION)); } else { // If a new short position is built up each share costs value + spread _shareValue = _shareValue.add(_marketSpread.mul(_orderLeverage).div(PRECISION)); } } return _shareValue; } function longShareValue( uint256 _positionAveragePrice, uint256 _positionAverageLeverage, uint256 _liquidationPrice, uint256 _marketPrice, uint256 _marketSpread, uint256 _orderLeverage, bool _sell ) public pure returns (uint256 _shareValue) { uint256 _averagePrice = _positionAveragePrice; uint256 _averageLeverage = _positionAverageLeverage; if (_positionAverageLeverage < PRECISION) { // Leverage can never be less than 1. Fail safe for empty positions, i.e. undefined _positionAverageLeverage _averageLeverage = PRECISION; } if (_sell == false) { // New long position // It costs marketPrice + marketSpread to build up a new long position _averagePrice = _marketPrice; // This is the average Leverage _averageLeverage = _orderLeverage; } if ( _marketPrice <= _liquidationPrice ) { // Position is worthless _shareValue = 0; } else { _shareValue = _averagePrice.mul(_averageLeverage.sub(PRECISION)).div(PRECISION); // The regular share value is market price times leverage minus entry price times entry leverage minus one. _shareValue = (_marketPrice.mul(_averageLeverage).div(PRECISION)).sub(_shareValue); if (_sell == true) { // We sell a long and have to correct the shareValue with the averageSpread and the currentSpread for selling. _shareValue = _shareValue.sub(_marketSpread.mul(_averageLeverage).div(PRECISION)); } else { // We buy a new long position and have to pay the spread _shareValue = _shareValue.add(_marketSpread.mul(_orderLeverage).div(PRECISION)); } } return _shareValue; } // ---------------------------------------------------------------------------- // processBuyOrder(bytes32 _orderId) // Converts orders specified in virtual shares to orders specified in Morpher token // and computes the number of short shares that are sold and long shares that are bought. // long shares are bought only if the order amount exceeds all open short positions // ---------------------------------------------------------------------------- function processBuyOrder(bytes32 _orderId) private { if (orders[_orderId].tradeAmountGivenInShares == false) { // Investment was specified in units of MPH if (orders[_orderId].tradeAmount <= state.getShortShares( orders[_orderId].userId, orders[_orderId].marketId ).mul( shortShareValue( state.getMeanEntryPrice(orders[_orderId].userId, orders[_orderId].marketId), state.getMeanEntryLeverage(orders[_orderId].userId, orders[_orderId].marketId), state.getLiquidationPrice(orders[_orderId].userId, orders[_orderId].marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, PRECISION, true )) ) { // Partial closing of short position orders[_orderId].longSharesOrder = 0; orders[_orderId].shortSharesOrder = orders[_orderId].tradeAmount.div(shortShareValue( state.getMeanEntryPrice(orders[_orderId].userId, orders[_orderId].marketId), state.getMeanEntryLeverage(orders[_orderId].userId, orders[_orderId].marketId), state.getLiquidationPrice(orders[_orderId].userId, orders[_orderId].marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, PRECISION, true )); } else { // Closing of entire short position orders[_orderId].shortSharesOrder = state.getShortShares(orders[_orderId].userId, orders[_orderId].marketId); orders[_orderId].longSharesOrder = orders[_orderId].tradeAmount.sub(( state.getShortShares( orders[_orderId].userId, orders[_orderId].marketId ).mul( shortShareValue( state.getMeanEntryPrice(orders[_orderId].userId, orders[_orderId].marketId), state.getMeanEntryLeverage(orders[_orderId].userId, orders[_orderId].marketId), state.getLiquidationPrice(orders[_orderId].userId, orders[_orderId].marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, PRECISION, true )) )); orders[_orderId].longSharesOrder = orders[_orderId].longSharesOrder.div( longShareValue( orders[_orderId].marketPrice, orders[_orderId].orderLeverage, 0, orders[_orderId].marketPrice, orders[_orderId].marketSpread, orders[_orderId].orderLeverage, false )); } } else { // Investment was specified in shares if (orders[_orderId].tradeAmount <= state.getShortShares(orders[_orderId].userId, orders[_orderId].marketId)) { // Partial closing of short position orders[_orderId].longSharesOrder = 0; orders[_orderId].shortSharesOrder = orders[_orderId].tradeAmount; } else { // Closing of entire short position orders[_orderId].shortSharesOrder = state.getShortShares(orders[_orderId].userId, orders[_orderId].marketId); orders[_orderId].longSharesOrder = orders[_orderId].tradeAmount.sub( state.getShortShares(orders[_orderId].userId, orders[_orderId].marketId) ); } } // Investment equals number of shares now. if (orders[_orderId].shortSharesOrder > 0) { closeShort(_orderId); } if (orders[_orderId].longSharesOrder > 0) { openLong(_orderId); } } // ---------------------------------------------------------------------------- // processSellOrder(bytes32 _orderId) // Converts orders specified in virtual shares to orders specified in Morpher token // and computes the number of long shares that are sold and short shares that are bought. // short shares are bought only if the order amount exceeds all open long positions // ---------------------------------------------------------------------------- function processSellOrder(bytes32 _orderId) private { if (orders[_orderId].tradeAmountGivenInShares == false) { // Investment was specified in units of MPH if (orders[_orderId].tradeAmount <= state.getLongShares( orders[_orderId].userId, orders[_orderId].marketId ).mul( longShareValue( state.getMeanEntryPrice(orders[_orderId].userId, orders[_orderId].marketId), state.getMeanEntryLeverage(orders[_orderId].userId, orders[_orderId].marketId), state.getLiquidationPrice(orders[_orderId].userId, orders[_orderId].marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, PRECISION, true ))) { // Partial closing of long position orders[_orderId].shortSharesOrder = 0; orders[_orderId].longSharesOrder = orders[_orderId].tradeAmount.div( longShareValue( state.getMeanEntryPrice(orders[_orderId].userId, orders[_orderId].marketId), state.getMeanEntryLeverage(orders[_orderId].userId, orders[_orderId].marketId), state.getLiquidationPrice(orders[_orderId].userId, orders[_orderId].marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, PRECISION, true )); } else { // Closing of entire long position orders[_orderId].longSharesOrder = state.getLongShares(orders[_orderId].userId, orders[_orderId].marketId); orders[_orderId].shortSharesOrder = orders[_orderId].tradeAmount.sub(( state.getLongShares(orders[_orderId].userId, orders[_orderId].marketId ).mul( longShareValue( state.getMeanEntryPrice(orders[_orderId].userId, orders[_orderId].marketId), state.getMeanEntryLeverage(orders[_orderId].userId, orders[_orderId].marketId), state.getLiquidationPrice(orders[_orderId].userId, orders[_orderId].marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, PRECISION, true )) )); orders[_orderId].shortSharesOrder = orders[_orderId].shortSharesOrder.div( shortShareValue( orders[_orderId].marketPrice, orders[_orderId].orderLeverage, orders[_orderId].marketPrice.mul(100), orders[_orderId].marketPrice, orders[_orderId].marketSpread, orders[_orderId].orderLeverage, false )); } } else { // Investment was specified in shares if (orders[_orderId].tradeAmount <= state.getLongShares(orders[_orderId].userId, orders[_orderId].marketId)) { // Partial closing of long position orders[_orderId].shortSharesOrder = 0; orders[_orderId].longSharesOrder = orders[_orderId].tradeAmount; } else { // Closing of entire long position orders[_orderId].longSharesOrder = state.getLongShares(orders[_orderId].userId, orders[_orderId].marketId); orders[_orderId].shortSharesOrder = orders[_orderId].tradeAmount.sub( state.getLongShares(orders[_orderId].userId, orders[_orderId].marketId) ); } } // Investment equals number of shares now. if (orders[_orderId].longSharesOrder > 0) { closeLong(_orderId); } if (orders[_orderId].shortSharesOrder > 0) { openShort(_orderId); } } // ---------------------------------------------------------------------------- // openLong(bytes32 _orderId) // Opens a new long position and computes the new resulting average entry price/spread/leverage. // Computation is broken down to several instructions for readability. // ---------------------------------------------------------------------------- function openLong(bytes32 _orderId) private { address _userId = orders[_orderId].userId; bytes32 _marketId = orders[_orderId].marketId; uint256 _newMeanSpread; uint256 _newMeanLeverage; // Existing position is virtually liquidated and reopened with current marketPrice // orders[_orderId].newMeanEntryPrice = orders[_orderId].marketPrice; // _factorLongShares is a factor to adjust the existing longShares via virtual liqudiation and reopening at current market price uint256 _factorLongShares = state.getMeanEntryLeverage(_userId, _marketId); if (_factorLongShares < PRECISION) { _factorLongShares = PRECISION; } _factorLongShares = _factorLongShares.sub(PRECISION); _factorLongShares = _factorLongShares.mul(state.getMeanEntryPrice(_userId, _marketId)).div(orders[_orderId].marketPrice); if (state.getMeanEntryLeverage(_userId, _marketId) > _factorLongShares) { _factorLongShares = state.getMeanEntryLeverage(_userId, _marketId).sub(_factorLongShares); } else { _factorLongShares = 0; } uint256 _adjustedLongShares = _factorLongShares.mul(state.getLongShares(_userId, _marketId)).div(PRECISION); // _newMeanLeverage is the weighted leverage of the existing position and the new position _newMeanLeverage = state.getMeanEntryLeverage(_userId, _marketId).mul(_adjustedLongShares); _newMeanLeverage = _newMeanLeverage.add(orders[_orderId].orderLeverage.mul(orders[_orderId].longSharesOrder)); _newMeanLeverage = _newMeanLeverage.div(_adjustedLongShares.add(orders[_orderId].longSharesOrder)); // _newMeanSpread is the weighted spread of the existing position and the new position _newMeanSpread = state.getMeanEntrySpread(_userId, _marketId).mul(state.getLongShares(_userId, _marketId)); _newMeanSpread = _newMeanSpread.add(orders[_orderId].marketSpread.mul(orders[_orderId].longSharesOrder)); _newMeanSpread = _newMeanSpread.div(_adjustedLongShares.add(orders[_orderId].longSharesOrder)); orders[_orderId].balanceDown = orders[_orderId].longSharesOrder.mul(orders[_orderId].marketPrice).add( orders[_orderId].longSharesOrder.mul(orders[_orderId].marketSpread).mul(orders[_orderId].orderLeverage).div(PRECISION) ); orders[_orderId].balanceUp = 0; orders[_orderId].newLongShares = _adjustedLongShares.add(orders[_orderId].longSharesOrder); orders[_orderId].newShortShares = state.getShortShares(_userId, _marketId); orders[_orderId].newMeanEntryPrice = orders[_orderId].marketPrice; orders[_orderId].newMeanEntrySpread = _newMeanSpread; orders[_orderId].newMeanEntryLeverage = _newMeanLeverage; setPositionInState(_orderId); } // ---------------------------------------------------------------------------- // closeLong(bytes32 _orderId) // Closes an existing long position. Average entry price/spread/leverage do not change. // ---------------------------------------------------------------------------- function closeLong(bytes32 _orderId) private { address _userId = orders[_orderId].userId; bytes32 _marketId = orders[_orderId].marketId; uint256 _newLongShares = state.getLongShares(_userId, _marketId).sub(orders[_orderId].longSharesOrder); uint256 _balanceUp = orders[_orderId].longSharesOrder.mul(longShareValue( state.getMeanEntryPrice(_userId, _marketId), state.getMeanEntryLeverage(_userId, _marketId), state.getLiquidationPrice(_userId, _marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, state.getMeanEntryLeverage(_userId, _marketId), true )); uint256 _newMeanEntry; uint256 _newMeanSpread; uint256 _newMeanLeverage; if (orders[_orderId].longSharesOrder == state.getLongShares(_userId, _marketId)) { _newMeanEntry = 0; _newMeanSpread = 0; _newMeanLeverage = PRECISION; } else { _newMeanEntry = state.getMeanEntryPrice(_userId, _marketId); _newMeanSpread = state.getMeanEntrySpread(_userId, _marketId); _newMeanLeverage = state.getMeanEntryLeverage(_userId, _marketId); } orders[_orderId].balanceDown = 0; orders[_orderId].balanceUp = _balanceUp; orders[_orderId].newLongShares = _newLongShares; orders[_orderId].newShortShares = state.getShortShares(_userId, _marketId); orders[_orderId].newMeanEntryPrice = _newMeanEntry; orders[_orderId].newMeanEntrySpread = _newMeanSpread; orders[_orderId].newMeanEntryLeverage = _newMeanLeverage; setPositionInState(_orderId); } // ---------------------------------------------------------------------------- // closeShort(bytes32 _orderId) // Closes an existing short position. Average entry price/spread/leverage do not change. // ---------------------------------------------------------------------------- function closeShort(bytes32 _orderId) private { address _userId = orders[_orderId].userId; bytes32 _marketId = orders[_orderId].marketId; uint256 _newMeanEntry; uint256 _newMeanSpread; uint256 _newMeanLeverage; uint256 _newShortShares = state.getShortShares(_userId, _marketId).sub(orders[_orderId].shortSharesOrder); uint256 _balanceUp = orders[_orderId].shortSharesOrder.mul( shortShareValue( state.getMeanEntryPrice(_userId, _marketId), state.getMeanEntryLeverage(_userId, _marketId), state.getLiquidationPrice(_userId, _marketId), orders[_orderId].marketPrice, orders[_orderId].marketSpread, state.getMeanEntryLeverage(_userId, _marketId), true )); if (orders[_orderId].shortSharesOrder == state.getShortShares(_userId, _marketId)) { _newMeanEntry = 0; _newMeanSpread = 0; _newMeanLeverage = PRECISION; } else { _newMeanEntry = state.getMeanEntryPrice(_userId, _marketId); _newMeanSpread = state.getMeanEntrySpread(_userId, _marketId); _newMeanLeverage = state.getMeanEntryLeverage(_userId, _marketId); } orders[_orderId].balanceDown = 0; orders[_orderId].balanceUp = _balanceUp; orders[_orderId].newLongShares = state.getLongShares(orders[_orderId].userId, orders[_orderId].marketId); orders[_orderId].newShortShares = _newShortShares; orders[_orderId].newMeanEntryPrice = _newMeanEntry; orders[_orderId].newMeanEntrySpread = _newMeanSpread; orders[_orderId].newMeanEntryLeverage = _newMeanLeverage; setPositionInState(_orderId); } // ---------------------------------------------------------------------------- // openShort(bytes32 _orderId) // Opens a new short position and computes the new resulting average entry price/spread/leverage. // Computation is broken down to several instructions for readability. // ---------------------------------------------------------------------------- function openShort(bytes32 _orderId) private { address _userId = orders[_orderId].userId; bytes32 _marketId = orders[_orderId].marketId; uint256 _newMeanSpread; uint256 _newMeanLeverage; // // Existing position is virtually liquidated and reopened with current marketPrice // orders[_orderId].newMeanEntryPrice = orders[_orderId].marketPrice; // _factorShortShares is a factor to adjust the existing shortShares via virtual liqudiation and reopening at current market price uint256 _factorShortShares = state.getMeanEntryLeverage(_userId, _marketId); if (_factorShortShares < PRECISION) { _factorShortShares = PRECISION; } _factorShortShares = _factorShortShares.add(PRECISION); _factorShortShares = _factorShortShares.mul(state.getMeanEntryPrice(_userId, _marketId)).div(orders[_orderId].marketPrice); if (state.getMeanEntryLeverage(_userId, _marketId) < _factorShortShares) { _factorShortShares = _factorShortShares.sub(state.getMeanEntryLeverage(_userId, _marketId)); } else { _factorShortShares = 0; } uint256 _adjustedShortShares = _factorShortShares.mul(state.getShortShares(_userId, _marketId)).div(PRECISION); // _newMeanLeverage is the weighted leverage of the existing position and the new position _newMeanLeverage = state.getMeanEntryLeverage(_userId, _marketId).mul(_adjustedShortShares); _newMeanLeverage = _newMeanLeverage.add(orders[_orderId].orderLeverage.mul(orders[_orderId].shortSharesOrder)); _newMeanLeverage = _newMeanLeverage.div(_adjustedShortShares.add(orders[_orderId].shortSharesOrder)); // _newMeanSpread is the weighted spread of the existing position and the new position _newMeanSpread = state.getMeanEntrySpread(_userId, _marketId).mul(state.getShortShares(_userId, _marketId)); _newMeanSpread = _newMeanSpread.add(orders[_orderId].marketSpread.mul(orders[_orderId].shortSharesOrder)); _newMeanSpread = _newMeanSpread.div(_adjustedShortShares.add(orders[_orderId].shortSharesOrder)); orders[_orderId].balanceDown = orders[_orderId].shortSharesOrder.mul(orders[_orderId].marketPrice).add( orders[_orderId].shortSharesOrder.mul(orders[_orderId].marketSpread).mul(orders[_orderId].orderLeverage).div(PRECISION) ); orders[_orderId].balanceUp = 0; orders[_orderId].newLongShares = state.getLongShares(_userId, _marketId); orders[_orderId].newShortShares = _adjustedShortShares.add(orders[_orderId].shortSharesOrder); orders[_orderId].newMeanEntryPrice = orders[_orderId].marketPrice; orders[_orderId].newMeanEntrySpread = _newMeanSpread; orders[_orderId].newMeanEntryLeverage = _newMeanLeverage; setPositionInState(_orderId); } function computeLiquidationPrice(bytes32 _orderId) public returns(uint256 _liquidationPrice) { orders[_orderId].newLiquidationPrice = 0; if (orders[_orderId].newLongShares > 0) { orders[_orderId].newLiquidationPrice = getLiquidationPrice(orders[_orderId].newMeanEntryPrice, orders[_orderId].newMeanEntryLeverage, true); } if (orders[_orderId].newShortShares > 0) { orders[_orderId].newLiquidationPrice = getLiquidationPrice(orders[_orderId].newMeanEntryPrice, orders[_orderId].newMeanEntryLeverage, false); } return orders[_orderId].newLiquidationPrice; } function getLiquidationPrice(uint256 _newMeanEntryPrice, uint256 _newMeanEntryLeverage, bool _long) public pure returns (uint256 _liquidiationPrice) { if (_long == true) { _liquidiationPrice = _newMeanEntryPrice.mul(_newMeanEntryLeverage.sub(PRECISION)).div(_newMeanEntryLeverage); } else { _liquidiationPrice = _newMeanEntryPrice.mul(_newMeanEntryLeverage.add(PRECISION)).div(_newMeanEntryLeverage); } return _liquidiationPrice; } // ---------------------------------------------------------------------------- // setPositionInState(bytes32 _orderId) // Updates the portfolio in Morpher State. Called by closeLong/closeShort/openLong/openShort // ---------------------------------------------------------------------------- function setPositionInState(bytes32 _orderId) private { require(state.balanceOf(orders[_orderId].userId).add(orders[_orderId].balanceUp) >= orders[_orderId].balanceDown, "MorpherTradeEngine: insufficient funds."); computeLiquidationPrice(_orderId); // Net balanceUp and balanceDown if (orders[_orderId].balanceUp > orders[_orderId].balanceDown) { orders[_orderId].balanceUp.sub(orders[_orderId].balanceDown); orders[_orderId].balanceDown = 0; } else { orders[_orderId].balanceDown.sub(orders[_orderId].balanceUp); orders[_orderId].balanceUp = 0; } if (orders[_orderId].balanceUp > 0) { state.mint(orders[_orderId].userId, orders[_orderId].balanceUp); } if (orders[_orderId].balanceDown > 0) { state.burn(orders[_orderId].userId, orders[_orderId].balanceDown); } state.setPosition( orders[_orderId].userId, orders[_orderId].marketId, orders[_orderId].timeStamp, orders[_orderId].newLongShares, orders[_orderId].newShortShares, orders[_orderId].newMeanEntryPrice, orders[_orderId].newMeanEntrySpread, orders[_orderId].newMeanEntryLeverage, orders[_orderId].newLiquidationPrice ); emit PositionUpdated( orders[_orderId].userId, orders[_orderId].marketId, orders[_orderId].timeStamp, orders[_orderId].newLongShares, orders[_orderId].newShortShares, orders[_orderId].newMeanEntryPrice, orders[_orderId].newMeanEntrySpread, orders[_orderId].newMeanEntryLeverage, orders[_orderId].newLiquidationPrice, orders[_orderId].balanceUp, orders[_orderId].balanceDown ); } }
pragma solidity 0.5.16; import "./IERC20.sol"; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller should be owner."); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. * @notice Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: use renounce ownership instead."); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } // ------------------------------------------------------------------------ // Owner can transfer out any accidentally sent ERC20 tokens // ------------------------------------------------------------------------ function transferAnyERC20Token(address _tokenAddress, uint256 _tokens) public onlyOwner returns (bool _success) { return IERC20(_tokenAddress).transfer(owner(), _tokens); } }
pragma solidity 0.5.16; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bool","name":"_mainChain","type":"bool"},{"internalType":"address","name":"_sideChainOperator","type":"address"},{"internalType":"address","name":"_morpherTreasury","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"administratorAddress","type":"address"}],"name":"AdministratorChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_bridgeAddress","type":"address"}],"name":"BridgeChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalToken","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"FastWithdrawsDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"governanceAddress","type":"address"}],"name":"GovernanceChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_periodLength","type":"uint256"}],"name":"InactivityPeriodUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"Last24HoursAmountWithdrawnReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"rewardsTime","type":"uint256"}],"name":"LastRewardTime","type":"event"},{"anonymous":false,"inputs":[],"name":"LastWithdrawAt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"mainChainWithdrawLimit24","type":"uint256"}],"name":"MainChainWithdrawLimitUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"activateMarket","type":"bytes32"}],"name":"MarketActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"deActivateMarket","type":"bytes32"}],"name":"MarketDeActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxLeverage","type":"uint256"}],"name":"MaximumLeverageChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalToken","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_transferNonce","type":"uint256"}],"name":"NewBridgeNonce","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sideChainOperator","type":"address"}],"name":"NewSideChainOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTotalOnOtherChain","type":"uint256"}],"name":"NewTotalInPositions","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTotalOnOtherChain","type":"uint256"}],"name":"NewTotalOnOtherChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"NewTotalSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_numberOfRequests","type":"uint256"}],"name":"NumberOfRequestsLimitUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OperatingRewardMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracleContract","type":"address"}],"name":"OracleChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewardsAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"rewardsBasisPoints","type":"uint256"}],"name":"RewardsChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_last24HoursAmountWithdrawn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_lastWithdrawLimitReductionTime","type":"uint256"}],"name":"RollingWithdrawnAmountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"SetAllowance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"balanceHash","type":"bytes32"}],"name":"SetBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"positionHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"bytes32","name":"marketId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"timeStamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"longShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shortShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"meanEntryPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"meanEntrySpread","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"meanEntryLeverage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidationPrice","type":"uint256"}],"name":"SetPosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"sideChainMerkleRoot","type":"bytes32"}],"name":"SideChainMerkleRootUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"blackList","type":"address"},{"indexed":true,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"StateAccessDenied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whiteList","type":"address"},{"indexed":true,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"StateAccessGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"administrator","type":"address"},{"indexed":false,"internalType":"bool","name":"_paused","type":"bool"}],"name":"StatePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"TokenChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalTokenSent","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"_tokenSentToLinkedChainHash","type":"bytes32"}],"name":"TokenSentToLinkedChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenTransferredToOtherChain","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"transferHash","type":"bytes32"}],"name":"TokenTransferredToOtherChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_token","type":"uint256"}],"name":"TransferredTokenClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"blackList","type":"address"}],"name":"TransfersDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whiteList","type":"address"}],"name":"TransfersEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"WithdrawLimitUpdated","type":"event"},{"constant":true,"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_activateMarket","type":"bytes32"}],"name":"activateMarket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"add24HoursWithdrawn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"administrator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_token","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_deActivateMarket","type":"bytes32"}],"name":"deActivateMarket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"denyAccess","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"disableFastWithdraws","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"disableTransfers","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"enableTransfers","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fastTransfersEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAdministrator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_tokenOwner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"getAllowance","outputs":[{"internalType":"uint256","name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_balance","type":"uint256"}],"name":"getBalanceHash","outputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"getBridgeNonce","outputs":[{"internalType":"uint256","name":"_nonce","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getCanTransfer","outputs":[{"internalType":"bool","name":"_hasAccess","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"uint256","name":"_mappingIndex","type":"uint256"}],"name":"getExposureMappingAddress","outputs":[{"internalType":"address","name":"_address","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"address","name":"_address","type":"address"}],"name":"getExposureMappingIndex","outputs":[{"internalType":"uint256","name":"_mappingIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGovernance","outputs":[{"internalType":"address","name":"_governanceContract","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getLastRequestBlock","outputs":[{"internalType":"uint256","name":"_lastRequestBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getLastUpdated","outputs":[{"internalType":"uint256","name":"_lastUpdated","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getLiquidationPrice","outputs":[{"internalType":"uint256","name":"_liquidationPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getLongShares","outputs":[{"internalType":"uint256","name":"_longShares","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMainChainWithdrawLimit","outputs":[{"internalType":"uint256","name":"_mainChainWithdrawLimit24","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getMarketActive","outputs":[{"internalType":"bool","name":"_active","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getMaxMappingIndex","outputs":[{"internalType":"uint256","name":"_maxMappingIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMaximumLeverage","outputs":[{"internalType":"uint256","name":"_maxLeverage","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getMeanEntryLeverage","outputs":[{"internalType":"uint256","name":"_meanEntryLeverage","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getMeanEntryPrice","outputs":[{"internalType":"uint256","name":"_meanEntryPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getMeanEntrySpread","outputs":[{"internalType":"uint256","name":"_meanEntrySpread","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMorpherBridge","outputs":[{"internalType":"address","name":"_currentBridge","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getNumberOfRequests","outputs":[{"internalType":"uint256","name":"_numberOfRequests","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfRequestsLimit","outputs":[{"internalType":"uint256","name":"_numberOfRequestsLimit","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOracleContract","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getPosition","outputs":[{"internalType":"uint256","name":"_longShares","type":"uint256"},{"internalType":"uint256","name":"_shortShares","type":"uint256"},{"internalType":"uint256","name":"_meanEntryPrice","type":"uint256"},{"internalType":"uint256","name":"_meanEntrySpread","type":"uint256"},{"internalType":"uint256","name":"_meanEntryLeverage","type":"uint256"},{"internalType":"uint256","name":"_liquidationPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_positionHash","type":"bytes32"}],"name":"getPositionClaimedOnMainChain","outputs":[{"internalType":"bool","name":"_alreadyClaimed","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"uint256","name":"_timeStamp","type":"uint256"},{"internalType":"uint256","name":"_longShares","type":"uint256"},{"internalType":"uint256","name":"_shortShares","type":"uint256"},{"internalType":"uint256","name":"_meanEntryPrice","type":"uint256"},{"internalType":"uint256","name":"_meanEntrySpread","type":"uint256"},{"internalType":"uint256","name":"_meanEntryLeverage","type":"uint256"},{"internalType":"uint256","name":"_liquidationPrice","type":"uint256"}],"name":"getPositionHash","outputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"}],"name":"getShortShares","outputs":[{"internalType":"uint256","name":"_shortShares","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSideChainMerkleRoot","outputs":[{"internalType":"bytes32","name":"_sideChainMerkleRoot","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSideChainMerkleRootWrittenAtTime","outputs":[{"internalType":"uint256","name":"_sideChainMerkleRoot","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSideChainOperator","outputs":[{"internalType":"address","name":"_address","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getStateAccess","outputs":[{"internalType":"bool","name":"_hasAccess","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getTokenClaimedOnThisChain","outputs":[{"internalType":"uint256","name":"_token","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTokenContract","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getTokenSentToLinkedChain","outputs":[{"internalType":"uint256","name":"_token","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getTokenSentToLinkedChainTime","outputs":[{"internalType":"uint256","name":"_timeStamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"grantAccess","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"inactivityPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"increaseNumberOfRequests","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"last24HoursAmountWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastWithdrawLimitReductionTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mainChain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mainChainWithdrawLimit24","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maximumLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_token","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"morpherBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"morpherGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"morpherRewards","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"morpherToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"numberOfRequestsLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracleContract","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pauseState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"payOperatingReward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"resetLast24HoursAmountWithdrawn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"set24HourWithdrawLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newAdministrator","type":"address"}],"name":"setAdministrator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"setAllowance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"setExposureMapping","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"setExposureMappingAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"setExposureMappingIndex","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newGovernanceContractAddress","type":"address"}],"name":"setGovernanceContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_periodLength","type":"uint256"}],"name":"setInactivityPeriod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setLastRequestBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_mainChainWithdrawLimit24","type":"uint256"}],"name":"setMainChainWithdrawLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"uint256","name":"_maxMappingIndex","type":"uint256"}],"name":"setMaxMappingIndex","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_newMaximumLeverage","type":"uint256"}],"name":"setMaximumLeverage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newBridge","type":"address"}],"name":"setMorpherBridge","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_numberOfRequests","type":"uint256"}],"name":"setNumberOfRequests","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_numberOfRequestsLimit","type":"uint256"}],"name":"setNumberOfRequestsLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newOracleContract","type":"address"}],"name":"setOracleContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bytes32","name":"_marketId","type":"bytes32"},{"internalType":"uint256","name":"_timeStamp","type":"uint256"},{"internalType":"uint256","name":"_longShares","type":"uint256"},{"internalType":"uint256","name":"_shortShares","type":"uint256"},{"internalType":"uint256","name":"_meanEntryPrice","type":"uint256"},{"internalType":"uint256","name":"_meanEntrySpread","type":"uint256"},{"internalType":"uint256","name":"_meanEntryLeverage","type":"uint256"},{"internalType":"uint256","name":"_liquidationPrice","type":"uint256"}],"name":"setPosition","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_positionHash","type":"bytes32"}],"name":"setPositionClaimedOnMainChain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newRewardsAddress","type":"address"}],"name":"setRewardAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_newRewardBasisPoints","type":"uint256"}],"name":"setRewardBasisPoints","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_sideChainMerkleRoot","type":"bytes32"}],"name":"setSideChainMerkleRoot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setSideChainOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_token","type":"uint256"}],"name":"setTokenClaimedOnThisChain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newTokenContract","type":"address"}],"name":"setTokenContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_token","type":"uint256"}],"name":"setTokenSentToLinkedChain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_totalInPositions","type":"uint256"}],"name":"setTotalInPositions","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_newTotalOnOtherChain","type":"uint256"}],"name":"setTotalOnOtherChain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"sideChainMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sideChainMerkleRootWrittenAtTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sideChainOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalInPositions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalOnOtherChain","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_token","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"transferAnyERC20Token","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"transferNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unPauseState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"update24HoursWithdrawLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"withdrawLimit24Hours","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052633b9aca006005556006805460ff191690556a108b2a2c280290940000006011556203f4806020553480156200003957600080fd5b5060405162004e9838038062004e98833981810160405260608110156200005f57600080fd5b5080516020820151604092830151600080546001600160a01b031916331780825594519394929391926001600160a01b0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36000805460ff60a01b1916600160a01b85151502179055620000d9426200038c565b6b01dba0fc757e49bc9f0000006b015f8d402a52368049000000620001196200010a6001600160e01b03620003bf16565b6001600160e01b03620003ce16565b6200013f620001306001600160e01b03620003bf16565b6001600160e01b036200047016565b600054600160a01b900460ff1662000235578160146000620001696001600160e01b03620003bf16565b6001600160a01b0316815260208101919091526040016000205560028290556200019b6001600160e01b03620003bf16565b6001600160a01b031660008051602062004ddd833981519152620001da620001cb6001600160e01b03620003bf16565b6001600160e01b036200050e16565b60408051918252602082018690528051918290030190a26200020660006001600160e01b036200052916565b6200021b60006001600160e01b036200065d16565b6200022f816001600160e01b036200070116565b62000304565b80601460006200024d6001600160e01b03620003bf16565b6001600160a01b0316815260208101919091526040016000205560028190556200027f6001600160e01b03620003bf16565b6001600160a01b031660008051602062004ddd833981519152620002af620001cb6001600160e01b03620003bf16565b60408051918252602082018590528051918290030190a2620002dc613a986001600160e01b036200052916565b620002f0836001600160e01b036200065d16565b62000304826001600160e01b036200070116565b6022805460ff191660011790556200032660036001600160e01b036200079a16565b620003476032600154816200033757fe5b046001600160e01b036200082a16565b6200035b846001600160e01b036200047016565b62000381620003726001600160e01b03620003bf16565b6001600160e01b03620008b116565b505050505062000a35565b600e81905560405181907fb11f7283fda904f54a0fc8af727d3bf56e40a6cbf7c8fbb177083f0a335152ed90600090a250565b6000546001600160a01b031690565b620003e16001600160e01b036200095016565b62000422576040805162461bcd60e51b8152602060048201819052602482015260008051602062004e78833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260126020526040808220805460ff19166001179055514392917f556646edb498605e1eaf0f4ab1619f3dbc4164f1cddc22ecae584e045838d13891a350565b620004836001600160e01b036200095016565b620004c4576040805162461bcd60e51b8152602060048201819052602482015260008051602062004e78833981519152604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0383169081179091556040517f07c5be40db03f5890f6ca87fc24a286cabbbd63a79791089701cb0b5eb71529890600090a250565b6001600160a01b031660009081526014602052604090205490565b6200053c6001600160e01b036200095016565b6200057d576040805162461bcd60e51b8152602060048201819052602482015260008051602062004e78833981519152604482015290519081900360640190fd5b600054600160a01b900460ff16151560011415620005de57613a98811115620005d85760405162461bcd60e51b815260040180806020018281038252604481526020018062004d5d6044913960600191505060405180910390fd5b6200061d565b80156200061d5760405162461bcd60e51b815260040180806020018281038252603e81526020018062004e3a603e913960400191505060405180910390fd5b600d81905560075460405182916001600160a01b0316907faa735ef3e20d6d58610022edb69ae0e7e8aaa0084dc5699a0b36a5683bc7a7c790600090a350565b620006706001600160e01b036200095016565b620006b1576040805162461bcd60e51b8152602060048201819052602482015260008051602062004e78833981519152604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b038316908117909155600d546040519091907faa735ef3e20d6d58610022edb69ae0e7e8aaa0084dc5699a0b36a5683bc7a7c790600090a350565b600a546001600160a01b031633146200074c5760405162461bcd60e51b815260040180806020018281038252603d81526020018062004dfd603d913960400191505060405180910390fd5b6004819055620007646001600160e01b036200096116565b6040805182815290517f38e3203d00fb51f959df7882c56c583370da2f7abea215c09e83e7ffa61281d29181900360200190a150565b3360009081526012602052604090205460ff161515600114620007ef5760405162461bcd60e51b815260040180806020018281038252603c81526020018062004da1603c913960400191505060405180910390fd5b60258190556040805182815290517f8347cc6d3a3b991db61121237578d3a133ddf434ee43936f1c48d2c815eb0ab39181900360200190a150565b6200083d6001600160e01b036200095016565b6200087e576040805162461bcd60e51b8152602060048201819052602482015260008051602062004e78833981519152604482015290519081900360640190fd5b601181905560405181907f1177d9c2a77eb9dd45c02329c8e4924e44101d64dabf8024543b0ce26e622f3690600090a250565b620008c46001600160e01b036200095016565b62000905576040805162461bcd60e51b8152602060048201819052602482015260008051602062004e78833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260126020526040808220805460ff19169055514392917fa40f23a963aabba33c55679497d6dd6d9815feadbeb0b0ad39d1285beda16bdd91a350565b6000546001600160a01b0316331490565b6200099a60045462000986600354600254620009d360201b62003c1a1790919060201c565b620009d360201b62003c1a1790919060201c565b600181905560408051918252517f5b1767df4e2cc8a7b2716959e609e0cdd987c9b88ac27b7fc4be99435aa1673b9181900360200190a1565b60008282018381101562000a2e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6143188062000a456000396000f3fe608060405234801561001057600080fd5b50600436106106e05760003560e01c80637c995e9111610387578063bfde5730116101de578063e4974f8d1161010f578063f2fde38b116100ad578063faddee1411610087578063faddee1414611292578063fbfc50f6146112be578063fc89a4fc146112c6578063ff047c38146112e3576106e0565b8063f2fde38b1461125c578063f53d0a8e14611282578063f606a41a1461128a576106e0565b8063ebd164fb116100e9578063ebd164fb146111c1578063ef5fa322146111e7578063ef92f83114611213578063efeecb0414611230576106e0565b8063e4974f8d14611194578063e4bd85221461119c578063e5160f80146111a4576106e0565b8063d8d5470d1161017c578063dc39d06d11610156578063dc39d06d1461110e578063df8089ef1461113a578063e291f13514611160578063e3bbb5651461118c576106e0565b8063d8d5470d146110b3578063da46098c146110bb578063da4b0f40146110f1576106e0565b8063c5e1b59a116101b8578063c5e1b59a14611060578063d362bd2b14611086578063d69082c41461108e578063d7118351146110ab576106e0565b8063bfde573014611015578063c209afac1461101d578063c5d90a1914611043576106e0565b8063aa43ced8116102b8578063b8ed12a411610256578063bcc3e34211610230578063bcc3e34214610f59578063be7e64b614610f7f578063beabacc814610fd7578063bece75321461100d576106e0565b8063b8ed12a414610f23578063bb65b24214610f2b578063bbcd5bbe14610f33576106e0565b8063acb17ba711610292578063acb17ba714610ebb578063af434a6d14610ee1578063b2bdfa7b14610efe578063b6554c2c14610f06576106e0565b8063aa43ced814610e8e578063aa7bcd5d14610e96578063ac981b1e14610e9e576106e0565b80639231cf7411610325578063a0580880116102ff578063a058088014610e2f578063a35ab9c814610e37578063a8c8afaa14610e54578063a99d389f14610e5c576106e0565b80639231cf7414610dde5780639dc29fac14610de65780639fe4e9d214610e12576106e0565b80638da5cb5b116103615780638da5cb5b14610d765780638ea09da614610d7e5780638f32d59b14610da45780639162298f14610dac576106e0565b80637c995e9114610d3a578063857b0da014610d425780638c4050b114610d6e576106e0565b80633d7f4f3c1161053b57806361afd5ac1161046c578063706277da1161040a57806373ed1fe2116103e457806373ed1fe214610cca578063755ca87a14610cd25780637a68744414610cda5780637b431ab114610d32576106e0565b8063706277da14610c9457806370a0823114610c9c578063715018a614610cc2576106e0565b806369c66c7b1161044657806369c66c7b14610c1757806369cdcfb714610c435780636c36a4ec14610c605780636d37e21814610c8c576106e0565b806361afd5ac14610bbd578063626be56714610be3578063652f176314610beb576106e0565b80634da3c199116104d95780635996e209116104b35780635996e20914610b615780635c8b933414610b695780635c975abb14610b8f5780635e00e67914610b97576106e0565b80634da3c19914610b3457806355b3374114610b51578063592b6aab14610b59576106e0565b8063422cc2e711610515578063422cc2e714610aa857806344ae029c14610ad4578063496ccd9b14610af15780634a4cce9714610b17576106e0565b80633d7f4f3c14610a485780633eedf76a14610a7457806340c10f1914610a7c576106e0565b8063169674071161061557806321c02c8e116105b357806328b7bede1161058d57806328b7bede146109cb5780632d7b42c1146109d35780633383e8d8146109f6578063364ae26e14610a22576106e0565b806321c02c8e1461099557806325fbf712146109bb578063289b3c0d146109c3576106e0565b80631864ba30116105ef5780631864ba30146109365780631bdbae90146109625780631cb110771461096a5780632020e69714610972576106e0565b806316967407146108f4578063174c51dc146108fc57806318160ddd1461092e576106e0565b80630b7c8e7f116106825780630fa8f5161161065c5780630fa8f516146108235780631129753f1461088257806314712512146108a857806314ce70ef146108ce576106e0565b80630b7c8e7f146107d95780630eb933dc146107e15780630f508e001461081b576106e0565b806309089f97116106be57806309089f97146107475780630aa7cee2146107615780630ae5e739146107855780630af4187d146107ab576106e0565b806304371f48146106e557806306442d0a1461070457806307a9100e14610721575b600080fd5b610702600480360360208110156106fb57600080fd5b50356112eb565b005b6107026004803603602081101561071a57600080fd5b503561140c565b6107026004803603602081101561073757600080fd5b50356001600160a01b03166114a3565b61074f611512565b60408051918252519081900360200190f35b6107696115af565b604080516001600160a01b039092168252519081900360200190f35b6107026004803603602081101561079b57600080fd5b50356001600160a01b03166115be565b61074f600480360360408110156107c157600080fd5b506001600160a01b0381358116916020013516611653565b61074f611680565b610807600480360360208110156107f757600080fd5b50356001600160a01b0316611686565b604080519115158252519081900360200190f35b6107696116a4565b61084f6004803603604081101561083957600080fd5b506001600160a01b0381351690602001356116b3565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b6107026004803603602081101561089857600080fd5b50356001600160a01b0316611700565b610807600480360360208110156108be57600080fd5b50356001600160a01b0316611799565b610702600480360360208110156108e457600080fd5b50356001600160a01b03166117b7565b610769611848565b6107026004803603606081101561091257600080fd5b508035906001600160a01b036020820135169060400135611857565b61074f6118e7565b61074f6004803603604081101561094c57600080fd5b506001600160a01b0381351690602001356118ed565b61074f611918565b61074f61191e565b6107026004803603604081101561098857600080fd5b5080359060200135611924565b61074f600480360360208110156109ab57600080fd5b50356001600160a01b0316611989565b61074f6119a4565b6107696119aa565b6107696119be565b610769600480360360408110156109e957600080fd5b50803590602001356119cd565b61070260048036036040811015610a0c57600080fd5b506001600160a01b0381351690602001356119f7565b61074f60048036036020811015610a3857600080fd5b50356001600160a01b0316611aa7565b61074f60048036036040811015610a5e57600080fd5b506001600160a01b038135169060200135611ac2565b61074f611aea565b61070260048036036040811015610a9257600080fd5b506001600160a01b038135169060200135611af0565b61070260048036036040811015610abe57600080fd5b506001600160a01b038135169060200135611d14565b61080760048036036020811015610aea57600080fd5b5035611dfa565b61070260048036036020811015610b0757600080fd5b50356001600160a01b0316611e0f565b61080760048036036020811015610b2d57600080fd5b5035611eb0565b61070260048036036020811015610b4a57600080fd5b5035611ec5565b61074f611f53565b610702611f59565b610702611fe5565b61074f60048036036020811015610b7f57600080fd5b50356001600160a01b0316612083565b61080761209e565b61070260048036036020811015610bad57600080fd5b50356001600160a01b03166120a7565b61070260048036036020811015610bd357600080fd5b50356001600160a01b031661213e565b61074f6121d0565b61074f60048036036040811015610c0157600080fd5b506001600160a01b0381351690602001356121d6565b61074f60048036036040811015610c2d57600080fd5b50803590602001356001600160a01b0316612201565b61070260048036036020811015610c5957600080fd5b503561222d565b61070260048036036040811015610c7657600080fd5b506001600160a01b0381351690602001356122a7565b610702612316565b61076961242b565b61074f60048036036020811015610cb257600080fd5b50356001600160a01b031661243a565b610702612455565b6107696124e6565b61074f6124f5565b61074f6004803603610120811015610cf157600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e08101359061010001356124fb565b61074f612573565b61074f612579565b61074f60048036036040811015610d5857600080fd5b506001600160a01b03813516906020013561257f565b61074f6125c3565b6107696125c9565b61070260048036036020811015610d9457600080fd5b50356001600160a01b03166125d8565b610807612668565b61070260048036036060811015610dc257600080fd5b508035906001600160a01b036020820135169060400135612679565b61074f6126e7565b61070260048036036040811015610dfc57600080fd5b506001600160a01b0381351690602001356126ed565b61070260048036036020811015610e2857600080fd5b503561292d565b6107026129bb565b61070260048036036020811015610e4d57600080fd5b5035612a42565b610769612b0c565b61070260048036036060811015610e7257600080fd5b508035906001600160a01b036020820135169060400135612b20565b61074f612b9d565b61074f612ba3565b61070260048036036020811015610eb457600080fd5b5035612ba9565b61070260048036036020811015610ed157600080fd5b50356001600160a01b0316612c43565b61070260048036036020811015610ef757600080fd5b5035612cd6565b610769612d69565b61070260048036036020811015610f1c57600080fd5b5035612d78565b61074f612dea565b61074f612df0565b61070260048036036020811015610f4957600080fd5b50356001600160a01b0316612df6565b61070260048036036020811015610f6f57600080fd5b50356001600160a01b0316612e87565b6107026004803603610120811015610f9657600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101000135612efa565b61070260048036036060811015610fed57600080fd5b506001600160a01b03813581169160208101359091169060400135613091565b6107696133a3565b6108076133b2565b61074f6004803603602081101561103357600080fd5b50356001600160a01b03166133c2565b6107026004803603602081101561105957600080fd5b50356133dd565b6107026004803603602081101561107657600080fd5b50356001600160a01b0316613469565b61074f613504565b610702600480360360208110156110a457600080fd5b503561350a565b6107026135ba565b61080761365e565b610702600480360360608110156110d157600080fd5b506001600160a01b03813581169160208101359091169060400135613667565b6107026004803603602081101561110757600080fd5b503561371c565b6108076004803603604081101561112457600080fd5b506001600160a01b0381351690602001356137f0565b6107026004803603602081101561115057600080fd5b50356001600160a01b03166138d3565b61074f6004803603604081101561117657600080fd5b506001600160a01b038135169060200135613974565b61076961399f565b6107696139ae565b61074f6139bd565b610702600480360360208110156111ba57600080fd5b50356139c3565b61074f600480360360208110156111d757600080fd5b50356001600160a01b0316613a5d565b61074f600480360360408110156111fd57600080fd5b506001600160a01b038135169060200135613a78565b61074f6004803603602081101561122957600080fd5b5035613aa3565b61074f6004803603604081101561124657600080fd5b506001600160a01b038135169060200135613ab5565b6107026004803603602081101561127257600080fd5b50356001600160a01b0316613ae0565b610769613b33565b610769613b42565b61074f600480360360408110156112a857600080fd5b506001600160a01b038135169060200135613b51565b61074f613b7c565b610702600480360360208110156112dc57600080fd5b5035613b82565b61074f613c14565b6112f3612668565b611332576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600054600160a01b900460ff1615156001141561138f57613a9881111561138a5760405162461bcd60e51b81526004018080602001828103825260448152602001806140876044913960600191505060405180910390fd5b6113cc565b80156113cc5760405162461bcd60e51b815260040180806020018281038252603e815260200180614227603e913960400191505060405180910390fd5b600d81905560075460405182916001600160a01b0316907faa735ef3e20d6d58610022edb69ae0e7e8aaa0084dc5699a0b36a5683bc7a7c790600090a350565b611414611848565b6001600160a01b0316336001600160a01b0316146114635760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b600081815260166020526040808220805460ff191690555182917f9cb9d54a58b209894faa9f115e54b1c61733c0764fe29ed01f97c7c425f2f24391a250565b3360009081526012602052604090205460ff1615156001146114f65760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03166000908152602360205260409020439055565b600061151c6124e6565b6001600160a01b0316336001600160a01b03161461156b5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b602180546001019081905560408051918252517f86423ef8971dc4252acb273ac1099fb639020a7a2f5a64dad077d033ab2ae8e29181900360200190a15060215490565b600a546001600160a01b031681565b6115c6612668565b611605576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260126020526040808220805460ff19166001179055514392917f556646edb498605e1eaf0f4ab1619f3dbc4164f1cddc22ecae584e045838d13891a350565b6001600160a01b038083166000908152601560209081526040808320938516835292905220545b92915050565b60035481565b6001600160a01b031660009081526013602052604090205460ff1690565b600a546001600160a01b031690565b6001600160a01b0391909116600090815260176020908152604080832093835292905220600181015460028201546003830154600484015460058501546006909501549395929491939092565b611708612668565b611747576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b60068054610100600160a81b0319166101006001600160a01b038416908102919091179091556040517f5ab1e8b2c0a96bffa69cb323894590e00556bdce76b87d529100949740e6a55a90600090a250565b6001600160a01b031660009081526012602052604090205460ff1690565b6117bf612668565b6117fe576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0383169081179091556040517f07c5be40db03f5890f6ca87fc24a286cabbbd63a79791089701cb0b5eb71529890600090a250565b6008546001600160a01b031690565b3360009081526012602052604090205460ff1615156001146118aa5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60009283526018602090815260408085209285526002909201905290912080546001600160a01b0319166001600160a01b03909216919091179055565b60015481565b6001600160a01b03919091166000908152601760209081526040808320938352929052206002015490565b60045481565b601f5481565b3360009081526012602052604090205460ff1615156001146119775760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60009182526018602052604090912055565b6001600160a01b031660009081526019602052604090205490565b600f5490565b60065461010090046001600160a01b031690565b600c546001600160a01b031690565b6000918252601860209081526040808420928452600290920190529020546001600160a01b031690565b6119ff6124e6565b6001600160a01b0316336001600160a01b031614611a4e5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6001600160a01b0382166000818152601960209081526040918290208490558151928352820183905280517fb83fc1206022cf828cdd927bea92f3cfe9ae485bc4d4308b65413dfdd0ab6edb9281900390910190a15050565b6001600160a01b03166000908152601a602052604090205490565b6001600160a01b03919091166000908152601760209081526040808320938352929052205490565b60055481565b3360009081526012602052604090205460ff161515600114611b435760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60065460ff1615611b855760405162461bcd60e51b815260040180806020018281038252602781526020018061429d6027913960400191505060405180910390fd5b6001600160a01b038216600090815260146020526040902054611bae908263ffffffff613c1a16565b6001600160a01b038316600090815260146020526040902055600254611bda908263ffffffff613c1a16565b600255611be5613c7b565b600c54604080516323de665160e01b81526000600482018190526001600160a01b03868116602484015260448301869052925192909316926323de66519260648084019382900301818387803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b505060025460408051858152602081019290925280516001600160a01b03871694507f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f9350918290030190a26001600160a01b038216600090815260146020526040902054611cc290839061257f565b6001600160a01b03831660008181526014602090815260409182902054825190815291517fd5cc1526bf6f20f18608ca8834d23bacab6780c93fa2e5e7033a5c85016af0469281900390910190a35050565b611d1c6124e6565b6001600160a01b0316336001600160a01b031614611d6b5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6001600160a01b0382166000908152601a60208181526040808420858155601b835293204290555254611d9f90839061257f565b6001600160a01b0383166000818152601a602090815260409182902054825193845290830185905282820152517fa3579111956ed8ebf7836e375375f707ea762883fa60008df45a289d53090b659181900360600190a25050565b6000908152601c602052604090205460ff1690565b611e176119aa565b6001600160a01b0316336001600160a01b031614611e665760405162461bcd60e51b815260040180806020018281038252604581526020018061412e6045913960600191505060405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517f127863dda9b4c03043886af0affd8e8ff8c0c65822d70f0b639eadce57271f0890600090a250565b60009081526016602052604090205460ff1690565b611ecd6124e6565b6001600160a01b0316336001600160a01b031614611f1c5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b600f8190554260105560405181907f2fe11f024562cd0798f5b3975c7be128c3b86e0249f9a66ad1e74bfb52f9246490600090a250565b60115481565b611f616124e6565b6001600160a01b0316336001600160a01b031614611fb05760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6022805460ff191690556040517ff6b2b9c63998bbfbe0a548dce3fa97702cb864dbfbdb42d4bcdb6f58c4209c3490600090a1565b611fed611848565b6001600160a01b0316336001600160a01b03161461203c5760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6006805460ff19169055604080513381526000602082015281517f532bec1988bda028bb59aba6eb1db09c7209eac3ac08644acb899122b604d1c2929181900390910190a1565b6001600160a01b031660009081526024602052604090205490565b60065460ff1681565b6120af612668565b6120ee576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b038316908117909155600d546040519091907faa735ef3e20d6d58610022edb69ae0e7e8aaa0084dc5699a0b36a5683bc7a7c790600090a350565b612146612668565b612185576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260126020526040808220805460ff19169055514392917fa40f23a963aabba33c55679497d6dd6d9815feadbeb0b0ad39d1285beda16bdd91a350565b60025481565b6001600160a01b03919091166000908152601760209081526040808320938352929052206006015490565b60008281526018602090815260408083206001600160a01b038516845260010190915290205492915050565b612235612668565b612274576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b601181905560405181907f1177d9c2a77eb9dd45c02329c8e4924e44101d64dabf8024543b0ce26e622f3690600090a250565b3360009081526012602052604090205460ff1615156001146122fa5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03909116600090815260246020526040902055565b600054600160a01b900460ff1615156001146123635760405162461bcd60e51b815260040180806020018281038252602e815260200180614173602e913960400191505060405180910390fd5b600e54612379906201518063ffffffff613c1a16565b4211156124295760006123ad6305f5e1006123a1600d54600154613cdd90919063ffffffff16565b9063ffffffff613d3616565b90506123cf6123ca62015180600e54613c1a90919063ffffffff16565b613d78565b6007546123e5906001600160a01b031682611af0565b6007546040805183815290516001600160a01b03909216917f38fec7f72e65a01ab4170fddd9ed4438b1b378e84bef08292112fb619abfc9a29181900360200190a2505b565b600c546001600160a01b031681565b6001600160a01b031660009081526014602052604090205490565b61245d612668565b61249c576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600b546001600160a01b031690565b60255490565b6040805160609a909a1b6bffffffffffffffffffffffff19166020808c019190915260348b019990995260548a01979097526074890195909552609488019390935260b487019190915260d486015260f485015261011480850191909152815180850390910181526101349093019052815191012090565b60105481565b60055490565b6040805160609390931b6bffffffffffffffffffffffff19166020808501919091526034808501939093528151808503909301835260549093019052805191012090565b60255481565b6000546001600160a01b031690565b6125e0612668565b61261f576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260136020526040808220805460ff19169055517f972d3365ef4d458e53aedba4b7422b4eea3046ea55b243b9e64341b1f1ad449d9190a250565b6000546001600160a01b0316331490565b3360009081526012602052604090205460ff1615156001146126cc5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6126d7838383612b20565b6126e2838383611857565b505050565b600e5481565b3360009081526012602052604090205460ff1615156001146127405760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60065460ff16156127825760405162461bcd60e51b815260040180806020018281038252602781526020018061429d6027913960400191505060405180910390fd5b6001600160a01b0382166000908152601460205260409020548111156127ef576040805162461bcd60e51b815260206004820152601f60248201527f4d6f727068657253746174653a204e6f7420656e6f75676820746f6b656e2e00604482015290519081900360640190fd5b6001600160a01b038216600090815260146020526040902054612818908263ffffffff613dab16565b6001600160a01b038316600090815260146020526040902055600254612844908263ffffffff613dab16565b60025561284f613c7b565b600c54604080516323de665160e01b81526001600160a01b0385811660048301526000602483018190526044830186905292519316926323de66519260648084019391929182900301818387803b1580156128a957600080fd5b505af11580156128bd573d6000803e3d6000fd5b505060025460408051858152602081019290925280516001600160a01b03871694507f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a9350918290030190a26001600160a01b038216600090815260146020526040902054611cc290839061257f565b3360009081526012602052604090205460ff1615156001146129805760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60258190556040805182815290517f8347cc6d3a3b991db61121237578d3a133ddf434ee43936f1c48d2c815eb0ab39181900360200190a150565b6129c36124e6565b6001600160a01b0316336001600160a01b031614612a125760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6000601e8190556040517fcada5cc63a6cd5770ca818284aa0ee429013dfd689c4f9587022943b408a09b19190a1565b612a4a6124e6565b6001600160a01b0316336001600160a01b031614612a995760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b80601e541115612abe57601e54612ab6908263ffffffff613dab16565b601e55612ac4565b6000601e555b42601d819055601e5460408051918252602082019290925281517fa11a2bc3cadf4e1be663d8cd5705d0e1dfab645a6d258fa97b350610640d30a0929181900390910190a150565b60065461010090046001600160a01b031681565b3360009081526012602052604090205460ff161515600114612b735760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60009283526018602090815260408085206001600160a01b03909416855260019093019052912055565b601d5481565b601e5481565b612bb1611848565b6001600160a01b0316336001600160a01b031614612c005760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b600081815260166020526040808220805460ff191660011790555182917f52ebf9d662e8bc70841a5b603c1711882a8e4b11a663af6b5709286fe7bd964591a250565b612c4b612668565b612c8a576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260136020526040808220805460ff19166001179055517f6d3bdb877ca7bde5be7e4afec9b4afd12e4f3dd1188c8fa57a7802f0f6cfa4d49190a250565b612cde6124e6565b6001600160a01b0316336001600160a01b031614612d2d5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b60208181556040805183815290517faf1ea5ac33bf092763f62a127ef50006ae56eef9cc122568bea97c7308d17376929181900390910190a150565b6000546001600160a01b031681565b612d806124e6565b6001600160a01b0316336001600160a01b031614612dcf5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6000908152601c60205260409020805460ff19166001179055565b60215481565b600d5481565b612dfe612668565b612e3d576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600c80546001600160a01b0319166001600160a01b0383169081179091556040517f0e6436d2b3e53a8a3ec2fbdd1d22525f0cd81d796bcb4beeef7337031a7e5efa90600090a250565b3360009081526012602052604090205460ff161515600114612eda5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b0316600090815260246020526040902080546001019055565b3360009081526012602052604090205460ff161515600114612f4d5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03891660009081526017602090815260408083208b845290915290208781556001810187905560028101869055600381018590556004810184905560058101839055600601819055612fad8989898989898989896124fb565b6001600160a01b038a1660009081526017602090815260408083208c845290915290206007015585151580612fe25750600085115b15612ff657612ff1888a613ded565b613000565b613000888a613e2d565b6001600160a01b03891660008181526017602090815260408083208c84528252918290206007015482518b81529182018a9052818301899052606082018890526080820187905260a0820186905260c0820185905291518b9392917f35ea872e77adbec19df83a66765d5bdc0adfe73d9ada9518cb384242ddb40d5d919081900360e00190a4505050505050505050565b3360009081526012602052604090205460ff1615156001146130e45760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60065460ff16156131265760405162461bcd60e51b815260040180806020018281038252602781526020018061429d6027913960400191505060405180910390fd5b6001600160a01b038316600090815260146020526040902054811115613193576040805162461bcd60e51b815260206004820152601f60248201527f4d6f727068657253746174653a204e6f7420656e6f75676820746f6b656e2e00604482015290519081900360640190fd5b6001600160a01b0383166000908152601460205260409020546131bc908263ffffffff613dab16565b6001600160a01b0380851660009081526014602052604080822093909355908416815220546131f1908263ffffffff613c1a16565b6001600160a01b0380841660008181526014602052604080822094909455600c5484516323de665160e01b81528885166004820152602481019390935260448301869052935193909216926323de66519260648084019391929182900301818387803b15801561326057600080fd5b505af1158015613274573d6000803e3d6000fd5b50506040805184815290516001600160a01b038087169450871692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a36001600160a01b0383166000908152601460205260409020546132de90849061257f565b6001600160a01b03841660008181526014602090815260409182902054825190815291517fd5cc1526bf6f20f18608ca8834d23bacab6780c93fa2e5e7033a5c85016af0469281900390910190a36001600160a01b03821660009081526014602052604090205461335090839061257f565b6001600160a01b03831660008181526014602090815260409182902054825190815291517fd5cc1526bf6f20f18608ca8834d23bacab6780c93fa2e5e7033a5c85016af0469281900390910190a3505050565b6009546001600160a01b031681565b600054600160a01b900460ff1681565b6001600160a01b031660009081526023602052604090205490565b600a546001600160a01b031633146134265760405162461bcd60e51b815260040180806020018281038252603d8152602001806141ea603d913960400191505060405180910390fd5b6004819055613433613c7b565b6040805182815290517f38e3203d00fb51f959df7882c56c583370da2f7abea215c09e83e7ffa61281d29181900360200190a150565b613471612668565b6134b0576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600b80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f631bdf9495e4e83ab921eecb28e1057d3598a3fa0fc5f40b06bafe3e7333bc5c9181900360200190a150565b60205481565b6135126124e6565b6001600160a01b0316336001600160a01b0316146135615760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b601e54613574908263ffffffff613c1a16565b601e819055601d5460408051928352602083019190915280517fa11a2bc3cadf4e1be663d8cd5705d0e1dfab645a6d258fa97b350610640d30a09281900390910190a150565b6135c2611848565b6001600160a01b0316336001600160a01b0316146136115760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6006805460ff1916600190811790915560408051338152602081019290925280517f532bec1988bda028bb59aba6eb1db09c7209eac3ac08644acb899122b604d1c29281900390910190a1565b60225460ff1681565b3360009081526012602052604090205460ff1615156001146136ba5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03808416600081815260156020908152604080832094871680845294825291829020859055815185815291517f3c07380f6fcae3bac39771c60e5c680334073911f2176b65f1d6925ba0badcdf9281900390910190a3505050565b613724611848565b6001600160a01b0316336001600160a01b0316146137735760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6305f5e10081116137b55760405162461bcd60e51b81526004018080602001828103825260278152602001806141076027913960400191505060405180910390fd5b60058190556040805182815290517f258a1584bca0aad852538c9d396233520174feedba906a03d19b307d3bad5f309181900360200190a150565b60006137fa612668565b613839576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b826001600160a01b031663a9059cbb6138506125c9565b846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156138a057600080fd5b505af11580156138b4573d6000803e3d6000fd5b505050506040513d60208110156138ca57600080fd5b50519392505050565b6138db6119aa565b6001600160a01b0316336001600160a01b03161461392a5760405162461bcd60e51b815260040180806020018281038252604581526020018061412e6045913960600191505060405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040517f47c6cd80582c55aabfec5a8be39d30b380cf41ba92dd2d13ba626c48c96bf27690600090a250565b6001600160a01b03919091166000908152601760209081526040808320938352929052206003015490565b6009546001600160a01b031690565b600b546001600160a01b031681565b60105490565b6139cb611848565b6001600160a01b0316336001600160a01b031614613a1a5760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6003819055613a27613c7b565b6040805182815290517ff915189a6212c055e85c9c0dc760b7a2a5d1ff9a9e64bd9af0a9897b4046dcd99181900360200190a150565b6001600160a01b03166000908152601b602052604090205490565b6001600160a01b03919091166000908152601760209081526040808320938352929052206001015490565b60009081526018602052604090205490565b6001600160a01b03919091166000908152601760209081526040808320938352929052206004015490565b613ae8612668565b613b27576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b613b3081613eb9565b50565b6008546001600160a01b031681565b6007546001600160a01b031681565b6001600160a01b03919091166000908152601760209081526040808320938352929052206005015490565b600f5481565b613b8a6124e6565b6001600160a01b0316336001600160a01b031614613bd95760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b601f8190556040805182815290517f0969f79b044617688492c7c9b226129947037ca88c450002a7561ed78aa549ac9181900360200190a150565b60115490565b600082820183811015613c74576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b613ca4600454613c98600354600254613c1a90919063ffffffff16565b9063ffffffff613c1a16565b600181905560408051918252517f5b1767df4e2cc8a7b2716959e609e0cdd987c9b88ac27b7fc4be99435aa1673b9181900360200190a1565b600082613cec5750600061167a565b82820282848281613cf957fe5b0414613c745760405162461bcd60e51b81526004018080602001828103825260218152602001806141c96021913960400191505060405180910390fd5b6000613c7483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613f59565b600e81905560405181907fb11f7283fda904f54a0fc8af727d3bf56e40a6cbf7c8fbb177083f0a335152ed90600090a250565b6000613c7483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613ffb565b6000613df98383612201565b9050806126e2576000613e106001613c9886613aa3565b9050613e1c8482611924565b613e27848483612679565b50505050565b6000613e398383612201565b90506000613e4684613aa3565b90506000613e5485836119cd565b90508215613eb25781831015613e7a57613e6f858285611857565b613e7a858285612b20565b613e8685600084611857565b613e9285856000612b20565b8115613eb257613eb285613ead84600163ffffffff613dab16565b611924565b5050505050565b6001600160a01b038116613efe5760405162461bcd60e51b81526004018080602001828103825260288152602001806141a16028913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008183613fe55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613faa578181015183820152602001613f92565b50505050905090810190601f168015613fd75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613ff157fe5b0495945050505050565b6000818484111561404d5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613faa578181015183820152602001613f92565b50505090039056fe4d6f727068657253746174653a2043616c6c6572206973206e6f7420746865204272696467652e2041626f7274696e672e4d6f727068657253746174653a2052657761726420626173697320706f696e7473206e65656420746f206265206c657373206f7220657175616c20746f2031353030302e4d6f727068657253746174653a204f6e6c7920506c6174666f726d20697320616c6c6f77656420746f2065786563757465206f7065726174696f6e2e4d6f727068657253746174653a204c6576657261676520707265636973696f6e206973203165384d6f727068657253746174653a2043616c6c696e6720636f6e7472616374206e6f742074686520476f7665726e616e636520436f6e74726163742e2041626f7274696e672e4d6f727068657253746174653a2043616e206f6e6c792062652063616c6c6564206f6e206d61696e636861696e2e4f776e61626c653a207573652072656e6f756e6365206f776e65727368697020696e73746561642e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774d6f727068657253746174653a2043616c6c6572206973206e6f74207468652053696465636861696e204f70657261746f722e2041626f7274696e672e4d6f727068657253746174653a2052657761726420626173697320706f696e74732063616e206f6e6c7920626520736574206f6e20457468657265756d2e4d6f727068657253746174653a2043616c6c6572206973206e6f74207468652041646d696e6973747261746f722e2041626f7274696e672e4d6f727068657253746174653a20436f6e7472616374207061757365642c2061626f7274696e674f776e61626c653a2063616c6c65722073686f756c64206265206f776e65722ea265627a7a72315820160459360f99868cb32b4e506044eeea98d9c28ae8691a9461867be3f47ceaa764736f6c634300051000324d6f727068657253746174653a2052657761726420626173697320706f696e7473206e65656420746f206265206c657373206f7220657175616c20746f2031353030302e4d6f727068657253746174653a204f6e6c7920506c6174666f726d20697320616c6c6f77656420746f2065786563757465206f7065726174696f6e2e4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f4d6f727068657253746174653a2043616c6c6572206973206e6f74207468652053696465636861696e204f70657261746f722e2041626f7274696e672e4d6f727068657253746174653a2052657761726420626173697320706f696e74732063616e206f6e6c7920626520736574206f6e20457468657265756d2e4f776e61626c653a2063616c6c65722073686f756c64206265206f776e65722e000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070dcdb66e128738189012dee12d7e13b377a1d3b000000000000000000000000e261d68bda5bd518598e31320ede6e1e2d53682f
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106106e05760003560e01c80637c995e9111610387578063bfde5730116101de578063e4974f8d1161010f578063f2fde38b116100ad578063faddee1411610087578063faddee1414611292578063fbfc50f6146112be578063fc89a4fc146112c6578063ff047c38146112e3576106e0565b8063f2fde38b1461125c578063f53d0a8e14611282578063f606a41a1461128a576106e0565b8063ebd164fb116100e9578063ebd164fb146111c1578063ef5fa322146111e7578063ef92f83114611213578063efeecb0414611230576106e0565b8063e4974f8d14611194578063e4bd85221461119c578063e5160f80146111a4576106e0565b8063d8d5470d1161017c578063dc39d06d11610156578063dc39d06d1461110e578063df8089ef1461113a578063e291f13514611160578063e3bbb5651461118c576106e0565b8063d8d5470d146110b3578063da46098c146110bb578063da4b0f40146110f1576106e0565b8063c5e1b59a116101b8578063c5e1b59a14611060578063d362bd2b14611086578063d69082c41461108e578063d7118351146110ab576106e0565b8063bfde573014611015578063c209afac1461101d578063c5d90a1914611043576106e0565b8063aa43ced8116102b8578063b8ed12a411610256578063bcc3e34211610230578063bcc3e34214610f59578063be7e64b614610f7f578063beabacc814610fd7578063bece75321461100d576106e0565b8063b8ed12a414610f23578063bb65b24214610f2b578063bbcd5bbe14610f33576106e0565b8063acb17ba711610292578063acb17ba714610ebb578063af434a6d14610ee1578063b2bdfa7b14610efe578063b6554c2c14610f06576106e0565b8063aa43ced814610e8e578063aa7bcd5d14610e96578063ac981b1e14610e9e576106e0565b80639231cf7411610325578063a0580880116102ff578063a058088014610e2f578063a35ab9c814610e37578063a8c8afaa14610e54578063a99d389f14610e5c576106e0565b80639231cf7414610dde5780639dc29fac14610de65780639fe4e9d214610e12576106e0565b80638da5cb5b116103615780638da5cb5b14610d765780638ea09da614610d7e5780638f32d59b14610da45780639162298f14610dac576106e0565b80637c995e9114610d3a578063857b0da014610d425780638c4050b114610d6e576106e0565b80633d7f4f3c1161053b57806361afd5ac1161046c578063706277da1161040a57806373ed1fe2116103e457806373ed1fe214610cca578063755ca87a14610cd25780637a68744414610cda5780637b431ab114610d32576106e0565b8063706277da14610c9457806370a0823114610c9c578063715018a614610cc2576106e0565b806369c66c7b1161044657806369c66c7b14610c1757806369cdcfb714610c435780636c36a4ec14610c605780636d37e21814610c8c576106e0565b806361afd5ac14610bbd578063626be56714610be3578063652f176314610beb576106e0565b80634da3c199116104d95780635996e209116104b35780635996e20914610b615780635c8b933414610b695780635c975abb14610b8f5780635e00e67914610b97576106e0565b80634da3c19914610b3457806355b3374114610b51578063592b6aab14610b59576106e0565b8063422cc2e711610515578063422cc2e714610aa857806344ae029c14610ad4578063496ccd9b14610af15780634a4cce9714610b17576106e0565b80633d7f4f3c14610a485780633eedf76a14610a7457806340c10f1914610a7c576106e0565b8063169674071161061557806321c02c8e116105b357806328b7bede1161058d57806328b7bede146109cb5780632d7b42c1146109d35780633383e8d8146109f6578063364ae26e14610a22576106e0565b806321c02c8e1461099557806325fbf712146109bb578063289b3c0d146109c3576106e0565b80631864ba30116105ef5780631864ba30146109365780631bdbae90146109625780631cb110771461096a5780632020e69714610972576106e0565b806316967407146108f4578063174c51dc146108fc57806318160ddd1461092e576106e0565b80630b7c8e7f116106825780630fa8f5161161065c5780630fa8f516146108235780631129753f1461088257806314712512146108a857806314ce70ef146108ce576106e0565b80630b7c8e7f146107d95780630eb933dc146107e15780630f508e001461081b576106e0565b806309089f97116106be57806309089f97146107475780630aa7cee2146107615780630ae5e739146107855780630af4187d146107ab576106e0565b806304371f48146106e557806306442d0a1461070457806307a9100e14610721575b600080fd5b610702600480360360208110156106fb57600080fd5b50356112eb565b005b6107026004803603602081101561071a57600080fd5b503561140c565b6107026004803603602081101561073757600080fd5b50356001600160a01b03166114a3565b61074f611512565b60408051918252519081900360200190f35b6107696115af565b604080516001600160a01b039092168252519081900360200190f35b6107026004803603602081101561079b57600080fd5b50356001600160a01b03166115be565b61074f600480360360408110156107c157600080fd5b506001600160a01b0381358116916020013516611653565b61074f611680565b610807600480360360208110156107f757600080fd5b50356001600160a01b0316611686565b604080519115158252519081900360200190f35b6107696116a4565b61084f6004803603604081101561083957600080fd5b506001600160a01b0381351690602001356116b3565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b6107026004803603602081101561089857600080fd5b50356001600160a01b0316611700565b610807600480360360208110156108be57600080fd5b50356001600160a01b0316611799565b610702600480360360208110156108e457600080fd5b50356001600160a01b03166117b7565b610769611848565b6107026004803603606081101561091257600080fd5b508035906001600160a01b036020820135169060400135611857565b61074f6118e7565b61074f6004803603604081101561094c57600080fd5b506001600160a01b0381351690602001356118ed565b61074f611918565b61074f61191e565b6107026004803603604081101561098857600080fd5b5080359060200135611924565b61074f600480360360208110156109ab57600080fd5b50356001600160a01b0316611989565b61074f6119a4565b6107696119aa565b6107696119be565b610769600480360360408110156109e957600080fd5b50803590602001356119cd565b61070260048036036040811015610a0c57600080fd5b506001600160a01b0381351690602001356119f7565b61074f60048036036020811015610a3857600080fd5b50356001600160a01b0316611aa7565b61074f60048036036040811015610a5e57600080fd5b506001600160a01b038135169060200135611ac2565b61074f611aea565b61070260048036036040811015610a9257600080fd5b506001600160a01b038135169060200135611af0565b61070260048036036040811015610abe57600080fd5b506001600160a01b038135169060200135611d14565b61080760048036036020811015610aea57600080fd5b5035611dfa565b61070260048036036020811015610b0757600080fd5b50356001600160a01b0316611e0f565b61080760048036036020811015610b2d57600080fd5b5035611eb0565b61070260048036036020811015610b4a57600080fd5b5035611ec5565b61074f611f53565b610702611f59565b610702611fe5565b61074f60048036036020811015610b7f57600080fd5b50356001600160a01b0316612083565b61080761209e565b61070260048036036020811015610bad57600080fd5b50356001600160a01b03166120a7565b61070260048036036020811015610bd357600080fd5b50356001600160a01b031661213e565b61074f6121d0565b61074f60048036036040811015610c0157600080fd5b506001600160a01b0381351690602001356121d6565b61074f60048036036040811015610c2d57600080fd5b50803590602001356001600160a01b0316612201565b61070260048036036020811015610c5957600080fd5b503561222d565b61070260048036036040811015610c7657600080fd5b506001600160a01b0381351690602001356122a7565b610702612316565b61076961242b565b61074f60048036036020811015610cb257600080fd5b50356001600160a01b031661243a565b610702612455565b6107696124e6565b61074f6124f5565b61074f6004803603610120811015610cf157600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e08101359061010001356124fb565b61074f612573565b61074f612579565b61074f60048036036040811015610d5857600080fd5b506001600160a01b03813516906020013561257f565b61074f6125c3565b6107696125c9565b61070260048036036020811015610d9457600080fd5b50356001600160a01b03166125d8565b610807612668565b61070260048036036060811015610dc257600080fd5b508035906001600160a01b036020820135169060400135612679565b61074f6126e7565b61070260048036036040811015610dfc57600080fd5b506001600160a01b0381351690602001356126ed565b61070260048036036020811015610e2857600080fd5b503561292d565b6107026129bb565b61070260048036036020811015610e4d57600080fd5b5035612a42565b610769612b0c565b61070260048036036060811015610e7257600080fd5b508035906001600160a01b036020820135169060400135612b20565b61074f612b9d565b61074f612ba3565b61070260048036036020811015610eb457600080fd5b5035612ba9565b61070260048036036020811015610ed157600080fd5b50356001600160a01b0316612c43565b61070260048036036020811015610ef757600080fd5b5035612cd6565b610769612d69565b61070260048036036020811015610f1c57600080fd5b5035612d78565b61074f612dea565b61074f612df0565b61070260048036036020811015610f4957600080fd5b50356001600160a01b0316612df6565b61070260048036036020811015610f6f57600080fd5b50356001600160a01b0316612e87565b6107026004803603610120811015610f9657600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101000135612efa565b61070260048036036060811015610fed57600080fd5b506001600160a01b03813581169160208101359091169060400135613091565b6107696133a3565b6108076133b2565b61074f6004803603602081101561103357600080fd5b50356001600160a01b03166133c2565b6107026004803603602081101561105957600080fd5b50356133dd565b6107026004803603602081101561107657600080fd5b50356001600160a01b0316613469565b61074f613504565b610702600480360360208110156110a457600080fd5b503561350a565b6107026135ba565b61080761365e565b610702600480360360608110156110d157600080fd5b506001600160a01b03813581169160208101359091169060400135613667565b6107026004803603602081101561110757600080fd5b503561371c565b6108076004803603604081101561112457600080fd5b506001600160a01b0381351690602001356137f0565b6107026004803603602081101561115057600080fd5b50356001600160a01b03166138d3565b61074f6004803603604081101561117657600080fd5b506001600160a01b038135169060200135613974565b61076961399f565b6107696139ae565b61074f6139bd565b610702600480360360208110156111ba57600080fd5b50356139c3565b61074f600480360360208110156111d757600080fd5b50356001600160a01b0316613a5d565b61074f600480360360408110156111fd57600080fd5b506001600160a01b038135169060200135613a78565b61074f6004803603602081101561122957600080fd5b5035613aa3565b61074f6004803603604081101561124657600080fd5b506001600160a01b038135169060200135613ab5565b6107026004803603602081101561127257600080fd5b50356001600160a01b0316613ae0565b610769613b33565b610769613b42565b61074f600480360360408110156112a857600080fd5b506001600160a01b038135169060200135613b51565b61074f613b7c565b610702600480360360208110156112dc57600080fd5b5035613b82565b61074f613c14565b6112f3612668565b611332576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600054600160a01b900460ff1615156001141561138f57613a9881111561138a5760405162461bcd60e51b81526004018080602001828103825260448152602001806140876044913960600191505060405180910390fd5b6113cc565b80156113cc5760405162461bcd60e51b815260040180806020018281038252603e815260200180614227603e913960400191505060405180910390fd5b600d81905560075460405182916001600160a01b0316907faa735ef3e20d6d58610022edb69ae0e7e8aaa0084dc5699a0b36a5683bc7a7c790600090a350565b611414611848565b6001600160a01b0316336001600160a01b0316146114635760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b600081815260166020526040808220805460ff191690555182917f9cb9d54a58b209894faa9f115e54b1c61733c0764fe29ed01f97c7c425f2f24391a250565b3360009081526012602052604090205460ff1615156001146114f65760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03166000908152602360205260409020439055565b600061151c6124e6565b6001600160a01b0316336001600160a01b03161461156b5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b602180546001019081905560408051918252517f86423ef8971dc4252acb273ac1099fb639020a7a2f5a64dad077d033ab2ae8e29181900360200190a15060215490565b600a546001600160a01b031681565b6115c6612668565b611605576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260126020526040808220805460ff19166001179055514392917f556646edb498605e1eaf0f4ab1619f3dbc4164f1cddc22ecae584e045838d13891a350565b6001600160a01b038083166000908152601560209081526040808320938516835292905220545b92915050565b60035481565b6001600160a01b031660009081526013602052604090205460ff1690565b600a546001600160a01b031690565b6001600160a01b0391909116600090815260176020908152604080832093835292905220600181015460028201546003830154600484015460058501546006909501549395929491939092565b611708612668565b611747576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b60068054610100600160a81b0319166101006001600160a01b038416908102919091179091556040517f5ab1e8b2c0a96bffa69cb323894590e00556bdce76b87d529100949740e6a55a90600090a250565b6001600160a01b031660009081526012602052604090205460ff1690565b6117bf612668565b6117fe576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0383169081179091556040517f07c5be40db03f5890f6ca87fc24a286cabbbd63a79791089701cb0b5eb71529890600090a250565b6008546001600160a01b031690565b3360009081526012602052604090205460ff1615156001146118aa5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60009283526018602090815260408085209285526002909201905290912080546001600160a01b0319166001600160a01b03909216919091179055565b60015481565b6001600160a01b03919091166000908152601760209081526040808320938352929052206002015490565b60045481565b601f5481565b3360009081526012602052604090205460ff1615156001146119775760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60009182526018602052604090912055565b6001600160a01b031660009081526019602052604090205490565b600f5490565b60065461010090046001600160a01b031690565b600c546001600160a01b031690565b6000918252601860209081526040808420928452600290920190529020546001600160a01b031690565b6119ff6124e6565b6001600160a01b0316336001600160a01b031614611a4e5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6001600160a01b0382166000818152601960209081526040918290208490558151928352820183905280517fb83fc1206022cf828cdd927bea92f3cfe9ae485bc4d4308b65413dfdd0ab6edb9281900390910190a15050565b6001600160a01b03166000908152601a602052604090205490565b6001600160a01b03919091166000908152601760209081526040808320938352929052205490565b60055481565b3360009081526012602052604090205460ff161515600114611b435760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60065460ff1615611b855760405162461bcd60e51b815260040180806020018281038252602781526020018061429d6027913960400191505060405180910390fd5b6001600160a01b038216600090815260146020526040902054611bae908263ffffffff613c1a16565b6001600160a01b038316600090815260146020526040902055600254611bda908263ffffffff613c1a16565b600255611be5613c7b565b600c54604080516323de665160e01b81526000600482018190526001600160a01b03868116602484015260448301869052925192909316926323de66519260648084019382900301818387803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b505060025460408051858152602081019290925280516001600160a01b03871694507f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f9350918290030190a26001600160a01b038216600090815260146020526040902054611cc290839061257f565b6001600160a01b03831660008181526014602090815260409182902054825190815291517fd5cc1526bf6f20f18608ca8834d23bacab6780c93fa2e5e7033a5c85016af0469281900390910190a35050565b611d1c6124e6565b6001600160a01b0316336001600160a01b031614611d6b5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6001600160a01b0382166000908152601a60208181526040808420858155601b835293204290555254611d9f90839061257f565b6001600160a01b0383166000818152601a602090815260409182902054825193845290830185905282820152517fa3579111956ed8ebf7836e375375f707ea762883fa60008df45a289d53090b659181900360600190a25050565b6000908152601c602052604090205460ff1690565b611e176119aa565b6001600160a01b0316336001600160a01b031614611e665760405162461bcd60e51b815260040180806020018281038252604581526020018061412e6045913960600191505060405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517f127863dda9b4c03043886af0affd8e8ff8c0c65822d70f0b639eadce57271f0890600090a250565b60009081526016602052604090205460ff1690565b611ecd6124e6565b6001600160a01b0316336001600160a01b031614611f1c5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b600f8190554260105560405181907f2fe11f024562cd0798f5b3975c7be128c3b86e0249f9a66ad1e74bfb52f9246490600090a250565b60115481565b611f616124e6565b6001600160a01b0316336001600160a01b031614611fb05760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6022805460ff191690556040517ff6b2b9c63998bbfbe0a548dce3fa97702cb864dbfbdb42d4bcdb6f58c4209c3490600090a1565b611fed611848565b6001600160a01b0316336001600160a01b03161461203c5760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6006805460ff19169055604080513381526000602082015281517f532bec1988bda028bb59aba6eb1db09c7209eac3ac08644acb899122b604d1c2929181900390910190a1565b6001600160a01b031660009081526024602052604090205490565b60065460ff1681565b6120af612668565b6120ee576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b038316908117909155600d546040519091907faa735ef3e20d6d58610022edb69ae0e7e8aaa0084dc5699a0b36a5683bc7a7c790600090a350565b612146612668565b612185576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260126020526040808220805460ff19169055514392917fa40f23a963aabba33c55679497d6dd6d9815feadbeb0b0ad39d1285beda16bdd91a350565b60025481565b6001600160a01b03919091166000908152601760209081526040808320938352929052206006015490565b60008281526018602090815260408083206001600160a01b038516845260010190915290205492915050565b612235612668565b612274576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b601181905560405181907f1177d9c2a77eb9dd45c02329c8e4924e44101d64dabf8024543b0ce26e622f3690600090a250565b3360009081526012602052604090205460ff1615156001146122fa5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03909116600090815260246020526040902055565b600054600160a01b900460ff1615156001146123635760405162461bcd60e51b815260040180806020018281038252602e815260200180614173602e913960400191505060405180910390fd5b600e54612379906201518063ffffffff613c1a16565b4211156124295760006123ad6305f5e1006123a1600d54600154613cdd90919063ffffffff16565b9063ffffffff613d3616565b90506123cf6123ca62015180600e54613c1a90919063ffffffff16565b613d78565b6007546123e5906001600160a01b031682611af0565b6007546040805183815290516001600160a01b03909216917f38fec7f72e65a01ab4170fddd9ed4438b1b378e84bef08292112fb619abfc9a29181900360200190a2505b565b600c546001600160a01b031681565b6001600160a01b031660009081526014602052604090205490565b61245d612668565b61249c576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600b546001600160a01b031690565b60255490565b6040805160609a909a1b6bffffffffffffffffffffffff19166020808c019190915260348b019990995260548a01979097526074890195909552609488019390935260b487019190915260d486015260f485015261011480850191909152815180850390910181526101349093019052815191012090565b60105481565b60055490565b6040805160609390931b6bffffffffffffffffffffffff19166020808501919091526034808501939093528151808503909301835260549093019052805191012090565b60255481565b6000546001600160a01b031690565b6125e0612668565b61261f576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260136020526040808220805460ff19169055517f972d3365ef4d458e53aedba4b7422b4eea3046ea55b243b9e64341b1f1ad449d9190a250565b6000546001600160a01b0316331490565b3360009081526012602052604090205460ff1615156001146126cc5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6126d7838383612b20565b6126e2838383611857565b505050565b600e5481565b3360009081526012602052604090205460ff1615156001146127405760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60065460ff16156127825760405162461bcd60e51b815260040180806020018281038252602781526020018061429d6027913960400191505060405180910390fd5b6001600160a01b0382166000908152601460205260409020548111156127ef576040805162461bcd60e51b815260206004820152601f60248201527f4d6f727068657253746174653a204e6f7420656e6f75676820746f6b656e2e00604482015290519081900360640190fd5b6001600160a01b038216600090815260146020526040902054612818908263ffffffff613dab16565b6001600160a01b038316600090815260146020526040902055600254612844908263ffffffff613dab16565b60025561284f613c7b565b600c54604080516323de665160e01b81526001600160a01b0385811660048301526000602483018190526044830186905292519316926323de66519260648084019391929182900301818387803b1580156128a957600080fd5b505af11580156128bd573d6000803e3d6000fd5b505060025460408051858152602081019290925280516001600160a01b03871694507f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a9350918290030190a26001600160a01b038216600090815260146020526040902054611cc290839061257f565b3360009081526012602052604090205460ff1615156001146129805760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60258190556040805182815290517f8347cc6d3a3b991db61121237578d3a133ddf434ee43936f1c48d2c815eb0ab39181900360200190a150565b6129c36124e6565b6001600160a01b0316336001600160a01b031614612a125760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6000601e8190556040517fcada5cc63a6cd5770ca818284aa0ee429013dfd689c4f9587022943b408a09b19190a1565b612a4a6124e6565b6001600160a01b0316336001600160a01b031614612a995760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b80601e541115612abe57601e54612ab6908263ffffffff613dab16565b601e55612ac4565b6000601e555b42601d819055601e5460408051918252602082019290925281517fa11a2bc3cadf4e1be663d8cd5705d0e1dfab645a6d258fa97b350610640d30a0929181900390910190a150565b60065461010090046001600160a01b031681565b3360009081526012602052604090205460ff161515600114612b735760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60009283526018602090815260408085206001600160a01b03909416855260019093019052912055565b601d5481565b601e5481565b612bb1611848565b6001600160a01b0316336001600160a01b031614612c005760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b600081815260166020526040808220805460ff191660011790555182917f52ebf9d662e8bc70841a5b603c1711882a8e4b11a663af6b5709286fe7bd964591a250565b612c4b612668565b612c8a576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260136020526040808220805460ff19166001179055517f6d3bdb877ca7bde5be7e4afec9b4afd12e4f3dd1188c8fa57a7802f0f6cfa4d49190a250565b612cde6124e6565b6001600160a01b0316336001600160a01b031614612d2d5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b60208181556040805183815290517faf1ea5ac33bf092763f62a127ef50006ae56eef9cc122568bea97c7308d17376929181900390910190a150565b6000546001600160a01b031681565b612d806124e6565b6001600160a01b0316336001600160a01b031614612dcf5760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b6000908152601c60205260409020805460ff19166001179055565b60215481565b600d5481565b612dfe612668565b612e3d576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600c80546001600160a01b0319166001600160a01b0383169081179091556040517f0e6436d2b3e53a8a3ec2fbdd1d22525f0cd81d796bcb4beeef7337031a7e5efa90600090a250565b3360009081526012602052604090205460ff161515600114612eda5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b0316600090815260246020526040902080546001019055565b3360009081526012602052604090205460ff161515600114612f4d5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03891660009081526017602090815260408083208b845290915290208781556001810187905560028101869055600381018590556004810184905560058101839055600601819055612fad8989898989898989896124fb565b6001600160a01b038a1660009081526017602090815260408083208c845290915290206007015585151580612fe25750600085115b15612ff657612ff1888a613ded565b613000565b613000888a613e2d565b6001600160a01b03891660008181526017602090815260408083208c84528252918290206007015482518b81529182018a9052818301899052606082018890526080820187905260a0820186905260c0820185905291518b9392917f35ea872e77adbec19df83a66765d5bdc0adfe73d9ada9518cb384242ddb40d5d919081900360e00190a4505050505050505050565b3360009081526012602052604090205460ff1615156001146130e45760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b60065460ff16156131265760405162461bcd60e51b815260040180806020018281038252602781526020018061429d6027913960400191505060405180910390fd5b6001600160a01b038316600090815260146020526040902054811115613193576040805162461bcd60e51b815260206004820152601f60248201527f4d6f727068657253746174653a204e6f7420656e6f75676820746f6b656e2e00604482015290519081900360640190fd5b6001600160a01b0383166000908152601460205260409020546131bc908263ffffffff613dab16565b6001600160a01b0380851660009081526014602052604080822093909355908416815220546131f1908263ffffffff613c1a16565b6001600160a01b0380841660008181526014602052604080822094909455600c5484516323de665160e01b81528885166004820152602481019390935260448301869052935193909216926323de66519260648084019391929182900301818387803b15801561326057600080fd5b505af1158015613274573d6000803e3d6000fd5b50506040805184815290516001600160a01b038087169450871692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a36001600160a01b0383166000908152601460205260409020546132de90849061257f565b6001600160a01b03841660008181526014602090815260409182902054825190815291517fd5cc1526bf6f20f18608ca8834d23bacab6780c93fa2e5e7033a5c85016af0469281900390910190a36001600160a01b03821660009081526014602052604090205461335090839061257f565b6001600160a01b03831660008181526014602090815260409182902054825190815291517fd5cc1526bf6f20f18608ca8834d23bacab6780c93fa2e5e7033a5c85016af0469281900390910190a3505050565b6009546001600160a01b031681565b600054600160a01b900460ff1681565b6001600160a01b031660009081526023602052604090205490565b600a546001600160a01b031633146134265760405162461bcd60e51b815260040180806020018281038252603d8152602001806141ea603d913960400191505060405180910390fd5b6004819055613433613c7b565b6040805182815290517f38e3203d00fb51f959df7882c56c583370da2f7abea215c09e83e7ffa61281d29181900360200190a150565b613471612668565b6134b0576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b600b80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f631bdf9495e4e83ab921eecb28e1057d3598a3fa0fc5f40b06bafe3e7333bc5c9181900360200190a150565b60205481565b6135126124e6565b6001600160a01b0316336001600160a01b0316146135615760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b601e54613574908263ffffffff613c1a16565b601e819055601d5460408051928352602083019190915280517fa11a2bc3cadf4e1be663d8cd5705d0e1dfab645a6d258fa97b350610640d30a09281900390910190a150565b6135c2611848565b6001600160a01b0316336001600160a01b0316146136115760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6006805460ff1916600190811790915560408051338152602081019290925280517f532bec1988bda028bb59aba6eb1db09c7209eac3ac08644acb899122b604d1c29281900390910190a1565b60225460ff1681565b3360009081526012602052604090205460ff1615156001146136ba5760405162461bcd60e51b815260040180806020018281038252603c8152602001806140cb603c913960400191505060405180910390fd5b6001600160a01b03808416600081815260156020908152604080832094871680845294825291829020859055815185815291517f3c07380f6fcae3bac39771c60e5c680334073911f2176b65f1d6925ba0badcdf9281900390910190a3505050565b613724611848565b6001600160a01b0316336001600160a01b0316146137735760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6305f5e10081116137b55760405162461bcd60e51b81526004018080602001828103825260278152602001806141076027913960400191505060405180910390fd5b60058190556040805182815290517f258a1584bca0aad852538c9d396233520174feedba906a03d19b307d3bad5f309181900360200190a150565b60006137fa612668565b613839576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b826001600160a01b031663a9059cbb6138506125c9565b846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156138a057600080fd5b505af11580156138b4573d6000803e3d6000fd5b505050506040513d60208110156138ca57600080fd5b50519392505050565b6138db6119aa565b6001600160a01b0316336001600160a01b03161461392a5760405162461bcd60e51b815260040180806020018281038252604581526020018061412e6045913960600191505060405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040517f47c6cd80582c55aabfec5a8be39d30b380cf41ba92dd2d13ba626c48c96bf27690600090a250565b6001600160a01b03919091166000908152601760209081526040808320938352929052206003015490565b6009546001600160a01b031690565b600b546001600160a01b031681565b60105490565b6139cb611848565b6001600160a01b0316336001600160a01b031614613a1a5760405162461bcd60e51b81526004018080602001828103825260388152602001806142656038913960400191505060405180910390fd5b6003819055613a27613c7b565b6040805182815290517ff915189a6212c055e85c9c0dc760b7a2a5d1ff9a9e64bd9af0a9897b4046dcd99181900360200190a150565b6001600160a01b03166000908152601b602052604090205490565b6001600160a01b03919091166000908152601760209081526040808320938352929052206001015490565b60009081526018602052604090205490565b6001600160a01b03919091166000908152601760209081526040808320938352929052206004015490565b613ae8612668565b613b27576040805162461bcd60e51b815260206004820181905260248201526000805160206142c4833981519152604482015290519081900360640190fd5b613b3081613eb9565b50565b6008546001600160a01b031681565b6007546001600160a01b031681565b6001600160a01b03919091166000908152601760209081526040808320938352929052206005015490565b600f5481565b613b8a6124e6565b6001600160a01b0316336001600160a01b031614613bd95760405162461bcd60e51b81526004018080602001828103825260318152602001806140566031913960400191505060405180910390fd5b601f8190556040805182815290517f0969f79b044617688492c7c9b226129947037ca88c450002a7561ed78aa549ac9181900360200190a150565b60115490565b600082820183811015613c74576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b613ca4600454613c98600354600254613c1a90919063ffffffff16565b9063ffffffff613c1a16565b600181905560408051918252517f5b1767df4e2cc8a7b2716959e609e0cdd987c9b88ac27b7fc4be99435aa1673b9181900360200190a1565b600082613cec5750600061167a565b82820282848281613cf957fe5b0414613c745760405162461bcd60e51b81526004018080602001828103825260218152602001806141c96021913960400191505060405180910390fd5b6000613c7483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613f59565b600e81905560405181907fb11f7283fda904f54a0fc8af727d3bf56e40a6cbf7c8fbb177083f0a335152ed90600090a250565b6000613c7483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613ffb565b6000613df98383612201565b9050806126e2576000613e106001613c9886613aa3565b9050613e1c8482611924565b613e27848483612679565b50505050565b6000613e398383612201565b90506000613e4684613aa3565b90506000613e5485836119cd565b90508215613eb25781831015613e7a57613e6f858285611857565b613e7a858285612b20565b613e8685600084611857565b613e9285856000612b20565b8115613eb257613eb285613ead84600163ffffffff613dab16565b611924565b5050505050565b6001600160a01b038116613efe5760405162461bcd60e51b81526004018080602001828103825260288152602001806141a16028913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008183613fe55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613faa578181015183820152602001613f92565b50505050905090810190601f168015613fd75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613ff157fe5b0495945050505050565b6000818484111561404d5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613faa578181015183820152602001613f92565b50505090039056fe4d6f727068657253746174653a2043616c6c6572206973206e6f7420746865204272696467652e2041626f7274696e672e4d6f727068657253746174653a2052657761726420626173697320706f696e7473206e65656420746f206265206c657373206f7220657175616c20746f2031353030302e4d6f727068657253746174653a204f6e6c7920506c6174666f726d20697320616c6c6f77656420746f2065786563757465206f7065726174696f6e2e4d6f727068657253746174653a204c6576657261676520707265636973696f6e206973203165384d6f727068657253746174653a2043616c6c696e6720636f6e7472616374206e6f742074686520476f7665726e616e636520436f6e74726163742e2041626f7274696e672e4d6f727068657253746174653a2043616e206f6e6c792062652063616c6c6564206f6e206d61696e636861696e2e4f776e61626c653a207573652072656e6f756e6365206f776e65727368697020696e73746561642e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774d6f727068657253746174653a2043616c6c6572206973206e6f74207468652053696465636861696e204f70657261746f722e2041626f7274696e672e4d6f727068657253746174653a2052657761726420626173697320706f696e74732063616e206f6e6c7920626520736574206f6e20457468657265756d2e4d6f727068657253746174653a2043616c6c6572206973206e6f74207468652041646d696e6973747261746f722e2041626f7274696e672e4d6f727068657253746174653a20436f6e7472616374207061757365642c2061626f7274696e674f776e61626c653a2063616c6c65722073686f756c64206265206f776e65722ea265627a7a72315820160459360f99868cb32b4e506044eeea98d9c28ae8691a9461867be3f47ceaa764736f6c63430005100032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070dcdb66e128738189012dee12d7e13b377a1d3b000000000000000000000000e261d68bda5bd518598e31320ede6e1e2d53682f
-----Decoded View---------------
Arg [0] : _mainChain (bool): True
Arg [1] : _sideChainOperator (address): 0x70Dcdb66E128738189012dee12d7e13b377A1D3B
Arg [2] : _morpherTreasury (address): 0xE261D68bDa5BD518598E31320edE6E1E2d53682f
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [1] : 00000000000000000000000070dcdb66e128738189012dee12d7e13b377a1d3b
Arg [2] : 000000000000000000000000e261d68bda5bd518598e31320ede6e1e2d53682f
Deployed Bytecode Sourcemap
513:33429:10:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;513:33429:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23210:503;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23210:503:10;;:::i;:::-;;24288:185;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24288:185:10;;:::i;15142:125::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15142:125:10;-1:-1:-1;;;;;15142:125:10;;:::i;14275:175::-;;;:::i;:::-;;;;;;;;;;;;;;;;1156:32;;;:::i;:::-;;;;-1:-1:-1;;;;;1156:32:10;;;;;;;;;;;;;;16815:158;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16815:158:10;-1:-1:-1;;;;;16815:158:10;;:::i;20958:153::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;20958:153:10;;;;;;;;;;:::i;675:31::-;;;:::i;17843:128::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17843:128:10;-1:-1:-1;;;;;17843:128:10;;:::i;:::-;;;;;;;;;;;;;;;;;;26065:112;;;:::i;28242:666::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;28242:666:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21336:215;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21336:215:10;-1:-1:-1;;;;;21336:215:10;;:::i;17142:124::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17142:124:10;-1:-1:-1;;;;;17142:124:10;;:::i;25904:155::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25904:155:10;-1:-1:-1;;;;;25904:155:10;;:::i;22683:94::-;;;:::i;11643:176::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11643:176:10;;;-1:-1:-1;;;;;11643:176:10;;;;;;;;;;:::i;612:26::-;;;:::i;30154:171::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30154:171:10;;;;;;;;:::i;712:32::-;;;:::i;3682:35::-;;;:::i;11043:172::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11043:172:10;;;;;;;:::i;12254:148::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12254:148:10;-1:-1:-1;;;;;12254:148:10;;:::i;25771:127::-;;;:::i;21557:116::-;;;:::i;22400:93::-;;;:::i;10851:186::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10851:186:10;;;;;;;:::i;12045:203::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;12045:203:10;;;;;;;;:::i;12760:146::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12760:146:10;-1:-1:-1;;;;;12760:146:10;;:::i;29803:171::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;29803:171:10;;;;;;;;:::i;750:38::-;;;:::i;18760:450::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;18760:450:10;;;;;;;;:::i;12408:346::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;12408:346:10;;;;;;;;:::i;14746:170::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14746:170:10;;:::i;21946:176::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21946:176:10;-1:-1:-1;;;;;21946:176:10;;:::i;24479:125::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24479:125:10;;:::i;25488:277::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25488:277:10;;:::i;1516:52::-;;;:::i;14456:133::-;;;:::i;25146:125::-;;;:::i;15708:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15708:144:10;-1:-1:-1;;;;;15708:144:10;;:::i;981:26::-;;;:::i;23014:190::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23014:190:10;-1:-1:-1;;;;;23014:190:10;;:::i;16979:157::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16979:157:10;-1:-1:-1;;;;;16979:157:10;;:::i;644:25::-;;;:::i;30901:186::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30901:186:10;;;;;;;;:::i;10665:180::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10665:180:10;;;;;;-1:-1:-1;;;;;10665:180:10;;:::i;16219:226::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16219:226:10;;:::i;15423:157::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;15423:157:10;;;;;;;;:::i;33564:376::-;;;:::i;1228:27::-;;;:::i;20627:123::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20627:123:10;-1:-1:-1;;;;;20627:123:10;;:::i;1482:137:13:-;;;:::i;21830:110:10:-;;;:::i;16079:134::-;;;:::i;28914:710::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;28914:710:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;1376:47::-;;;:::i;24902:111::-;;;:::i;29630:167::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;29630:167:10;;;;;;;;:::i;4160:36::-;;;:::i;682:77:13:-;;;:::i;17684:153:10:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17684:153:10;-1:-1:-1;;;;;17684:153:10;;:::i;1038:90:13:-;;;:::i;11221:235:10:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11221:235:10;;;-1:-1:-1;;;;;11221:235:10;;;;;;;;;;:::i;1300:29::-;;;:::i;19216:532::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;19216:532:10;;;;;;;;:::i;15858:215::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15858:215:10;;:::i;13935:156::-;;;:::i;13335:433::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13335:433:10;;:::i;1014:32::-;;;:::i;11462:175::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11462:175:10;;;-1:-1:-1;;;;;11462:175:10;;;;;;;;;;:::i;3584:45::-;;;:::i;3635:41::-;;;:::i;24108:174::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24108:174:10;;:::i;17528:150::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17528:150:10;-1:-1:-1;;;;;17528:150:10;;:::i;14097:172::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14097:172:10;;:::i;262:21:13:-;;;:::i;14595:145:10:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14595:145:10;;:::i;3769:28::-;;;:::i;1262:32::-;;;:::i;22230:164::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22230:164:10;-1:-1:-1;;;;;22230:164:10;;:::i;15586:116::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15586:116:10;-1:-1:-1;;;;;15586:116:10;;:::i;26556:1680::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;26556:1680:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;18187:567::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;18187:567:10;;;;;;;;;;;;;;;;;:::i;1121:29::-;;;:::i;585:21::-;;;:::i;15273:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15273:144:10;-1:-1:-1;;;;;15273:144:10;;:::i;20386:235::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20386:235:10;;:::i;21679:145::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21679:145:10;-1:-1:-1;;;;;21679:145:10;;:::i;3723:40::-;;;:::i;13076:253::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13076:253:10;;:::i;25019:121::-;;;:::i;3803:32::-;;;:::i;20756:196::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;20756:196:10;;;;;;;;;;;;;;;;;:::i;24610:286::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24610:286:10;;:::i;2498:184:13:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;2498:184:13;;;;;;;;:::i;22499:178:10:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22499:178:10;-1:-1:-1;;;;;22499:178:10;;:::i;30331:180::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30331:180:10;;;;;;;;:::i;22128:96::-;;;:::i;1194:28::-;;;:::i;26183:153::-;;;:::i;20164:216::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20164:216:10;;:::i;12912:158::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12912:158:10;-1:-1:-1;;;;;12912:158:10;;:::i;29980:168::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;29980:168:10;;;;;;;;:::i;10499:160::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10499:160:10;;:::i;30517:183::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30517:183:10;;;;;;;;:::i;1790:107:13:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1790:107:13;-1:-1:-1;;;;;1790:107:13;;:::i;1087:28:10:-;;;:::i;1052:29::-;;;:::i;30706:189::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30706:189:10;;;;;;;;:::i;1336:34::-;;;:::i;13774:155::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13774:155:10;;:::i;16451:141::-;;;:::i;23210:503::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;23302:9:10;;-1:-1:-1;;;23302:9:10;;;;:17;;23315:4;23302:17;23298:291;;;23368:5;23343:21;:30;;23335:111;;;;-1:-1:-1;;;23335:111:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23298:291;;;23485:26;;23477:101;;;;-1:-1:-1;;;23477:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23598:17;:41;;;23668:14;;23654:52;;23618:21;;-1:-1:-1;;;;;23668:14:10;;23654:52;;23668:14;;23654:52;23210:503;:::o;24288:185::-;7886:18;:16;:18::i;:::-;-1:-1:-1;;;;;7872:32:10;:10;-1:-1:-1;;;;;7872:32:10;;7864:101;;;;-1:-1:-1;;;7864:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24410:5;24376:31;;;:12;:31;;;;;;:39;;-1:-1:-1;;24376:39:10;;;24430:36;24389:17;;24430:36;;;24288:185;:::o;15142:125::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15219:26:10;;;;;:16;:26;;;;;15248:12;15219:41;;15142:125::o;14275:175::-;14328:14;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14354:13;:15;;;;;;;;14384:29;;;;;;;;;;;;;;;;-1:-1:-1;14430:13:10;;14275:175;:::o;1156:32::-;;;-1:-1:-1;;;;;1156:32:10;;:::o;16815:158::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;-1:-1:-1;;;;;16881:21:10;;;;;;:11;:21;;;;;;:28;;-1:-1:-1;;16881:28:10;16905:4;16881:28;;;16924:42;16953:12;;16881:21;16924:42;;;16815:158;:::o;20958:153::-;-1:-1:-1;;;;;21075:20:10;;;21039:17;21075:20;;;:7;:20;;;;;;;;:29;;;;;;;;;;20958:153;;;;;:::o;675:31::-;;;;:::o;17843:128::-;-1:-1:-1;;;;;17939:25:10;17905:15;17939:25;;;:15;:25;;;;;;;;;17843:128::o;26065:112::-;26153:17;;-1:-1:-1;;;;;26153:17:10;26065:112;:::o;28242:666::-;-1:-1:-1;;;;;28572:19:10;;;;28352;28572;;;:9;:19;;;;;;;;:30;;;;;;;:41;;;;28623:42;;;;28675:45;;;;28730:46;;;;28786:48;;;;28844:47;;;;;28572:41;;28623:42;;28675:45;;28730:46;;28242:666::o;21336:215::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;21433:17:10;:49;;-1:-1:-1;;;;;;21433:49:10;;-1:-1:-1;;;;;21433:49:10;;;;;;;;;;;;21497:47;;;;-1:-1:-1;;21497:47:10;21336:215;:::o;17142:124::-;-1:-1:-1;;;;;17238:21:10;17204:15;17238:21;;;:11;:21;;;;;;;;;17142:124::o;25904:155::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;25979:17:10;:28;;-1:-1:-1;;;;;;25979:28:10;-1:-1:-1;;;;;25979:28:10;;;;;;;;26022:30;;;;-1:-1:-1;;26022:30:10;25904:155;:::o;22683:94::-;22757:13;;-1:-1:-1;;;;;22757:13:10;22683:94;:::o;11643:176::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11761:27;;;;:16;:27;;;;;;;;:40;;;:32;;;;:40;;;;;:51;;-1:-1:-1;;;;;;11761:51:10;-1:-1:-1;;;;;11761:51:10;;;;;;;;;11643:176::o;612:26::-;;;;:::o;30154:171::-;-1:-1:-1;;;;;30275:19:10;;;;30236:20;30275:19;;;:9;:19;;;;;;;;:30;;;;;;;:42;;;;30154:171::o;712:32::-;;;;:::o;3682:35::-;;;;:::o;11043:172::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11146:27;;;;:16;:27;;;;;;:62;11043:172::o;12254:148::-;-1:-1:-1;;;;;12362:33:10;12329:14;12362:33;;;:23;:33;;;;;;;12254:148::o;25771:127::-;25872:19;;25771:127;:::o;21557:116::-;21649:17;;;;;-1:-1:-1;;;;;21649:17:10;;21557:116::o;22400:93::-;22474:12;;-1:-1:-1;;;;;22474:12:10;22400:93;:::o;10851:186::-;10948:16;10983:27;;;:16;:27;;;;;;;;:47;;;:32;;;;:47;;;;;-1:-1:-1;;;;;10983:47:10;;10851:186::o;12045:203::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;12143:33:10;;;;;;:23;:33;;;;;;;;;:42;;;12200:41;;;;;;;;;;;;;;;;;;;;;;12045:203;;:::o;12760:146::-;-1:-1:-1;;;;;12867:32:10;12834:14;12867:32;;;:22;:32;;;;;;;12760:146::o;29803:171::-;-1:-1:-1;;;;;29924:19:10;;;;29885:20;29924:19;;;:9;:19;;;;;;;;:30;;;;;;;:42;;29803:171::o;750:38::-;;;;:::o;18760:450::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7415:6;;;;:15;7407:67;;;;-1:-1:-1;;;7407:67:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18869:18:10;;;;;;:8;:18;;;;;;:30;;18892:6;18869:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;18848:18:10;;;;;;:8;:18;;;;;:51;18922:10;;:22;;18937:6;18922:22;:14;:22;:::i;:::-;18909:10;:35;18954:19;:17;:19::i;:::-;18997:12;;18983:70;;;-1:-1:-1;;;18983:70:10;;18997:12;18983:70;;;;;;-1:-1:-1;;;;;18983:70:10;;;;;;;;;;;;;;;18997:12;;;;;18983:40;;:70;;;;;;;;;;18997:12;;18983:70;;;5:2:-1;;;;30:1;27;20:12;5:2;18983:70:10;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;19091:10:10;;19068:34;;;;;;;;;;;;;;;-1:-1:-1;;;;;19068:34:10;;;-1:-1:-1;19068:34:10;;-1:-1:-1;19068:34:10;;;;;;;-1:-1:-1;;;;;19183:18:10;;;;;;:8;:18;;;;;;19158:44;;19173:8;;19158:14;:44::i;:::-;-1:-1:-1;;;;;19117:86:10;;19138:18;;;;:8;:18;;;;;;;;;;19117:86;;;;;;;;;;;;;;;;;18760:450;;:::o;12408:346::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;12505:32:10;;;;;;:22;:32;;;;;;;;:41;;;12556:26;:36;;;;12595:3;12556:42;;12713:32;;12688:58;;12528:8;;12688:14;:58::i;:::-;-1:-1:-1;;;;;12654:32:10;;;;;;:22;:32;;;;;;;;;;12613:134;;;;;;;;;;;;;;;;;;;;;;;;;12408:346;;:::o;14746:170::-;14829:20;14868:41;;;:26;:41;;;;;;;;;14746:170::o;21946:176::-;7714:15;:13;:15::i;:::-;-1:-1:-1;;;;;7700:29:10;:10;-1:-1:-1;;;;;7700:29:10;;7692:111;;;;-1:-1:-1;;;7692:111:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22033:14;:35;;-1:-1:-1;;;;;;22033:35:10;-1:-1:-1;;;;;22033:35:10;;;;;;;;22083:32;;;;-1:-1:-1;;22083:32:10;21946:176;:::o;24479:125::-;24543:12;24574:23;;;:12;:23;;;;;;;;;24479:125::o;25488:277::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25578:19;:42;;;25665:3;25630:32;:38;25711:47;;25600:20;;25711:47;;-1:-1:-1;;25711:47:10;25488:277;:::o;1516:52::-;;;;:::o;14456:133::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14516:20;:28;;-1:-1:-1;;14516:28:10;;;14559:23;;;;14539:5;;14559:23;14456:133::o;25146:125::-;7886:18;:16;:18::i;:::-;-1:-1:-1;;;;;7872:32:10;:10;-1:-1:-1;;;;;7872:32:10;;7864:101;;;;-1:-1:-1;;;7864:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25205:6;:14;;-1:-1:-1;;25205:14:10;;;25234:30;;;25246:10;25234:30;;25214:5;25234:30;;;;;;;;;;;;;;;;;25146:125::o;15708:144::-;-1:-1:-1;;;;;15819:26:10;15775:25;15819:26;;;:16;:26;;;;;;;15708:144::o;981:26::-;;;;;;:::o;23014:190::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;23095:14:10;:35;;-1:-1:-1;;;;;;23095:35:10;-1:-1:-1;;;;;23095:35:10;;;;;;;;23179:17;;23145:52;;23179:17;;23095:35;23145:52;;-1:-1:-1;;23145:52:10;23014:190;:::o;16979:157::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;-1:-1:-1;;;;;17044:21:10;;17068:5;17044:21;;;:11;:21;;;;;;:29;;-1:-1:-1;;17044:29:10;;;17088:41;17116:12;;17044:21;17088:41;;;16979:157;:::o;644:25::-;;;;:::o;30901:186::-;-1:-1:-1;;;;;31032:19:10;;;;30988:25;31032:19;;;:9;:19;;;;;;;;:30;;;;;;;:47;;;;30901:186::o;10665:180::-;10755:21;10795:27;;;:16;:27;;;;;;;;-1:-1:-1;;;;;10795:43:10;;;;:33;;:43;;;;;;10665:180;;;;:::o;16219:226::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;16316:24:10;:52;;;16383:55;;16343:25;;16383:55;;;;;16219:226;:::o;15423:157::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15527:26:10;;;;;;;:16;:26;;;;;:46;15423:157::o;33564:376::-;8496:9;;-1:-1:-1;;;8496:9:10;;;;:17;;8509:4;8496:17;8488:76;;;;-1:-1:-1;;;8488:76:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33635:14;;:32;;969:6;33635:32;:18;:32;:::i;:::-;33629:3;:38;33625:309;;;33683:15;33701:49;890:5;33701:34;33717:17;;33701:11;;:15;;:34;;;;:::i;:::-;:38;:49;:38;:49;:::i;:::-;33683:67;;33764:51;33782:32;969:6;33782:14;;:18;;:32;;;;:::i;:::-;33764:17;:51::i;:::-;33834:14;;33829:29;;-1:-1:-1;;;;;33834:14:10;33850:7;33829:4;:29::i;:::-;33899:14;;33877:46;;;;;;;;-1:-1:-1;;;;;33899:14:10;;;;33877:46;;;;;;;;;33625:309;;33564:376::o;1228:27::-;;;-1:-1:-1;;;;;1228:27:10;;:::o;20627:123::-;-1:-1:-1;;;;;20722:21:10;20688:15;20722:21;;;:8;:21;;;;;;;20627:123::o;1482:137:13:-;886:9;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;1580:1;1564:6;;1543:40;;-1:-1:-1;;;;;1564:6:13;;;;1543:40;;1580:1;;1543:40;1610:1;1593:19;;-1:-1:-1;;;;;;1593:19:13;;;1482:137::o;21830:110:10:-;21920:13;;-1:-1:-1;;;;;21920:13:10;21830:110;:::o;16079:134::-;16185:21;;16079:134;:::o;28914:710::-;29299:308;;;;;;;;-1:-1:-1;;29299:308:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;29299:308:10;;;;;;29276:341;;;;;;28914:710::o;1376:47::-;;;;:::o;24902:111::-;24991:15;;24902:111;:::o;29630:167::-;29753:36;;;;;;;;-1:-1:-1;;29753:36:10;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;29753:36:10;;;;;;29743:47;;;;;;29630:167::o;4160:36::-;;;;:::o;682:77:13:-;720:7;746:6;-1:-1:-1;;;;;746:6:13;682:77;:::o;17684:153:10:-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;-1:-1:-1;;;;;17755:25:10;;17783:5;17755:25;;;:15;:25;;;;;;:33;;-1:-1:-1;;17755:33:10;;;17803:27;;;17783:5;17803:27;17684:153;:::o;1038:90:13:-;1078:4;1115:6;-1:-1:-1;;;;;1115:6:13;1101:10;:20;;1038:90::o;11221:235:10:-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11333:52;11357:9;11368:8;11378:6;11333:23;:52::i;:::-;11395:54;11421:9;11432:8;11442:6;11395:25;:54::i;:::-;11221:235;;;:::o;1300:29::-;;;;:::o;19216:532::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7415:6;;;;:15;7407:67;;;;-1:-1:-1;;;7407:67:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19312:18:10;;;;;;:8;:18;;;;;;:28;-1:-1:-1;19312:28:10;19304:72;;;;;-1:-1:-1;;;19304:72:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19407:18:10;;;;;;:8;:18;;;;;;:30;;19430:6;19407:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;19386:18:10;;;;;;:8;:18;;;;;:51;19460:10;;:22;;19475:6;19460:22;:14;:22;:::i;:::-;19447:10;:35;19492:19;:17;:19::i;:::-;19535:12;;19521:70;;;-1:-1:-1;;;19521:70:10;;-1:-1:-1;;;;;19521:70:10;;;;;;;19535:12;19521:70;;;;;;;;;;;;;;19535:12;;;19521:40;;:70;;;;;19535:12;;19521:70;;;;;;19535:12;;19521:70;;;5:2:-1;;;;30:1;27;20:12;5:2;19521:70:10;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;19629:10:10;;19606:34;;;;;;;;;;;;;;;-1:-1:-1;;;;;19606:34:10;;;-1:-1:-1;19606:34:10;;-1:-1:-1;19606:34:10;;;;;;;-1:-1:-1;;;;;19721:18:10;;;;;;:8;:18;;;;;;19696:44;;19711:8;;19696:14;:44::i;15858:215::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15954:21;:46;;;16015:51;;;;;;;;;;;;;;;;;15858:215;:::o;13935:156::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14035:1;14006:26;:30;;;14051:33;;;;14035:1;14051:33;13935:156::o;13335:433::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13449:7;13420:26;;:36;13416:196;;;13501:26;;:39;;13532:7;13501:39;:30;:39;:::i;:::-;13472:26;:68;13416:196;;;13600:1;13571:26;:30;13416:196;13654:3;13621:30;:36;;;13702:26;;13672:89;;;;;;;;;;;;;;;;;;;;;;;;;;13335:433;:::o;1014:32::-;;;;;;-1:-1:-1;;;;;1014:32:10;;:::o;11462:175::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11578:27;;;;:16;:27;;;;;;;;-1:-1:-1;;;;;11578:43:10;;;;;:33;;;;:43;;;;:52;11462:175::o;3584:45::-;;;;:::o;3635:41::-;;;;:::o;24108:174::-;7886:18;:16;:18::i;:::-;-1:-1:-1;;;;;7872:32:10;:10;-1:-1:-1;;;;;7872:32:10;;7864:101;;;;-1:-1:-1;;;7864:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24192:29;;;;:12;:29;;;;;;:36;;-1:-1:-1;;24192:36:10;24224:4;24192:36;;;24243:32;24205:15;;24243:32;;;24108:174;:::o;17528:150::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;-1:-1:-1;;;;;17598:25:10;;;;;;:15;:25;;;;;;:32;;-1:-1:-1;;17598:32:10;17626:4;17598:32;;;17645:26;;;17598:25;17645:26;17528:150;:::o;14097:172::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14177:16;:32;;;14224:38;;;;;;;;;;;;;;;;;;;14097:172;:::o;262:21:13:-;;;-1:-1:-1;;;;;262:21:13;;:::o;14595:145:10:-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14685:41;;;;:26;:41;;;;;:48;;-1:-1:-1;;14685:48:10;14729:4;14685:48;;;14595:145::o;3769:28::-;;;;:::o;1262:32::-;;;;:::o;22230:164::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;22310:12:10;:32;;-1:-1:-1;;;;;;22310:32:10;-1:-1:-1;;;;;22310:32:10;;;;;;;;22357:30;;;;-1:-1:-1;;22357:30:10;22230:164;:::o;15586:116::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15667:26:10;;;;;:16;:26;;;;;:28;;;;;;15586:116::o;26556:1680::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26891:19:10;;;;;;:9;:19;;;;;;;;:30;;;;;;;;:55;;;26956:41;;;:55;;;27021:42;;;:57;;;27088:45;;;:63;;;27161:46;;;:65;;;27236:48;;;:69;;;27315:47;;:67;;;27438:267;26891:19;:30;:55;26956;27021:57;27088:63;27161:65;27236:69;27315:67;27438:15;:267::i;:::-;-1:-1:-1;;;;;27392:19:10;;;;;;:9;:19;;;;;;;;:30;;;;;;;;:43;;:313;27719:15;;;;:35;;;27753:1;27738:12;:16;27719:35;27715:180;;;27770:40;27790:9;27801:8;27770:19;:40::i;:::-;27715:180;;;27841:43;27864:9;27875:8;27841:22;:43::i;:::-;-1:-1:-1;;;;;27909:320:10;;27934:19;;;;:9;:19;;;;;;;;:30;;;;;;;;;:43;;;27909:320;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28013:9;;27909:320;27934:43;27909:320;;;;;;;;;;26556:1680;;;;;;;;;:::o;18187:567::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7415:6;;;;:15;7407:67;;;;-1:-1:-1;;;7407:67:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18297:15:10;;;;;;:8;:15;;;;;;:25;-1:-1:-1;18297:25:10;18289:69;;;;;-1:-1:-1;;;18289:69:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18386:15:10;;;;;;:8;:15;;;;;;:27;;18406:6;18386:27;:19;:27;:::i;:::-;-1:-1:-1;;;;;18368:15:10;;;;;;;:8;:15;;;;;;:45;;;;18439:13;;;;;;;:25;;18457:6;18439:25;:17;:25;:::i;:::-;-1:-1:-1;;;;;18423:13:10;;;;;;;:8;:13;;;;;;:41;;;;18488:12;;18474:60;;-1:-1:-1;;;18474:60:10;;;;;;;;;;;;;;;;;;;;;;;;18488:12;;;;;18474:40;;:60;;;;;18423:13;;18474:60;;;;;;18423:13;18488:12;18474:60;;;5:2:-1;;;;30:1;27;20:12;5:2;18474:60:10;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;18549:28:10;;;;;;;;-1:-1:-1;;;;;18549:28:10;;;;-1:-1:-1;18549:28:10;;;-1:-1:-1;18549:28:10;;;;;;;;;-1:-1:-1;;;;;18649:15:10;;;;;;:8;:15;;;;;;18627:38;;18642:5;;18627:14;:38::i;:::-;-1:-1:-1;;;;;18592:74:10;;18610:15;;;;:8;:15;;;;;;;;;;18592:74;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18732:13:10;;;;;;:8;:13;;;;;;18712:34;;18727:3;;18712:14;:34::i;:::-;-1:-1:-1;;;;;18681:66:10;;18697:13;;;;:8;:13;;;;;;;;;;18681:66;;;;;;;;;;;;;;;;;18187:567;;;:::o;1121:29::-;;;-1:-1:-1;;;;;1121:29:10;;:::o;585:21::-;;;-1:-1:-1;;;585:21:10;;;;;:::o;15273:144::-;-1:-1:-1;;;;;15384:26:10;15340:25;15384:26;;;:16;:26;;;;;;;15273:144::o;20386:235::-;8052:17;;-1:-1:-1;;;;;8052:17:10;8038:10;:31;8030:105;;;;-1:-1:-1;;;8030:105:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20486:17;:41;;;20537:19;:17;:19::i;:::-;20571:43;;;;;;;;;;;;;;;;;20386:235;:::o;21679:145::-;886:9:13;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;21752:13:10;:26;;-1:-1:-1;;;;;21752:26:10;;-1:-1:-1;;;;;;21752:26:10;;;;;;;;21793:24;;;;;;;;;;;;;;;;21679:145;:::o;3723:40::-;;;;:::o;13076:253::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13179:26;;:39;;13210:7;13179:39;:30;:39;:::i;:::-;13150:26;:68;;;13291:30;;13233:89;;;;;;;;;;;;;;;;;;;;;;;;;13076:253;:::o;25019:121::-;7886:18;:16;:18::i;:::-;-1:-1:-1;;;;;7872:32:10;:10;-1:-1:-1;;;;;7872:32:10;;7864:101;;;;-1:-1:-1;;;7864:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25076:6;:13;;-1:-1:-1;;25076:13:10;25085:4;25076:13;;;;;;25104:29;;;25116:10;25104:29;;;;;;;;;;;;;;;;;;;;;25019:121::o;3803:32::-;;;;;;:::o;20756:196::-;7550:10;7538:23;;;;:11;:23;;;;;;;;:31;;:23;:31;7530:104;;;;-1:-1:-1;;;7530:104:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20858:14:10;;;;;;;:7;:14;;;;;;;;:24;;;;;;;;;;;;;:34;;;20907:38;;;;;;;;;;;;;;;;;20756:196;;;:::o;24610:286::-;7886:18;:16;:18::i;:::-;-1:-1:-1;;;;;7872:32:10;:10;-1:-1:-1;;;;;7872:32:10;;7864:101;;;;-1:-1:-1;;;7864:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;890:5;24710:19;:31;24702:83;;;;-1:-1:-1;;;24702:83:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24795:15;:37;;;24847:42;;;;;;;;;;;;;;;;;24610:286;:::o;2498:184:13:-;2595:13;886:9;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;2634:13;-1:-1:-1;;;;;2627:30:13;;2658:7;:5;:7::i;:::-;2667;2627:48;;;;;;;;;;;;;-1:-1:-1;;;;;2627:48:13;-1:-1:-1;;;;;2627:48:13;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2627:48:13;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2627:48:13;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2627:48:13;;2498:184;-1:-1:-1;;;2498:184:13:o;22499:178:10:-;7714:15;:13;:15::i;:::-;-1:-1:-1;;;;;7700:29:10;:10;-1:-1:-1;;;;;7700:29:10;;7692:111;;;;-1:-1:-1;;;7692:111:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22584:13;:33;;-1:-1:-1;;;;;;22584:33:10;-1:-1:-1;;;;;22584:33:10;;;;;;;;22632:38;;;;-1:-1:-1;;22632:38:10;22499:178;:::o;30331:180::-;-1:-1:-1;;;;;30458:19:10;;;;30416:23;30458:19;;;:9;:19;;;;;;;;:30;;;;;;;:45;;;;30331:180::o;22128:96::-;22203:14;;-1:-1:-1;;;;;22203:14:10;22128:96;:::o;1194:28::-;;;-1:-1:-1;;;;;1194:28:10;;:::o;26183:153::-;26297:32;;26183:153;:::o;20164:216::-;7886:18;:16;:18::i;:::-;-1:-1:-1;;;;;7872:32:10;:10;-1:-1:-1;;;;;7872:32:10;;7864:101;;;;-1:-1:-1;;;7864:101:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20255:16;:36;;;20301:19;:17;:19::i;:::-;20335:38;;;;;;;;;;;;;;;;;20164:216;:::o;12912:158::-;-1:-1:-1;;;;;13027:36:10;12990:18;13027:36;;;:26;:36;;;;;;;12912:158::o;29980:168::-;-1:-1:-1;;;;;30099:19:10;;;;30061;30099;;;:9;:19;;;;;;;;:30;;;;;;;:41;;;;29980:168::o;10499:160::-;10566:24;10609:27;;;:16;:27;;;;;:43;;10499:160::o;30517:183::-;-1:-1:-1;;;;;30646:19:10;;;;30603:24;30646:19;;;:9;:19;;;;;;;;:30;;;;;;;:46;;;;30517:183::o;1790:107:13:-;886:9;:7;:9::i;:::-;878:54;;;;;-1:-1:-1;;;878:54:13;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;878:54:13;;;;;;;;;;;;;;;1862:28;1881:8;1862:18;:28::i;:::-;1790:107;:::o;1087:28:10:-;;;-1:-1:-1;;;;;1087:28:10;;:::o;1052:29::-;;;-1:-1:-1;;;;;1052:29:10;;:::o;30706:189::-;-1:-1:-1;;;;;30839:19:10;;;;30794:26;30839:19;;;:9;:19;;;;;;;;:30;;;;;;;:48;;;;30706:189::o;1336:34::-;;;;:::o;13774:155::-;8359:18;:16;:18::i;:::-;-1:-1:-1;;;;;8345:32:10;:10;-1:-1:-1;;;;;8345:32:10;;8337:94;;;;-1:-1:-1;;;8337:94:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13850:20;:29;;;13894:28;;;;;;;;;;;;;;;;;13774:155;:::o;16451:141::-;16561:24;;16451:141;:::o;834:176:14:-;892:7;923:5;;;946:6;;;;938:46;;;;;-1:-1:-1;;;938:46:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;1002:1;834:176;-1:-1:-1;;;834:176:14:o;19993:165:10:-;20054:55;20091:17;;20054:32;20069:16;;20054:10;;:14;;:32;;;;:::i;:::-;:36;:55;:36;:55;:::i;:::-;20040:11;:69;;;20124:27;;;;;;;;;;;;;;;;19993:165::o;2159:459:14:-;2217:7;2458:6;2454:45;;-1:-1:-1;2487:1:14;2480:8;;2454:45;2521:5;;;2525:1;2521;:5;:1;2544:5;;;;;:10;2536:56;;;;-1:-1:-1;;;2536:56:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3073:130;3131:7;3157:39;3161:1;3164;3157:39;;;;;;;;;;;;;;;;;:3;:39::i;23719:155:10:-;23789:14;:32;;;23836:31;;23806:15;;23836:31;;;;;23719:155;:::o;1274:134:14:-;1332:7;1358:43;1362:1;1365;1358:43;;;;;;;;;;;;;;;;;:3;:43::i;31372:455:10:-;31501:24;31528:42;31552:7;31561:8;31528:23;:42::i;:::-;31501:69;-1:-1:-1;31584:21:10;31580:241;;31621:24;31648:34;31680:1;31648:27;31667:7;31648:18;:27::i;:34::-;31621:61;;31696:45;31715:7;31724:16;31696:18;:45::i;:::-;31755:55;31774:7;31783:8;31793:16;31755:18;:55::i;:::-;31580:241;31372:455;;;:::o;31833:1321::-;31953:24;31980:42;32004:7;32013:8;31980:23;:42::i;:::-;31953:69;;32071:18;32092:27;32111:7;32092:18;:27::i;:::-;32071:48;;32129:20;32152:46;32178:7;32187:10;32152:25;:46::i;:::-;32129:69;-1:-1:-1;32330:20:10;;32326:822;;32558:10;32539:16;:29;32535:216;;;32588:66;32614:7;32623:12;32637:16;32588:25;:66::i;:::-;32672:64;32696:7;32705:12;32719:16;32672:23;:64::i;:::-;32850:58;32876:7;32893:1;32897:10;32850:25;:58::i;:::-;32922:45;32946:7;32955:8;32965:1;32922:23;:45::i;:::-;33043:14;;33039:99;;33077:46;33096:7;33105:17;:10;33120:1;33105:17;:14;:17;:::i;:::-;33077:18;:46::i;:::-;31833:1321;;;;;:::o;2041:227:13:-;-1:-1:-1;;;;;2114:22:13;;2106:75;;;;-1:-1:-1;;;2106:75:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2217:6;;;2196:38;;-1:-1:-1;;;;;2196:38:13;;;;2217:6;;;2196:38;;;2244:6;:17;;-1:-1:-1;;;;;;2244:17:13;-1:-1:-1;;;;;2244:17:13;;;;;;;;;;2041:227::o;3718:338:14:-;3804:7;3904:12;3897:5;3889:28;;;;-1:-1:-1;;;3889:28:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;3889:28:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3927:9;3943:1;3939;:5;;;;;;;3718:338;-1:-1:-1;;;;;3718:338:14:o;1732:187::-;1818:7;1853:12;1845:6;;;;1837:29;;;;-1:-1:-1;;;1837:29:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;1837:29:14;-1:-1:-1;;;1888:5:14;;;1732:187::o
Swarm Source
bzzr://160459360f99868cb32b4e506044eeea98d9c28ae8691a9461867be3f47ceaa7
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.