More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 3,134 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Sell | 2537175 | 856 days ago | IN | 0 GLMR | 0.01281116 | ||||
Buy | 2537096 | 856 days ago | IN | 0 GLMR | 0.01455848 | ||||
Buy | 2536597 | 856 days ago | IN | 0 GLMR | 0.01329896 | ||||
Buy | 2536447 | 856 days ago | IN | 0 GLMR | 0.01329773 | ||||
Buy | 2536167 | 856 days ago | IN | 0 GLMR | 0.01504802 | ||||
Buy | 2533121 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2533108 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Sell | 2532142 | 857 days ago | IN | 0 GLMR | 0.01281362 | ||||
Buy | 2532022 | 857 days ago | IN | 0 GLMR | 0.01505048 | ||||
Buy | 2531514 | 857 days ago | IN | 0 GLMR | 0.01455725 | ||||
Buy | 2531509 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2531391 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2531388 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Sell | 2530035 | 857 days ago | IN | 0 GLMR | 0.01281485 | ||||
Buy | 2530024 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2530014 | 857 days ago | IN | 0 GLMR | 0.01504802 | ||||
Buy | 2529985 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2529797 | 857 days ago | IN | 0 GLMR | 0.01505171 | ||||
Buy | 2529790 | 857 days ago | IN | 0 GLMR | 0.01490486 | ||||
Buy | 2528755 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2528748 | 857 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2528042 | 858 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2528038 | 858 days ago | IN | 0 GLMR | 0.01504925 | ||||
Buy | 2526182 | 858 days ago | IN | 0 GLMR | 0.01504802 | ||||
Buy | 2526179 | 858 days ago | IN | 0 GLMR | 0.01505048 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
PredictionMarketV2
Compiler Version
v0.6.2+commit.bacdbe57
Contract Source Code (Solidity)
/** *Submitted for verification at moonbeam.moonscan.io on 2022-11-11 */ // File: contracts/RealitioERC20.sol /** *Submitted for verification at Etherscan.io on 2021-06-09 */ pragma solidity >0.4.24; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } pragma solidity >0.4.24; /** * @title ReailtioSafeMath256 * @dev Math operations with safety checks that throw on error */ library RealitioSafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } } pragma solidity >0.4.24; /** * @title RealitioSafeMath32 * @dev Math operations with safety checks that throw on error * @dev Copy of SafeMath but for uint32 instead of uint256 * @dev Deleted functions we don't use */ library RealitioSafeMath32 { function add(uint32 a, uint32 b) internal pure returns (uint32) { uint32 c = a + b; assert(c >= a); return c; } } pragma solidity >0.4.18; contract BalanceHolder { IERC20 public token; mapping(address => uint256) public balanceOf; event LogWithdraw( address indexed user, uint256 amount ); function withdraw() public { uint256 bal = balanceOf[msg.sender]; balanceOf[msg.sender] = 0; require(token.transfer(msg.sender, bal)); emit LogWithdraw(msg.sender, bal); } } pragma solidity >0.4.24; contract RealitioERC20 is BalanceHolder { using RealitioSafeMath256 for uint256; using RealitioSafeMath32 for uint32; address constant NULL_ADDRESS = address(0); // History hash when no history is created, or history has been cleared bytes32 constant NULL_HASH = bytes32(0); // An unitinalized finalize_ts for a question will indicate an unanswered question. uint32 constant UNANSWERED = 0; // An unanswered reveal_ts for a commitment will indicate that it does not exist. uint256 constant COMMITMENT_NON_EXISTENT = 0; // Commit->reveal timeout is 1/8 of the question timeout (rounded down). uint32 constant COMMITMENT_TIMEOUT_RATIO = 8; event LogSetQuestionFee( address arbitrator, uint256 amount ); event LogNewTemplate( uint256 indexed template_id, address indexed user, string question_text ); event LogNewQuestion( bytes32 indexed question_id, address indexed user, uint256 template_id, string question, bytes32 indexed content_hash, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 nonce, uint256 created ); event LogFundAnswerBounty( bytes32 indexed question_id, uint256 bounty_added, uint256 bounty, address indexed user ); event LogNewAnswer( bytes32 answer, bytes32 indexed question_id, bytes32 history_hash, address indexed user, uint256 bond, uint256 ts, bool is_commitment ); event LogAnswerReveal( bytes32 indexed question_id, address indexed user, bytes32 indexed answer_hash, bytes32 answer, uint256 nonce, uint256 bond ); event LogNotifyOfArbitrationRequest( bytes32 indexed question_id, address indexed user ); event LogFinalize( bytes32 indexed question_id, bytes32 indexed answer ); event LogClaim( bytes32 indexed question_id, address indexed user, uint256 amount ); struct Question { bytes32 content_hash; address arbitrator; uint32 opening_ts; uint32 timeout; uint32 finalize_ts; bool is_pending_arbitration; uint256 bounty; bytes32 best_answer; bytes32 history_hash; uint256 bond; } // Stored in a mapping indexed by commitment_id, a hash of commitment hash, question, bond. struct Commitment { uint32 reveal_ts; bool is_revealed; bytes32 revealed_answer; } // Only used when claiming more bonds than fits into a transaction // Stored in a mapping indexed by question_id. struct Claim { address payee; uint256 last_bond; uint256 queued_funds; } uint256 nextTemplateID = 0; mapping(uint256 => uint256) public templates; mapping(uint256 => bytes32) public template_hashes; mapping(bytes32 => Question) public questions; mapping(bytes32 => Claim) public question_claims; mapping(bytes32 => Commitment) public commitments; mapping(address => uint256) public arbitrator_question_fees; modifier onlyArbitrator(bytes32 question_id) { require(msg.sender == questions[question_id].arbitrator, "msg.sender must be arbitrator"); _; } modifier stateAny() { _; } modifier stateNotCreated(bytes32 question_id) { require(questions[question_id].timeout == 0, "question must not exist"); _; } modifier stateOpen(bytes32 question_id) { require(questions[question_id].timeout > 0, "question must exist"); require(!questions[question_id].is_pending_arbitration, "question must not be pending arbitration"); uint32 finalize_ts = questions[question_id].finalize_ts; require(finalize_ts == UNANSWERED || finalize_ts > uint32(now), "finalization deadline must not have passed"); uint32 opening_ts = questions[question_id].opening_ts; require(opening_ts == 0 || opening_ts <= uint32(now), "opening date must have passed"); _; } modifier statePendingArbitration(bytes32 question_id) { require(questions[question_id].is_pending_arbitration, "question must be pending arbitration"); _; } modifier stateOpenOrPendingArbitration(bytes32 question_id) { require(questions[question_id].timeout > 0, "question must exist"); uint32 finalize_ts = questions[question_id].finalize_ts; require(finalize_ts == UNANSWERED || finalize_ts > uint32(now), "finalization dealine must not have passed"); uint32 opening_ts = questions[question_id].opening_ts; require(opening_ts == 0 || opening_ts <= uint32(now), "opening date must have passed"); _; } modifier stateFinalized(bytes32 question_id) { require(isFinalized(question_id), "question must be finalized"); _; } modifier bondMustDouble(bytes32 question_id, uint256 tokens) { require(tokens > 0, "bond must be positive"); require(tokens >= (questions[question_id].bond.mul(2)), "bond must be double at least previous bond"); _; } modifier previousBondMustNotBeatMaxPrevious(bytes32 question_id, uint256 max_previous) { if (max_previous > 0) { require(questions[question_id].bond <= max_previous, "bond must exceed max_previous"); } _; } function setToken(IERC20 _token) public { require(token == IERC20(0x0), "Token can only be initialized once"); token = _token; } /// @notice Constructor, sets up some initial templates /// @dev Creates some generalized templates for different question types used in the DApp. constructor() public { createTemplate('{"title": "%s", "type": "bool", "category": "%s", "lang": "%s"}'); createTemplate('{"title": "%s", "type": "uint", "decimals": 18, "category": "%s", "lang": "%s"}'); createTemplate('{"title": "%s", "type": "single-select", "outcomes": [%s], "category": "%s", "lang": "%s"}'); createTemplate('{"title": "%s", "type": "multiple-select", "outcomes": [%s], "category": "%s", "lang": "%s"}'); createTemplate('{"title": "%s", "type": "datetime", "category": "%s", "lang": "%s"}'); } /// @notice Function for arbitrator to set an optional per-question fee. /// @dev The per-question fee, charged when a question is asked, is intended as an anti-spam measure. /// @param fee The fee to be charged by the arbitrator when a question is asked function setQuestionFee(uint256 fee) stateAny() external { arbitrator_question_fees[msg.sender] = fee; emit LogSetQuestionFee(msg.sender, fee); } /// @notice Create a reusable template, which should be a JSON document. /// Placeholders should use gettext() syntax, eg %s. /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage. /// @param content The template content /// @return The ID of the newly-created template, which is created sequentially. function createTemplate(string memory content) stateAny() public returns (uint256) { uint256 id = nextTemplateID; templates[id] = block.number; template_hashes[id] = keccak256(abi.encodePacked(content)); emit LogNewTemplate(id, msg.sender, content); nextTemplateID = id.add(1); return id; } /// @notice Create a new reusable template and use it to ask a question /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage. /// @param content The template content /// @param question A string containing the parameters that will be passed into the template to make the question /// @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute /// @param timeout How long the contract should wait after the answer is changed before finalizing on that answer /// @param opening_ts If set, the earliest time it should be possible to answer the question. /// @param nonce A user-specified nonce used in the question ID. Change it to repeat a question. /// @return The ID of the newly-created template, which is created sequentially. function createTemplateAndAskQuestion( string memory content, string memory question, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 nonce ) // stateNotCreated is enforced by the internal _askQuestion public returns (bytes32) { uint256 template_id = createTemplate(content); return askQuestion(template_id, question, arbitrator, timeout, opening_ts, nonce); } /// @notice Ask a new question without a bounty and return the ID /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage. /// @dev Calling without the token param will only work if there is no arbitrator-set question fee. /// @dev This has the same function signature as askQuestion() in the non-ERC20 version, which is optionally payable. /// @param template_id The ID number of the template the question will use /// @param question A string containing the parameters that will be passed into the template to make the question /// @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute /// @param timeout How long the contract should wait after the answer is changed before finalizing on that answer /// @param opening_ts If set, the earliest time it should be possible to answer the question. /// @param nonce A user-specified nonce used in the question ID. Change it to repeat a question. /// @return The ID of the newly-created question, created deterministically. function askQuestion(uint256 template_id, string memory question, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 nonce) // stateNotCreated is enforced by the internal _askQuestion public returns (bytes32) { require(templates[template_id] > 0, "template must exist"); bytes32 content_hash = keccak256(abi.encodePacked(template_id, opening_ts, question)); bytes32 question_id = keccak256(abi.encodePacked(content_hash, arbitrator, timeout, msg.sender, nonce)); _askQuestion(question_id, content_hash, arbitrator, timeout, opening_ts, 0); emit LogNewQuestion(question_id, msg.sender, template_id, question, content_hash, arbitrator, timeout, opening_ts, nonce, now); return question_id; } /// @notice Ask a new question with a bounty and return the ID /// @dev Template data is only stored in the event logs, but its block number is kept in contract storage. /// @param template_id The ID number of the template the question will use /// @param question A string containing the parameters that will be passed into the template to make the question /// @param arbitrator The arbitration contract that will have the final word on the answer if there is a dispute /// @param timeout How long the contract should wait after the answer is changed before finalizing on that answer /// @param opening_ts If set, the earliest time it should be possible to answer the question. /// @param nonce A user-specified nonce used in the question ID. Change it to repeat a question. /// @param tokens The combined initial question bounty and question fee /// @return The ID of the newly-created question, created deterministically. function askQuestionERC20(uint256 template_id, string memory question, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 nonce, uint256 tokens) // stateNotCreated is enforced by the internal _askQuestion public returns (bytes32) { _deductTokensOrRevert(tokens); require(templates[template_id] > 0, "template must exist"); bytes32 content_hash = keccak256(abi.encodePacked(template_id, opening_ts, question)); bytes32 question_id = keccak256(abi.encodePacked(content_hash, arbitrator, timeout, msg.sender, nonce)); _askQuestion(question_id, content_hash, arbitrator, timeout, opening_ts, tokens); emit LogNewQuestion(question_id, msg.sender, template_id, question, content_hash, arbitrator, timeout, opening_ts, nonce, now); return question_id; } function _deductTokensOrRevert(uint256 tokens) internal { if (tokens == 0) { return; } uint256 bal = balanceOf[msg.sender]; // Deduct any tokens you have in your internal balance first if (bal > 0) { if (bal >= tokens) { balanceOf[msg.sender] = bal.sub(tokens); return; } else { tokens = tokens.sub(bal); balanceOf[msg.sender] = 0; } } // Now we need to charge the rest from require(token.transferFrom(msg.sender, address(this), tokens), "Transfer of tokens failed, insufficient approved balance?"); return; } function _askQuestion(bytes32 question_id, bytes32 content_hash, address arbitrator, uint32 timeout, uint32 opening_ts, uint256 tokens) stateNotCreated(question_id) internal { uint256 bounty = tokens; // A timeout of 0 makes no sense, and we will use this to check existence require(timeout > 0, "timeout must be positive"); require(timeout < 365 days, "timeout must be less than 365 days"); require(arbitrator != NULL_ADDRESS, "arbitrator must be set"); // The arbitrator can set a fee for asking a question. // This is intended as an anti-spam defence. // The fee is waived if the arbitrator is asking the question. // This allows them to set an impossibly high fee and make users proxy the question through them. // This would allow more sophisticated pricing, question whitelisting etc. if (msg.sender != arbitrator) { uint256 question_fee = arbitrator_question_fees[arbitrator]; require(bounty >= question_fee, "Tokens provided must cover question fee"); bounty = bounty.sub(question_fee); balanceOf[arbitrator] = balanceOf[arbitrator].add(question_fee); } questions[question_id].content_hash = content_hash; questions[question_id].arbitrator = arbitrator; questions[question_id].opening_ts = opening_ts; questions[question_id].timeout = timeout; questions[question_id].bounty = bounty; } /// @notice Add funds to the bounty for a question /// @dev Add bounty funds after the initial question creation. Can be done any time until the question is finalized. /// @param question_id The ID of the question you wish to fund /// @param tokens The number of tokens to fund function fundAnswerBountyERC20(bytes32 question_id, uint256 tokens) stateOpen(question_id) external { _deductTokensOrRevert(tokens); questions[question_id].bounty = questions[question_id].bounty.add(tokens); emit LogFundAnswerBounty(question_id, tokens, questions[question_id].bounty, msg.sender); } /// @notice Submit an answer for a question. /// @dev Adds the answer to the history and updates the current "best" answer. /// May be subject to front-running attacks; Substitute submitAnswerCommitment()->submitAnswerReveal() to prevent them. /// @param question_id The ID of the question /// @param answer The answer, encoded into bytes32 /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction. /// @param tokens The amount of tokens to submit function submitAnswerERC20(bytes32 question_id, bytes32 answer, uint256 max_previous, uint256 tokens) stateOpen(question_id) bondMustDouble(question_id, tokens) previousBondMustNotBeatMaxPrevious(question_id, max_previous) external { _deductTokensOrRevert(tokens); _addAnswerToHistory(question_id, answer, msg.sender, tokens, false); _updateCurrentAnswer(question_id, answer, questions[question_id].timeout); } // @notice Verify and store a commitment, including an appropriate timeout // @param question_id The ID of the question to store // @param commitment The ID of the commitment function _storeCommitment(bytes32 question_id, bytes32 commitment_id) internal { require(commitments[commitment_id].reveal_ts == COMMITMENT_NON_EXISTENT, "commitment must not already exist"); uint32 commitment_timeout = questions[question_id].timeout / COMMITMENT_TIMEOUT_RATIO; commitments[commitment_id].reveal_ts = uint32(now).add(commitment_timeout); } /// @notice Submit the hash of an answer, laying your claim to that answer if you reveal it in a subsequent transaction. /// @dev Creates a hash, commitment_id, uniquely identifying this answer, to this question, with this bond. /// The commitment_id is stored in the answer history where the answer would normally go. /// Does not update the current best answer - this is left to the later submitAnswerReveal() transaction. /// @param question_id The ID of the question /// @param answer_hash The hash of your answer, plus a nonce that you will later reveal /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction. /// @param _answerer If specified, the address to be given as the question answerer. Defaults to the sender. /// @param tokens Number of tokens sent /// @dev Specifying the answerer is useful if you want to delegate the commit-and-reveal to a third-party. function submitAnswerCommitmentERC20(bytes32 question_id, bytes32 answer_hash, uint256 max_previous, address _answerer, uint256 tokens) stateOpen(question_id) bondMustDouble(question_id, tokens) previousBondMustNotBeatMaxPrevious(question_id, max_previous) external { _deductTokensOrRevert(tokens); bytes32 commitment_id = keccak256(abi.encodePacked(question_id, answer_hash, tokens)); address answerer = (_answerer == NULL_ADDRESS) ? msg.sender : _answerer; _storeCommitment(question_id, commitment_id); _addAnswerToHistory(question_id, commitment_id, answerer, tokens, true); } /// @notice Submit the answer whose hash you sent in a previous submitAnswerCommitment() transaction /// @dev Checks the parameters supplied recreate an existing commitment, and stores the revealed answer /// Updates the current answer unless someone has since supplied a new answer with a higher bond /// msg.sender is intentionally not restricted to the user who originally sent the commitment; /// For example, the user may want to provide the answer+nonce to a third-party service and let them send the tx /// NB If we are pending arbitration, it will be up to the arbitrator to wait and see any outstanding reveal is sent /// @param question_id The ID of the question /// @param answer The answer, encoded as bytes32 /// @param nonce The nonce that, combined with the answer, recreates the answer_hash you gave in submitAnswerCommitment() /// @param bond The bond that you paid in your submitAnswerCommitment() transaction function submitAnswerReveal(bytes32 question_id, bytes32 answer, uint256 nonce, uint256 bond) stateOpenOrPendingArbitration(question_id) external { bytes32 answer_hash = keccak256(abi.encodePacked(answer, nonce)); bytes32 commitment_id = keccak256(abi.encodePacked(question_id, answer_hash, bond)); require(!commitments[commitment_id].is_revealed, "commitment must not have been revealed yet"); require(commitments[commitment_id].reveal_ts > uint32(now), "reveal deadline must not have passed"); commitments[commitment_id].revealed_answer = answer; commitments[commitment_id].is_revealed = true; if (bond == questions[question_id].bond) { _updateCurrentAnswer(question_id, answer, questions[question_id].timeout); } emit LogAnswerReveal(question_id, msg.sender, answer_hash, answer, nonce, bond); } function _addAnswerToHistory(bytes32 question_id, bytes32 answer_or_commitment_id, address answerer, uint256 bond, bool is_commitment) internal { bytes32 new_history_hash = keccak256(abi.encodePacked(questions[question_id].history_hash, answer_or_commitment_id, bond, answerer, is_commitment)); // Update the current bond level, if there's a bond (ie anything except arbitration) if (bond > 0) { questions[question_id].bond = bond; } questions[question_id].history_hash = new_history_hash; emit LogNewAnswer(answer_or_commitment_id, question_id, new_history_hash, answerer, bond, now, is_commitment); } function _updateCurrentAnswer(bytes32 question_id, bytes32 answer, uint32 timeout_secs) internal { questions[question_id].best_answer = answer; questions[question_id].finalize_ts = uint32(now).add(timeout_secs); } /// @notice Notify the contract that the arbitrator has been paid for a question, freezing it pending their decision. /// @dev The arbitrator contract is trusted to only call this if they've been paid, and tell us who paid them. /// @param question_id The ID of the question /// @param requester The account that requested arbitration /// @param max_previous If specified, reverts if a bond higher than this was submitted after you sent your transaction. function notifyOfArbitrationRequest(bytes32 question_id, address requester, uint256 max_previous) onlyArbitrator(question_id) stateOpen(question_id) previousBondMustNotBeatMaxPrevious(question_id, max_previous) external { require(questions[question_id].bond > 0, "Question must already have an answer when arbitration is requested"); questions[question_id].is_pending_arbitration = true; emit LogNotifyOfArbitrationRequest(question_id, requester); } /// @notice Submit the answer for a question, for use by the arbitrator. /// @dev Doesn't require (or allow) a bond. /// If the current final answer is correct, the account should be whoever submitted it. /// If the current final answer is wrong, the account should be whoever paid for arbitration. /// However, the answerer stipulations are not enforced by the contract. /// @param question_id The ID of the question /// @param answer The answer, encoded into bytes32 /// @param answerer The account credited with this answer for the purpose of bond claims function submitAnswerByArbitrator(bytes32 question_id, bytes32 answer, address answerer) onlyArbitrator(question_id) statePendingArbitration(question_id) external { require(answerer != NULL_ADDRESS, "answerer must be provided"); emit LogFinalize(question_id, answer); questions[question_id].is_pending_arbitration = false; _addAnswerToHistory(question_id, answer, answerer, 0, false); _updateCurrentAnswer(question_id, answer, 0); } /// @notice Report whether the answer to the specified question is finalized /// @param question_id The ID of the question /// @return Return true if finalized function isFinalized(bytes32 question_id) view public returns (bool) { uint32 finalize_ts = questions[question_id].finalize_ts; return ( !questions[question_id].is_pending_arbitration && (finalize_ts > UNANSWERED) && (finalize_ts <= uint32(now)) ); } /// @notice (Deprecated) Return the final answer to the specified question, or revert if there isn't one /// @param question_id The ID of the question /// @return The answer formatted as a bytes32 function getFinalAnswer(bytes32 question_id) stateFinalized(question_id) external view returns (bytes32) { return questions[question_id].best_answer; } /// @notice Return the final answer to the specified question, or revert if there isn't one /// @param question_id The ID of the question /// @return The answer formatted as a bytes32 function resultFor(bytes32 question_id) stateFinalized(question_id) external view returns (bytes32) { return questions[question_id].best_answer; } /// @notice Return the final answer to the specified question, provided it matches the specified criteria. /// @dev Reverts if the question is not finalized, or if it does not match the specified criteria. /// @param question_id The ID of the question /// @param content_hash The hash of the question content (template ID + opening time + question parameter string) /// @param arbitrator The arbitrator chosen for the question (regardless of whether they are asked to arbitrate) /// @param min_timeout The timeout set in the initial question settings must be this high or higher /// @param min_bond The bond sent with the final answer must be this high or higher /// @return The answer formatted as a bytes32 function getFinalAnswerIfMatches( bytes32 question_id, bytes32 content_hash, address arbitrator, uint32 min_timeout, uint256 min_bond ) stateFinalized(question_id) external view returns (bytes32) { require(content_hash == questions[question_id].content_hash, "content hash must match"); require(arbitrator == questions[question_id].arbitrator, "arbitrator must match"); require(min_timeout <= questions[question_id].timeout, "timeout must be long enough"); require(min_bond <= questions[question_id].bond, "bond must be high enough"); return questions[question_id].best_answer; } /// @notice Assigns the winnings (bounty and bonds) to everyone who gave the accepted answer /// Caller must provide the answer history, in reverse order /// @dev Works up the chain and assign bonds to the person who gave the right answer /// If someone gave the winning answer earlier, they must get paid from the higher bond /// That means we can't pay out the bond added at n until we have looked at n-1 /// The first answer is authenticated by checking against the stored history_hash. /// One of the inputs to history_hash is the history_hash before it, so we use that to authenticate the next entry, etc /// Once we get to a null hash we'll know we're done and there are no more answers. /// Usually you would call the whole thing in a single transaction, but if not then the data is persisted to pick up later. /// @param question_id The ID of the question /// @param history_hashes Second-last-to-first, the hash of each history entry. (Final one should be empty). /// @param addrs Last-to-first, the address of each answerer or commitment sender /// @param bonds Last-to-first, the bond supplied with each answer or commitment /// @param answers Last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal function claimWinnings( bytes32 question_id, bytes32[] memory history_hashes, address[] memory addrs, uint256[] memory bonds, bytes32[] memory answers ) stateFinalized(question_id) public { require(history_hashes.length > 0, "at least one history hash entry must be provided"); // These are only set if we split our claim over multiple transactions. address payee = question_claims[question_id].payee; uint256 last_bond = question_claims[question_id].last_bond; uint256 queued_funds = question_claims[question_id].queued_funds; // Starts as the hash of the final answer submitted. It'll be cleared when we're done. // If we're splitting the claim over multiple transactions, it'll be the hash where we left off last time bytes32 last_history_hash = questions[question_id].history_hash; bytes32 best_answer = questions[question_id].best_answer; uint256 i; for (i = 0; i < history_hashes.length; i++) { // Check input against the history hash, and see which of 2 possible values of is_commitment fits. bool is_commitment = _verifyHistoryInputOrRevert(last_history_hash, history_hashes[i], answers[i], bonds[i], addrs[i]); queued_funds = queued_funds.add(last_bond); (queued_funds, payee) = _processHistoryItem( question_id, best_answer, queued_funds, payee, addrs[i], bonds[i], answers[i], is_commitment); // Line the bond up for next time, when it will be added to somebody's queued_funds last_bond = bonds[i]; last_history_hash = history_hashes[i]; } if (last_history_hash != NULL_HASH) { // We haven't yet got to the null hash (1st answer), ie the caller didn't supply the full answer chain. // Persist the details so we can pick up later where we left off later. // If we know who to pay we can go ahead and pay them out, only keeping back last_bond // (We always know who to pay unless all we saw were unrevealed commits) if (payee != NULL_ADDRESS) { _payPayee(question_id, payee, queued_funds); queued_funds = 0; } question_claims[question_id].payee = payee; question_claims[question_id].last_bond = last_bond; question_claims[question_id].queued_funds = queued_funds; } else { // There is nothing left below us so the payee can keep what remains _payPayee(question_id, payee, queued_funds.add(last_bond)); delete question_claims[question_id]; } questions[question_id].history_hash = last_history_hash; } function _payPayee(bytes32 question_id, address payee, uint256 value) internal { balanceOf[payee] = balanceOf[payee].add(value); emit LogClaim(question_id, payee, value); } function _verifyHistoryInputOrRevert( bytes32 last_history_hash, bytes32 history_hash, bytes32 answer, uint256 bond, address addr ) internal pure returns (bool) { if (last_history_hash == keccak256(abi.encodePacked(history_hash, answer, bond, addr, true)) ) { return true; } if (last_history_hash == keccak256(abi.encodePacked(history_hash, answer, bond, addr, false)) ) { return false; } revert("History input provided did not match the expected hash"); } function _processHistoryItem( bytes32 question_id, bytes32 best_answer, uint256 queued_funds, address payee, address addr, uint256 bond, bytes32 answer, bool is_commitment ) internal returns (uint256, address) { // For commit-and-reveal, the answer history holds the commitment ID instead of the answer. // We look at the referenced commitment ID and switch in the actual answer. if (is_commitment) { bytes32 commitment_id = answer; // If it's a commit but it hasn't been revealed, it will always be considered wrong. if (!commitments[commitment_id].is_revealed) { delete commitments[commitment_id]; return (queued_funds, payee); } else { answer = commitments[commitment_id].revealed_answer; delete commitments[commitment_id]; } } if (answer == best_answer) { if (payee == NULL_ADDRESS) { // The entry is for the first payee we come to, ie the winner. // They get the question bounty. payee = addr; queued_funds = queued_funds.add(questions[question_id].bounty); questions[question_id].bounty = 0; } else if (addr != payee) { // Answerer has changed, ie we found someone lower down who needs to be paid // The lower answerer will take over receiving bonds from higher answerer. // They should also be paid the takeover fee, which is set at a rate equivalent to their bond. // (This is our arbitrary rule, to give consistent right-answerers a defence against high-rollers.) // There should be enough for the fee, but if not, take what we have. // There's an edge case involving weird arbitrator behaviour where we may be short. uint256 answer_takeover_fee = (queued_funds >= bond) ? bond : queued_funds; // Settle up with the old (higher-bonded) payee _payPayee(question_id, payee, queued_funds.sub(answer_takeover_fee)); // Now start queued_funds again for the new (lower-bonded) payee payee = addr; queued_funds = answer_takeover_fee; } } return (queued_funds, payee); } /// @notice Convenience function to assign bounties/bonds for multiple questions in one go, then withdraw all your funds. /// Caller must provide the answer history for each question, in reverse order /// @dev Can be called by anyone to assign bonds/bounties, but funds are only withdrawn for the user making the call. /// @param question_ids The IDs of the questions you want to claim for /// @param lengths The number of history entries you will supply for each question ID /// @param hist_hashes In a single list for all supplied questions, the hash of each history entry. /// @param addrs In a single list for all supplied questions, the address of each answerer or commitment sender /// @param bonds In a single list for all supplied questions, the bond supplied with each answer or commitment /// @param answers In a single list for all supplied questions, each answer supplied, or commitment ID function claimMultipleAndWithdrawBalance( bytes32[] memory question_ids, uint256[] memory lengths, bytes32[] memory hist_hashes, address[] memory addrs, uint256[] memory bonds, bytes32[] memory answers ) stateAny() // The finalization checks are done in the claimWinnings function public { uint256 qi; uint256 i; for (qi = 0; qi < question_ids.length; qi++) { bytes32 qid = question_ids[qi]; uint256 ln = lengths[qi]; bytes32[] memory hh = new bytes32[](ln); address[] memory ad = new address[](ln); uint256[] memory bo = new uint256[](ln); bytes32[] memory an = new bytes32[](ln); uint256 j; for (j = 0; j < ln; j++) { hh[j] = hist_hashes[i]; ad[j] = addrs[i]; bo[j] = bonds[i]; an[j] = answers[i]; i++; } claimWinnings(qid, hh, ad, bo, an); } withdraw(); } /// @notice Returns the questions's content hash, identifying the question content /// @param question_id The ID of the question function getContentHash(bytes32 question_id) public view returns(bytes32) { return questions[question_id].content_hash; } /// @notice Returns the arbitrator address for the question /// @param question_id The ID of the question function getArbitrator(bytes32 question_id) public view returns(address) { return questions[question_id].arbitrator; } /// @notice Returns the timestamp when the question can first be answered /// @param question_id The ID of the question function getOpeningTS(bytes32 question_id) public view returns(uint32) { return questions[question_id].opening_ts; } /// @notice Returns the timeout in seconds used after each answer /// @param question_id The ID of the question function getTimeout(bytes32 question_id) public view returns(uint32) { return questions[question_id].timeout; } /// @notice Returns the timestamp at which the question will be/was finalized /// @param question_id The ID of the question function getFinalizeTS(bytes32 question_id) public view returns(uint32) { return questions[question_id].finalize_ts; } /// @notice Returns whether the question is pending arbitration /// @param question_id The ID of the question function isPendingArbitration(bytes32 question_id) public view returns(bool) { return questions[question_id].is_pending_arbitration; } /// @notice Returns the current total unclaimed bounty /// @dev Set back to zero once the bounty has been claimed /// @param question_id The ID of the question function getBounty(bytes32 question_id) public view returns(uint256) { return questions[question_id].bounty; } /// @notice Returns the current best answer /// @param question_id The ID of the question function getBestAnswer(bytes32 question_id) public view returns(bytes32) { return questions[question_id].best_answer; } /// @notice Returns the history hash of the question /// @param question_id The ID of the question /// @dev Updated on each answer, then rewound as each is claimed function getHistoryHash(bytes32 question_id) public view returns(bytes32) { return questions[question_id].history_hash; } /// @notice Returns the highest bond posted so far for a question /// @param question_id The ID of the question function getBond(bytes32 question_id) public view returns(uint256) { return questions[question_id].bond; } } // File: @openzeppelin/contracts/math/SafeMath.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File: contracts/PredictionMarketV2.sol pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; // openzeppelin imports library CeilDiv { // calculates ceil(x/y) function ceildiv(uint256 x, uint256 y) internal pure returns (uint256) { if (x > 0) return ((x - 1) / y) + 1; return x / y; } } /// @title Market Contract Factory contract PredictionMarketV2 { using SafeMath for uint256; using CeilDiv for uint256; // ------ Events ------ event MarketCreated(address indexed user, uint256 indexed marketId, uint256 outcomes, string question, string image); event MarketActionTx( address indexed user, MarketAction indexed action, uint256 indexed marketId, uint256 outcomeId, uint256 shares, uint256 value, uint256 timestamp ); event MarketOutcomePrice(uint256 indexed marketId, uint256 indexed outcomeId, uint256 value, uint256 timestamp); event MarketLiquidity( uint256 indexed marketId, uint256 value, // total liquidity uint256 price, // value of one liquidity share; max: 1 (50-50 situation) uint256 timestamp ); event MarketResolved(address indexed user, uint256 indexed marketId, uint256 outcomeId, uint256 timestamp); // ------ Events End ------ uint256 public constant MAX_UINT_256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935; uint256 public constant ONE = 10**18; enum MarketState { open, closed, resolved } enum MarketAction { buy, sell, addLiquidity, removeLiquidity, claimWinnings, claimLiquidity, claimFees, claimVoided } struct Market { // market details uint256 closesAtTimestamp; uint256 balance; // total stake uint256 liquidity; // stake held uint256 sharesAvailable; // shares held (all outcomes) mapping(address => uint256) liquidityShares; mapping(address => bool) liquidityClaims; // wether user has claimed liquidity earnings MarketState state; // resolution variables MarketResolution resolution; // fees MarketFees fees; // market outcomes uint256[] outcomeIds; mapping(uint256 => MarketOutcome) outcomes; IERC20 token; // ERC20 token market will use for trading } struct MarketFees { uint256 value; // fee % taken from every transaction uint256 poolWeight; // internal var used to ensure pro-rate fee distribution mapping(address => uint256) claimed; } struct MarketResolution { bool resolved; uint256 outcomeId; bytes32 questionId; // realitio questionId } struct MarketOutcome { uint256 marketId; uint256 id; Shares shares; } struct Shares { uint256 total; // number of shares uint256 available; // available shares mapping(address => uint256) holders; mapping(address => bool) claims; // wether user has claimed winnings mapping(address => bool) voidedClaims; // wether user has claimed voided market shares } struct CreateMarketArgs { uint256 value; uint256 closesAt; uint256 outcomes; IERC20 token; uint256[] distribution; string question; string image; address arbitrator; } uint256[] marketIds; mapping(uint256 => Market) markets; uint256 public marketIndex; // governance uint256 public fee; // fee % taken from every transaction // realitio configs address public realitioAddress; uint256 public realitioTimeout; // market creation IERC20 public requiredBalanceToken; // token used for rewards / market creation uint256 public requiredBalance; // required balance for market creation // ------ Modifiers ------ modifier isMarket(uint256 marketId) { require(marketId < marketIndex, "Market not found"); _; } modifier timeTransitions(uint256 marketId) { if (now > markets[marketId].closesAtTimestamp && markets[marketId].state == MarketState.open) { nextState(marketId); } _; } modifier atState(uint256 marketId, MarketState state) { require(markets[marketId].state == state, "Market in incorrect state"); _; } modifier notAtState(uint256 marketId, MarketState state) { require(markets[marketId].state != state, "Market in incorrect state"); _; } modifier transitionNext(uint256 marketId) { _; nextState(marketId); } modifier mustHoldRequiredBalance() { require( requiredBalance == 0 || requiredBalanceToken.balanceOf(msg.sender) >= requiredBalance, "msg.sender must hold minimum erc20 balance" ); _; } // ------ Modifiers End ------ /// @dev protocol is immutable and has no ownership constructor( uint256 _fee, IERC20 _requiredBalanceToken, uint256 _requiredBalance, address _realitioAddress, uint256 _realitioTimeout ) public { require(_realitioAddress != address(0), "_realitioAddress is address 0"); require(_realitioTimeout > 0, "timeout must be positive"); fee = _fee; requiredBalanceToken = _requiredBalanceToken; requiredBalance = _requiredBalance; realitioAddress = _realitioAddress; realitioTimeout = _realitioTimeout; } // ------ Core Functions ------ /// @dev Creates a market, initializes the outcome shares pool and submits a question in Realitio function createMarket(CreateMarketArgs calldata args) external mustHoldRequiredBalance returns (uint256) { uint256 marketId = marketIndex; marketIds.push(marketId); Market storage market = markets[marketId]; require(args.value > 0, "stake needs to be > 0"); require(args.closesAt > now, "market must resolve after the current date"); require(args.arbitrator != address(0), "invalid arbitrator address"); require(args.outcomes <= 2 ** 8, "number of outcomes has to be less or equal than 256"); market.token = args.token; market.closesAtTimestamp = args.closesAt; market.state = MarketState.open; market.fees.value = fee; // setting intial value to an integer that does not map to any outcomeId market.resolution.outcomeId = MAX_UINT_256; // creating market outcomes for (uint256 i = 0; i < args.outcomes; i++) { market.outcomeIds.push(i); MarketOutcome storage outcome = market.outcomes[i]; outcome.marketId = marketId; outcome.id = i; } // creating question in realitio RealitioERC20(realitioAddress).askQuestionERC20( 2, args.question, args.arbitrator, uint32(realitioTimeout), uint32(args.closesAt), 0, 0 ); addLiquidity(marketId, args.value, args.distribution); // emiting initial price events emitMarketOutcomePriceEvents(marketId); emit MarketCreated(msg.sender, marketId, args.outcomes, args.question, args.image); // incrementing market array index marketIndex = marketIndex + 1; return marketId; } /// @dev Calculates the number of shares bought with "amount" balance function calcBuyAmount( uint256 amount, uint256 marketId, uint256 outcomeId ) public view returns (uint256) { Market storage market = markets[marketId]; uint256[] memory outcomesShares = getMarketOutcomesShares(marketId); uint256 amountMinusFees = amount.sub(amount.mul(market.fees.value) / ONE); uint256 buyTokenPoolBalance = outcomesShares[outcomeId]; uint256 endingOutcomeBalance = buyTokenPoolBalance.mul(ONE); for (uint256 i = 0; i < outcomesShares.length; i++) { if (i != outcomeId) { uint256 outcomeShares = outcomesShares[i]; endingOutcomeBalance = endingOutcomeBalance.mul(outcomeShares).ceildiv(outcomeShares.add(amountMinusFees)); } } require(endingOutcomeBalance > 0, "must have non-zero balances"); return buyTokenPoolBalance.add(amountMinusFees).sub(endingOutcomeBalance.ceildiv(ONE)); } /// @dev Calculates the number of shares needed to be sold in order to receive "amount" in balance function calcSellAmount( uint256 amount, uint256 marketId, uint256 outcomeId ) public view returns (uint256 outcomeTokenSellAmount) { Market storage market = markets[marketId]; uint256[] memory outcomesShares = getMarketOutcomesShares(marketId); uint256 amountPlusFees = amount.mul(ONE) / ONE.sub(market.fees.value); uint256 sellTokenPoolBalance = outcomesShares[outcomeId]; uint256 endingOutcomeBalance = sellTokenPoolBalance.mul(ONE); for (uint256 i = 0; i < outcomesShares.length; i++) { if (i != outcomeId) { uint256 outcomeShares = outcomesShares[i]; endingOutcomeBalance = endingOutcomeBalance.mul(outcomeShares).ceildiv(outcomeShares.sub(amountPlusFees)); } } require(endingOutcomeBalance > 0, "must have non-zero balances"); return amountPlusFees.add(endingOutcomeBalance.ceildiv(ONE)).sub(sellTokenPoolBalance); } /// @dev Buy shares of a market outcome function buy( uint256 marketId, uint256 outcomeId, uint256 minOutcomeSharesToBuy, uint256 value ) external timeTransitions(marketId) atState(marketId, MarketState.open) { Market storage market = markets[marketId]; uint256 shares = calcBuyAmount(value, marketId, outcomeId); require(shares >= minOutcomeSharesToBuy, "minimum buy amount not reached"); require(shares > 0, "shares amount is 0"); // subtracting fee from transaction value uint256 feeAmount = value.mul(market.fees.value) / ONE; market.fees.poolWeight = market.fees.poolWeight.add(feeAmount); uint256 valueMinusFees = value.sub(feeAmount); MarketOutcome storage outcome = market.outcomes[outcomeId]; // Funding market shares with received funds addSharesToMarket(marketId, valueMinusFees); require(outcome.shares.available >= shares, "outcome shares pool balance is too low"); transferOutcomeSharesfromPool(msg.sender, marketId, outcomeId, shares); require(market.token.transferFrom(msg.sender, address(this), value), "erc20 transfer failed"); emit MarketActionTx(msg.sender, MarketAction.buy, marketId, outcomeId, shares, value, now); emitMarketOutcomePriceEvents(marketId); } /// @dev Sell shares of a market outcome function sell( uint256 marketId, uint256 outcomeId, uint256 value, uint256 maxOutcomeSharesToSell ) external timeTransitions(marketId) atState(marketId, MarketState.open) { Market storage market = markets[marketId]; MarketOutcome storage outcome = market.outcomes[outcomeId]; uint256 shares = calcSellAmount(value, marketId, outcomeId); require(shares <= maxOutcomeSharesToSell, "maximum sell amount exceeded"); require(shares > 0, "shares amount is 0"); require(outcome.shares.holders[msg.sender] >= shares, "user does not have enough balance"); transferOutcomeSharesToPool(msg.sender, marketId, outcomeId, shares); // adding fee to transaction value uint256 feeAmount = value.mul(market.fees.value) / (ONE.sub(fee)); market.fees.poolWeight = market.fees.poolWeight.add(feeAmount); uint256 valuePlusFees = value.add(feeAmount); require(market.balance >= valuePlusFees, "market does not have enough balance"); // Rebalancing market shares removeSharesFromMarket(marketId, valuePlusFees); // Transferring funds to user require(market.token.transfer(msg.sender, value), "erc20 transfer failed"); emit MarketActionTx(msg.sender, MarketAction.sell, marketId, outcomeId, shares, value, now); emitMarketOutcomePriceEvents(marketId); } /// @dev Adds liquidity to a market - external function addLiquidity( uint256 marketId, uint256 value, uint256[] memory distribution ) public timeTransitions(marketId) atState(marketId, MarketState.open) { Market storage market = markets[marketId]; require(value > 0, "stake has to be greater than 0."); uint256 liquidityAmount; uint256[] memory outcomesShares = getMarketOutcomesShares(marketId); uint256[] memory sendBackAmounts = new uint256[](outcomesShares.length); uint256 poolWeight = 0; if (market.liquidity > 0) { require(distribution.length == 0, "market already has liquidity, can't distribute liquidity"); // part of the liquidity is exchanged for outcome shares if market is not balanced for (uint256 i = 0; i < outcomesShares.length; i++) { uint256 outcomeShares = outcomesShares[i]; if (poolWeight < outcomeShares) poolWeight = outcomeShares; } for (uint256 i = 0; i < outcomesShares.length; i++) { uint256 remaining = value.mul(outcomesShares[i]) / poolWeight; sendBackAmounts[i] = value.sub(remaining); } liquidityAmount = value.mul(market.liquidity) / poolWeight; // re-balancing fees pool rebalanceFeesPool(marketId, liquidityAmount, MarketAction.addLiquidity); } else { // funding market with no liquidity if (distribution.length > 0) { require(distribution.length == outcomesShares.length, "weight distribution length does not match"); uint256 maxHint = 0; for (uint256 i = 0; i < distribution.length; i++) { uint256 hint = distribution[i]; if (maxHint < hint) maxHint = hint; } for (uint256 i = 0; i < distribution.length; i++) { uint256 remaining = value.mul(distribution[i]) / maxHint; require(remaining > 0, "must hint a valid distribution"); sendBackAmounts[i] = value.sub(remaining); } } // funding market with total liquidity amount liquidityAmount = value; } // funding market market.liquidity = market.liquidity.add(liquidityAmount); market.liquidityShares[msg.sender] = market.liquidityShares[msg.sender].add(liquidityAmount); addSharesToMarket(marketId, value); // transform sendBackAmounts to array of amounts added for (uint256 i = 0; i < sendBackAmounts.length; i++) { if (sendBackAmounts[i] > 0) { uint256 marketShares = market.sharesAvailable; uint256 outcomeShares = market.outcomes[i].shares.available; transferOutcomeSharesfromPool(msg.sender, marketId, i, sendBackAmounts[i]); emit MarketActionTx( msg.sender, MarketAction.buy, marketId, i, sendBackAmounts[i], (marketShares.sub(outcomeShares)).mul(sendBackAmounts[i]).div(market.sharesAvailable), // price * shares now ); } } uint256 liquidityPrice = getMarketLiquidityPrice(marketId); uint256 liquidityValue = liquidityPrice.mul(liquidityAmount) / ONE; require(market.token.transferFrom(msg.sender, address(this), value), "erc20 transfer failed"); emit MarketActionTx(msg.sender, MarketAction.addLiquidity, marketId, 0, liquidityAmount, liquidityValue, now); emit MarketLiquidity(marketId, market.liquidity, liquidityPrice, now); } /// @dev Removes liquidity to a market - external function removeLiquidity(uint256 marketId, uint256 shares) external timeTransitions(marketId) atState(marketId, MarketState.open) { Market storage market = markets[marketId]; require(market.liquidityShares[msg.sender] >= shares, "user does not have enough balance"); // claiming any pending fees claimFees(marketId); // re-balancing fees pool rebalanceFeesPool(marketId, shares, MarketAction.removeLiquidity); uint256[] memory outcomesShares = getMarketOutcomesShares(marketId); uint256[] memory sendAmounts = new uint256[](outcomesShares.length); uint256 poolWeight = MAX_UINT_256; // part of the liquidity is exchanged for outcome shares if market is not balanced for (uint256 i = 0; i < outcomesShares.length; i++) { uint256 outcomeShares = outcomesShares[i]; if (poolWeight > outcomeShares) poolWeight = outcomeShares; } uint256 liquidityAmount = shares.mul(poolWeight).div(market.liquidity); for (uint256 i = 0; i < outcomesShares.length; i++) { sendAmounts[i] = outcomesShares[i].mul(shares) / market.liquidity; sendAmounts[i] = sendAmounts[i].sub(liquidityAmount); } // removing liquidity from market removeSharesFromMarket(marketId, liquidityAmount); market.liquidity = market.liquidity.sub(shares); // removing liquidity tokens from market creator market.liquidityShares[msg.sender] = market.liquidityShares[msg.sender].sub(shares); for (uint256 i = 0; i < outcomesShares.length; i++) { if (sendAmounts[i] > 0) { uint256 marketShares = market.sharesAvailable; uint256 outcomeShares = market.outcomes[i].shares.available; transferOutcomeSharesfromPool(msg.sender, marketId, i, sendAmounts[i]); emit MarketActionTx( msg.sender, MarketAction.buy, marketId, i, sendAmounts[i], (marketShares.sub(outcomeShares)).mul(sendAmounts[i]).div(market.sharesAvailable), // price * shares now ); } } // transferring user funds from liquidity removed require(market.token.transfer(msg.sender, liquidityAmount), "erc20 transfer failed"); emit MarketActionTx(msg.sender, MarketAction.removeLiquidity, marketId, 0, shares, liquidityAmount, now); emit MarketLiquidity(marketId, market.liquidity, getMarketLiquidityPrice(marketId), now); } /// @dev Fetches winning outcome from Realitio and resolves the market function resolveMarketOutcome(uint256 marketId) external timeTransitions(marketId) atState(marketId, MarketState.closed) transitionNext(marketId) returns (uint256) { Market storage market = markets[marketId]; RealitioERC20 realitio = RealitioERC20(realitioAddress); // will fail if question is not finalized uint256 outcomeId = uint256(realitio.resultFor(market.resolution.questionId)); market.resolution.outcomeId = outcomeId; emit MarketResolved(msg.sender, marketId, outcomeId, now); emitMarketOutcomePriceEvents(marketId); return market.resolution.outcomeId; } /// @dev Allows holders of resolved outcome shares to claim earnings. function claimWinnings(uint256 marketId) external atState(marketId, MarketState.resolved) { Market storage market = markets[marketId]; MarketOutcome storage resolvedOutcome = market.outcomes[market.resolution.outcomeId]; require(resolvedOutcome.shares.holders[msg.sender] > 0, "user does not hold resolved outcome shares"); require(resolvedOutcome.shares.claims[msg.sender] == false, "user already claimed resolved outcome winnings"); // 1 share => price = 1 uint256 value = resolvedOutcome.shares.holders[msg.sender]; // assuring market has enough funds require(market.balance >= value, "Market does not have enough balance"); market.balance = market.balance.sub(value); resolvedOutcome.shares.claims[msg.sender] = true; emit MarketActionTx( msg.sender, MarketAction.claimWinnings, marketId, market.resolution.outcomeId, resolvedOutcome.shares.holders[msg.sender], value, now ); require(market.token.transfer(msg.sender, value), "erc20 transfer failed"); } /// @dev Allows holders of voided outcome shares to claim balance back. function claimVoidedOutcomeShares(uint256 marketId, uint256 outcomeId) external atState(marketId, MarketState.resolved) { Market storage market = markets[marketId]; MarketOutcome storage outcome = market.outcomes[outcomeId]; require(outcome.shares.holders[msg.sender] > 0, "user does not hold outcome shares"); require(outcome.shares.voidedClaims[msg.sender] == false, "user already claimed outcome shares"); // voided market - shares are valued at last market price uint256 price = getMarketOutcomePrice(marketId, outcomeId); uint256 value = price.mul(outcome.shares.holders[msg.sender]).div(ONE); // assuring market has enough funds require(market.balance >= value, "Market does not have enough balance"); market.balance = market.balance.sub(value); outcome.shares.voidedClaims[msg.sender] = true; emit MarketActionTx( msg.sender, MarketAction.claimVoided, marketId, outcomeId, outcome.shares.holders[msg.sender], value, now ); require(market.token.transfer(msg.sender, value), "erc20 transfer failed"); } /// @dev Allows liquidity providers to claim earnings from liquidity providing. function claimLiquidity(uint256 marketId) external atState(marketId, MarketState.resolved) { Market storage market = markets[marketId]; // claiming any pending fees claimFees(marketId); require(market.liquidityShares[msg.sender] > 0, "user does not hold liquidity shares"); require(market.liquidityClaims[msg.sender] == false, "user already claimed liquidity winnings"); // value = total resolved outcome pool shares * pool share (%) uint256 liquidityPrice = getMarketLiquidityPrice(marketId); uint256 value = liquidityPrice.mul(market.liquidityShares[msg.sender]) / ONE; // assuring market has enough funds require(market.balance >= value, "Market does not have enough balance"); market.balance = market.balance.sub(value); market.liquidityClaims[msg.sender] = true; emit MarketActionTx( msg.sender, MarketAction.claimLiquidity, marketId, 0, market.liquidityShares[msg.sender], value, now ); require(market.token.transfer(msg.sender, value), "erc20 transfer failed"); } /// @dev Allows liquidity providers to claim their fees share from fees pool function claimFees(uint256 marketId) public { Market storage market = markets[marketId]; uint256 claimableFees = getUserClaimableFees(marketId, msg.sender); if (claimableFees > 0) { market.fees.claimed[msg.sender] = market.fees.claimed[msg.sender].add(claimableFees); require(market.token.transfer(msg.sender, claimableFees), "erc20 transfer failed"); } emit MarketActionTx( msg.sender, MarketAction.claimFees, marketId, 0, market.liquidityShares[msg.sender], claimableFees, now ); } /// @dev Rebalances the fees pool. Needed in every AddLiquidity / RemoveLiquidity call function rebalanceFeesPool( uint256 marketId, uint256 liquidityShares, MarketAction action ) private returns (uint256) { Market storage market = markets[marketId]; uint256 poolWeight = liquidityShares.mul(market.fees.poolWeight).div(market.liquidity); if (action == MarketAction.addLiquidity) { market.fees.poolWeight = market.fees.poolWeight.add(poolWeight); market.fees.claimed[msg.sender] = market.fees.claimed[msg.sender].add(poolWeight); } else { market.fees.poolWeight = market.fees.poolWeight.sub(poolWeight); market.fees.claimed[msg.sender] = market.fees.claimed[msg.sender].sub(poolWeight); } } /// @dev Transitions market to next state function nextState(uint256 marketId) private { Market storage market = markets[marketId]; market.state = MarketState(uint256(market.state) + 1); } /// @dev Emits a outcome price event for every outcome function emitMarketOutcomePriceEvents(uint256 marketId) private { Market storage market = markets[marketId]; for (uint256 i = 0; i < market.outcomeIds.length; i++) { emit MarketOutcomePrice(marketId, i, getMarketOutcomePrice(marketId, i), now); } // liquidity shares also change value emit MarketLiquidity(marketId, market.liquidity, getMarketLiquidityPrice(marketId), now); } /// @dev Adds outcome shares to shares pool function addSharesToMarket(uint256 marketId, uint256 shares) private { Market storage market = markets[marketId]; for (uint256 i = 0; i < market.outcomeIds.length; i++) { MarketOutcome storage outcome = market.outcomes[i]; outcome.shares.available = outcome.shares.available.add(shares); outcome.shares.total = outcome.shares.total.add(shares); // only adding to market total shares, the available remains market.sharesAvailable = market.sharesAvailable.add(shares); } market.balance = market.balance.add(shares); } /// @dev Removes outcome shares from shares pool function removeSharesFromMarket(uint256 marketId, uint256 shares) private { Market storage market = markets[marketId]; for (uint256 i = 0; i < market.outcomeIds.length; i++) { MarketOutcome storage outcome = market.outcomes[i]; outcome.shares.available = outcome.shares.available.sub(shares); outcome.shares.total = outcome.shares.total.sub(shares); // only subtracting from market total shares, the available remains market.sharesAvailable = market.sharesAvailable.sub(shares); } market.balance = market.balance.sub(shares); } /// @dev Transfer outcome shares from pool to user balance function transferOutcomeSharesfromPool( address user, uint256 marketId, uint256 outcomeId, uint256 shares ) private { Market storage market = markets[marketId]; MarketOutcome storage outcome = market.outcomes[outcomeId]; // transfering shares from shares pool to user outcome.shares.holders[user] = outcome.shares.holders[user].add(shares); outcome.shares.available = outcome.shares.available.sub(shares); market.sharesAvailable = market.sharesAvailable.sub(shares); } /// @dev Transfer outcome shares from user balance back to pool function transferOutcomeSharesToPool( address user, uint256 marketId, uint256 outcomeId, uint256 shares ) private { Market storage market = markets[marketId]; MarketOutcome storage outcome = market.outcomes[outcomeId]; // adding shares back to pool outcome.shares.holders[user] = outcome.shares.holders[user].sub(shares); outcome.shares.available = outcome.shares.available.add(shares); market.sharesAvailable = market.sharesAvailable.add(shares); } // ------ Core Functions End ------ // ------ Getters ------ function getUserMarketShares(uint256 marketId, address user) external view returns ( uint256, uint256[] memory ) { Market storage market = markets[marketId]; uint256[] memory outcomeShares = new uint256[](market.outcomeIds.length); for (uint256 i = 0; i < market.outcomeIds.length; i++) { outcomeShares[i] = market.outcomes[i].shares.holders[user]; } return ( market.liquidityShares[user], outcomeShares ); } function getUserClaimStatus(uint256 marketId, address user) external view returns ( bool, bool, bool, bool, uint256 ) { Market storage market = markets[marketId]; // market still not resolved if (market.state != MarketState.resolved) { return (false, false, false, false, getUserClaimableFees(marketId, user)); } MarketOutcome storage outcome = market.outcomes[market.resolution.outcomeId]; return ( outcome.shares.holders[user] > 0, outcome.shares.claims[user], market.liquidityShares[user] > 0, market.liquidityClaims[user], getUserClaimableFees(marketId, user) ); } function getUserLiquidityPoolShare(uint256 marketId, address user) external view returns (uint256) { Market storage market = markets[marketId]; return market.liquidityShares[user].mul(ONE).div(market.liquidity); } function getUserClaimableFees(uint256 marketId, address user) public view returns (uint256) { Market storage market = markets[marketId]; uint256 rawAmount = market.fees.poolWeight.mul(market.liquidityShares[user]).div(market.liquidity); // No fees left to claim if (market.fees.claimed[user] > rawAmount) return 0; return rawAmount.sub(market.fees.claimed[user]); } function getMarkets() external view returns (uint256[] memory) { return marketIds; } function getMarketData(uint256 marketId) external view returns ( MarketState, uint256, uint256, uint256, uint256, int256 ) { Market storage market = markets[marketId]; return ( market.state, market.closesAtTimestamp, market.liquidity, market.balance, market.sharesAvailable, getMarketResolvedOutcome(marketId) ); } function getMarketAltData(uint256 marketId) external view returns ( uint256, bytes32, uint256 ) { Market storage market = markets[marketId]; return (market.fees.value, market.resolution.questionId, uint256(market.resolution.questionId)); } function getMarketQuestion(uint256 marketId) external view returns (bytes32) { Market storage market = markets[marketId]; return (market.resolution.questionId); } function getMarketPrices(uint256 marketId) external view returns ( uint256, uint256[] memory ) { Market storage market = markets[marketId]; uint256[] memory prices = new uint256[](market.outcomeIds.length); for (uint256 i = 0; i < market.outcomeIds.length; i++) { prices[i] = getMarketOutcomePrice(marketId, i); } return (getMarketLiquidityPrice(marketId), prices); } function getMarketLiquidityPrice(uint256 marketId) public view returns (uint256) { Market storage market = markets[marketId]; if (market.state == MarketState.resolved && !isMarketVoided(marketId)) { // resolved market, outcome prices are either 0 or 1 // final liquidity price = outcome shares / liquidity shares return market.outcomes[market.resolution.outcomeId].shares.available.mul(ONE).div(market.liquidity); } // liquidity price = product(every outcome shares) / sum (every outcomeOddsWeight) * # outcomes / liquidity shares uint256 marketSharesProduct = ONE; uint256 marketSharesSum = 0; for (uint256 i = 0; i < market.outcomeIds.length; i++) { MarketOutcome storage outcome = market.outcomes[i]; marketSharesProduct = marketSharesProduct.mul(outcome.shares.available).div(ONE); marketSharesSum = marketSharesSum.add(getOutcomeOddsWeight(marketId, i)); } return marketSharesProduct.mul(market.outcomeIds.length).mul(ONE).div(marketSharesSum).mul(ONE).div(market.liquidity); } function getMarketResolvedOutcome(uint256 marketId) public view returns (int256) { Market storage market = markets[marketId]; // returning -1 if market still not resolved if (market.state != MarketState.resolved) { return -1; } return int256(market.resolution.outcomeId); } function isMarketVoided(uint256 marketId) public view returns (bool) { Market storage market = markets[marketId]; // market still not resolved, still in valid state if (market.state != MarketState.resolved) { return false; } // resolved market id does not match any of the market ids return market.resolution.outcomeId >= market.outcomeIds.length; } // ------ Outcome Getters ------ function getMarketOutcomeIds(uint256 marketId) external view returns (uint256[] memory) { Market storage market = markets[marketId]; return market.outcomeIds; } function getOutcomeOddsWeight(uint256 marketId, uint256 outcomeId) public view returns (uint256) { Market storage market = markets[marketId]; uint256 productWeight = ONE; for (uint256 i = 0; i < market.outcomeIds.length; i++) { if (i == outcomeId) continue; productWeight = productWeight.mul(market.outcomes[i].shares.available).div(ONE); } return productWeight; } function getMarketOutcomePrice(uint256 marketId, uint256 outcomeId) public view returns (uint256) { Market storage market = markets[marketId]; if (market.state == MarketState.resolved && !isMarketVoided(marketId)) { // resolved market, price is either 0 or 1 return outcomeId == market.resolution.outcomeId ? ONE : 0; } uint256 sumOutcomeOddsWeight = 0; for (uint256 i = 0; i < market.outcomeIds.length; i++) { sumOutcomeOddsWeight = sumOutcomeOddsWeight.add(getOutcomeOddsWeight(marketId, i)); } // outcome price = outcomeOddsWeight / sum(every outcomeOddsWeight) return getOutcomeOddsWeight(marketId, outcomeId).mul(ONE).div(sumOutcomeOddsWeight); } function getMarketOutcomeData(uint256 marketId, uint256 outcomeId) external view returns ( uint256, uint256, uint256 ) { Market storage market = markets[marketId]; MarketOutcome storage outcome = market.outcomes[outcomeId]; return (getMarketOutcomePrice(marketId, outcomeId), outcome.shares.available, outcome.shares.total); } function getMarketOutcomesShares(uint256 marketId) private view returns (uint256[] memory) { Market storage market = markets[marketId]; uint256[] memory shares = new uint256[](market.outcomeIds.length); for (uint256 i = 0; i < market.outcomeIds.length; i++) { shares[i] = market.outcomes[i].shares.available; } return shares; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"contract IERC20","name":"_requiredBalanceToken","type":"address"},{"internalType":"uint256","name":"_requiredBalance","type":"uint256"},{"internalType":"address","name":"_realitioAddress","type":"address"},{"internalType":"uint256","name":"_realitioTimeout","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"enum PredictionMarketV2.MarketAction","name":"action","type":"uint8"},{"indexed":true,"internalType":"uint256","name":"marketId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outcomeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MarketActionTx","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"marketId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outcomes","type":"uint256"},{"indexed":false,"internalType":"string","name":"question","type":"string"},{"indexed":false,"internalType":"string","name":"image","type":"string"}],"name":"MarketCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"marketId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MarketLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"marketId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"outcomeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MarketOutcomePrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"marketId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outcomeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MarketResolved","type":"event"},{"inputs":[],"name":"MAX_UINT_256","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"},{"internalType":"uint256","name":"minOutcomeSharesToBuy","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"}],"name":"calcBuyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"}],"name":"calcSellAmount","outputs":[{"internalType":"uint256","name":"outcomeTokenSellAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"claimLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"}],"name":"claimVoidedOutcomeShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"claimWinnings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"closesAt","type":"uint256"},{"internalType":"uint256","name":"outcomes","type":"uint256"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"},{"internalType":"string","name":"question","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"address","name":"arbitrator","type":"address"}],"internalType":"struct PredictionMarketV2.CreateMarketArgs","name":"args","type":"tuple"}],"name":"createMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketAltData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketData","outputs":[{"internalType":"enum PredictionMarketV2.MarketState","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketLiquidityPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"}],"name":"getMarketOutcomeData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketOutcomeIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"}],"name":"getMarketOutcomePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketQuestion","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"getMarketResolvedOutcome","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMarkets","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"}],"name":"getOutcomeOddsWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserClaimStatus","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserClaimableFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserLiquidityPoolShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserMarketShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"isMarketVoided","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"realitioAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"realitioTimeout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requiredBalanceToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"}],"name":"resolveMarketOutcome","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"maxOutcomeSharesToSell","type":"uint256"}],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003ee338038062003ee38339810160408190526200003491620000ca565b6001600160a01b038216620000665760405162461bcd60e51b81526004016200005d9062000125565b60405180910390fd5b60008111620000895760405162461bcd60e51b81526004016200005d906200015c565b600394909455600680546001600160a01b039485166001600160a01b03199182161790915560079290925560048054919093169116179055600555620001ac565b600080600080600060a08688031215620000e2578081fd5b855194506020860151620000f68162000193565b604087015160608801519195509350620001108162000193565b80925050608086015190509295509295909350565b6020808252601d908201527f5f7265616c6974696f4164647265737320697320616464726573732030000000604082015260600190565b60208082526018908201527f74696d656f7574206d75737420626520706f7369746976650000000000000000604082015260600190565b6001600160a01b0381168114620001a957600080fd5b50565b613d2780620001bc6000396000f3fe608060405234801561001057600080fd5b50600436106101ac5760003560e01c806308560ace146101b15780631281311d146101cf5780631d7920aa146101e457806328747a80146102065780632a9ee5d2146102195780632c2aa24e1461022c57806331877a38146102505780633620875e146102705780633d41a26b146102835780633fe45e3b1461028b578063429c9dff146102935780634397c4ce146102a6578063441cf65e146102b95780635c6d91d0146102d95780635e648eff146102ee578063677bd9ff146103015780637b34e6e01461031457806385b91d8e1461031c5780638671c2ee1461033d5780638c7adc15146103505780638cd41552146103585780639d7de6b31461036b578063aa22a02e1461037e578063ac68a74814610391578063b31eb895146103a4578063bf455721146103b7578063bfacba3d146103ca578063c2ee3a08146103ef578063c346a9d0146103f7578063c8f70d011461040a578063ddca3f431461041d578063ec2c901614610425578063ec93f0f51461042d578063ecb5409a14610440578063efce431314610453578063fdff808514610466575b600080fd5b6101b9610479565b6040516101c69190613433565b60405180910390f35b6101e26101dd366004613308565b61047f565b005b6101f76101f23660046131be565b61070a565b6040516101c693929190613c16565b6101b96102143660046131be565b610729565b6101b9610227366004613205565b6108b6565b61023f61023a3660046131d6565b61093d565b6040516101c695949392919061340c565b61026361025e3660046131be565b610a0d565b6040516101c691906133ee565b6101e261027e366004613308565b610a76565b6101b9610d19565b6101b9610d1f565b6101b96102a13660046132dd565b610d25565b6101b96102b43660046131be565b610e85565b6102cc6102c73660046131be565b610e9a565b6040516101c69190613401565b6102e1610edf565b6040516101c6919061339d565b6101e26102fc3660046131be565b610eee565b6101e261030f3660046131be565b61112f565b6102e161129a565b61032f61032a3660046131be565b6112a9565b6040516101c6929190613bfd565b6101e261034b366004613226565b61133c565b6101b96118ee565b6101b9610366366004613205565b6118f4565b6101e2610379366004613205565b6119ab565b6101b961038c3660046131d6565b611dfc565b6101e261039f3660046131be565b611e4f565b61032f6103b23660046131d6565b611f8c565b6101b96103c53660046131be565b612053565b6103dd6103d83660046131be565b612090565b6040516101c69695949392919061343c565b6101b96120e9565b6101b96104053660046132dd565b6120f5565b6101b96104183660046131be565b612225565b6101b9612356565b61026361235c565b6101e261043b366004613205565b6123b4565b6101b961044e366004613185565b6125fb565b6101f7610461366004613205565b612a88565b6101b96104743660046131d6565b612acc565b60075481565b6000848152600160205260409020548490421180156104bb575060008181526001602052604081206006015460ff1660028111156104b957fe5b145b156104c9576104c981612b72565b8460008060008381526001602052604090206006015460ff1660028111156104ed57fe5b146105135760405162461bcd60e51b815260040161050a90613a48565b60405180910390fd5b60008781526001602052604081209061052d868a8a610d25565b90508681101561054f5760405162461bcd60e51b815260040161050a90613af5565b6000811161056f5760405162461bcd60e51b815260040161050a90613603565b600a820154600090670de0b6b3a76400009061059290899063ffffffff612bc216565b8161059957fe5b600b85015491900491506105b3908263ffffffff612c0316565b600b84015560006105ca888363ffffffff612c2816565b60008b8152600e8601602052604090209091506105e78c83612c50565b600381015484111561060b5760405162461bcd60e51b815260040161050a90613a7b565b610617338d8d87612cf3565b600f8501546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061064d90339030908e906004016133b1565b602060405180830381600087803b15801561066757600080fd5b505af115801561067b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061069f919081019061314d565b6106bb5760405162461bcd60e51b815260040161050a9061390b565b8b6000336001600160a01b0316600080516020613cb28339815191528e888e426040516106eb9493929190613473565b60405180910390a46106fc8c612d92565b505050505050505050505050565b6000908152600160205260409020600a81015460099091015490918190565b600081815260016020526040812054829042118015610765575060008181526001602052604081206006015460ff16600281111561076357fe5b145b156107735761077381612b72565b8260018060008381526001602052604090206006015460ff16600281111561079757fe5b146107b45760405162461bcd60e51b815260040161050a90613a48565b600085815260016020526040808220600480546009830154935163684e62bf60e11b81528a9593946001600160a01b039092169392849263d09cc57e926107fb9201613433565b60206040518083038186803b15801561081357600080fd5b505afa158015610827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061084b919081019061316d565b60088401819055604051909150899033907f67a6457c8912ae1b7a9fbdfa311cbd016ba606b548bf06bc80bc751072d91bbc9061088b9085904290613c65565b60405180910390a361089c89612d92565b50506008015494506108ad81612b72565b50505050919050565b6000828152600160205260408120670de0b6b3a7640000825b600d83015481101561093257848114156108e85761092a565b6000818152600e8401602052604090206003015461092790670de0b6b3a76400009061091b90859063ffffffff612bc216565b9063ffffffff612e3516565b91505b6001016108cf565b509150505b92915050565b600082815260016020526040812081908190819081906002600682015460ff16600281111561096857fe5b1461098d5760008060008061097d8c8c612acc565b9550955095509550955050610a03565b60088101546000908152600e8201602090815260408083206001600160a01b038b16845260048082018452828520546005808401865284872054928801865284872054908801909552929094205490939115159260ff9283169290151591166109f68d8d612acc565b9650965096509650965050505b9295509295909350565b600081815260016020908152604091829020600d810180548451818502810185019095528085526060949293830182828015610a6857602002820191906000526020600020905b815481526020019060010190808311610a54575b50505050509150505b919050565b600084815260016020526040902054849042118015610ab2575060008181526001602052604081206006015460ff166002811115610ab057fe5b145b15610ac057610ac081612b72565b8460008060008381526001602052604090206006015460ff166002811115610ae457fe5b14610b015760405162461bcd60e51b815260040161050a90613a48565b6000878152600160209081526040808320898452600e810190925282209091610b2b888b8b6120f5565b905086811115610b4d5760405162461bcd60e51b815260040161050a90613b2c565b60008111610b6d5760405162461bcd60e51b815260040161050a90613603565b336000908152600483016020526040902054811115610b9e5760405162461bcd60e51b815260040161050a90613a07565b610baa338b8b84612e67565b6000610bc9600354670de0b6b3a7640000612c2890919063ffffffff16565b600a850154610bdf908b9063ffffffff612bc216565b81610be657fe5b600b8601549190049150610c00908263ffffffff612c0316565b600b8501556000610c178a8363ffffffff612c0316565b90508085600101541015610c3d5760405162461bcd60e51b815260040161050a906139c4565b610c478c82612ef6565b600f85015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90610c7b9033908e906004016133d5565b602060405180830381600087803b158015610c9557600080fd5b505af1158015610ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ccd919081019061314d565b610ce95760405162461bcd60e51b815260040161050a9061390b565b8b6001336001600160a01b0316600080516020613cb28339815191528e878f426040516106eb9493929190613473565b60001981565b60055481565b60008281526001602052604081206060610d3e85612f8f565b90506000610d7e670de0b6b3a7640000610d6885600a01600001548a612bc290919063ffffffff16565b81610d6f57fe5b8991900463ffffffff612c2816565b90506000828681518110610d8e57fe5b602002602001015190506000610db5670de0b6b3a764000083612bc290919063ffffffff16565b905060005b8451811015610e2057878114610e18576000858281518110610dd857fe5b60200260200101519050610e14610df88683612c0390919063ffffffff16565b610e08858463ffffffff612bc216565b9063ffffffff61302216565b9250505b600101610dba565b5060008111610e415760405162461bcd60e51b815260040161050a906134e0565b610e78610e5c82670de0b6b3a764000063ffffffff61302216565b610e6c848663ffffffff612c0316565b9063ffffffff612c2816565b9998505050505050505050565b60009081526001602052604090206009015490565b60008181526001602052604081206002600682015460ff166002811115610ebd57fe5b14610ecc576000915050610a71565b600d810154600890910154101592915050565b6006546001600160a01b031681565b8060028060008381526001602052604090206006015460ff166002811115610f1257fe5b14610f2f5760405162461bcd60e51b815260040161050a90613a48565b6000838152600160205260409020610f4684611e4f565b336000908152600482016020526040902054610f745760405162461bcd60e51b815260040161050a90613981565b33600090815260058201602052604090205460ff1615610fa65760405162461bcd60e51b815260040161050a9061393a565b6000610fb185612225565b33600090815260048401602052604081205491925090670de0b6b3a764000090610fe290849063ffffffff612bc216565b81610fe957fe5b04905080836001015410156110105760405162461bcd60e51b815260040161050a906136e7565b6001830154611025908263ffffffff612c2816565b600184810191909155336000818152600580870160209081526040808420805460ff19169096179095556004880190528382205493518a94919392600080516020613cb28339815191529261107d9288904290613473565b60405180910390a4600f83015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906110b990339085906004016133d5565b602060405180830381600087803b1580156110d357600080fd5b505af11580156110e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061110b919081019061314d565b6111275760405162461bcd60e51b815260040161050a9061390b565b505050505050565b8060028060008381526001602052604090206006015460ff16600281111561115357fe5b146111705760405162461bcd60e51b815260040161050a90613a48565b600083815260016020908152604080832060088101548452600e81018352818420338552600481019093529220546111ba5760405162461bcd60e51b815260040161050a9061362f565b33600090815260058201602052604090205460ff16156111ec5760405162461bcd60e51b815260040161050a906137fb565b33600090815260048201602052604090205460018301548111156112225760405162461bcd60e51b815260040161050a906136e7565b6001830154611237908263ffffffff612c2816565b6001808501919091553360009081526005840160205260409020805460ff191690911790558560046008850154336000818152600487016020526040908190205490519192600080516020613cb28339815191529261107d929088904290613473565b6004546001600160a01b031681565b6000818152600160209081526040808320600d81015482518181528185028101909401909252606092909183919080156112ed578160200160208202803883390190505b50905060005b600d8301548110156113285761130986826118f4565b82828151811061131557fe5b60209081029190910101526001016112f3565b5061133285612225565b9350915050915091565b600083815260016020526040902054839042118015611378575060008181526001602052604081206006015460ff16600281111561137657fe5b145b156113865761138681612b72565b8360008060008381526001602052604090206006015460ff1660028111156113aa57fe5b146113c75760405162461bcd60e51b815260040161050a90613a48565b6000868152600160205260409020856113f25760405162461bcd60e51b815260040161050a90613679565b600060606113ff89612f8f565b90506060815160405190808252806020026020018201604052801561142e578160200160208202803883390190505b5060028501549091506000901561153c5788511561145e5760405162461bcd60e51b815260040161050a90613ba5565b60005b835181101561149757600084828151811061147857fe5b602002602001015190508083101561148e578092505b50600101611461565b5060005b8351811015611507576000826114cd8684815181106114b657fe5b60200260200101518e612bc290919063ffffffff16565b816114d457fe5b0490506114e78c8263ffffffff612c2816565b8483815181106114f357fe5b60209081029190910101525060010161149b565b508061152086600201548c612bc290919063ffffffff16565b8161152757fe5b0493506115368b856002613041565b50611635565b8851156116315782518951146115645760405162461bcd60e51b815260040161050a90613544565b6000805b8a5181101561159e5760008b828151811061157f57fe5b6020026020010151905080831015611595578092505b50600101611568565b5060005b8a5181101561162e576000826115d48d84815181106115bd57fe5b60200260200101518f612bc290919063ffffffff16565b816115db57fe5b049050600081116115fe5760405162461bcd60e51b815260040161050a90613849565b61160e8d8263ffffffff612c2816565b85838151811061161a57fe5b6020908102919091010152506001016115a2565b50505b8993505b600285015461164a908563ffffffff612c0316565b6002860155336000908152600486016020526040902054611671908563ffffffff612c0316565b33600090815260048701602052604090205561168d8b8b612c50565b60005b82518110156117905760008382815181106116a757fe5b6020026020010151111561178857600086600301549050600087600e0160008481526020019081526020016000206002016001015490506116fd338f858887815181106116f057fe5b6020026020010151612cf3565b8d6000336001600160a01b0316600080516020613cb28339815191528689888151811061172657fe5b602002602001015161176c8e6003015461091b8d8c8151811061174557fe5b60200260200101516117608b8d612c2890919063ffffffff16565b9063ffffffff612bc216565b4260405161177d9493929190613473565b60405180910390a450505b600101611690565b50600061179c8c612225565b90506000670de0b6b3a76400006117b9838863ffffffff612bc216565b816117c057fe5b04905086600f0160009054906101000a90046001600160a01b03166001600160a01b03166323b872dd33308f6040518463ffffffff1660e01b815260040161180a939291906133b1565b602060405180830381600087803b15801561182457600080fd5b505af1158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061185c919081019061314d565b6118785760405162461bcd60e51b815260040161050a9061390b565b8c6002336001600160a01b0316600080516020613cb283398151915260008a86426040516118a99493929190613473565b60405180910390a48c600080516020613cd2833981519152886002015484426040516118d793929190613c16565b60405180910390a250505050505050505050505050565b60025481565b60008281526001602052604081206002600682015460ff16600281111561191757fe5b14801561192a575061192884610e9a565b155b15611953576008810154831461194157600061194b565b670de0b6b3a76400005b915050610937565b6000805b600d8301548110156119875761197d61197087836108b6565b839063ffffffff612c0316565b9150600101611957565b506119a28161091b670de0b6b3a764000061176089896108b6565b95945050505050565b6000828152600160205260409020548290421180156119e7575060008181526001602052604081206006015460ff1660028111156119e557fe5b145b156119f5576119f581612b72565b8260008060008381526001602052604090206006015460ff166002811115611a1957fe5b14611a365760405162461bcd60e51b815260040161050a90613a48565b60008581526001602090815260408083203384526004810190925290912054851115611a745760405162461bcd60e51b815260040161050a90613a07565b611a7d86611e4f565b611a8986866003613041565b506060611a9587612f8f565b905060608151604051908082528060200260200182016040528015611ac4578160200160208202803883390190505b50905060001960005b8351811015611b03576000848281518110611ae457fe5b6020026020010151905080831115611afa578092505b50600101611acd565b506002840154600090611b209061091b8b8563ffffffff612bc216565b905060005b8451811015611bbe578560020154611b598b878481518110611b4357fe5b6020026020010151612bc290919063ffffffff16565b81611b6057fe5b04848281518110611b6d57fe5b602002602001018181525050611b9f82858381518110611b8957fe5b6020026020010151612c2890919063ffffffff16565b848281518110611bab57fe5b6020908102919091010152600101611b25565b50611bc98a82612ef6565b6002850154611bde908a63ffffffff612c2816565b6002860155336000908152600486016020526040902054611c05908a63ffffffff612c2816565b3360009081526004870160205260408120919091555b8451811015611cde576000848281518110611c3257fe5b60200260200101511115611cd6576003808701546000838152600e890160205260409020909101548551611c729033908f9086908a90829081106116f057fe5b8c6000336001600160a01b0316600080516020613cb2833981519152868a8881518110611c9b57fe5b6020026020010151611cba8e6003015461091b8e8c8151811061174557fe5b42604051611ccb9493929190613473565b60405180910390a450505b600101611c1b565b50600f85015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611d1390339085906004016133d5565b602060405180830381600087803b158015611d2d57600080fd5b505af1158015611d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d65919081019061314d565b611d815760405162461bcd60e51b815260040161050a9061390b565b896003336001600160a01b0316600080516020613cb283398151915260008d8642604051611db29493929190613473565b60405180910390a489600080516020613cd28339815191528660020154611dd88d612225565b42604051611de893929190613c16565b60405180910390a250505050505050505050565b600082815260016020908152604080832060028101546001600160a01b038616855260048201909352908320549091611e479161091b90670de0b6b3a764000063ffffffff612bc216565b949350505050565b600081815260016020526040812090611e688333612acc565b90508015611f4857336000908152600c83016020526040902054611e92908263ffffffff612c0316565b336000818152600c850160205260409081902092909255600f840154915163a9059cbb60e01b81526001600160a01b039092169163a9059cbb91611eda9185906004016133d5565b602060405180830381600087803b158015611ef457600080fd5b505af1158015611f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f2c919081019061314d565b611f485760405162461bcd60e51b815260040161050a9061390b565b826006336000818152600486016020526040808220549051600080516020613cb283398151915292611f7f92909188904290613473565b60405180910390a4505050565b6000828152600160209081526040808320600d8101548251818152818502810190940190925260609290918391908015611fd0578160200160208202803883390190505b50905060005b600d83015481101561202b576000818152600e8401602090815260408083206001600160a01b038a168452600401909152902054825183908390811061201857fe5b6020908102919091010152600101611fd6565b506001600160a01b039490941660009081526004919091016020526040902054949293505050565b60008181526001602052604081206002600682015460ff16600281111561207657fe5b1461208657600019915050610a71565b6008015492915050565b6000818152600160208190526040822060068101548154600283015493830154600384015486958695869586958695929460ff90921693909290916120d48d612053565b949d939c50919a509850965090945092505050565b670de0b6b3a764000081565b6000828152600160205260408120606061210e85612f8f565b600a83015490915060009061213290670de0b6b3a76400009063ffffffff612c2816565b61214a88670de0b6b3a764000063ffffffff612bc216565b8161215157fe5b049050600082868151811061216257fe5b602002602001015190506000612189670de0b6b3a764000083612bc290919063ffffffff16565b905060005b84518110156121d8578781146121d05760008582815181106121ac57fe5b602002602001015190506121cc610df88683612c2890919063ffffffff16565b9250505b60010161218e565b50600081116121f95760405162461bcd60e51b815260040161050a906134e0565b610e7882610e6c61221884670de0b6b3a764000063ffffffff61302216565b869063ffffffff612c0316565b60008181526001602052604081206002600682015460ff16600281111561224857fe5b14801561225b575061225983610e9a565b155b156122a357600281015460088201546000908152600e8301602052604090206003015461229b919061091b90670de0b6b3a764000063ffffffff612bc216565b915050610a71565b670de0b6b3a76400006000805b600d840154811015612317576000818152600e85016020526040902060038101546122f090670de0b6b3a76400009061091b90879063ffffffff612bc216565b935061230c6122ff88846108b6565b849063ffffffff612c0316565b9250506001016122b0565b506119a2836002015461091b670de0b6b3a76400006117608561091b670de0b6b3a76400006117608b600d01805490508b612bc290919063ffffffff16565b60035481565b606060008054806020026020016040519081016040528092919081815260200182805480156123aa57602002820191906000526020600020905b815481526020019060010190808311612396575b5050505050905090565b8160028060008381526001602052604090206006015460ff1660028111156123d857fe5b146123f55760405162461bcd60e51b815260040161050a90613a48565b6000848152600160209081526040808320868452600e810183528184203385526004810190935292205461243b5760405162461bcd60e51b815260040161050a9061358d565b33600090815260068201602052604090205460ff161561246d5760405162461bcd60e51b815260040161050a90613b62565b600061247987876118f4565b336000908152600484016020526040812054919250906124ae90670de0b6b3a76400009061091b90859063ffffffff612bc216565b905080846001015410156124d45760405162461bcd60e51b815260040161050a906136e7565b60018401546124e9908263ffffffff612c2816565b6001808601919091553360009081526006850160205260409020805460ff1916909117905587600733600081815260048701602052604090819020549051600080516020613cb283398151915291612547918d919088904290613473565b60405180910390a4600f84015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061258390339085906004016133d5565b602060405180830381600087803b15801561259d57600080fd5b505af11580156125b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125d5919081019061314d565b6125f15760405162461bcd60e51b815260040161050a9061390b565b5050505050505050565b60006007546000148061268f57506007546006546040516370a0823160e01b81526001600160a01b03909116906370a082319061263c90339060040161339d565b60206040518083038186803b15801561265457600080fd5b505afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268c919081019061316d565b10155b6126ab5760405162461bcd60e51b815260040161050a9061375e565b60025460008054600181810183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639091018390558282526020526040902083356127085760405162461bcd60e51b815260040161050a90613515565b4284602001351161272b5760405162461bcd60e51b815260040161050a906138c1565b600061273e610100860160e08701613131565b6001600160a01b031614156127655760405162461bcd60e51b815260040161050a90613ac1565b6101008460400135111561278b5760405162461bcd60e51b815260040161050a906137a8565b61279b6080850160608601613131565b600f820180546001600160a01b0319166001600160a01b03929092169190911790556020840135815560068101805460ff19169055600354600a820155600019600882015560005b846040013581101561282957600d820180546001818101835560009283526020808420909201849055838352600e850190915260409091208481558101829055016127e3565b506004546001600160a01b031663d4876b9f60028660a081018035601e193684900301811261285757600080fd5b909101602081019150356001600160401b0381111561287557600080fd5b3681900382131561288557600080fd5b6128966101008a0160e08b01613131565b6005548a602001356000806040518963ffffffff1660e01b81526004016128c498979695949392919061348e565b602060405180830381600087803b1580156128de57600080fd5b505af11580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612916919081019061316d565b5061299e82853586608081018035601e193684900301811261293757600080fd5b909101602081019150356001600160401b0381111561295557600080fd5b60208102360382131561296757600080fd5b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061133c92505050565b6129a782612d92565b81337f928446b14f4c661d8499681f1d2eb118eb6e89066877a7d43e0672a27cc63a3260408701358760a081018035601e19368490030181126129e957600080fd5b909101602081019150356001600160401b03811115612a0757600080fd5b36819003821315612a1757600080fd5b8960c081018035601e1936849003018112612a3157600080fd5b909101602081019150356001600160401b03811115612a4f57600080fd5b36819003821315612a5f57600080fd5b604051612a70959493929190613c2c565b60405180910390a35060028054600101905592915050565b6000828152600160209081526040808320848452600e8101909252822082918291612ab387876118f4565b6003820154600290920154909891975095509350505050565b600082815260016020908152604080832060028101546001600160a01b03861685526004820190935290832054600b82015491928492612b169261091b919063ffffffff612bc216565b6001600160a01b0385166000908152600c84016020526040902054909150811015612b4657600092505050610937565b6001600160a01b0384166000908152600c830160205260409020546119a290829063ffffffff612c2816565b6000818152600160205260409020600681015460ff166002811115612b9357fe5b6001016002811115612ba157fe5b60068201805460ff19166001836002811115612bb957fe5b02179055505050565b600082612bd157506000610937565b82820282848281612bde57fe5b0414612bfc5760405162461bcd60e51b815260040161050a90613880565b9392505050565b600082820183811015612bfc5760405162461bcd60e51b815260040161050a906135ce565b600082821115612c4a5760405162461bcd60e51b815260040161050a906136b0565b50900390565b6000828152600160205260408120905b600d820154811015612cd3576000818152600e8301602052604090206003810154612c91908563ffffffff612c0316565b60038201556002810154612cab908563ffffffff612c0316565b60028201556003830154612cc5908563ffffffff612c0316565b600384015550600101612c60565b506001810154612ce9908363ffffffff612c0316565b6001909101555050565b6000838152600160209081526040808320858452600e810183528184206001600160a01b038916855260048101909352922054612d36908463ffffffff612c0316565b6001600160a01b03871660009081526004830160205260409020556003810154612d66908463ffffffff612c2816565b600380830191909155820154612d82908463ffffffff612c2816565b8260030181905550505050505050565b6000818152600160205260408120905b600d820154811015612dfa5780837f8270f0a0534b13b7f92d1dbd58aa75c5207b40c55fefa7a17110c6136ad7270b612ddb86856118f4565b42604051612dea929190613c65565b60405180910390a3600101612da2565b5081600080516020613cd28339815191528260020154612e1985612225565b42604051612e2993929190613c16565b60405180910390a25050565b6000808211612e565760405162461bcd60e51b815260040161050a9061372a565b818381612e5f57fe5b049392505050565b6000838152600160209081526040808320858452600e810183528184206001600160a01b038916855260048101909352922054612eaa908463ffffffff612c2816565b6001600160a01b03871660009081526004830160205260409020556003810154612eda908463ffffffff612c0316565b600380830191909155820154612d82908463ffffffff612c0316565b6000828152600160205260408120905b600d820154811015612f79576000818152600e8301602052604090206003810154612f37908563ffffffff612c2816565b60038201556002810154612f51908563ffffffff612c2816565b60028201556003830154612f6b908563ffffffff612c2816565b600384015550600101612f06565b506001810154612ce9908363ffffffff612c2816565b600081815260016020908152604091829020600d81015483518181528184028101909301909352606092909183918015612fd3578160200160208202803883390190505b50905060005b600d83015481101561301a576000818152600e84016020526040902060030154825183908390811061300757fe5b6020908102919091010152600101612fd9565b509392505050565b60008215612e565781600184038161303657fe5b046001019050610937565b60008381526001602052604081206002810154600b82015483916130709161091b90889063ffffffff612bc216565b9050600284600781111561308057fe5b14156130d957600b82015461309b908263ffffffff612c0316565b600b830155336000908152600c830160205260409020546130c2908263ffffffff612c0316565b336000908152600c84016020526040902055613128565b600b8201546130ee908263ffffffff612c2816565b600b830155336000908152600c83016020526040902054613115908263ffffffff612c2816565b336000908152600c840160205260409020555b50509392505050565b600060208284031215613142578081fd5b8135612bfc81613c99565b60006020828403121561315e578081fd5b81518015158114612bfc578182fd5b60006020828403121561317e578081fd5b5051919050565b600060208284031215613196578081fd5b81356001600160401b038111156131ab578182fd5b8083016101008186031215611e47578283fd5b6000602082840312156131cf578081fd5b5035919050565b600080604083850312156131e8578081fd5b8235915060208301356131fa81613c99565b809150509250929050565b60008060408385031215613217578182fd5b50508035926020909101359150565b60008060006060848603121561323a578081fd5b83359250602080850135925060408501356001600160401b038082111561325f578384fd5b81870188601f820112613270578485fd5b8035925081831115613280578485fd5b8383029150613290848301613c73565b8381528481019082860184840187018c10156132aa578788fd5b8794505b858510156132cc5780358352600194909401939186019186016132ae565b508096505050505050509250925092565b6000806000606084860312156132f1578283fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561331d578081fd5b5050823594602084013594506040840135936060013592509050565b6000815180845260208085019450808401835b838110156133685781518752958201959082019060010161334c565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252612bfc6020830184613339565b901515815260200190565b94151585529215156020850152901515604084015215156060830152608082015260a00190565b90815260200190565b60c081016003881061344a57fe5b968152602081019590955260408501939093526060840191909152608083015260a09091015290565b93845260208401929092526040830152606082015260800190565b600089825260e060208301526134a860e08301898b613373565b6001600160a01b039790971660408301525063ffffffff948516606082015292909316608083015260a082015260c001529392505050565b6020808252601b908201527a6d7573742068617665206e6f6e2d7a65726f2062616c616e63657360281b604082015260600190565b60208082526015908201527407374616b65206e6565647320746f206265203e203605c1b604082015260600190565b60208082526029908201527f77656967687420646973747269627574696f6e206c656e67746820646f6573206040820152680dcdee840dac2e8c6d60bb1b606082015260800190565b60208082526021908201527f7573657220646f6573206e6f7420686f6c64206f7574636f6d652073686172656040820152607360f81b606082015260800190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b602080825260129082015271073686172657320616d6f756e7420697320360741b604082015260600190565b6020808252602a908201527f7573657220646f6573206e6f7420686f6c64207265736f6c766564206f7574636040820152696f6d652073686172657360b01b606082015260800190565b6020808252601f908201527f7374616b652068617320746f2062652067726561746572207468616e20302e00604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526023908201527f4d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b6020808252601a9082015279536166654d6174683a206469766973696f6e206279207a65726f60301b604082015260600190565b6020808252602a908201527f6d73672e73656e646572206d75737420686f6c64206d696e696d756d2065726360408201526932302062616c616e636560b01b606082015260800190565b60208082526033908201527f6e756d626572206f66206f7574636f6d65732068617320746f206265206c6573604082015272399037b91032b8bab0b6103a3430b710191a9b60691b606082015260800190565b6020808252602e908201527f7573657220616c726561647920636c61696d6564207265736f6c766564206f7560408201526d74636f6d652077696e6e696e677360901b606082015260800190565b6020808252601e908201527f6d7573742068696e7420612076616c696420646973747269627574696f6e0000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602a908201527f6d61726b6574206d757374207265736f6c7665206166746572207468652063756040820152697272656e74206461746560b01b606082015260800190565b602080825260159082015274195c98cc8c081d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60208082526027908201527f7573657220616c726561647920636c61696d6564206c69717569646974792077604082015266696e6e696e677360c81b606082015260800190565b60208082526023908201527f7573657220646f6573206e6f7420686f6c64206c69717569646974792073686160408201526272657360e81b606082015260800190565b60208082526023908201527f6d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b60208082526021908201527f7573657220646f6573206e6f74206861766520656e6f7567682062616c616e636040820152606560f81b606082015260800190565b6020808252601990820152784d61726b657420696e20696e636f727265637420737461746560381b604082015260600190565b60208082526026908201527f6f7574636f6d652073686172657320706f6f6c2062616c616e636520697320746040820152656f6f206c6f7760d01b606082015260800190565b6020808252601a9082015279696e76616c69642061726269747261746f72206164647265737360301b604082015260600190565b6020808252601e908201527f6d696e696d756d2062757920616d6f756e74206e6f7420726561636865640000604082015260600190565b6020808252601c908201527b1b585e1a5b5d5b481cd95b1b08185b5bdd5b9d08195e18d95959195960221b604082015260600190565b60208082526023908201527f7573657220616c726561647920636c61696d6564206f7574636f6d652073686160408201526272657360e81b606082015260800190565b60208082526038908201527f6d61726b657420616c726561647920686173206c69717569646974792c2063616040820152776e27742064697374726962757465206c697175696469747960401b606082015260800190565b600083825260406020830152611e476040830184613339565b9283526020830191909152604082015260600190565b600086825260606020830152613c46606083018688613373565b8281036040840152613c59818587613373565b98975050505050505050565b918252602082015260400190565b6040518181016001600160401b0381118282101715613c9157600080fd5b604052919050565b6001600160a01b0381168114613cae57600080fd5b5056fe9dcabe311735ed0d65f0c22c5425d1f17331f94c9d0767f59e58473cf95ada611eca98f266e5348ae38d5d057a4d8e451e76672f69ac6ba4b0e3b31ea9c7eb2ba264697066735822122068fd6c05689e8d7a7488ae04ebdbb0a264441770f67ff28140cdcff76367533264736f6c63430006020033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048ae491c075ea48ba1275f967503dcadf5dc1f580000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009ab1213d360bea3eda75d88d81d7fbfc9fd37f2b0000000000000000000000000000000000000000000000000000000000000e10
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101ac5760003560e01c806308560ace146101b15780631281311d146101cf5780631d7920aa146101e457806328747a80146102065780632a9ee5d2146102195780632c2aa24e1461022c57806331877a38146102505780633620875e146102705780633d41a26b146102835780633fe45e3b1461028b578063429c9dff146102935780634397c4ce146102a6578063441cf65e146102b95780635c6d91d0146102d95780635e648eff146102ee578063677bd9ff146103015780637b34e6e01461031457806385b91d8e1461031c5780638671c2ee1461033d5780638c7adc15146103505780638cd41552146103585780639d7de6b31461036b578063aa22a02e1461037e578063ac68a74814610391578063b31eb895146103a4578063bf455721146103b7578063bfacba3d146103ca578063c2ee3a08146103ef578063c346a9d0146103f7578063c8f70d011461040a578063ddca3f431461041d578063ec2c901614610425578063ec93f0f51461042d578063ecb5409a14610440578063efce431314610453578063fdff808514610466575b600080fd5b6101b9610479565b6040516101c69190613433565b60405180910390f35b6101e26101dd366004613308565b61047f565b005b6101f76101f23660046131be565b61070a565b6040516101c693929190613c16565b6101b96102143660046131be565b610729565b6101b9610227366004613205565b6108b6565b61023f61023a3660046131d6565b61093d565b6040516101c695949392919061340c565b61026361025e3660046131be565b610a0d565b6040516101c691906133ee565b6101e261027e366004613308565b610a76565b6101b9610d19565b6101b9610d1f565b6101b96102a13660046132dd565b610d25565b6101b96102b43660046131be565b610e85565b6102cc6102c73660046131be565b610e9a565b6040516101c69190613401565b6102e1610edf565b6040516101c6919061339d565b6101e26102fc3660046131be565b610eee565b6101e261030f3660046131be565b61112f565b6102e161129a565b61032f61032a3660046131be565b6112a9565b6040516101c6929190613bfd565b6101e261034b366004613226565b61133c565b6101b96118ee565b6101b9610366366004613205565b6118f4565b6101e2610379366004613205565b6119ab565b6101b961038c3660046131d6565b611dfc565b6101e261039f3660046131be565b611e4f565b61032f6103b23660046131d6565b611f8c565b6101b96103c53660046131be565b612053565b6103dd6103d83660046131be565b612090565b6040516101c69695949392919061343c565b6101b96120e9565b6101b96104053660046132dd565b6120f5565b6101b96104183660046131be565b612225565b6101b9612356565b61026361235c565b6101e261043b366004613205565b6123b4565b6101b961044e366004613185565b6125fb565b6101f7610461366004613205565b612a88565b6101b96104743660046131d6565b612acc565b60075481565b6000848152600160205260409020548490421180156104bb575060008181526001602052604081206006015460ff1660028111156104b957fe5b145b156104c9576104c981612b72565b8460008060008381526001602052604090206006015460ff1660028111156104ed57fe5b146105135760405162461bcd60e51b815260040161050a90613a48565b60405180910390fd5b60008781526001602052604081209061052d868a8a610d25565b90508681101561054f5760405162461bcd60e51b815260040161050a90613af5565b6000811161056f5760405162461bcd60e51b815260040161050a90613603565b600a820154600090670de0b6b3a76400009061059290899063ffffffff612bc216565b8161059957fe5b600b85015491900491506105b3908263ffffffff612c0316565b600b84015560006105ca888363ffffffff612c2816565b60008b8152600e8601602052604090209091506105e78c83612c50565b600381015484111561060b5760405162461bcd60e51b815260040161050a90613a7b565b610617338d8d87612cf3565b600f8501546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061064d90339030908e906004016133b1565b602060405180830381600087803b15801561066757600080fd5b505af115801561067b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061069f919081019061314d565b6106bb5760405162461bcd60e51b815260040161050a9061390b565b8b6000336001600160a01b0316600080516020613cb28339815191528e888e426040516106eb9493929190613473565b60405180910390a46106fc8c612d92565b505050505050505050505050565b6000908152600160205260409020600a81015460099091015490918190565b600081815260016020526040812054829042118015610765575060008181526001602052604081206006015460ff16600281111561076357fe5b145b156107735761077381612b72565b8260018060008381526001602052604090206006015460ff16600281111561079757fe5b146107b45760405162461bcd60e51b815260040161050a90613a48565b600085815260016020526040808220600480546009830154935163684e62bf60e11b81528a9593946001600160a01b039092169392849263d09cc57e926107fb9201613433565b60206040518083038186803b15801561081357600080fd5b505afa158015610827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061084b919081019061316d565b60088401819055604051909150899033907f67a6457c8912ae1b7a9fbdfa311cbd016ba606b548bf06bc80bc751072d91bbc9061088b9085904290613c65565b60405180910390a361089c89612d92565b50506008015494506108ad81612b72565b50505050919050565b6000828152600160205260408120670de0b6b3a7640000825b600d83015481101561093257848114156108e85761092a565b6000818152600e8401602052604090206003015461092790670de0b6b3a76400009061091b90859063ffffffff612bc216565b9063ffffffff612e3516565b91505b6001016108cf565b509150505b92915050565b600082815260016020526040812081908190819081906002600682015460ff16600281111561096857fe5b1461098d5760008060008061097d8c8c612acc565b9550955095509550955050610a03565b60088101546000908152600e8201602090815260408083206001600160a01b038b16845260048082018452828520546005808401865284872054928801865284872054908801909552929094205490939115159260ff9283169290151591166109f68d8d612acc565b9650965096509650965050505b9295509295909350565b600081815260016020908152604091829020600d810180548451818502810185019095528085526060949293830182828015610a6857602002820191906000526020600020905b815481526020019060010190808311610a54575b50505050509150505b919050565b600084815260016020526040902054849042118015610ab2575060008181526001602052604081206006015460ff166002811115610ab057fe5b145b15610ac057610ac081612b72565b8460008060008381526001602052604090206006015460ff166002811115610ae457fe5b14610b015760405162461bcd60e51b815260040161050a90613a48565b6000878152600160209081526040808320898452600e810190925282209091610b2b888b8b6120f5565b905086811115610b4d5760405162461bcd60e51b815260040161050a90613b2c565b60008111610b6d5760405162461bcd60e51b815260040161050a90613603565b336000908152600483016020526040902054811115610b9e5760405162461bcd60e51b815260040161050a90613a07565b610baa338b8b84612e67565b6000610bc9600354670de0b6b3a7640000612c2890919063ffffffff16565b600a850154610bdf908b9063ffffffff612bc216565b81610be657fe5b600b8601549190049150610c00908263ffffffff612c0316565b600b8501556000610c178a8363ffffffff612c0316565b90508085600101541015610c3d5760405162461bcd60e51b815260040161050a906139c4565b610c478c82612ef6565b600f85015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90610c7b9033908e906004016133d5565b602060405180830381600087803b158015610c9557600080fd5b505af1158015610ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ccd919081019061314d565b610ce95760405162461bcd60e51b815260040161050a9061390b565b8b6001336001600160a01b0316600080516020613cb28339815191528e878f426040516106eb9493929190613473565b60001981565b60055481565b60008281526001602052604081206060610d3e85612f8f565b90506000610d7e670de0b6b3a7640000610d6885600a01600001548a612bc290919063ffffffff16565b81610d6f57fe5b8991900463ffffffff612c2816565b90506000828681518110610d8e57fe5b602002602001015190506000610db5670de0b6b3a764000083612bc290919063ffffffff16565b905060005b8451811015610e2057878114610e18576000858281518110610dd857fe5b60200260200101519050610e14610df88683612c0390919063ffffffff16565b610e08858463ffffffff612bc216565b9063ffffffff61302216565b9250505b600101610dba565b5060008111610e415760405162461bcd60e51b815260040161050a906134e0565b610e78610e5c82670de0b6b3a764000063ffffffff61302216565b610e6c848663ffffffff612c0316565b9063ffffffff612c2816565b9998505050505050505050565b60009081526001602052604090206009015490565b60008181526001602052604081206002600682015460ff166002811115610ebd57fe5b14610ecc576000915050610a71565b600d810154600890910154101592915050565b6006546001600160a01b031681565b8060028060008381526001602052604090206006015460ff166002811115610f1257fe5b14610f2f5760405162461bcd60e51b815260040161050a90613a48565b6000838152600160205260409020610f4684611e4f565b336000908152600482016020526040902054610f745760405162461bcd60e51b815260040161050a90613981565b33600090815260058201602052604090205460ff1615610fa65760405162461bcd60e51b815260040161050a9061393a565b6000610fb185612225565b33600090815260048401602052604081205491925090670de0b6b3a764000090610fe290849063ffffffff612bc216565b81610fe957fe5b04905080836001015410156110105760405162461bcd60e51b815260040161050a906136e7565b6001830154611025908263ffffffff612c2816565b600184810191909155336000818152600580870160209081526040808420805460ff19169096179095556004880190528382205493518a94919392600080516020613cb28339815191529261107d9288904290613473565b60405180910390a4600f83015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906110b990339085906004016133d5565b602060405180830381600087803b1580156110d357600080fd5b505af11580156110e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061110b919081019061314d565b6111275760405162461bcd60e51b815260040161050a9061390b565b505050505050565b8060028060008381526001602052604090206006015460ff16600281111561115357fe5b146111705760405162461bcd60e51b815260040161050a90613a48565b600083815260016020908152604080832060088101548452600e81018352818420338552600481019093529220546111ba5760405162461bcd60e51b815260040161050a9061362f565b33600090815260058201602052604090205460ff16156111ec5760405162461bcd60e51b815260040161050a906137fb565b33600090815260048201602052604090205460018301548111156112225760405162461bcd60e51b815260040161050a906136e7565b6001830154611237908263ffffffff612c2816565b6001808501919091553360009081526005840160205260409020805460ff191690911790558560046008850154336000818152600487016020526040908190205490519192600080516020613cb28339815191529261107d929088904290613473565b6004546001600160a01b031681565b6000818152600160209081526040808320600d81015482518181528185028101909401909252606092909183919080156112ed578160200160208202803883390190505b50905060005b600d8301548110156113285761130986826118f4565b82828151811061131557fe5b60209081029190910101526001016112f3565b5061133285612225565b9350915050915091565b600083815260016020526040902054839042118015611378575060008181526001602052604081206006015460ff16600281111561137657fe5b145b156113865761138681612b72565b8360008060008381526001602052604090206006015460ff1660028111156113aa57fe5b146113c75760405162461bcd60e51b815260040161050a90613a48565b6000868152600160205260409020856113f25760405162461bcd60e51b815260040161050a90613679565b600060606113ff89612f8f565b90506060815160405190808252806020026020018201604052801561142e578160200160208202803883390190505b5060028501549091506000901561153c5788511561145e5760405162461bcd60e51b815260040161050a90613ba5565b60005b835181101561149757600084828151811061147857fe5b602002602001015190508083101561148e578092505b50600101611461565b5060005b8351811015611507576000826114cd8684815181106114b657fe5b60200260200101518e612bc290919063ffffffff16565b816114d457fe5b0490506114e78c8263ffffffff612c2816565b8483815181106114f357fe5b60209081029190910101525060010161149b565b508061152086600201548c612bc290919063ffffffff16565b8161152757fe5b0493506115368b856002613041565b50611635565b8851156116315782518951146115645760405162461bcd60e51b815260040161050a90613544565b6000805b8a5181101561159e5760008b828151811061157f57fe5b6020026020010151905080831015611595578092505b50600101611568565b5060005b8a5181101561162e576000826115d48d84815181106115bd57fe5b60200260200101518f612bc290919063ffffffff16565b816115db57fe5b049050600081116115fe5760405162461bcd60e51b815260040161050a90613849565b61160e8d8263ffffffff612c2816565b85838151811061161a57fe5b6020908102919091010152506001016115a2565b50505b8993505b600285015461164a908563ffffffff612c0316565b6002860155336000908152600486016020526040902054611671908563ffffffff612c0316565b33600090815260048701602052604090205561168d8b8b612c50565b60005b82518110156117905760008382815181106116a757fe5b6020026020010151111561178857600086600301549050600087600e0160008481526020019081526020016000206002016001015490506116fd338f858887815181106116f057fe5b6020026020010151612cf3565b8d6000336001600160a01b0316600080516020613cb28339815191528689888151811061172657fe5b602002602001015161176c8e6003015461091b8d8c8151811061174557fe5b60200260200101516117608b8d612c2890919063ffffffff16565b9063ffffffff612bc216565b4260405161177d9493929190613473565b60405180910390a450505b600101611690565b50600061179c8c612225565b90506000670de0b6b3a76400006117b9838863ffffffff612bc216565b816117c057fe5b04905086600f0160009054906101000a90046001600160a01b03166001600160a01b03166323b872dd33308f6040518463ffffffff1660e01b815260040161180a939291906133b1565b602060405180830381600087803b15801561182457600080fd5b505af1158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061185c919081019061314d565b6118785760405162461bcd60e51b815260040161050a9061390b565b8c6002336001600160a01b0316600080516020613cb283398151915260008a86426040516118a99493929190613473565b60405180910390a48c600080516020613cd2833981519152886002015484426040516118d793929190613c16565b60405180910390a250505050505050505050505050565b60025481565b60008281526001602052604081206002600682015460ff16600281111561191757fe5b14801561192a575061192884610e9a565b155b15611953576008810154831461194157600061194b565b670de0b6b3a76400005b915050610937565b6000805b600d8301548110156119875761197d61197087836108b6565b839063ffffffff612c0316565b9150600101611957565b506119a28161091b670de0b6b3a764000061176089896108b6565b95945050505050565b6000828152600160205260409020548290421180156119e7575060008181526001602052604081206006015460ff1660028111156119e557fe5b145b156119f5576119f581612b72565b8260008060008381526001602052604090206006015460ff166002811115611a1957fe5b14611a365760405162461bcd60e51b815260040161050a90613a48565b60008581526001602090815260408083203384526004810190925290912054851115611a745760405162461bcd60e51b815260040161050a90613a07565b611a7d86611e4f565b611a8986866003613041565b506060611a9587612f8f565b905060608151604051908082528060200260200182016040528015611ac4578160200160208202803883390190505b50905060001960005b8351811015611b03576000848281518110611ae457fe5b6020026020010151905080831115611afa578092505b50600101611acd565b506002840154600090611b209061091b8b8563ffffffff612bc216565b905060005b8451811015611bbe578560020154611b598b878481518110611b4357fe5b6020026020010151612bc290919063ffffffff16565b81611b6057fe5b04848281518110611b6d57fe5b602002602001018181525050611b9f82858381518110611b8957fe5b6020026020010151612c2890919063ffffffff16565b848281518110611bab57fe5b6020908102919091010152600101611b25565b50611bc98a82612ef6565b6002850154611bde908a63ffffffff612c2816565b6002860155336000908152600486016020526040902054611c05908a63ffffffff612c2816565b3360009081526004870160205260408120919091555b8451811015611cde576000848281518110611c3257fe5b60200260200101511115611cd6576003808701546000838152600e890160205260409020909101548551611c729033908f9086908a90829081106116f057fe5b8c6000336001600160a01b0316600080516020613cb2833981519152868a8881518110611c9b57fe5b6020026020010151611cba8e6003015461091b8e8c8151811061174557fe5b42604051611ccb9493929190613473565b60405180910390a450505b600101611c1b565b50600f85015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611d1390339085906004016133d5565b602060405180830381600087803b158015611d2d57600080fd5b505af1158015611d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d65919081019061314d565b611d815760405162461bcd60e51b815260040161050a9061390b565b896003336001600160a01b0316600080516020613cb283398151915260008d8642604051611db29493929190613473565b60405180910390a489600080516020613cd28339815191528660020154611dd88d612225565b42604051611de893929190613c16565b60405180910390a250505050505050505050565b600082815260016020908152604080832060028101546001600160a01b038616855260048201909352908320549091611e479161091b90670de0b6b3a764000063ffffffff612bc216565b949350505050565b600081815260016020526040812090611e688333612acc565b90508015611f4857336000908152600c83016020526040902054611e92908263ffffffff612c0316565b336000818152600c850160205260409081902092909255600f840154915163a9059cbb60e01b81526001600160a01b039092169163a9059cbb91611eda9185906004016133d5565b602060405180830381600087803b158015611ef457600080fd5b505af1158015611f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f2c919081019061314d565b611f485760405162461bcd60e51b815260040161050a9061390b565b826006336000818152600486016020526040808220549051600080516020613cb283398151915292611f7f92909188904290613473565b60405180910390a4505050565b6000828152600160209081526040808320600d8101548251818152818502810190940190925260609290918391908015611fd0578160200160208202803883390190505b50905060005b600d83015481101561202b576000818152600e8401602090815260408083206001600160a01b038a168452600401909152902054825183908390811061201857fe5b6020908102919091010152600101611fd6565b506001600160a01b039490941660009081526004919091016020526040902054949293505050565b60008181526001602052604081206002600682015460ff16600281111561207657fe5b1461208657600019915050610a71565b6008015492915050565b6000818152600160208190526040822060068101548154600283015493830154600384015486958695869586958695929460ff90921693909290916120d48d612053565b949d939c50919a509850965090945092505050565b670de0b6b3a764000081565b6000828152600160205260408120606061210e85612f8f565b600a83015490915060009061213290670de0b6b3a76400009063ffffffff612c2816565b61214a88670de0b6b3a764000063ffffffff612bc216565b8161215157fe5b049050600082868151811061216257fe5b602002602001015190506000612189670de0b6b3a764000083612bc290919063ffffffff16565b905060005b84518110156121d8578781146121d05760008582815181106121ac57fe5b602002602001015190506121cc610df88683612c2890919063ffffffff16565b9250505b60010161218e565b50600081116121f95760405162461bcd60e51b815260040161050a906134e0565b610e7882610e6c61221884670de0b6b3a764000063ffffffff61302216565b869063ffffffff612c0316565b60008181526001602052604081206002600682015460ff16600281111561224857fe5b14801561225b575061225983610e9a565b155b156122a357600281015460088201546000908152600e8301602052604090206003015461229b919061091b90670de0b6b3a764000063ffffffff612bc216565b915050610a71565b670de0b6b3a76400006000805b600d840154811015612317576000818152600e85016020526040902060038101546122f090670de0b6b3a76400009061091b90879063ffffffff612bc216565b935061230c6122ff88846108b6565b849063ffffffff612c0316565b9250506001016122b0565b506119a2836002015461091b670de0b6b3a76400006117608561091b670de0b6b3a76400006117608b600d01805490508b612bc290919063ffffffff16565b60035481565b606060008054806020026020016040519081016040528092919081815260200182805480156123aa57602002820191906000526020600020905b815481526020019060010190808311612396575b5050505050905090565b8160028060008381526001602052604090206006015460ff1660028111156123d857fe5b146123f55760405162461bcd60e51b815260040161050a90613a48565b6000848152600160209081526040808320868452600e810183528184203385526004810190935292205461243b5760405162461bcd60e51b815260040161050a9061358d565b33600090815260068201602052604090205460ff161561246d5760405162461bcd60e51b815260040161050a90613b62565b600061247987876118f4565b336000908152600484016020526040812054919250906124ae90670de0b6b3a76400009061091b90859063ffffffff612bc216565b905080846001015410156124d45760405162461bcd60e51b815260040161050a906136e7565b60018401546124e9908263ffffffff612c2816565b6001808601919091553360009081526006850160205260409020805460ff1916909117905587600733600081815260048701602052604090819020549051600080516020613cb283398151915291612547918d919088904290613473565b60405180910390a4600f84015460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061258390339085906004016133d5565b602060405180830381600087803b15801561259d57600080fd5b505af11580156125b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125d5919081019061314d565b6125f15760405162461bcd60e51b815260040161050a9061390b565b5050505050505050565b60006007546000148061268f57506007546006546040516370a0823160e01b81526001600160a01b03909116906370a082319061263c90339060040161339d565b60206040518083038186803b15801561265457600080fd5b505afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268c919081019061316d565b10155b6126ab5760405162461bcd60e51b815260040161050a9061375e565b60025460008054600181810183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639091018390558282526020526040902083356127085760405162461bcd60e51b815260040161050a90613515565b4284602001351161272b5760405162461bcd60e51b815260040161050a906138c1565b600061273e610100860160e08701613131565b6001600160a01b031614156127655760405162461bcd60e51b815260040161050a90613ac1565b6101008460400135111561278b5760405162461bcd60e51b815260040161050a906137a8565b61279b6080850160608601613131565b600f820180546001600160a01b0319166001600160a01b03929092169190911790556020840135815560068101805460ff19169055600354600a820155600019600882015560005b846040013581101561282957600d820180546001818101835560009283526020808420909201849055838352600e850190915260409091208481558101829055016127e3565b506004546001600160a01b031663d4876b9f60028660a081018035601e193684900301811261285757600080fd5b909101602081019150356001600160401b0381111561287557600080fd5b3681900382131561288557600080fd5b6128966101008a0160e08b01613131565b6005548a602001356000806040518963ffffffff1660e01b81526004016128c498979695949392919061348e565b602060405180830381600087803b1580156128de57600080fd5b505af11580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612916919081019061316d565b5061299e82853586608081018035601e193684900301811261293757600080fd5b909101602081019150356001600160401b0381111561295557600080fd5b60208102360382131561296757600080fd5b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061133c92505050565b6129a782612d92565b81337f928446b14f4c661d8499681f1d2eb118eb6e89066877a7d43e0672a27cc63a3260408701358760a081018035601e19368490030181126129e957600080fd5b909101602081019150356001600160401b03811115612a0757600080fd5b36819003821315612a1757600080fd5b8960c081018035601e1936849003018112612a3157600080fd5b909101602081019150356001600160401b03811115612a4f57600080fd5b36819003821315612a5f57600080fd5b604051612a70959493929190613c2c565b60405180910390a35060028054600101905592915050565b6000828152600160209081526040808320848452600e8101909252822082918291612ab387876118f4565b6003820154600290920154909891975095509350505050565b600082815260016020908152604080832060028101546001600160a01b03861685526004820190935290832054600b82015491928492612b169261091b919063ffffffff612bc216565b6001600160a01b0385166000908152600c84016020526040902054909150811015612b4657600092505050610937565b6001600160a01b0384166000908152600c830160205260409020546119a290829063ffffffff612c2816565b6000818152600160205260409020600681015460ff166002811115612b9357fe5b6001016002811115612ba157fe5b60068201805460ff19166001836002811115612bb957fe5b02179055505050565b600082612bd157506000610937565b82820282848281612bde57fe5b0414612bfc5760405162461bcd60e51b815260040161050a90613880565b9392505050565b600082820183811015612bfc5760405162461bcd60e51b815260040161050a906135ce565b600082821115612c4a5760405162461bcd60e51b815260040161050a906136b0565b50900390565b6000828152600160205260408120905b600d820154811015612cd3576000818152600e8301602052604090206003810154612c91908563ffffffff612c0316565b60038201556002810154612cab908563ffffffff612c0316565b60028201556003830154612cc5908563ffffffff612c0316565b600384015550600101612c60565b506001810154612ce9908363ffffffff612c0316565b6001909101555050565b6000838152600160209081526040808320858452600e810183528184206001600160a01b038916855260048101909352922054612d36908463ffffffff612c0316565b6001600160a01b03871660009081526004830160205260409020556003810154612d66908463ffffffff612c2816565b600380830191909155820154612d82908463ffffffff612c2816565b8260030181905550505050505050565b6000818152600160205260408120905b600d820154811015612dfa5780837f8270f0a0534b13b7f92d1dbd58aa75c5207b40c55fefa7a17110c6136ad7270b612ddb86856118f4565b42604051612dea929190613c65565b60405180910390a3600101612da2565b5081600080516020613cd28339815191528260020154612e1985612225565b42604051612e2993929190613c16565b60405180910390a25050565b6000808211612e565760405162461bcd60e51b815260040161050a9061372a565b818381612e5f57fe5b049392505050565b6000838152600160209081526040808320858452600e810183528184206001600160a01b038916855260048101909352922054612eaa908463ffffffff612c2816565b6001600160a01b03871660009081526004830160205260409020556003810154612eda908463ffffffff612c0316565b600380830191909155820154612d82908463ffffffff612c0316565b6000828152600160205260408120905b600d820154811015612f79576000818152600e8301602052604090206003810154612f37908563ffffffff612c2816565b60038201556002810154612f51908563ffffffff612c2816565b60028201556003830154612f6b908563ffffffff612c2816565b600384015550600101612f06565b506001810154612ce9908363ffffffff612c2816565b600081815260016020908152604091829020600d81015483518181528184028101909301909352606092909183918015612fd3578160200160208202803883390190505b50905060005b600d83015481101561301a576000818152600e84016020526040902060030154825183908390811061300757fe5b6020908102919091010152600101612fd9565b509392505050565b60008215612e565781600184038161303657fe5b046001019050610937565b60008381526001602052604081206002810154600b82015483916130709161091b90889063ffffffff612bc216565b9050600284600781111561308057fe5b14156130d957600b82015461309b908263ffffffff612c0316565b600b830155336000908152600c830160205260409020546130c2908263ffffffff612c0316565b336000908152600c84016020526040902055613128565b600b8201546130ee908263ffffffff612c2816565b600b830155336000908152600c83016020526040902054613115908263ffffffff612c2816565b336000908152600c840160205260409020555b50509392505050565b600060208284031215613142578081fd5b8135612bfc81613c99565b60006020828403121561315e578081fd5b81518015158114612bfc578182fd5b60006020828403121561317e578081fd5b5051919050565b600060208284031215613196578081fd5b81356001600160401b038111156131ab578182fd5b8083016101008186031215611e47578283fd5b6000602082840312156131cf578081fd5b5035919050565b600080604083850312156131e8578081fd5b8235915060208301356131fa81613c99565b809150509250929050565b60008060408385031215613217578182fd5b50508035926020909101359150565b60008060006060848603121561323a578081fd5b83359250602080850135925060408501356001600160401b038082111561325f578384fd5b81870188601f820112613270578485fd5b8035925081831115613280578485fd5b8383029150613290848301613c73565b8381528481019082860184840187018c10156132aa578788fd5b8794505b858510156132cc5780358352600194909401939186019186016132ae565b508096505050505050509250925092565b6000806000606084860312156132f1578283fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561331d578081fd5b5050823594602084013594506040840135936060013592509050565b6000815180845260208085019450808401835b838110156133685781518752958201959082019060010161334c565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252612bfc6020830184613339565b901515815260200190565b94151585529215156020850152901515604084015215156060830152608082015260a00190565b90815260200190565b60c081016003881061344a57fe5b968152602081019590955260408501939093526060840191909152608083015260a09091015290565b93845260208401929092526040830152606082015260800190565b600089825260e060208301526134a860e08301898b613373565b6001600160a01b039790971660408301525063ffffffff948516606082015292909316608083015260a082015260c001529392505050565b6020808252601b908201527a6d7573742068617665206e6f6e2d7a65726f2062616c616e63657360281b604082015260600190565b60208082526015908201527407374616b65206e6565647320746f206265203e203605c1b604082015260600190565b60208082526029908201527f77656967687420646973747269627574696f6e206c656e67746820646f6573206040820152680dcdee840dac2e8c6d60bb1b606082015260800190565b60208082526021908201527f7573657220646f6573206e6f7420686f6c64206f7574636f6d652073686172656040820152607360f81b606082015260800190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b602080825260129082015271073686172657320616d6f756e7420697320360741b604082015260600190565b6020808252602a908201527f7573657220646f6573206e6f7420686f6c64207265736f6c766564206f7574636040820152696f6d652073686172657360b01b606082015260800190565b6020808252601f908201527f7374616b652068617320746f2062652067726561746572207468616e20302e00604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526023908201527f4d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b6020808252601a9082015279536166654d6174683a206469766973696f6e206279207a65726f60301b604082015260600190565b6020808252602a908201527f6d73672e73656e646572206d75737420686f6c64206d696e696d756d2065726360408201526932302062616c616e636560b01b606082015260800190565b60208082526033908201527f6e756d626572206f66206f7574636f6d65732068617320746f206265206c6573604082015272399037b91032b8bab0b6103a3430b710191a9b60691b606082015260800190565b6020808252602e908201527f7573657220616c726561647920636c61696d6564207265736f6c766564206f7560408201526d74636f6d652077696e6e696e677360901b606082015260800190565b6020808252601e908201527f6d7573742068696e7420612076616c696420646973747269627574696f6e0000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602a908201527f6d61726b6574206d757374207265736f6c7665206166746572207468652063756040820152697272656e74206461746560b01b606082015260800190565b602080825260159082015274195c98cc8c081d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60208082526027908201527f7573657220616c726561647920636c61696d6564206c69717569646974792077604082015266696e6e696e677360c81b606082015260800190565b60208082526023908201527f7573657220646f6573206e6f7420686f6c64206c69717569646974792073686160408201526272657360e81b606082015260800190565b60208082526023908201527f6d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b60208082526021908201527f7573657220646f6573206e6f74206861766520656e6f7567682062616c616e636040820152606560f81b606082015260800190565b6020808252601990820152784d61726b657420696e20696e636f727265637420737461746560381b604082015260600190565b60208082526026908201527f6f7574636f6d652073686172657320706f6f6c2062616c616e636520697320746040820152656f6f206c6f7760d01b606082015260800190565b6020808252601a9082015279696e76616c69642061726269747261746f72206164647265737360301b604082015260600190565b6020808252601e908201527f6d696e696d756d2062757920616d6f756e74206e6f7420726561636865640000604082015260600190565b6020808252601c908201527b1b585e1a5b5d5b481cd95b1b08185b5bdd5b9d08195e18d95959195960221b604082015260600190565b60208082526023908201527f7573657220616c726561647920636c61696d6564206f7574636f6d652073686160408201526272657360e81b606082015260800190565b60208082526038908201527f6d61726b657420616c726561647920686173206c69717569646974792c2063616040820152776e27742064697374726962757465206c697175696469747960401b606082015260800190565b600083825260406020830152611e476040830184613339565b9283526020830191909152604082015260600190565b600086825260606020830152613c46606083018688613373565b8281036040840152613c59818587613373565b98975050505050505050565b918252602082015260400190565b6040518181016001600160401b0381118282101715613c9157600080fd5b604052919050565b6001600160a01b0381168114613cae57600080fd5b5056fe9dcabe311735ed0d65f0c22c5425d1f17331f94c9d0767f59e58473cf95ada611eca98f266e5348ae38d5d057a4d8e451e76672f69ac6ba4b0e3b31ea9c7eb2ba264697066735822122068fd6c05689e8d7a7488ae04ebdbb0a264441770f67ff28140cdcff76367533264736f6c63430006020033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048ae491c075ea48ba1275f967503dcadf5dc1f580000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009ab1213d360bea3eda75d88d81d7fbfc9fd37f2b0000000000000000000000000000000000000000000000000000000000000e10
-----Decoded View---------------
Arg [0] : _fee (uint256): 0
Arg [1] : _requiredBalanceToken (address): 0x48ae491c075ea48Ba1275f967503DCadf5DC1f58
Arg [2] : _requiredBalance (uint256): 1000000000000000000
Arg [3] : _realitioAddress (address): 0x9aB1213d360bEa3edA75D88D81D7fbfc9fd37F2b
Arg [4] : _realitioTimeout (uint256): 3600
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000048ae491c075ea48ba1275f967503dcadf5dc1f58
Arg [2] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [3] : 0000000000000000000000009ab1213d360bea3eda75d88d81d7fbfc9fd37f2b
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000e10
Deployed Bytecode Sourcemap
49505:33727:0:-:0;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49505:33727:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52805:30;;;:::i;:::-;;;;;;;;;;;;;;;;58289:1261;;;;;;;;;:::i;:::-;;78362:298;;;;;;;;;:::i;:::-;;;;;;;;;;67035:643;;;;;;;;;:::i;81320:414::-;;;;;;;;;:::i;76460:712::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;81141:173;;;;;;;;;:::i;:::-;;;;;;;;59600:1360;;;;;;;;;:::i;50435:117::-;;;:::i;52665:30::-;;;:::i;56305:903::-;;;;;;;;;:::i;78666:177::-;;;;;;;;;:::i;80704:393::-;;;;;;;;;:::i;:::-;;;;;;;;52722:34;;;:::i;:::-;;;;;;;;70167:1111;;;;;;;;;:::i;67757:1086::-;;;;;;;;;:::i;52630:30::-;;;:::i;78849:443::-;;;;;;;;;:::i;:::-;;;;;;;;;61016:3416;;;;;;;;;:::i;52496:26::-;;;:::i;81740:721::-;;;;;;;;;:::i;64491:2464::-;;;;;;;;;:::i;77178:228::-;;;;;;;;;:::i;71364:585::-;;;;;;;;;:::i;75951:503::-;;;;;;;;;:::i;80386:312::-;;;;;;;;;:::i;77915:441::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;50559:36;;;:::i;57316:924::-;;;;;;;;;:::i;79298:1082::-;;;;;;;;;:::i;52546:18::-;;;:::i;77817:92::-;;;:::i;68924:1154::-;;;;;;;;;:::i;54591:1635::-;;;;;;;;;:::i;82467:390::-;;;;;;;;;:::i;77412:399::-;;;;;;;;;:::i;52805:30::-;;;;:::o;58289:1261::-;53088:17;;;;:7;:17;;;;;:35;58435:8;;53082:3;:41;:88;;;;-1:-1:-1;53154:16:0;53127:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;53082:88;53078:130;;;53181:19;53191:8;53181:9;:19::i;:::-;58453:8;58463:16:::1;::::0;53296:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;53288:70;;;;-1:-1:-1::0;;;53288:70:0::1;;;;;;;;;;;;;;;;;58488:21:::2;58512:17:::0;;;:7:::2;:17;::::0;;;;;58555:41:::2;58569:5:::0;58520:8;58586:9;58555:13:::2;:41::i;:::-;58538:58;;58621:21;58611:6;:31;;58603:74;;;;-1:-1:-1::0;;;58603:74:0::2;;;;;;;;;58701:1;58692:6;:10;58684:41;;;;-1:-1:-1::0;;;58684:41:0::2;;;;;;;;;58811:11;::::0;::::2;:17:::0;58781::::2;::::0;50589:6:::2;::::0;58801:28:::2;::::0;:5;;:28:::2;:9;:28;:::i;:::-;:34;;;;;58867:22:::0;;;;58801:34;;::::2;::::0;-1:-1:-1;58867:37:0::2;::::0;58801:34;58867:37:::2;:26;:37;:::i;:::-;58842:22:::0;;;:62;58911:22:::2;58936:20;:5:::0;58946:9;58936:20:::2;:9;:20;:::i;:::-;58965:29;58997:26:::0;;;:15:::2;::::0;::::2;:26;::::0;;;;58911:45;;-1:-1:-1;59082:43:0::2;59100:8:::0;58911:45;59082:17:::2;:43::i;:::-;59142:24:::0;;;;:34;-1:-1:-1;59142:34:0::2;59134:85;;;;-1:-1:-1::0;;;59134:85:0::2;;;;;;;;;59228:70;59258:10;59270:8;59280:9;59291:6;59228:29;:70::i;:::-;59315:12;::::0;::::2;::::0;:59:::2;::::0;-1:-1:-1;;;59315:59:0;;-1:-1:-1;;;;;59315:12:0;;::::2;::::0;:25:::2;::::0;:59:::2;::::0;59341:10:::2;::::0;59361:4:::2;::::0;59368:5;;59315:59:::2;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::2;5:2;59315:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;59315:59:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59315:59:0;;;;;;;;;59307:93;;;;-1:-1:-1::0;;;59307:93:0::2;;;;;;;;;59459:8:::0;59441:16:::2;59429:10;-1:-1:-1::0;;;;;59414:85:0::2;-1:-1:-1::0;;;;;;;;;;;59469:9:0::2;59480:6;59488:5;59495:3;59414:85;;;;;;;;;;;;;;;;;;59506:38;59535:8;59506:28;:38::i;:::-;53365:1;;;;;53214::::1;;58289:1261:::0;;;;;:::o;78362:298::-;78452:7;78533:17;;;:7;:17;;;;;78567:11;;;:17;78586:28;;;;;78567:17;;78586:28;;78362:298::o;67035:643::-;67215:7;53088:17;;;:7;:17;;;;;:35;67118:8;;53082:3;:41;:88;;;;-1:-1:-1;53154:16:0;53127:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;53082:88;53078:130;;;53181:19;53191:8;53181:9;:19::i;:::-;67141:8;67151:18:::1;::::0;53296:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;53288:70;;;;-1:-1:-1::0;;;53288:70:0::1;;;;;;;;;67234:21:::3;67258:17:::0;;;:7:::3;:17;::::0;;;;;67323:15:::3;::::0;;67440:28;;;;67421:48;;-1:-1:-1;;;67421:48:0;;67191:8;;67258:17;;-1:-1:-1;;;;;67323:15:0;;::::3;::::0;67234:21;67323:15;;67421:18:::3;::::0;:48:::3;::::0;::::3;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::3;5:2;67421:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::3;77:16;74:1;67:27;5:2;67421:48:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;67421:48:0;;;;;;;;;67479:27:::0;;;:39;;;67532:52:::3;::::0;67413:57;;-1:-1:-1;67559:8:0;;67547:10:::3;::::0;67532:52:::3;::::0;::::3;::::0;67413:57;;67580:3:::3;::::0;67532:52:::3;;;;;;;;;;67591:38;67620:8;67591:28;:38::i;:::-;-1:-1:-1::0;;67645:27:0;;;;-1:-1:-1;53589:19:0::2;53599:8;53589:9;:19::i;:::-;53365:1;53214::::1;;67035:643:::0;;;;:::o;81320:414::-;81408:7;81448:17;;;:7;:17;;;;;50589:6;81408:7;81510:190;81534:17;;;:24;81530:28;;81510:190;;;81583:9;81578:1;:14;81574:28;;;81594:8;;81574:28;81647:18;;;;:15;;;:18;;;;;:35;;;81629:63;;50589:6;;81629:54;;:13;;:54;:17;:54;:::i;:::-;:58;:63;:58;:63;:::i;:::-;81613:79;;81510:190;81560:3;;81510:190;;;-1:-1:-1;81715:13:0;-1:-1:-1;;81320:414:0;;;;;:::o;76460:712::-;76566:4;76667:17;;;:7;:17;;;;;76566:4;;;;;;;;76747:20;76731:12;;;;;;:36;;;;;;;;;76727:132;;76786:5;76793;76800;76807;76814:36;76835:8;76845:4;76814:20;:36::i;:::-;76778:73;;;;;;;;;;;;;76727:132;76915:27;;;;76867:29;76899:44;;;:15;;;:44;;;;;;;;-1:-1:-1;;;;;76968:28:0;;;;:22;;;;:28;;;;;;77009:21;;;;:27;;;;;;77045:22;;;:28;;;;;;77086:22;;;:28;;;;;;;;76899:44;;76968:32;;;;77009:27;;;;;77045:32;;;;77086:28;77123:36;77144:8;76991:4;77123:20;:36::i;:::-;76952:214;;;;;;;;;;;;76460:712;;;;;;;;;:::o;81141:173::-;81236:21;81260:17;;;:7;:17;;;;;;;;;81291;;;81284:24;;;;;;;;;;;;;;;;;81211:16;;81260:17;;81284:24;;81291:17;81284:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81141:173;;;;:::o;59600:1360::-;53088:17;;;;:7;:17;;;;;:35;59748:8;;53082:3;:41;:88;;;;-1:-1:-1;53154:16:0;53127:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;53082:88;53078:130;;;53181:19;53191:8;53181:9;:19::i;:::-;59766:8;59776:16:::1;::::0;53296:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;53288:70;;;;-1:-1:-1::0;;;53288:70:0::1;;;;;;;;;59801:21:::2;59825:17:::0;;;:7:::2;:17;::::0;;;;;;;59881:26;;;:15:::2;::::0;::::2;:26:::0;;;;;59825:17;;59933:42:::2;59948:5:::0;59833:8;59897:9;59933:14:::2;:42::i;:::-;59916:59;;60002:22;59992:6;:32;;59984:73;;;;-1:-1:-1::0;;;59984:73:0::2;;;;;;;;;60081:1;60072:6;:10;60064:41;;;;-1:-1:-1::0;;;60064:41:0::2;;;;;;;;;60143:10;60120:34;::::0;;;:22;;;:34:::2;::::0;;;;;:44;-1:-1:-1;60120:44:0::2;60112:90;;;;-1:-1:-1::0;;;60112:90:0::2;;;;;;;;;60211:68;60239:10;60251:8;60261:9;60272:6;60211:27;:68::i;:::-;60328:17;60380:12;60388:3;;50589:6;60380:7;;:12;;;;:::i;:::-;60358:11;::::0;::::2;:17:::0;60348:28:::2;::::0;:5;;:28:::2;:9;:28;:::i;:::-;:45;;;;;60425:22:::0;;;;60348:45;;::::2;::::0;-1:-1:-1;60425:37:0::2;::::0;60348:45;60425:37:::2;:26;:37;:::i;:::-;60400:22:::0;;;:62;60469:21:::2;60493:20;:5:::0;60503:9;60493:20:::2;:9;:20;:::i;:::-;60469:44;;60548:13;60530:6;:14;;;:31;;60522:79;;;;-1:-1:-1::0;;;60522:79:0::2;;;;;;;;;60644:47;60667:8;60677:13;60644:22;:47::i;:::-;60743:12;::::0;::::2;::::0;:40:::2;::::0;-1:-1:-1;;;60743:40:0;;-1:-1:-1;;;;;60743:12:0;;::::2;::::0;:21:::2;::::0;:40:::2;::::0;60765:10:::2;::::0;60777:5;;60743:40:::2;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::2;5:2;60743:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;60743:40:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;60743:40:0;;;;;;;;;60735:74;;;;-1:-1:-1::0;;;60735:74:0::2;;;;;;;;;60869:8:::0;60850:17:::2;60838:10;-1:-1:-1::0;;;;;60823:86:0::2;-1:-1:-1::0;;;;;;;;;;;60879:9:0::2;60890:6;60898:5;60905:3;60823:86;;;;;;;;;;50435:117:::0;-1:-1:-1;;50435:117:0;:::o;52665:30::-;;;;:::o;56305:903::-;56422:7;56462:17;;;:7;:17;;;;;56488:31;56522:33;56470:8;56522:23;:33::i;:::-;56488:67;;56562:23;56588:47;50589:6;56599:29;56610:6;:11;;:17;;;56599:6;:10;;:29;;;;:::i;:::-;:35;;;;;56588:6;;56599:35;;56588:47;:10;:47;:::i;:::-;56562:73;;56642:27;56672:14;56687:9;56672:25;;;;;;;;;;;;;;56642:55;;56704:28;56735;50589:6;56735:19;:23;;:28;;;;:::i;:::-;56704:59;-1:-1:-1;56775:9:0;56770:267;56794:14;:21;56790:1;:25;56770:267;;;56840:9;56835:1;:14;56831:199;;56862:21;56886:14;56901:1;56886:17;;;;;;;;;;;;;;56862:41;;56937:83;56985:34;57003:15;56985:13;:17;;:34;;;;:::i;:::-;56937:39;:20;56962:13;56937:39;:24;:39;:::i;:::-;:47;:83;:47;:83;:::i;:::-;56914:106;;56831:199;;56817:3;;56770:267;;;;57074:1;57051:20;:24;57043:64;;;;-1:-1:-1;;;57043:64:0;;;;;;;;;57123:79;57168:33;:20;50589:6;57168:33;:28;:33;:::i;:::-;57123:40;:19;57147:15;57123:40;:23;:40;:::i;:::-;:44;:79;:44;:79;:::i;:::-;57116:86;56305:903;-1:-1:-1;;;;;;;;;56305:903:0:o;78666:177::-;78734:7;78774:17;;;:7;:17;;;;;78808:28;;;;78666:177::o;80704:393::-;80767:4;80804:17;;;:7;:17;;;;;80906:20;80890:12;;;;;;:36;;;;;;;;;80886:71;;80944:5;80937:12;;;;;80886:71;81067:17;;;:24;81036:27;;;;;:55;;;80704:393;-1:-1:-1;;80704:393:0:o;52722:34::-;;;-1:-1:-1;;;;;52722:34:0;;:::o;70167:1111::-;70226:8;70236:20;;53296:17;;;;:7;:17;;;;;:23;;;;;:32;;;;;;;;;53288:70;;;;-1:-1:-1;;;53288:70:0;;;;;;;;;70265:21:::1;70289:17:::0;;;:7:::1;:17;::::0;;;;70349:19:::1;70297:8:::0;70349:9:::1;:19::i;:::-;70408:10;70422:1;70385:34:::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;70377:86:::1;;;;-1:-1:-1::0;;;70377:86:0::1;;;;;;;;;70501:10;70478:34;::::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;::::1;;:43;70470:95;;;;-1:-1:-1::0;;;70470:95:0::1;;;;;;;;;70642:22;70667:33;70691:8;70667:23;:33::i;:::-;70765:10;70707:13;70742:34:::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;70642:58;;-1:-1:-1;70707:13:0;50589:6:::1;::::0;70723:54:::1;::::0;70642:58;;70723:54:::1;:18;:54;:::i;:::-;:60;;;;;;70707:76;;70859:5;70841:6;:14;;;:23;;70833:71;;;;-1:-1:-1::0;;;70833:71:0::1;;;;;;;;;70930:14;::::0;::::1;::::0;:25:::1;::::0;70949:5;70930:25:::1;:18;:25;:::i;:::-;70913:14;::::0;;::::1;:42:::0;;;;70985:10:::1;70962:34;::::0;;;:22:::1;::::0;;::::1;:34;::::0;;;;;;;:41;;-1:-1:-1;;70962:41:0::1;::::0;;::::1;::::0;;;71122:22:::1;::::0;::::1;:34:::0;;;;;;71017:172;;71095:8;;70962:22;;70985:10;-1:-1:-1;;;;;;;;;;;71017:172:0;::::1;::::0;71165:5;;71179:3:::1;::::0;71017:172:::1;;;;;;;;;;71206:12;::::0;::::1;::::0;:40:::1;::::0;-1:-1:-1;;;71206:40:0;;-1:-1:-1;;;;;71206:12:0;;::::1;::::0;:21:::1;::::0;:40:::1;::::0;71228:10:::1;::::0;71240:5;;71206:40:::1;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;71206:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;71206:40:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71206:40:0;;;;;;;;;71198:74;;;;-1:-1:-1::0;;;71198:74:0::1;;;;;;;;;53365:1;;;70167:1111:::0;;;:::o;67757:1086::-;67815:8;67825:20;;53296:17;;;;:7;:17;;;;;:23;;;;;:32;;;;;;;;;53288:70;;;;-1:-1:-1;;;53288:70:0;;;;;;;;;67854:21:::1;67878:17:::0;;;:7:::1;:17;::::0;;;;;;;67958:27;;;;67942:44;;:15:::1;::::0;::::1;:44:::0;;;;;68034:10:::1;68003:42:::0;;:30;;;:42;;;;;;67995:101:::1;;;;-1:-1:-1::0;;;67995:101:0::1;;;;;;;;;68141:10;68111:41;::::0;;;:29;;;:41:::1;::::0;;;;;::::1;;:50;68103:109;;;;-1:-1:-1::0;;;68103:109:0::1;;;;;;;;;68297:10;68250:13;68266:42:::0;;;:30;;;:42:::1;::::0;;;;;68366:14:::1;::::0;::::1;::::0;:23;-1:-1:-1;68366:23:0::1;68358:71;;;;-1:-1:-1::0;;;68358:71:0::1;;;;;;;;;68455:14;::::0;::::1;::::0;:25:::1;::::0;68474:5;68455:25:::1;:18;:25;:::i;:::-;68438:14;::::0;;::::1;:42:::0;;;;68517:10:::1;68487:41;::::0;;;:29;;;:41:::1;::::0;;;;:48;;-1:-1:-1;;68487:48:0::1;::::0;;::::1;::::0;;68626:8;68591:26:::1;68643:27:::0;;;;68572:10:::1;68679:42;::::0;;;:30;;;:42:::1;::::0;;;;;;;68549:205;;68572:10;;-1:-1:-1;;;;;;;;;;;68549:205:0;::::1;::::0;68679:42;68730:5;;68744:3:::1;::::0;68549:205:::1;;52630:30:::0;;;-1:-1:-1;;;;;52630:30:0;;:::o;78849:443::-;78938:7;79012:17;;;:7;:17;;;;;;;;79076;;;:24;79062:39;;;;;;;;;;;;;;;;78954:16;;79012:17;;78954:16;;79062:39;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;79062:39:0;-1:-1:-1;79036:65:0;-1:-1:-1;79115:9:0;79110:118;79134:17;;;:24;79130:28;;79110:118;;;79186:34;79208:8;79218:1;79186:21;:34::i;:::-;79174:6;79181:1;79174:9;;;;;;;;;;;;;;;;;:46;79160:3;;79110:118;;;;79244:33;79268:8;79244:23;:33::i;:::-;79236:50;-1:-1:-1;79279:6:0;-1:-1:-1;;78849:443:0;;;:::o;61016:3416::-;53088:17;;;;:7;:17;;;;;:35;61145:8;;53082:3;:41;:88;;;;-1:-1:-1;53154:16:0;53127:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;53082:88;53078:130;;;53181:19;53191:8;53181:9;:19::i;:::-;61163:8;61173:16:::1;::::0;53296:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;53288:70;;;;-1:-1:-1::0;;;53288:70:0::1;;;;;;;;;61198:21:::2;61222:17:::0;;;:7:::2;:17;::::0;;;;61256:9;61248:53:::2;;;;-1:-1:-1::0;;;61248:53:0::2;;;;;;;;;61310:23;61342:31;61376:33;61400:8;61376:23;:33::i;:::-;61342:67;;61416:32;61465:14;:21;61451:36;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;::::0;-1:-1;61451:36:0::2;-1:-1:-1::0;61529:16:0::2;::::0;::::2;::::0;61416:71;;-1:-1:-1;61494:18:0::2;::::0;61529:20;61525:1559:::2;;61568:19:::0;;:24;61560:93:::2;;;;-1:-1:-1::0;;;61560:93:0::2;;;;;;;;;61759:9;61754:183;61778:14;:21;61774:1;:25;61754:183;;;61817:21;61841:14;61856:1;61841:17;;;;;;;;;;;;;;61817:41;;61886:13;61873:10;:26;61869:58;;;61914:13;61901:26;;61869:58;-1:-1:-1::0;61801:3:0::2;;61754:183;;;-1:-1:-1::0;61952:9:0::2;61947:186;61971:14;:21;61967:1;:25;61947:186;;;62010:17;62061:10;62030:28;62040:14;62055:1;62040:17;;;;;;;;;;;;;;62030:5;:9;;:28;;;;:::i;:::-;:41;;;;;;::::0;-1:-1:-1;62103:20:0::2;:5:::0;62030:41;62103:20:::2;:9;:20;:::i;:::-;62082:15;62098:1;62082:18;;;;;;;;;::::0;;::::2;::::0;;;;;:41;-1:-1:-1;61994:3:0::2;;61947:186;;;;62191:10;62161:27;62171:6;:16;;;62161:5;:9;;:27;;;;:::i;:::-;:40;;;;;;62143:58;;62245:71;62263:8;62273:15;62290:25;62245:17;:71::i;:::-;;61525:1559;;;62386:19:::0;;:23;62382:608:::2;;62453:14;:21;62430:12;:19;:44;62422:98;;;;-1:-1:-1::0;;;62422:98:0::2;;;;;;;;;62533:15;::::0;62563:152:::2;62587:12;:19;62583:1;:23;62563:152;;;62626:12;62641;62654:1;62641:15;;;;;;;;;;;;;;62626:30;;62683:4;62673:7;:14;62669:34;;;62699:4;62689:14;;62669:34;-1:-1:-1::0;62608:3:0::2;;62563:152;;;-1:-1:-1::0;62732:9:0::2;62727:254;62751:12;:19;62747:1;:23;62727:254;;;62790:17;62839:7;62810:26;62820:12;62833:1;62820:15;;;;;;;;;;;;;;62810:5;:9;;:26;;;;:::i;:::-;:36;;;;;;62790:56;;62879:1;62867:9;:13;62859:56;;;;-1:-1:-1::0;;;62859:56:0::2;;;;;;;;;62949:20;:5:::0;62959:9;62949:20:::2;:9;:20;:::i;:::-;62928:15;62944:1;62928:18;;;;;;;;;::::0;;::::2;::::0;;;;;:41;-1:-1:-1;62772:3:0::2;;62727:254;;;;62382:608;;63071:5;63053:23;;61525:1559;63134:16;::::0;::::2;::::0;:37:::2;::::0;63155:15;63134:37:::2;:20;:37;:::i;:::-;63115:16;::::0;::::2;:56:::0;63238:10:::2;63215:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;;:55:::2;::::0;63254:15;63215:55:::2;:38;:55;:::i;:::-;63201:10;63178:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;:92;63279:34:::2;63297:8:::0;63307:5;63279:17:::2;:34::i;:::-;63387:9;63382:609;63406:15;:22;63402:1;:26;63382:609;;;63469:1;63448:15;63464:1;63448:18;;;;;;;;;;;;;;:22;63444:540;;;63483:20;63506:6;:22;;;63483:45;;63539:21;63563:6;:15;;:18;63579:1;63563:18;;;;;;;;;;;:25;;:35;;;63539:59;;63609:74;63639:10;63651:8;63661:1;63664:15;63680:1;63664:18;;;;;;;;;;;;;;63609:29;:74::i;:::-;63778:8:::0;63749:16:::2;63726:10;-1:-1:-1::0;;;;;63699:275:0::2;-1:-1:-1::0;;;;;;;;;;;63799:1:0::2;63813:15;63829:1;63813:18;;;;;;;;;;;;;;63844:85;63906:6;:22;;;63844:57;63882:15;63898:1;63882:18;;;;;;;;;;;;;;63845:31;63862:13;63845:12;:16;;:31;;;;:::i;:::-;63844:37:::0;:57:::2;:37;:57;:::i;:85::-;63960:3;63699:275;;;;;;;;;;;;;;;;;;63444:540;;;63430:3;;63382:609;;;;63999:22;64024:33;64048:8;64024:23;:33::i;:::-;63999:58:::0;-1:-1:-1;64064:22:0::2;50589:6;64089:35;63999:58:::0;64108:15;64089:35:::2;:18;:35;:::i;:::-;:41;;;;;;64064:66;;64147:6;:12;;;;;;;;;;-1:-1:-1::0;;;;;64147:12:0::2;-1:-1:-1::0;;;;;64147:25:0::2;;64173:10;64193:4;64200:5;64147:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::2;5:2;64147:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;64147:59:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64147:59:0;;;;;;;;;64139:93;;;;-1:-1:-1::0;;;64139:93:0::2;;;;;;;;;64300:8:::0;64273:25:::2;64261:10;-1:-1:-1::0;;;;;64246:104:0::2;-1:-1:-1::0;;;;;;;;;;;64310:1:0::2;64313:15;64330:14;64346:3;64246:104;;;;;;;;;;;;;;;;;;64378:8;-1:-1:-1::0;;;;;;;;;;;64388:6:0::2;:16;;;64406:14;64422:3;64362:64;;;;;;;;;;;;;;;;;53365:1;;;;;;;53214::::1;;61016:3416:::0;;;;:::o;52496:26::-;;;;:::o;81740:721::-;81829:7;81869:17;;;:7;:17;;;;;81915:20;81899:12;;;;;;:36;;;;;;;;;:65;;;;;81940:24;81955:8;81940:14;:24::i;:::-;81939:25;81899:65;81895:195;;;82045:27;;;;82032:40;;:50;;82081:1;82032:50;;;50589:6;82032:50;82025:57;;;;;81895:195;82098:28;;82137:154;82161:17;;;:24;82157:28;;82137:154;;;82224:59;82249:33;82270:8;82280:1;82249:20;:33::i;:::-;82224:20;;:59;:24;:59;:::i;:::-;82201:82;-1:-1:-1;82187:3:0;;82137:154;;;;82379:76;82434:20;82379:50;50589:6;82379:41;82400:8;82410:9;82379:20;:41::i;:76::-;82372:83;81740:721;-1:-1:-1;;;;;81740:721:0:o;64491:2464::-;53088:17;;;;:7;:17;;;;;:35;64585:8;;53082:3;:41;:88;;;;-1:-1:-1;53154:16:0;53127:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;53082:88;53078:130;;;53181:19;53191:8;53181:9;:19::i;:::-;64608:8;64618:16:::1;::::0;53296:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;53288:70;;;;-1:-1:-1::0;;;53288:70:0::1;;;;;;;;;64646:21:::2;64670:17:::0;;;:7:::2;:17;::::0;;;;;;;64727:10:::2;64704:34:::0;;:22:::2;::::0;::::2;:34:::0;;;;;;;:44;-1:-1:-1;64704:44:0::2;64696:90;;;;-1:-1:-1::0;;;64696:90:0::2;;;;;;;;;64827:19;64837:8;64827:9;:19::i;:::-;64886:65;64904:8;64914:6;64922:28;64886:17;:65::i;:::-;;64960:31;64994:33;65018:8;64994:23;:33::i;:::-;64960:67;;65034:28;65079:14;:21;65065:36;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;::::0;-1:-1;65065:36:0::2;-1:-1:-1::0;65034:67:0;-1:-1:-1;;;65108:18:0::2;65238:177;65262:14;:21;65258:1;:25;65238:177;;;65299:21;65323:14;65338:1;65323:17;;;;;;;;;;;;;;65299:41;;65366:13;65353:10;:26;65349:58;;;65394:13;65381:26;;65349:58;-1:-1:-1::0;65285:3:0::2;;65238:177;;;-1:-1:-1::0;65476:16:0::2;::::0;::::2;::::0;65423:23:::2;::::0;65449:44:::2;::::0;:22:::2;:6:::0;65460:10;65449:22:::2;:10;:22;:::i;:44::-;65423:70:::0;-1:-1:-1;65507:9:0::2;65502:195;65526:14;:21;65522:1;:25;65502:195;;;65612:6;:16;;;65580:29;65602:6;65580:14;65595:1;65580:17;;;;;;;;;;;;;;:21;;:29;;;;:::i;:::-;:48;;;;;;65563:11;65575:1;65563:14;;;;;;;;;;;;;:65;;;::::0;::::2;65654:35;65673:15;65654:11;65666:1;65654:14;;;;;;;;;;;;;;:18;;:35;;;;:::i;:::-;65637:11;65649:1;65637:14;;;;;;;;;::::0;;::::2;::::0;;;;;:52;65549:3:::2;;65502:195;;;;65744:49;65767:8;65777:15;65744:22;:49::i;:::-;65819:16;::::0;::::2;::::0;:28:::2;::::0;65840:6;65819:28:::2;:20;:28;:::i;:::-;65800:16;::::0;::::2;:47:::0;65968:10:::2;65945:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;;:46:::2;::::0;65984:6;65945:46:::2;:38;:46;:::i;:::-;65931:10;65908:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;:83;;;;66000:594:::2;66024:14;:21;66020:1;:25;66000:594;;;66082:1;66065:11;66077:1;66065:14;;;;;;;;;;;;;;:18;66061:526;;;66119:22;::::0;;::::2;::::0;66096:20:::2;66176:18:::0;;;:15:::2;::::0;::::2;:18;::::0;;;;:35;;;;66279:14;;66224:70:::2;::::0;66254:10:::2;::::0;66266:8;;66192:1;;66279:11;;66192:1;;66279:14;::::2;;;;66224:70;66389:8:::0;66360:16:::2;66337:10;-1:-1:-1::0;;;;;66310:267:0::2;-1:-1:-1::0;;;;;;;;;;;66410:1:0::2;66424:11;66436:1;66424:14;;;;;;;;;;;;;;66451:81;66509:6;:22;;;66451:53;66489:11;66501:1;66489:14;;;;;;;66451:81;66563:3;66310:267;;;;;;;;;;;;;;;;;;66061:526;;;66047:3;;66000:594;;;-1:-1:-1::0;66665:12:0::2;::::0;::::2;::::0;:50:::2;::::0;-1:-1:-1;;;66665:50:0;;-1:-1:-1;;;;;66665:12:0;;::::2;::::0;:21:::2;::::0;:50:::2;::::0;66687:10:::2;::::0;66699:15;;66665:50:::2;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::2;5:2;66665:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;66665:50:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;66665:50:0;;;;;;;;;66657:84;;;;-1:-1:-1::0;;;66657:84:0::2;;;;;;;;;66812:8:::0;66782:28:::2;66770:10;-1:-1:-1::0;;;;;66755:99:0::2;-1:-1:-1::0;;;;;;;;;;;66822:1:0::2;66825:6;66833:15;66850:3;66755:99;;;;;;;;;;;;;;;;;;66882:8;-1:-1:-1::0;;;;;;;;;;;66892:6:0::2;:16;;;66910:33;66934:8;66910:23;:33::i;:::-;66945:3;66866:83;;;;;;;;;;;;;;;;;53365:1;;;;;53214::::1;;64491:2464:::0;;;:::o;77178:228::-;77268:7;77308:17;;;:7;:17;;;;;;;;77383:16;;;;-1:-1:-1;;;;;77341:28:0;;;;:22;;;:28;;;;;;;77308:17;;77341:59;;:37;;50589:6;77341:37;:32;:37;:::i;:59::-;77334:66;77178:228;-1:-1:-1;;;;77178:228:0:o;71364:585::-;71415:21;71439:17;;;:7;:17;;;;;;71489:42;71447:8;71520:10;71489:20;:42::i;:::-;71465:66;-1:-1:-1;71544:17:0;;71540:215;;71626:10;71606:31;;;;:19;;;:31;;;;;;:50;;71642:13;71606:50;:35;:50;:::i;:::-;71592:10;71572:31;;;;:19;;;:31;;;;;;;:84;;;;71673:12;;;;:48;;-1:-1:-1;;;71673:48:0;;-1:-1:-1;;;;;71673:12:0;;;;:21;;:48;;71707:13;;71673:48;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71673:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71673:48:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71673:48:0;;;;;;;;;71665:82;;;;-1:-1:-1;;;71665:82:0;;;;;;;;;71841:8;71810:22;71791:10;71858:1;71868:34;;;:22;;;:34;;;;;;;71768:175;;-1:-1:-1;;;;;;;;;;;71768:175:0;;;71858:1;;71911:13;;71933:3;;71768:175;;;;;;;;;;71364:585;;;:::o;75951:503::-;76058:7;76132:17;;;:7;:17;;;;;;;;76203;;;:24;76189:39;;;;;;;;;;;;;;;;76074:16;;76132:17;;76074:16;;76189:39;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;76189:39:0;-1:-1:-1;76156:72:0;-1:-1:-1;76242:9:0;76237:130;76261:17;;;:24;76257:28;;76237:130;;;76320:18;;;;:15;;;:18;;;;;;;;-1:-1:-1;;;;;76320:39:0;;;;:33;;:39;;;;;;76301:16;;:13;;76336:1;;76301:16;;;;;;;;;;;;;;;:58;76287:3;;76237:130;;;-1:-1:-1;;;;;;76391:28:0;;;;;;;;:22;;;;;:28;;;;;;;;;-1:-1:-1;;;75951:503:0:o;80386:312::-;80459:6;80498:17;;;:7;:17;;;;;80594:20;80578:12;;;;;;:36;;;;;;;;;80574:68;;-1:-1:-1;;80625:9:0;;;;;80574:68;80664:27;;;;80386:312;-1:-1:-1;;80386:312:0:o;77915:441::-;78002:11;78134:17;;;:7;:17;;;;;;;78176:12;;;;78197:24;;78230:16;;;;78255:14;;;;78278:22;;;;78002:11;;;;;;;;;;78134:17;;78176:12;;;;;78197:24;;78230:16;;78309:34;78142:8;78309:24;:34::i;:::-;78160:190;;;;-1:-1:-1;78160:190:0;;-1:-1:-1;78160:190:0;-1:-1:-1;78160:190:0;-1:-1:-1;78160:190:0;;-1:-1:-1;77915:441:0;-1:-1:-1;;;77915:441:0:o;50559:36::-;50589:6;50559:36;:::o;57316:924::-;57434:30;57497:17;;;:7;:17;;;;;57523:31;57557:33;57505:8;57557:23;:33::i;:::-;57648:11;;;:17;57523:67;;-1:-1:-1;57597:22:0;;57640:26;;50589:6;;57640:26;:7;:26;:::i;:::-;57622:15;:6;50589;57622:15;:10;:15;:::i;:::-;:44;;;;;;57597:69;;57673:28;57704:14;57719:9;57704:25;;;;;;;;;;;;;;57673:56;;57736:28;57767:29;50589:6;57767:20;:24;;:29;;;;:::i;:::-;57736:60;-1:-1:-1;57808:9:0;57803:266;57827:14;:21;57823:1;:25;57803:266;;;57873:9;57868:1;:14;57864:198;;57895:21;57919:14;57934:1;57919:17;;;;;;;;;;;;;;57895:41;;57970:82;58018:33;58036:14;58018:13;:17;;:33;;;;:::i;57970:82::-;57947:105;;57864:198;;57850:3;;57803:266;;;;58106:1;58083:20;:24;58075:64;;;;-1:-1:-1;;;58075:64:0;;;;;;;;;58155:79;58213:20;58155:53;58174:33;:20;50589:6;58174:33;:28;:33;:::i;:::-;58155:14;;:53;:18;:53;:::i;79298:1082::-;79370:7;79410:17;;;:7;:17;;;;;79456:20;79440:12;;;;;;:36;;;;;;;;;:65;;;;;79481:24;79496:8;79481:14;:24::i;:::-;79480:25;79440:65;79436:315;;;79726:16;;;;79667:27;;;;79651:44;;;;:15;;;:44;;;;;:61;;;:92;;79726:16;79651:70;;50589:6;79651:70;:65;:70;:::i;:92::-;79644:99;;;;;79436:315;50589:6;79879:27;;79955:294;79979:17;;;:24;79975:28;;79955:294;;;80019:29;80051:18;;;:15;;;:18;;;;;80126:24;;;;80102:58;;50589:6;;80102:49;;:19;;:49;:23;:49;:::i;:58::-;80080:80;;80187:54;80207:33;80228:8;80238:1;80207:20;:33::i;:::-;80187:15;;:54;:19;:54;:::i;:::-;80169:72;-1:-1:-1;;80005:3:0;;79955:294;;;;80264:110;80357:6;:16;;;80264:88;50589:6;80264:79;80327:15;80264:58;50589:6;80264:49;80288:6;:17;;:24;;;;80264:19;:23;;:49;;;;:::i;52546:18::-;;;;:::o;77817:92::-;77862:16;77894:9;77887:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77817:92;:::o;68924:1154::-;69022:8;69032:20;;53296:17;;;;:7;:17;;;;;:23;;;;;:32;;;;;;;;;53288:70;;;;-1:-1:-1;;;53288:70:0;;;;;;;;;69064:21:::1;69088:17:::0;;;:7:::1;:17;::::0;;;;;;;69144:26;;;:15:::1;::::0;::::1;:26:::0;;;;;69210:10:::1;69187:34:::0;;:22;;;:34;;;;;;69179:84:::1;;;;-1:-1:-1::0;;;69179:84:0::1;;;;;;;;;69306:10;69278:39;::::0;;;:27;;;:39:::1;::::0;;;;;::::1;;:48;69270:96;;;;-1:-1:-1::0;;;69270:96:0::1;;;;;;;;;69438:13;69454:42;69476:8;69486:9;69454:21;:42::i;:::-;69552:10;69503:13;69529:34:::0;;;:22;;;:34:::1;::::0;;;;;69438:58;;-1:-1:-1;69503:13:0;69519:54:::1;::::0;50589:6:::1;::::0;69519:45:::1;::::0;69438:58;;69519:45:::1;:9;:45;:::i;:54::-;69503:70;;69649:5;69631:6;:14;;;:23;;69623:71;;;;-1:-1:-1::0;;;69623:71:0::1;;;;;;;;;69720:14;::::0;::::1;::::0;:25:::1;::::0;69739:5;69720:25:::1;:18;:25;:::i;:::-;69703:14;::::0;;::::1;:42:::0;;;;69780:10:::1;69752:39;::::0;;;:27;;;:39:::1;::::0;;;;:46;;-1:-1:-1;;69752:46:0::1;::::0;;::::1;::::0;;69887:8;69854:24:::1;69835:10;69922:34;::::0;;;:22;;;:34:::1;::::0;;;;;;;69812:177;;-1:-1:-1;;;;;;;;;;;69812:177:0;::::1;::::0;69904:9;;69922:34;69965:5;;69979:3:::1;::::0;69812:177:::1;;;;;;;;;;70006:12;::::0;::::1;::::0;:40:::1;::::0;-1:-1:-1;;;70006:40:0;;-1:-1:-1;;;;;70006:12:0;;::::1;::::0;:21:::1;::::0;:40:::1;::::0;70028:10:::1;::::0;70040:5;;70006:40:::1;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;70006:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;70006:40:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70006:40:0;;;;;;;;;69998:74;;;;-1:-1:-1::0;;;69998:74:0::1;;;;;;;;;53365:1;;;;68924:1154:::0;;;;:::o;54591:1635::-;54687:7;53678:15;;53697:1;53678:20;:85;;;-1:-1:-1;53748:15:0;;53702:20;;:42;;-1:-1:-1;;;53702:42:0;;-1:-1:-1;;;;;53702:20:0;;;;:30;;:42;;53733:10;;53702:42;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53702:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53702:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53702:42:0;;;;;;;;;:61;;53678:85;53662:161;;;;-1:-1:-1;;;53662:161:0;;;;;;;;;54722:11:::1;::::0;54703:16:::1;27:10:-1::0;;39:1:::1;23:18:::0;;::::1;45:23:::0;;54740:24:0;;;::::1;::::0;;;54797:17;;;54740:24:::1;54797:17:::0;;;;54831:10;::::1;54823:48;;;;-1:-1:-1::0;;;54823:48:0::1;;;;;;;;;54902:3;54886:4;:13;;;:19;54878:74;;;;-1:-1:-1::0;;;54878:74:0::1;;;;;;;;;54994:1;54967:15;::::0;;;::::1;::::0;::::1;;;;-1:-1:-1::0;;;;;54967:29:0::1;;;54959:68;;;;-1:-1:-1::0;;;54959:68:0::1;;;;;;;;;55059:6;55042:4;:13;;;:23;;55034:87;;;;-1:-1:-1::0;;;55034:87:0::1;;;;;;;;;55145:10;::::0;;;::::1;::::0;::::1;;;;55130:12;::::0;::::1;:25:::0;;-1:-1:-1;;;;;;55130:25:0::1;-1:-1:-1::0;;;;;55130:25:0;;;::::1;::::0;;;::::1;::::0;;55189:13:::1;::::0;::::1;;55162:40:::0;;55209:12:::1;::::0;::::1;:31:::0;;-1:-1:-1;;55209:31:0::1;::::0;;55267:3:::1;::::0;55247:11:::1;::::0;::::1;:23:::0;-1:-1:-1;;55355:27:0;;;:42;-1:-1:-1;55439:206:0::1;55463:4;:13;;;55459:1;:17;55439:206;;;55492:17;::::0;::::1;27:10:-1::0;;39:1:::1;23:18:::0;;::::1;45:23:::0;;-1:-1;55492:25:0;;;::::1;::::0;;;;;::::1;::::0;;;55558:18;;;:15:::1;::::0;::::1;:18:::0;;;;;;;55587:27;;;55623:10;::::1;:14:::0;;;55478:3:::1;55439:206;;;-1:-1:-1::0;55705:15:0::1;::::0;-1:-1:-1;;;;;55705:15:0::1;55691:47;55747:1;55757:4:::0;:13:::1;::::0;::::1;30:25:-1::0;::::1;-1:-1:::0;;100:14:::1;96:29:::0;;::::1;92:48:::0;68:73;::::1;58:2;;155:1;152::::0;145:12:::1;58:2;174:33:::0;;::::1;69:4;55:19:::0;::::1;::::0;-1:-1;16:22:::1;-1:-1:::0;;;;;82:30;::::1;79:2;;;125:1;122::::0;115:12:::1;79:2;155:14;151:38:::0;;::::1;137:53:::0;::::1;134:2;;;203:1;200::::0;193:12:::1;134:2;55779:15:0;::::0;;;::::1;::::0;::::1;;;;55810;;55842:4;:13;;;55865:1;55875::::0;55691:192:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;55691:192:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;55691:192:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;55691:192:0;;;;;;;;;-1:-1:-1::0;55892:53:0::1;55905:8:::0;55915:10;::::1;:4:::0;55927:17:::1;::::0;::::1;30:25:-1::0;::::1;-1:-1:::0;;100:14:::1;96:29:::0;;::::1;92:48:::0;68:73;::::1;58:2;;155:1;152::::0;145:12:::1;58:2;174:33:::0;;::::1;69:4;55:19:::0;::::1;::::0;-1:-1;16:22:::1;-1:-1:::0;;;;;82:30;::::1;79:2;;;125:1;122::::0;115:12:::1;79:2;183:4;175:6;171:17;155:14;151:38;141:8;137:53;134:2;;;203:1;200::::0;193:12:::1;134:2;55892:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::1;74:27:::0;;;;-1:-1;55892:12:0::1;::::0;-1:-1:-1;;;55892:53:0:i:1;:::-;55991:38;56020:8;55991:28;:38::i;:::-;56067:8:::0;56055:10:::1;56041:77;56077:13;::::0;::::1;;:4:::0;56092:13:::1;::::0;::::1;30:25:-1::0;::::1;-1:-1:::0;;100:14:::1;96:29:::0;;::::1;92:48:::0;68:73;::::1;58:2;;155:1;152::::0;145:12:::1;58:2;174:33:::0;;::::1;69:4;55:19:::0;::::1;::::0;-1:-1;16:22:::1;-1:-1:::0;;;;;82:30;::::1;79:2;;;125:1;122::::0;115:12:::1;79:2;155:14;151:38:::0;;::::1;137:53:::0;::::1;134:2;;;203:1;200::::0;193:12:::1;134:2;56107:4:0::0;:10:::1;::::0;::::1;30:25:-1::0;::::1;-1:-1:::0;;100:14:::1;96:29:::0;;::::1;92:48:::0;68:73;::::1;58:2;;155:1;152::::0;145:12:::1;58:2;174:33:::0;;::::1;69:4;55:19:::0;::::1;::::0;-1:-1;16:22:::1;-1:-1:::0;;;;;82:30;::::1;79:2;;;125:1;122::::0;115:12:::1;79:2;155:14;151:38:::0;;::::1;137:53:::0;::::1;134:2;;;203:1;200::::0;193:12:::1;134:2;56041:77:0;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;56181:11:0::1;::::0;;56195:1:::1;56181:15;56167:29:::0;;56212:8;54591:1635;-1:-1:-1;;54591:1635:0:o;82467:390::-;82580:7;82661:17;;;:7;:17;;;;;;;;82717:26;;;:15;;;:26;;;;;82580:7;;;;82760:42;82669:8;82733:9;82760:21;:42::i;:::-;82804:24;;;;:14;;;;82830:20;82752:99;;82804:24;;-1:-1:-1;82830:20:0;-1:-1:-1;82467:390:0;-1:-1:-1;;;;82467:390:0:o;77412:399::-;77495:7;77535:17;;;:7;:17;;;;;;;;77642:16;;;;-1:-1:-1;;;;;77608:28:0;;;;:22;;;:28;;;;;;;77581:22;;;;77535:17;;77495:7;;77581:78;;:56;;:22;:56;:26;:56;:::i;:78::-;-1:-1:-1;;;;;77702:25:0;;;;;;:19;;;:25;;;;;;77561:98;;-1:-1:-1;77702:37:0;-1:-1:-1;77698:51:0;;;77748:1;77741:8;;;;;;77698:51;-1:-1:-1;;;;;77779:25:0;;;;;;:19;;;:25;;;;;;77765:40;;:9;;:40;:13;:40;:::i;72777:159::-;72829:21;72853:17;;;:7;:17;;;;;72912:12;;;;;;72904:21;;;;;;;;72928:1;72904:25;72892:38;;;;;;;;72877:12;;;:53;;-1:-1:-1;;72877:53:0;;;;;;;;;;;;;;;;72777:159;;:::o;45350:220::-;45408:7;45432:6;45428:20;;-1:-1:-1;45447:1:0;45440:8;;45428:20;45471:5;;;45475:1;45471;:5;:1;45495:5;;;;;:10;45487:56;;;;-1:-1:-1;;;45487:56:0;;;;;;;;;45561:1;45350:220;-1:-1:-1;;;45350:220:0:o;44471:179::-;44529:7;44561:5;;;44585:6;;;;44577:46;;;;-1:-1:-1;;;44577:46:0;;;;;;;;44933:158;44991:7;45024:1;45019;:6;;45011:49;;;;-1:-1:-1;;;45011:49:0;;;;;;;;;-1:-1:-1;45078:5:0;;;44933:158::o;73468:581::-;73544:21;73568:17;;;:7;:17;;;;;;73594:398;73618:17;;;:24;73614:28;;73594:398;;;73658:29;73690:18;;;:15;;;:18;;;;;73746:24;;;;:36;;73775:6;73746:36;:28;:36;:::i;:::-;73719:24;;;:63;:14;;;73814:20;:32;;73839:6;73814:32;:24;:32;:::i;:::-;73791:14;;;:55;73950:22;;;;:34;;73977:6;73950:34;:26;:34;:::i;:::-;73925:22;;;:59;-1:-1:-1;73644:3:0;;73594:398;;;-1:-1:-1;74017:14:0;;;;:26;;74036:6;74017:26;:18;:26;:::i;:::-;74000:14;;;;:43;-1:-1:-1;;73468:581:0:o;74768:526::-;74914:21;74938:17;;;:7;:17;;;;;;;;74994:26;;;:15;;;:26;;;;;-1:-1:-1;;;;;75112:28:0;;;;:22;;;:28;;;;;;:40;;75145:6;75112:40;:32;:40;:::i;:::-;-1:-1:-1;;;;;75081:28:0;;;;;;:22;;;:28;;;;;:71;75186:24;;;;:36;;75215:6;75186:36;:28;:36;:::i;:::-;75159:24;;;;:63;;;;75254:22;;;:34;;75281:6;75254:34;:26;:34;:::i;:::-;75229:6;:22;;:59;;;;74768:526;;;;;;:::o;73000:415::-;73071:21;73095:17;;;:7;:17;;;;;;73121:149;73145:17;;;:24;73141:28;;73121:149;;;73219:1;73209:8;73190:72;73222:34;73244:8;73254:1;73222:21;:34::i;:::-;73258:3;73190:72;;;;;;;;;;;;;;;;73171:3;;73121:149;;;;73342:8;-1:-1:-1;;;;;;;;;;;73352:6:0;:16;;;73370:33;73394:8;73370:23;:33::i;:::-;73405:3;73326:83;;;;;;;;;;;;;;;;;73000:415;;:::o;46048:153::-;46106:7;46138:1;46134;:5;46126:44;;;;-1:-1:-1;;;46126:44:0;;;;;;;;;46192:1;46188;:5;;;;;;;46048:153;-1:-1:-1;;;46048:153:0:o;75367:507::-;75511:21;75535:17;;;:7;:17;;;;;;;;75591:26;;;:15;;;:26;;;;;-1:-1:-1;;;;;75692:28:0;;;;:22;;;:28;;;;;;:40;;75725:6;75692:40;:32;:40;:::i;:::-;-1:-1:-1;;;;;75661:28:0;;;;;;:22;;;:28;;;;;:71;75766:24;;;;:36;;75795:6;75766:36;:28;:36;:::i;:::-;75739:24;;;;:63;;;;75834:22;;;:34;;75861:6;75834:34;:26;:34;:::i;74107:593::-;74188:21;74212:17;;;:7;:17;;;;;;74238:405;74262:17;;;:24;74258:28;;74238:405;;;74302:29;74334:18;;;:15;;;:18;;;;;74390:24;;;;:36;;74419:6;74390:36;:28;:36;:::i;:::-;74363:24;;;:63;:14;;;74458:20;:32;;74483:6;74458:32;:24;:32;:::i;:::-;74435:14;;;:55;74601:22;;;;:34;;74628:6;74601:34;:26;:34;:::i;:::-;74576:22;;;:59;-1:-1:-1;74288:3:0;;74238:405;;;-1:-1:-1;74668:14:0;;;;:26;;74687:6;74668:26;:18;:26;:::i;82863:366::-;82961:21;82985:17;;;:7;:17;;;;;;;;;83051;;;:24;83037:39;;;;;;;;;;;;;;;;82936:16;;82985:17;;82936:16;;83037:39;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;83037:39:0;-1:-1:-1;83011:65:0;-1:-1:-1;83088:9:0;83083:119;83107:17;;;:24;83103:28;;83083:119;;;83159:18;;;;:15;;;:18;;;;;:35;;;83147:9;;:6;;83175:1;;83147:9;;;;;;;;;;;;;;;:47;83133:3;;83083:119;;;-1:-1:-1;83217:6:0;82863:366;-1:-1:-1;;;82863:366:0:o;49324:138::-;49386:7;49406:5;;49402:35;;49431:1;49426;49422;:5;49421:11;;;;;;49436:1;49420:17;49413:24;;;;72045:681;72173:7;72213:17;;;:7;:17;;;;;72308:16;;;;72280:22;;;;72173:7;;72260:65;;:43;;:15;;:43;:19;:43;:::i;:65::-;72239:86;-1:-1:-1;72348:25:0;72338:6;:35;;;;;;;;;72334:387;;;72409:22;;;;:38;;72436:10;72409:38;:26;:38;:::i;:::-;72384:22;;;:63;72510:10;72490:31;;;;:19;;;:31;;;;;;:47;;72526:10;72490:47;:35;:47;:::i;:::-;72476:10;72456:31;;;;:19;;;:31;;;;;:81;72334:387;;;72585:22;;;;:38;;72612:10;72585:38;:26;:38;:::i;:::-;72560:22;;;:63;72686:10;72666:31;;;;:19;;;:31;;;;;;:47;;72702:10;72666:47;:35;:47;:::i;:::-;72652:10;72632:31;;;;:19;;;:31;;;;;:81;72334:387;72045:681;;;;;;;:::o;1818:241:-1:-;;1922:2;1910:9;1901:7;1897:23;1893:32;1890:2;;;-1:-1;;1928:12;1890:2;85:6;72:20;97:33;124:5;97:33;;2066:257;;2178:2;2166:9;2157:7;2153:23;2149:32;2146:2;;;-1:-1;;2184:12;2146:2;956:6;950:13;44191:5;41820:13;41813:21;44169:5;44166:32;44156:2;;-1:-1;;44202:12;2330:263;;2445:2;2433:9;2424:7;2420:23;2416:32;2413:2;;;-1:-1;;2451:12;2413:2;-1:-1;1088:13;;2407:186;-1:-1;2407:186;2874:399;;3014:2;3002:9;2993:7;2989:23;2985:32;2982:2;;;-1:-1;;3020:12;2982:2;3065:31;;-1:-1;;;;;3105:30;;3102:2;;;-1:-1;;3138:12;3102:2;3240:6;3229:9;3225:22;1485:3;1476:6;1471:3;1467:16;1463:26;1460:2;;;-1:-1;;1492:12;3280:241;;3384:2;3372:9;3363:7;3359:23;3355:32;3352:2;;;-1:-1;;3390:12;3352:2;-1:-1;1607:20;;3346:175;-1:-1;3346:175;3798:366;;;3919:2;3907:9;3898:7;3894:23;3890:32;3887:2;;;-1:-1;;3925:12;3887:2;1620:6;1607:20;3977:63;;4077:2;4120:9;4116:22;72:20;97:33;124:5;97:33;;;4085:63;;;;3881:283;;;;;;4171:366;;;4292:2;4280:9;4271:7;4267:23;4263:32;4260:2;;;-1:-1;;4298:12;4260:2;-1:-1;;1607:20;;;4450:2;4489:22;;;1607:20;;-1:-1;4254:283;4544:627;;;;4707:2;4695:9;4686:7;4682:23;4678:32;4675:2;;;-1:-1;;4713:12;4675:2;1607:20;;;-1:-1;4865:2;4904:22;;;1607:20;;-1:-1;5001:2;4986:18;;4973:32;-1:-1;;;;;5014:30;;;5011:2;;;-1:-1;;5047:12;5011:2;5138:6;5127:9;5123:22;277:3;270:4;262:6;258:17;254:27;244:2;;-1:-1;;285:12;244:2;332:6;319:20;305:34;;5025:18;40720:6;40717:30;40714:2;;;-1:-1;;40750:12;40714:2;4865;40787:6;40783:17;;;354:80;4865:2;40783:17;40848:15;354:80;;;462:21;;;519:14;;;;494:17;;;599:27;;;;;596:36;-1:-1;593:2;;;-1:-1;;635:12;593:2;-1:-1;661:10;;655:206;680:6;677:1;674:13;655:206;;;1607:20;;748:50;;702:1;695:9;;;;;812:14;;;;840;;655:206;;;659:14;5067:88;;;;;;;;;4669:502;;;;;;5178:491;;;;5316:2;5304:9;5295:7;5291:23;5287:32;5284:2;;;-1:-1;;5322:12;5284:2;-1:-1;;1607:20;;;5474:2;5513:22;;1607:20;;-1:-1;5582:2;5621:22;;;1607:20;;5278:391;-1:-1;5278:391;5676:617;;;;;5831:3;5819:9;5810:7;5806:23;5802:33;5799:2;;;-1:-1;;5838:12;5799:2;-1:-1;;1607:20;;;5990:2;6029:22;;1607:20;;-1:-1;6098:2;6137:22;;1607:20;;6206:2;6245:22;1607:20;;-1:-1;5793:500;-1:-1;5793:500;6782:690;;6975:5;41141:12;41428:6;41423:3;41416:19;41465:4;;41460:3;41456:14;6987:93;;41465:4;7151:5;40995:14;-1:-1;7190:260;7215:6;7212:1;7209:13;7190:260;;;7276:13;;7662:37;;6454:14;;;;41271;;;;7237:1;7230:9;7190:260;;;-1:-1;7456:10;;6906:566;-1:-1;;;;;6906:566;8471:296;;41428:6;41423:3;41416:19;43695:6;43690:3;41465:4;41460:3;41456:14;43672:30;-1:-1;41465:4;43742:6;41460:3;43733:16;;43726:27;41465:4;43851:7;;43855:2;8753:6;43835:14;43831:28;41460:3;8722:39;;8715:46;;8569:198;;;;;;19651:213;-1:-1;;;;;42321:54;;;;6702:37;;19769:2;19754:18;;19740:124;20107:451;-1:-1;;;;;42321:54;;;6561:58;;42321:54;;;;20461:2;20446:18;;6702:37;20544:2;20529:18;;7662:37;;;;20289:2;20274:18;;20260:298;20565:340;-1:-1;;;;;42321:54;;;;6561:58;;20891:2;20876:18;;7662:37;20719:2;20704:18;;20690:215;20912:361;;21080:2;21101:17;21094:47;21155:108;21080:2;21069:9;21065:18;21249:6;21155:108;;21280:201;41820:13;;41813:21;7545:34;;21392:2;21377:18;;21363:118;21488:611;41820:13;;41813:21;7545:34;;41820:13;;41813:21;21847:2;21832:18;;7545:34;41820:13;;41813:21;21924:2;21909:18;;7545:34;41820:13;41813:21;22001:2;21986:18;;7545:34;22084:3;22069:19;;7662:37;21694:3;21679:19;;21665:434;22106:213;7662:37;;;22224:2;22209:18;;22195:124;22572:795;22842:3;22827:19;;43957:1;43947:12;;43937:2;;43963:9;43937:2;7955:64;;;23021:2;23006:18;;7662:37;;;;23104:2;23089:18;;7662:37;;;;23187:2;23172:18;;7662:37;;;;23270:3;23255:19;;7662:37;23352:3;23337:19;;;7662:37;22813:554;;23590:563;8227:58;;;23973:2;23958:18;;7662:37;;;;24056:2;24041:18;;7662:37;24139:2;24124:18;;7662:37;23800:3;23785:19;;23771:382;24160:1023;;43211:24;8234:3;8227:58;24492:3;24619:2;24608:9;24604:18;24597:48;24659:84;24492:3;24481:9;24477:19;24729:6;24721;24659:84;;;-1:-1;;;;;42321:54;;;;24822:2;24807:18;;6702:37;-1:-1;42538:10;42527:22;;;24903:2;24888:18;;19603:36;42527:22;;;;24984:3;24969:19;;19603:36;42332:42;25061:19;;8227:58;25168:3;25153:19;8227:58;24651:92;24463:720;-1:-1;;;24463:720;25190:407;25381:2;25395:47;;;9000:2;25366:18;;;41416:19;-1:-1;;;41456:14;;;9016:50;9085:12;;;25352:245;25604:407;25795:2;25809:47;;;9336:2;25780:18;;;41416:19;-1:-1;;;41456:14;;;9352:44;9415:12;;;25766:245;26018:407;26209:2;26223:47;;;9666:2;26194:18;;;41416:19;9702:34;41456:14;;;9682:55;-1:-1;;;9757:12;;;9750:33;9802:12;;;26180:245;26432:407;26623:2;26637:47;;;10053:2;26608:18;;;41416:19;10089:34;41456:14;;;10069:55;-1:-1;;;10144:12;;;10137:25;10181:12;;;26594:245;26846:407;27037:2;27051:47;;;10432:2;27022:18;;;41416:19;-1:-1;;;41456:14;;;10448:50;10517:12;;;27008:245;27260:407;27451:2;27465:47;;;10768:2;27436:18;;;41416:19;-1:-1;;;41456:14;;;10784:41;10844:12;;;27422:245;27674:407;27865:2;27879:47;;;11095:2;27850:18;;;41416:19;11131:34;41456:14;;;11111:55;-1:-1;;;11186:12;;;11179:34;11232:12;;;27836:245;28088:407;28279:2;28293:47;;;11483:2;28264:18;;;41416:19;11519:33;41456:14;;;11499:54;11572:12;;;28250:245;28502:407;28693:2;28707:47;;;11823:2;28678:18;;;41416:19;11859:32;41456:14;;;11839:53;11911:12;;;28664:245;28916:407;29107:2;29121:47;;;12162:2;29092:18;;;41416:19;12198:34;41456:14;;;12178:55;-1:-1;;;12253:12;;;12246:27;12292:12;;;29078:245;29330:407;29521:2;29535:47;;;12543:2;29506:18;;;41416:19;-1:-1;;;41456:14;;;12559:49;12627:12;;;29492:245;29744:407;29935:2;29949:47;;;12878:2;29920:18;;;41416:19;12914:34;41456:14;;;12894:55;-1:-1;;;12969:12;;;12962:34;13015:12;;;29906:245;30158:407;30349:2;30363:47;;;13266:2;30334:18;;;41416:19;13302:34;41456:14;;;13282:55;-1:-1;;;13357:12;;;13350:43;13412:12;;;30320:245;30572:407;30763:2;30777:47;;;13663:2;30748:18;;;41416:19;13699:34;41456:14;;;13679:55;-1:-1;;;13754:12;;;13747:38;13804:12;;;30734:245;30986:407;31177:2;31191:47;;;14055:2;31162:18;;;41416:19;14091:32;41456:14;;;14071:53;14143:12;;;31148:245;31400:407;31591:2;31605:47;;;14394:2;31576:18;;;41416:19;14430:34;41456:14;;;14410:55;-1:-1;;;14485:12;;;14478:25;14522:12;;;31562:245;31814:407;32005:2;32019:47;;;14773:2;31990:18;;;41416:19;14809:34;41456:14;;;14789:55;-1:-1;;;14864:12;;;14857:34;14910:12;;;31976:245;32228:407;32419:2;32433:47;;;15161:2;32404:18;;;41416:19;-1:-1;;;41456:14;;;15177:44;15240:12;;;32390:245;32642:407;32833:2;32847:47;;;15491:2;32818:18;;;41416:19;15527:34;41456:14;;;15507:55;-1:-1;;;15582:12;;;15575:31;15625:12;;;32804:245;33056:407;33247:2;33261:47;;;15876:2;33232:18;;;41416:19;15912:34;41456:14;;;15892:55;-1:-1;;;15967:12;;;15960:27;16006:12;;;33218:245;33470:407;33661:2;33675:47;;;16257:2;33646:18;;;41416:19;16293:34;41456:14;;;16273:55;-1:-1;;;16348:12;;;16341:27;16387:12;;;33632:245;33884:407;34075:2;34089:47;;;16638:2;34060:18;;;41416:19;16674:34;41456:14;;;16654:55;-1:-1;;;16729:12;;;16722:25;16766:12;;;34046:245;34298:407;34489:2;34503:47;;;17017:2;34474:18;;;41416:19;-1:-1;;;41456:14;;;17033:48;17100:12;;;34460:245;34712:407;34903:2;34917:47;;;17351:2;34888:18;;;41416:19;17387:34;41456:14;;;17367:55;-1:-1;;;17442:12;;;17435:30;17484:12;;;34874:245;35126:407;35317:2;35331:47;;;17735:2;35302:18;;;41416:19;-1:-1;;;41456:14;;;17751:49;17819:12;;;35288:245;35540:407;35731:2;35745:47;;;18070:2;35716:18;;;41416:19;18106:32;41456:14;;;18086:53;18158:12;;;35702:245;35954:407;36145:2;36159:47;;;18409:2;36130:18;;;41416:19;-1:-1;;;41456:14;;;18425:51;18495:12;;;36116:245;36368:407;36559:2;36573:47;;;18746:2;36544:18;;;41416:19;18782:34;41456:14;;;18762:55;-1:-1;;;18837:12;;;18830:27;18876:12;;;36530:245;36782:407;36973:2;36987:47;;;19127:2;36958:18;;;41416:19;19163:34;41456:14;;;19143:55;-1:-1;;;19218:12;;;19211:48;19278:12;;;36944:245;37416:472;;7692:5;7669:3;7662:37;37612:2;37730;37719:9;37715:18;37708:48;37770:108;37612:2;37601:9;37597:18;37864:6;37770:108;;37895:435;7662:37;;;38233:2;38218:18;;7662:37;;;;38316:2;38301:18;;7662:37;38069:2;38054:18;;38040:290;38337:635;;7692:5;7669:3;7662:37;38563:2;38681;38670:9;38666:18;38659:48;38721:84;38563:2;38552:9;38548:18;38791:6;38783;38721:84;;;38853:9;38847:4;38843:20;38838:2;38827:9;38823:18;38816:48;38878:84;38957:4;38948:6;38940;38878:84;;;38870:92;38534:438;-1:-1;;;;;;;;38534:438;38979:324;7662:37;;;39289:2;39274:18;;7662:37;39125:2;39110:18;;39096:207;40306:256;40368:2;40362:9;40394:17;;;-1:-1;;;;;40454:34;;40490:22;;;40451:62;40448:2;;;40526:1;;40516:12;40448:2;40368;40535:22;40346:216;;-1:-1;40346:216;43986:117;-1:-1;;;;;42321:54;;44045:35;;44035:2;;44094:1;;44084:12;44035:2;44029:74;
Swarm Source
ipfs://68fd6c05689e8d7a7488ae04ebdbb0a264441770f67ff28140cdcff763675332
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
MOVR | 100.00% | $6.14 | 28.7997 | $176.83 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.