Overview
GLMR Balance
0 GLMR
GLMR Value
$0.00More Info
Private Name Tags
ContractCreator:
Latest 25 from a total of 15,124 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Resolve Market O... | 5266515 | 79 days ago | IN | 0 GLMR | 0.01844064 | ||||
Resolve Market O... | 5266514 | 79 days ago | IN | 0 GLMR | 0.01844566 | ||||
Resolve Market O... | 5266512 | 79 days ago | IN | 0 GLMR | 0.01844436 | ||||
Resolve Market O... | 5266512 | 79 days ago | IN | 0 GLMR | 0.01844436 | ||||
Resolve Market O... | 5266501 | 79 days ago | IN | 0 GLMR | 0.01841684 | ||||
Resolve Market O... | 5266501 | 79 days ago | IN | 0 GLMR | 0.01841684 | ||||
Resolve Market O... | 5266500 | 79 days ago | IN | 0 GLMR | 0.0184218 | ||||
Resolve Market O... | 5266499 | 79 days ago | IN | 0 GLMR | 0.01843425 | ||||
Claim Winnings | 5266494 | 79 days ago | IN | 0 GLMR | 0.00972263 | ||||
Claim Winnings | 5266493 | 79 days ago | IN | 0 GLMR | 0.0097244 | ||||
Claim Winnings | 5266493 | 79 days ago | IN | 0 GLMR | 0.0097244 | ||||
Resolve Market O... | 5266485 | 79 days ago | IN | 0 GLMR | 0.01838774 | ||||
Resolve Market O... | 5266485 | 79 days ago | IN | 0 GLMR | 0.01838774 | ||||
Resolve Market O... | 5266484 | 79 days ago | IN | 0 GLMR | 0.0183877 | ||||
Buy | 5112714 | 101 days ago | IN | 0.55 GLMR | 0.01167628 | ||||
Claim Winnings | 5104389 | 102 days ago | IN | 0 GLMR | 0.00847734 | ||||
Claim Winnings | 5104389 | 102 days ago | IN | 0 GLMR | 0.00847734 | ||||
Claim Winnings | 5104388 | 102 days ago | IN | 0 GLMR | 0.00847734 | ||||
Claim Winnings | 5104387 | 102 days ago | IN | 0 GLMR | 0.00847734 | ||||
Claim Winnings | 5104387 | 102 days ago | IN | 0 GLMR | 0.00847734 | ||||
Buy | 4413236 | 199 days ago | IN | 3.33 GLMR | 0.01711533 | ||||
Claim Winnings | 4384923 | 203 days ago | IN | 0 GLMR | 0.00847887 | ||||
Claim Winnings | 4384923 | 203 days ago | IN | 0 GLMR | 0.00847887 | ||||
Claim Winnings | 4382552 | 203 days ago | IN | 0 GLMR | 0.0085694 | ||||
Resolve Market O... | 4382540 | 203 days ago | IN | 0 GLMR | 0.01627057 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
5266494 | 79 days ago | 18.71439429 GLMR | ||||
5266493 | 79 days ago | 1.14940278 GLMR | ||||
5266493 | 79 days ago | 49.87005877 GLMR | ||||
5104389 | 102 days ago | 207.13213904 GLMR | ||||
5104389 | 102 days ago | 14.74949699 GLMR | ||||
5104388 | 102 days ago | 8.1885906 GLMR | ||||
5104387 | 102 days ago | 8.84969696 GLMR | ||||
5104387 | 102 days ago | 14.74949494 GLMR | ||||
4384923 | 203 days ago | 32.40230856 GLMR | ||||
4384923 | 203 days ago | 0.02960938 GLMR | ||||
4382552 | 203 days ago | 48.37033764 GLMR | ||||
3920675 | 268 days ago | 7.27391056 GLMR | ||||
3788344 | 287 days ago | 2.94989898 GLMR | ||||
3788343 | 287 days ago | 2.50133508 GLMR | ||||
3788283 | 287 days ago | 38.86459261 GLMR | ||||
3788283 | 287 days ago | 1.25232665 GLMR | ||||
3788282 | 287 days ago | 28.07912443 GLMR | ||||
3788282 | 287 days ago | 0.74133574 GLMR | ||||
3788282 | 287 days ago | 35.22082335 GLMR | ||||
3788282 | 287 days ago | 0.26 GLMR | ||||
3788281 | 287 days ago | 22.19730244 GLMR | ||||
3788281 | 287 days ago | 0.32 GLMR | ||||
3788281 | 287 days ago | 5.88429419 GLMR | ||||
3788281 | 287 days ago | 1.22960133 GLMR | ||||
3788278 | 287 days ago | 14.33192755 GLMR |
Loading...
Loading
Contract Name:
PredictionMarket
Compiler Version
v0.6.2+commit.bacdbe57
Contract Source Code (Solidity)
/** *Submitted for verification at moonbeam.moonscan.io on 2022-02-08 */ // 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/PredictionMarket.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 PredictionMarket { 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; } 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 } 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 token; // 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(token.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 _token, uint256 _requiredBalance, address _realitioAddress, uint256 _realitioTimeout ) public { require(_realitioAddress != address(0), "_realitioAddress is address 0"); require(_realitioTimeout > 0, "timeout must be positive"); fee = _fee; token = _token; 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( string calldata question, string calldata image, uint256 closesAt, address arbitrator, uint256 outcomes ) external payable mustHoldRequiredBalance() returns (uint256) { uint256 marketId = marketIndex; marketIds.push(marketId); Market storage market = markets[marketId]; require(msg.value > 0, "stake needs to be > 0"); require(closesAt > now, "market must resolve after the current date"); require(arbitrator != address(0), "invalid arbitrator address"); // v1 - only binary markets require(outcomes == 2, "number of outcomes has to be 2"); market.closesAtTimestamp = 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 < outcomes; i++) { market.outcomeIds.push(i); MarketOutcome storage outcome = market.outcomes[i]; outcome.marketId = marketId; outcome.id = i; } // creating question in realitio RealitioERC20 realitio = RealitioERC20(realitioAddress); market.resolution.questionId = realitio.askQuestionERC20( 2, question, arbitrator, uint32(realitioTimeout), uint32(closesAt), 0, 0 ); addLiquidity(marketId, msg.value); // emiting initial price events emitMarketOutcomePriceEvents(marketId); emit MarketCreated(msg.sender, marketId, outcomes, question, 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 ) external payable timeTransitions(marketId) atState(marketId, MarketState.open) { Market storage market = markets[marketId]; uint256 value = msg.value; 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); 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 payable 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 msg.sender.transfer(value); emit MarketActionTx(msg.sender, MarketAction.sell, marketId, outcomeId, shares, value, now); emitMarketOutcomePriceEvents(marketId); } /// @dev Adds liquidity to a market - external function addLiquidity(uint256 marketId) external payable timeTransitions(marketId) atState(marketId, MarketState.open) { addLiquidity(marketId, msg.value); } /// @dev Private function, used by addLiquidity and CreateMarket function addLiquidity(uint256 marketId, uint256 value) private 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) { // 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 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; 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 payable 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 msg.sender.transfer(liquidityAmount); 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 ); msg.sender.transfer(value); } /// @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 ); msg.sender.transfer(value); } /// @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 ); msg.sender.transfer(value); } /// @dev Allows liquidity providers to claim their fees share from fees pool function claimFees(uint256 marketId) public payable { 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); msg.sender.transfer(claimableFees); } 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, uint256 ) { Market storage market = markets[marketId]; return ( market.liquidityShares[user], market.outcomes[0].shares.holders[user], market.outcomes[1].shares.holders[user] ); } 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, uint256 ) { return (getMarketLiquidityPrice(marketId), getMarketOutcomePrice(marketId, 0), getMarketOutcomePrice(marketId, 1)); } function getMarketLiquidityPrice(uint256 marketId) public view returns (uint256) { Market storage market = markets[marketId]; if (market.state == MarketState.resolved && !isMarketVoided(marketId)) { // resolved market, price is 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 = # liquidity shares / # outcome shares * # outcomes return market.liquidity.mul(ONE * market.outcomeIds.length).div(market.sharesAvailable); } 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 getMarketOutcomePrice(uint256 marketId, uint256 outcomeId) public view returns (uint256) { Market storage market = markets[marketId]; MarketOutcome storage outcome = market.outcomes[outcomeId]; if (market.state == MarketState.resolved && !isMarketVoided(marketId)) { // resolved market, price is either 0 or 1 return outcomeId == market.resolution.outcomeId ? ONE : 0; } return (market.sharesAvailable.sub(outcome.shares.available)).mul(ONE).div(market.sharesAvailable); } 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
[{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"contract IERC20","name":"_token","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 PredictionMarket.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"}],"name":"addLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketId","type":"uint256"},{"internalType":"uint256","name":"outcomeId","type":"uint256"},{"internalType":"uint256","name":"minOutcomeSharesToBuy","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","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":"payable","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":[{"internalType":"string","name":"question","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"uint256","name":"closesAt","type":"uint256"},{"internalType":"address","name":"arbitrator","type":"address"},{"internalType":"uint256","name":"outcomes","type":"uint256"}],"name":"createMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","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 PredictionMarket.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"},{"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":"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"},{"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":"payable","type":"function"},{"inputs":[],"name":"requiredBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"payable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003685380380620036858339810160408190526200003491620000ca565b6001600160a01b038216620000665760405162461bcd60e51b81526004016200005d9062000125565b60405180910390fd5b60008111620000895760405162461bcd60e51b81526004016200005d906200015c565b600394909455600680546001600160a01b039485166001600160a01b03199182161790915560079290925560048054919093169116179055600555620001ac565b600080600080600060a08688031215620000e2578081fd5b855194506020860151620000f68162000193565b604087015160608801519195509350620001108162000193565b80925050608086015190509295509295909350565b6020808252601d908201527f5f7265616c6974696f4164647265737320697320616464726573732030000000604082015260600190565b60208082526018908201527f74696d656f7574206d75737420626520706f7369746976650000000000000000604082015260600190565b6001600160a01b0381168114620001a957600080fd5b50565b6134c980620001bc6000396000f3fe6080604052600436106101945760003560e01c806308560ace146101995780631d7920aa146101c457806328747a80146101f35780632c2aa24e1461021357806331877a38146102445780633620875e146102715780633d41a26b146102865780633fe45e3b1461029b57806340993b26146102b0578063429c9dff146102c35780634397c4ce146102e3578063441cf65e1461030357806351c6590a146103305780635e648eff14610343578063677bd9ff146103635780637b34e6e01461038357806385b91d8e146103a55780638c7adc15146103c55780638cd41552146103da5780639d7de6b3146103fa578063aa22a02e1461040d578063ac68a7481461042d578063b31eb89514610440578063bf45572114610460578063bfacba3d14610480578063c2ee3a08146104b2578063c346a9d0146104c7578063c8f70d01146104e7578063ddca3f4314610507578063ec2c90161461051c578063ec93f0f514610531578063efbc47dc14610551578063efce431314610564578063fc0c546a14610584578063fdff808514610599575b600080fd5b3480156101a557600080fd5b506101ae6105b9565b6040516101bb9190612d4f565b60405180910390f35b3480156101d057600080fd5b506101e46101df366004612bda565b6105bf565b6040516101bb939291906133f6565b3480156101ff57600080fd5b506101ae61020e366004612bda565b6105de565b34801561021f57600080fd5b5061023361022e366004612bf2565b610774565b6040516101bb959493929190612d28565b34801561025057600080fd5b5061026461025f366004612bda565b610844565b6040516101bb9190612cd9565b61028461027f366004612c6a565b6108ad565b005b34801561029257600080fd5b506101ae610afb565b3480156102a757600080fd5b506101ae610b01565b6102846102be366004612c3f565b610b07565b3480156102cf57600080fd5b506101ae6102de366004612c3f565b610cc8565b3480156102ef57600080fd5b506101ae6102fe366004612bda565b610e28565b34801561030f57600080fd5b5061032361031e366004612bda565b610e3d565b6040516101bb9190612d1d565b61028461033e366004612bda565b610e82565b34801561034f57600080fd5b5061028461035e366004612bda565b610f1d565b34801561036f57600080fd5b5061028461037e366004612bda565b6110ea565b34801561038f57600080fd5b50610398611255565b6040516101bb9190612cc5565b3480156103b157600080fd5b506101e46103c0366004612bda565b611264565b3480156103d157600080fd5b506101ae611295565b3480156103e657600080fd5b506101ae6103f5366004612c1e565b61129b565b610284610408366004612c1e565b61135b565b34801561041957600080fd5b506101ae610428366004612bf2565b611760565b61028461043b366004612bda565b6117b3565b34801561044c57600080fd5b506101e461045b366004612bf2565b61187c565b34801561046c57600080fd5b506101ae61047b366004612bda565b6118d7565b34801561048c57600080fd5b506104a061049b366004612bda565b611914565b6040516101bb96959493929190612d58565b3480156104be57600080fd5b506101ae61196d565b3480156104d357600080fd5b506101ae6104e2366004612c3f565b611979565b3480156104f357600080fd5b506101ae610502366004612bda565b611aa9565b34801561051357600080fd5b506101ae611b5c565b34801561052857600080fd5b50610264611b62565b34801561053d57600080fd5b5061028461054c366004612c1e565b611bba565b6101ae61055f366004612b4a565b611d8d565b34801561057057600080fd5b506101e461057f366004612c1e565b612079565b34801561059057600080fd5b506103986120bd565b3480156105a557600080fd5b506101ae6105b4366004612bf2565b6120cc565b60075481565b6000908152600160205260409020600a81015460099091015490918190565b60008181526001602052604081205482904211801561061a575060008181526001602052604081206006015460ff16600281111561061857fe5b145b156106285761062881612172565b8260018060008381526001602052604090206006015460ff16600281111561064c57fe5b146106725760405162461bcd60e51b815260040161066990613299565b60405180910390fd5b600085815260016020526040808220600480546009830154935163684e62bf60e11b81528a9593946001600160a01b039092169392849263d09cc57e926106b99201612d4f565b60206040518083038186803b1580156106d157600080fd5b505afa1580156106e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107099190810190612b32565b60088401819055604051909150899033907f67a6457c8912ae1b7a9fbdfa311cbd016ba606b548bf06bc80bc751072d91bbc906107499085904290613445565b60405180910390a361075a896121c2565b505060080154945061076b81612172565b50505050919050565b600082815260016020526040812081908190819081906002600682015460ff16600281111561079f57fe5b146107c4576000806000806107b48c8c6120cc565b955095509550955095505061083a565b60088101546000908152600e8201602090815260408083206001600160a01b038b16845260048082018452828520546005808401865284872054928801865284872054908801909552929094205490939115159260ff92831692901515911661082d8d8d6120cc565b9650965096509650965050505b9295509295909350565b600081815260016020908152604091829020600d81018054845181850281018501909552808552606094929383018282801561089f57602002820191906000526020600020905b81548152602001906001019080831161088b575b50505050509150505b919050565b6000848152600160205260409020548490421180156108e9575060008181526001602052604081206006015460ff1660028111156108e757fe5b145b156108f7576108f781612172565b8460008060008381526001602052604090206006015460ff16600281111561091b57fe5b146109385760405162461bcd60e51b815260040161066990613299565b6000878152600160209081526040808320898452600e810190925282209091610962888b8b611979565b9050868111156109845760405162461bcd60e51b81526004016106699061337d565b600081116109a45760405162461bcd60e51b815260040161066990612ed6565b3360009081526004830160205260409020548111156109d55760405162461bcd60e51b815260040161066990613258565b6109e1338b8b84612265565b6000610a00600354670de0b6b3a764000061230490919063ffffffff16565b600a850154610a16908b9063ffffffff61232c16565b81610a1d57fe5b600b8601549190049150610a37908263ffffffff61236616565b600b8501556000610a4e8a8363ffffffff61236616565b90508085600101541015610a745760405162461bcd60e51b815260040161066990613215565b610a7e8c8261238b565b60405133908b156108fc02908c906000818181858888f19350505050158015610aab573d6000803e3d6000fd5b508b6001336001600160a01b03166000805160206134548339815191528e878f42604051610adc9493929190612d8f565b60405180910390a4610aed8c6121c2565b505050505050505050505050565b60001981565b60055481565b600083815260016020526040902054839042118015610b43575060008181526001602052604081206006015460ff166002811115610b4157fe5b145b15610b5157610b5181612172565b8360008060008381526001602052604090206006015460ff166002811115610b7557fe5b14610b925760405162461bcd60e51b815260040161066990613299565b6000868152600160205260408120903490610bae828a8a610cc8565b905086811015610bd05760405162461bcd60e51b815260040161066990613346565b60008111610bf05760405162461bcd60e51b815260040161066990612ed6565b600a830154600090670de0b6b3a764000090610c1390859063ffffffff61232c16565b81610c1a57fe5b600b8601549190049150610c34908263ffffffff61236616565b600b8501556000610c4b848363ffffffff61230416565b60008b8152600e870160205260409020909150610c688c8361242e565b6003810154841115610c8c5760405162461bcd60e51b8152600401610669906132cc565b610c98338d8d876124c7565b8b6000336001600160a01b03166000805160206134548339815191528e888a42604051610adc9493929190612d8f565b60008281526001602052604081206060610ce185612556565b90506000610d21670de0b6b3a7640000610d0b85600a01600001548a61232c90919063ffffffff16565b81610d1257fe5b8991900463ffffffff61230416565b90506000828681518110610d3157fe5b602002602001015190506000610d58670de0b6b3a76400008361232c90919063ffffffff16565b905060005b8451811015610dc357878114610dbb576000858281518110610d7b57fe5b60200260200101519050610db7610d9b868361236690919063ffffffff16565b610dab858463ffffffff61232c16565b9063ffffffff6125e916565b9250505b600101610d5d565b5060008111610de45760405162461bcd60e51b815260040161066990612dfc565b610e1b610dff82670de0b6b3a764000063ffffffff6125e916565b610e0f848663ffffffff61236616565b9063ffffffff61230416565b9998505050505050505050565b60009081526001602052604090206009015490565b60008181526001602052604081206002600682015460ff166002811115610e6057fe5b14610e6f5760009150506108a8565b600d810154600890910154101592915050565b600081815260016020526040902054819042118015610ebe575060008181526001602052604081206006015460ff166002811115610ebc57fe5b145b15610ecc57610ecc81612172565b8160008060008381526001602052604090206006015460ff166002811115610ef057fe5b14610f0d5760405162461bcd60e51b815260040161066990613299565b610f178434612619565b50505050565b8060028060008381526001602052604090206006015460ff166002811115610f4157fe5b14610f5e5760405162461bcd60e51b815260040161066990613299565b6000838152600160205260409020610f75846117b3565b336000908152600482016020526040902054610fa35760405162461bcd60e51b8152600401610669906131d2565b33600090815260058201602052604090205460ff1615610fd55760405162461bcd60e51b81526004016106699061318b565b6000610fe085611aa9565b33600090815260048401602052604081205491925090670de0b6b3a76400009061101190849063ffffffff61232c16565b8161101857fe5b049050808360010154101561103f5760405162461bcd60e51b815260040161066990612ff1565b6001830154611054908263ffffffff61230416565b600184810191909155336000818152600580870160209081526040808420805460ff19169096179095556004880190528382205493518a94919392600080516020613454833981519152926110ac9288904290612d8f565b60405180910390a4604051339082156108fc029083906000818181858888f193505050501580156110e1573d6000803e3d6000fd5b50505050505050565b8060028060008381526001602052604090206006015460ff16600281111561110e57fe5b1461112b5760405162461bcd60e51b815260040161066990613299565b600083815260016020908152604080832060088101548452600e81018352818420338552600481019093529220546111755760405162461bcd60e51b815260040161066990612f02565b33600090815260058201602052604090205460ff16156111a75760405162461bcd60e51b8152600401610669906130b2565b33600090815260048201602052604090205460018301548111156111dd5760405162461bcd60e51b815260040161066990612ff1565b60018301546111f2908263ffffffff61230416565b6001808501919091553360009081526005840160205260409020805460ff191690911790558560046008850154336000818152600487016020526040908190205490519192600080516020613454833981519152926110ac929088904290612d8f565b6004546001600160a01b031681565b600080600061127284611aa9565b61127d85600061129b565b61128886600161129b565b9250925092509193909250565b60025481565b6000828152600160209081526040808320848452600e810190925282206002600683015460ff1660028111156112cd57fe5b1480156112e057506112de85610e3d565b155b1561130a57600882015484146112f7576000611301565b670de0b6b3a76400005b92505050611355565b60038083015490820154611350919061134490670de0b6b3a76400009061133890849063ffffffff61230416565b9063ffffffff61232c16565b9063ffffffff6129c416565b925050505b92915050565b600082815260016020526040902054829042118015611397575060008181526001602052604081206006015460ff16600281111561139557fe5b145b156113a5576113a581612172565b8260008060008381526001602052604090206006015460ff1660028111156113c957fe5b146113e65760405162461bcd60e51b815260040161066990613299565b600085815260016020908152604080832033845260048101909252909120548511156114245760405162461bcd60e51b815260040161066990613258565b61142d866117b3565b611439868660036129e5565b50606061144587612556565b905060608151604051908082528060200260200182016040528015611474578160200160208202803883390190505b50905060001960005b83518110156114b357600084828151811061149457fe5b60200260200101519050808311156114aa578092505b5060010161147d565b5060028401546000906114d0906113448b8563ffffffff61232c16565b905060005b845181101561156e5785600201546115098b8784815181106114f357fe5b602002602001015161232c90919063ffffffff16565b8161151057fe5b0484828151811061151d57fe5b60200260200101818152505061154f8285838151811061153957fe5b602002602001015161230490919063ffffffff16565b84828151811061155b57fe5b60209081029190910101526001016114d5565b506115798a8261238b565b600285015461158e908a63ffffffff61230416565b60028601553360009081526004860160205260409020546115b5908a63ffffffff61230416565b3360009081526004870160205260408120919091555b84518110156116b65760008482815181106115e257fe5b602002602001015111156116ae576003808701546000838152600e89016020526040902090910154855161162f9033908f9086908a908290811061162257fe5b60200260200101516124c7565b8c6000336001600160a01b0316600080516020613454833981519152868a888151811061165857fe5b60200260200101516116928e600301546113448e8c8151811061167757fe5b60200260200101516113388b8d61230490919063ffffffff16565b426040516116a39493929190612d8f565b60405180910390a450505b6001016115cb565b50604051339082156108fc029083906000818181858888f193505050501580156116e4573d6000803e3d6000fd5b50896003336001600160a01b031660008051602061345483398151915260008d86426040516117169493929190612d8f565b60405180910390a489600080516020613474833981519152866002015461173c8d611aa9565b4260405161174c939291906133f6565b60405180910390a250505050505050505050565b600082815260016020908152604080832060028101546001600160a01b0386168552600482019093529083205490916117ab9161134490670de0b6b3a764000063ffffffff61232c16565b949350505050565b6000818152600160205260408120906117cc83336120cc565b9050801561183857336000908152600c830160205260409020546117f6908263ffffffff61236616565b336000818152600c85016020526040808220939093559151909183156108fc02918491818181858888f19350505050158015611836573d6000803e3d6000fd5b505b8260063360008181526004860160205260408082205490516000805160206134548339815191529261186f92909188904290612d8f565b60405180910390a4505050565b60009182526001602081815260408085206001600160a01b03949094168086526004808601845282872054878052600e9096018085528388208389528201855283882054958852845282872091875201909152909220549092565b60008181526001602052604081206002600682015460ff1660028111156118fa57fe5b1461190a576000199150506108a8565b6008015492915050565b6000818152600160208190526040822060068101548154600283015493830154600384015486958695869586958695929460ff90921693909290916119588d6118d7565b949d939c50919a509850965090945092505050565b670de0b6b3a764000081565b6000828152600160205260408120606061199285612556565b600a8301549091506000906119b690670de0b6b3a76400009063ffffffff61230416565b6119ce88670de0b6b3a764000063ffffffff61232c16565b816119d557fe5b04905060008286815181106119e657fe5b602002602001015190506000611a0d670de0b6b3a76400008361232c90919063ffffffff16565b905060005b8451811015611a5c57878114611a54576000858281518110611a3057fe5b60200260200101519050611a50610d9b868361230490919063ffffffff16565b9250505b600101611a12565b5060008111611a7d5760405162461bcd60e51b815260040161066990612dfc565b610e1b82610e0f611a9c84670de0b6b3a764000063ffffffff6125e916565b869063ffffffff61236616565b60008181526001602052604081206002600682015460ff166002811115611acc57fe5b148015611adf5750611add83610e3d565b155b15611b2757600281015460088201546000908152600e83016020526040902060030154611b1f919061134490670de0b6b3a764000063ffffffff61232c16565b9150506108a8565b6003810154600d8201546002830154611b5592916113449190670de0b6b3a76400000263ffffffff61232c16565b9392505050565b60035481565b60606000805480602002602001604051908101604052809291908181526020018280548015611bb057602002820191906000526020600020905b815481526020019060010190808311611b9c575b5050505050905090565b8160028060008381526001602052604090206006015460ff166002811115611bde57fe5b14611bfb5760405162461bcd60e51b815260040161066990613299565b6000848152600160209081526040808320868452600e8101835281842033855260048101909352922054611c415760405162461bcd60e51b815260040161066990612e60565b33600090815260068201602052604090205460ff1615611c735760405162461bcd60e51b8152600401610669906133b3565b6000611c7f878761129b565b33600090815260048401602052604081205491925090611cb490670de0b6b3a76400009061134490859063ffffffff61232c16565b90508084600101541015611cda5760405162461bcd60e51b815260040161066990612ff1565b6001840154611cef908263ffffffff61230416565b6001808601919091553360009081526006850160205260409020805460ff191690911790558760073360008181526004870160205260409081902054905160008051602061345483398151915291611d4d918d919088904290612d8f565b60405180910390a4604051339082156108fc029083906000818181858888f19350505050158015611d82573d6000803e3d6000fd5b505050505050505050565b6007546006546040516370a0823160e01b8152600092916001600160a01b0316906370a0823190611dc2903390600401612cc5565b60206040518083038186803b158015611dda57600080fd5b505afa158015611dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e129190810190612b32565b1015611e305760405162461bcd60e51b815260040161066990613068565b60025460008054600181810183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639091018390558282526020526040902034611e8c5760405162461bcd60e51b815260040161066990612e31565b428611611eab5760405162461bcd60e51b815260040161066990613141565b6001600160a01b038516611ed15760405162461bcd60e51b815260040161066990613312565b83600214611ef15760405162461bcd60e51b815260040161066990612f4c565b85815560068101805460ff19169055600354600a820155600019600882015560005b84811015611f5557600d820180546001818101835560009283526020808420909201849055838352600e85019091526040909120848155810182905501611f13565b506000600460009054906101000a90046001600160a01b03169050806001600160a01b031663d4876b9f60028d8d8a6005548d6000806040518963ffffffff1660e01b8152600401611fae989796959493929190612daa565b602060405180830381600087803b158015611fc857600080fd5b505af1158015611fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120009190810190612b32565b600983015561200f8334612619565b612018836121c2565b82336001600160a01b03167f928446b14f4c661d8499681f1d2eb118eb6e89066877a7d43e0672a27cc63a32878e8e8e8e60405161205a95949392919061340c565b60405180910390a3505060028054600101905598975050505050505050565b6000828152600160209081526040808320848452600e81019092528220829182916120a4878761129b565b6003820154600290920154909891975095509350505050565b6006546001600160a01b031681565b600082815260016020908152604080832060028101546001600160a01b03861685526004820190935290832054600b8201549192849261211692611344919063ffffffff61232c16565b6001600160a01b0385166000908152600c8401602052604090205490915081101561214657600092505050611355565b6001600160a01b0384166000908152600c8301602052604090205461135090829063ffffffff61230416565b6000818152600160205260409020600681015460ff16600281111561219357fe5b60010160028111156121a157fe5b60068201805460ff191660018360028111156121b957fe5b02179055505050565b6000818152600160205260408120905b600d82015481101561222a5780837f8270f0a0534b13b7f92d1dbd58aa75c5207b40c55fefa7a17110c6136ad7270b61220b868561129b565b4260405161221a929190613445565b60405180910390a36001016121d2565b5081600080516020613474833981519152826002015461224985611aa9565b42604051612259939291906133f6565b60405180910390a25050565b6000838152600160209081526040808320858452600e810183528184206001600160a01b0389168552600481019093529220546122a8908463ffffffff61230416565b6001600160a01b038716600090815260048301602052604090205560038101546122d8908463ffffffff61236616565b6003808301919091558201546122f4908463ffffffff61236616565b8260030181905550505050505050565b6000828211156123265760405162461bcd60e51b815260040161066990612fba565b50900390565b60008261233b57506000611355565b8282028284828161234857fe5b0414611b555760405162461bcd60e51b815260040161066990613100565b600082820183811015611b555760405162461bcd60e51b815260040161066990612ea1565b6000828152600160205260408120905b600d82015481101561240e576000818152600e83016020526040902060038101546123cc908563ffffffff61230416565b600382015560028101546123e6908563ffffffff61230416565b60028201556003830154612400908563ffffffff61230416565b60038401555060010161239b565b506001810154612424908363ffffffff61230416565b6001909101555050565b6000828152600160205260408120905b600d8201548110156124b1576000818152600e830160205260409020600381015461246f908563ffffffff61236616565b60038201556002810154612489908563ffffffff61236616565b600282015560038301546124a3908563ffffffff61236616565b60038401555060010161243e565b506001810154612424908363ffffffff61236616565b6000838152600160209081526040808320858452600e810183528184206001600160a01b03891685526004810190935292205461250a908463ffffffff61236616565b6001600160a01b0387166000908152600483016020526040902055600381015461253a908463ffffffff61230416565b6003808301919091558201546122f4908463ffffffff61230416565b600081815260016020908152604091829020600d8101548351818152818402810190930190935260609290918391801561259a578160200160208202803883390190505b50905060005b600d8301548110156125e1576000818152600e8401602052604090206003015482518390839081106125ce57fe5b60209081029190910101526001016125a0565b509392505050565b60008215612608578160018403816125fd57fe5b046001019050611355565b81838161261157fe5b049392505050565b600082815260016020526040902054829042118015612655575060008181526001602052604081206006015460ff16600281111561265357fe5b145b156126635761266381612172565b8260008060008381526001602052604090206006015460ff16600281111561268757fe5b146126a45760405162461bcd60e51b815260040161066990613299565b6000858152600160205260409020846126cf5760405162461bcd60e51b815260040161066990612f83565b600060606126dc88612556565b90506060815160405190808252806020026020018201604052801561270b578160200160208202803883390190505b506002850154909150600090156127fa5760005b835181101561275557600084828151811061273657fe5b602002602001015190508083101561274c578092505b5060010161271f565b5060005b83518110156127c55760008261278b86848151811061277457fe5b60200260200101518d61232c90919063ffffffff16565b8161279257fe5b0490506127a58b8263ffffffff61230416565b8483815181106127b157fe5b602090810291909101015250600101612759565b50806127de86600201548b61232c90919063ffffffff16565b816127e557fe5b0493506127f48a8560026129e5565b506127fe565b8893505b6002850154612813908563ffffffff61236616565b600286015533600090815260048601602052604090205461283a908563ffffffff61236616565b3360009081526004870160205260409020556128568a8a61242e565b60005b825181101561291c57600083828151811061287057fe5b60200260200101511115612914576003808701546000838152600e8901602052604090209091015484516128b09033908f90869089908290811061162257fe5b8c6000336001600160a01b0316600080516020613454833981519152868988815181106128d957fe5b60200260200101516128f88e600301546113448d8c8151811061167757fe5b426040516129099493929190612d8f565b60405180910390a450505b600101612859565b5060006129288b611aa9565b90506000670de0b6b3a7640000612945838863ffffffff61232c16565b8161294c57fe5b0490508b6002336001600160a01b031660008051602061345483398151915260008a86426040516129809493929190612d8f565b60405180910390a48b600080516020613474833981519152886002015484426040516129ae939291906133f6565b60405180910390a2505050505050505050505050565b60008082116126085760405162461bcd60e51b815260040161066990613034565b60008381526001602052604081206002810154600b8201548391612a149161134490889063ffffffff61232c16565b90506002846007811115612a2457fe5b1415612a7d57600b820154612a3f908263ffffffff61236616565b600b830155336000908152600c83016020526040902054612a66908263ffffffff61236616565b336000908152600c84016020526040902055612acc565b600b820154612a92908263ffffffff61230416565b600b830155336000908152600c83016020526040902054612ab9908263ffffffff61230416565b336000908152600c840160205260409020555b50509392505050565b80356001600160a01b038116811461135557600080fd5b60008083601f840112612afd578182fd5b5081356001600160401b03811115612b13578182fd5b602083019150836020828501011115612b2b57600080fd5b9250929050565b600060208284031215612b43578081fd5b5051919050565b600080600080600080600060a0888a031215612b64578283fd5b87356001600160401b0380821115612b7a578485fd5b612b868b838c01612aec565b909950975060208a0135915080821115612b9e578485fd5b50612bab8a828b01612aec565b90965094505060408801359250612bc58960608a01612ad5565b91506080880135905092959891949750929550565b600060208284031215612beb578081fd5b5035919050565b60008060408385031215612c04578182fd5b82359150612c158460208501612ad5565b90509250929050565b60008060408385031215612c30578182fd5b50508035926020909101359150565b600080600060608486031215612c53578283fd5b505081359360208301359350604090920135919050565b60008060008060808587031215612c7f578384fd5b5050823594602084013594506040840135936060013592509050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b81811015612d1157835183529284019291840191600101612cf5565b50909695505050505050565b901515815260200190565b94151585529215156020850152901515604084015215156060830152608082015260a00190565b90815260200190565b60c0810160038810612d6657fe5b968152602081019590955260408501939093526060840191909152608083015260a09091015290565b93845260208401929092526040830152606082015260800190565b600089825260e06020830152612dc460e08301898b612c9b565b6001600160a01b039790971660408301525063ffffffff948516606082015292909316608083015260a082015260c001529392505050565b6020808252601b908201527a6d7573742068617665206e6f6e2d7a65726f2062616c616e63657360281b604082015260600190565b60208082526015908201527407374616b65206e6565647320746f206265203e203605c1b604082015260600190565b60208082526021908201527f7573657220646f6573206e6f7420686f6c64206f7574636f6d652073686172656040820152607360f81b606082015260800190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b602080825260129082015271073686172657320616d6f756e7420697320360741b604082015260600190565b6020808252602a908201527f7573657220646f6573206e6f7420686f6c64207265736f6c766564206f7574636040820152696f6d652073686172657360b01b606082015260800190565b6020808252601e908201527f6e756d626572206f66206f7574636f6d65732068617320746f20626520320000604082015260600190565b6020808252601f908201527f7374616b652068617320746f2062652067726561746572207468616e20302e00604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526023908201527f4d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b6020808252601a9082015279536166654d6174683a206469766973696f6e206279207a65726f60301b604082015260600190565b6020808252602a908201527f6d73672e73656e646572206d75737420686f6c64206d696e696d756d2065726360408201526932302062616c616e636560b01b606082015260800190565b6020808252602e908201527f7573657220616c726561647920636c61696d6564207265736f6c766564206f7560408201526d74636f6d652077696e6e696e677360901b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602a908201527f6d61726b6574206d757374207265736f6c7665206166746572207468652063756040820152697272656e74206461746560b01b606082015260800190565b60208082526027908201527f7573657220616c726561647920636c61696d6564206c69717569646974792077604082015266696e6e696e677360c81b606082015260800190565b60208082526023908201527f7573657220646f6573206e6f7420686f6c64206c69717569646974792073686160408201526272657360e81b606082015260800190565b60208082526023908201527f6d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b60208082526021908201527f7573657220646f6573206e6f74206861766520656e6f7567682062616c616e636040820152606560f81b606082015260800190565b6020808252601990820152784d61726b657420696e20696e636f727265637420737461746560381b604082015260600190565b60208082526026908201527f6f7574636f6d652073686172657320706f6f6c2062616c616e636520697320746040820152656f6f206c6f7760d01b606082015260800190565b6020808252601a9082015279696e76616c69642061726269747261746f72206164647265737360301b604082015260600190565b6020808252601e908201527f6d696e696d756d2062757920616d6f756e74206e6f7420726561636865640000604082015260600190565b6020808252601c908201527b1b585e1a5b5d5b481cd95b1b08185b5bdd5b9d08195e18d95959195960221b604082015260600190565b60208082526023908201527f7573657220616c726561647920636c61696d6564206f7574636f6d652073686160408201526272657360e81b606082015260800190565b9283526020830191909152604082015260600190565b600086825260606020830152613426606083018688612c9b565b8281036040840152613439818587612c9b565b98975050505050505050565b91825260208201526040019056fe9dcabe311735ed0d65f0c22c5425d1f17331f94c9d0767f59e58473cf95ada611eca98f266e5348ae38d5d057a4d8e451e76672f69ac6ba4b0e3b31ea9c7eb2ba26469706673582212209a05a587712745fd0a97aa37b7f385f4630d7eefab295188f89f8ce263f95ce064736f6c6343000602003300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000008b29344f368b5fa35595325903fe0eaab70c8e1f00000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000083d3f4769a19f1b43337888b0290f5473cf508b2000000000000000000000000000000000000000000000000000000000003f480
Deployed Bytecode
0x6080604052600436106101945760003560e01c806308560ace146101995780631d7920aa146101c457806328747a80146101f35780632c2aa24e1461021357806331877a38146102445780633620875e146102715780633d41a26b146102865780633fe45e3b1461029b57806340993b26146102b0578063429c9dff146102c35780634397c4ce146102e3578063441cf65e1461030357806351c6590a146103305780635e648eff14610343578063677bd9ff146103635780637b34e6e01461038357806385b91d8e146103a55780638c7adc15146103c55780638cd41552146103da5780639d7de6b3146103fa578063aa22a02e1461040d578063ac68a7481461042d578063b31eb89514610440578063bf45572114610460578063bfacba3d14610480578063c2ee3a08146104b2578063c346a9d0146104c7578063c8f70d01146104e7578063ddca3f4314610507578063ec2c90161461051c578063ec93f0f514610531578063efbc47dc14610551578063efce431314610564578063fc0c546a14610584578063fdff808514610599575b600080fd5b3480156101a557600080fd5b506101ae6105b9565b6040516101bb9190612d4f565b60405180910390f35b3480156101d057600080fd5b506101e46101df366004612bda565b6105bf565b6040516101bb939291906133f6565b3480156101ff57600080fd5b506101ae61020e366004612bda565b6105de565b34801561021f57600080fd5b5061023361022e366004612bf2565b610774565b6040516101bb959493929190612d28565b34801561025057600080fd5b5061026461025f366004612bda565b610844565b6040516101bb9190612cd9565b61028461027f366004612c6a565b6108ad565b005b34801561029257600080fd5b506101ae610afb565b3480156102a757600080fd5b506101ae610b01565b6102846102be366004612c3f565b610b07565b3480156102cf57600080fd5b506101ae6102de366004612c3f565b610cc8565b3480156102ef57600080fd5b506101ae6102fe366004612bda565b610e28565b34801561030f57600080fd5b5061032361031e366004612bda565b610e3d565b6040516101bb9190612d1d565b61028461033e366004612bda565b610e82565b34801561034f57600080fd5b5061028461035e366004612bda565b610f1d565b34801561036f57600080fd5b5061028461037e366004612bda565b6110ea565b34801561038f57600080fd5b50610398611255565b6040516101bb9190612cc5565b3480156103b157600080fd5b506101e46103c0366004612bda565b611264565b3480156103d157600080fd5b506101ae611295565b3480156103e657600080fd5b506101ae6103f5366004612c1e565b61129b565b610284610408366004612c1e565b61135b565b34801561041957600080fd5b506101ae610428366004612bf2565b611760565b61028461043b366004612bda565b6117b3565b34801561044c57600080fd5b506101e461045b366004612bf2565b61187c565b34801561046c57600080fd5b506101ae61047b366004612bda565b6118d7565b34801561048c57600080fd5b506104a061049b366004612bda565b611914565b6040516101bb96959493929190612d58565b3480156104be57600080fd5b506101ae61196d565b3480156104d357600080fd5b506101ae6104e2366004612c3f565b611979565b3480156104f357600080fd5b506101ae610502366004612bda565b611aa9565b34801561051357600080fd5b506101ae611b5c565b34801561052857600080fd5b50610264611b62565b34801561053d57600080fd5b5061028461054c366004612c1e565b611bba565b6101ae61055f366004612b4a565b611d8d565b34801561057057600080fd5b506101e461057f366004612c1e565b612079565b34801561059057600080fd5b506103986120bd565b3480156105a557600080fd5b506101ae6105b4366004612bf2565b6120cc565b60075481565b6000908152600160205260409020600a81015460099091015490918190565b60008181526001602052604081205482904211801561061a575060008181526001602052604081206006015460ff16600281111561061857fe5b145b156106285761062881612172565b8260018060008381526001602052604090206006015460ff16600281111561064c57fe5b146106725760405162461bcd60e51b815260040161066990613299565b60405180910390fd5b600085815260016020526040808220600480546009830154935163684e62bf60e11b81528a9593946001600160a01b039092169392849263d09cc57e926106b99201612d4f565b60206040518083038186803b1580156106d157600080fd5b505afa1580156106e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107099190810190612b32565b60088401819055604051909150899033907f67a6457c8912ae1b7a9fbdfa311cbd016ba606b548bf06bc80bc751072d91bbc906107499085904290613445565b60405180910390a361075a896121c2565b505060080154945061076b81612172565b50505050919050565b600082815260016020526040812081908190819081906002600682015460ff16600281111561079f57fe5b146107c4576000806000806107b48c8c6120cc565b955095509550955095505061083a565b60088101546000908152600e8201602090815260408083206001600160a01b038b16845260048082018452828520546005808401865284872054928801865284872054908801909552929094205490939115159260ff92831692901515911661082d8d8d6120cc565b9650965096509650965050505b9295509295909350565b600081815260016020908152604091829020600d81018054845181850281018501909552808552606094929383018282801561089f57602002820191906000526020600020905b81548152602001906001019080831161088b575b50505050509150505b919050565b6000848152600160205260409020548490421180156108e9575060008181526001602052604081206006015460ff1660028111156108e757fe5b145b156108f7576108f781612172565b8460008060008381526001602052604090206006015460ff16600281111561091b57fe5b146109385760405162461bcd60e51b815260040161066990613299565b6000878152600160209081526040808320898452600e810190925282209091610962888b8b611979565b9050868111156109845760405162461bcd60e51b81526004016106699061337d565b600081116109a45760405162461bcd60e51b815260040161066990612ed6565b3360009081526004830160205260409020548111156109d55760405162461bcd60e51b815260040161066990613258565b6109e1338b8b84612265565b6000610a00600354670de0b6b3a764000061230490919063ffffffff16565b600a850154610a16908b9063ffffffff61232c16565b81610a1d57fe5b600b8601549190049150610a37908263ffffffff61236616565b600b8501556000610a4e8a8363ffffffff61236616565b90508085600101541015610a745760405162461bcd60e51b815260040161066990613215565b610a7e8c8261238b565b60405133908b156108fc02908c906000818181858888f19350505050158015610aab573d6000803e3d6000fd5b508b6001336001600160a01b03166000805160206134548339815191528e878f42604051610adc9493929190612d8f565b60405180910390a4610aed8c6121c2565b505050505050505050505050565b60001981565b60055481565b600083815260016020526040902054839042118015610b43575060008181526001602052604081206006015460ff166002811115610b4157fe5b145b15610b5157610b5181612172565b8360008060008381526001602052604090206006015460ff166002811115610b7557fe5b14610b925760405162461bcd60e51b815260040161066990613299565b6000868152600160205260408120903490610bae828a8a610cc8565b905086811015610bd05760405162461bcd60e51b815260040161066990613346565b60008111610bf05760405162461bcd60e51b815260040161066990612ed6565b600a830154600090670de0b6b3a764000090610c1390859063ffffffff61232c16565b81610c1a57fe5b600b8601549190049150610c34908263ffffffff61236616565b600b8501556000610c4b848363ffffffff61230416565b60008b8152600e870160205260409020909150610c688c8361242e565b6003810154841115610c8c5760405162461bcd60e51b8152600401610669906132cc565b610c98338d8d876124c7565b8b6000336001600160a01b03166000805160206134548339815191528e888a42604051610adc9493929190612d8f565b60008281526001602052604081206060610ce185612556565b90506000610d21670de0b6b3a7640000610d0b85600a01600001548a61232c90919063ffffffff16565b81610d1257fe5b8991900463ffffffff61230416565b90506000828681518110610d3157fe5b602002602001015190506000610d58670de0b6b3a76400008361232c90919063ffffffff16565b905060005b8451811015610dc357878114610dbb576000858281518110610d7b57fe5b60200260200101519050610db7610d9b868361236690919063ffffffff16565b610dab858463ffffffff61232c16565b9063ffffffff6125e916565b9250505b600101610d5d565b5060008111610de45760405162461bcd60e51b815260040161066990612dfc565b610e1b610dff82670de0b6b3a764000063ffffffff6125e916565b610e0f848663ffffffff61236616565b9063ffffffff61230416565b9998505050505050505050565b60009081526001602052604090206009015490565b60008181526001602052604081206002600682015460ff166002811115610e6057fe5b14610e6f5760009150506108a8565b600d810154600890910154101592915050565b600081815260016020526040902054819042118015610ebe575060008181526001602052604081206006015460ff166002811115610ebc57fe5b145b15610ecc57610ecc81612172565b8160008060008381526001602052604090206006015460ff166002811115610ef057fe5b14610f0d5760405162461bcd60e51b815260040161066990613299565b610f178434612619565b50505050565b8060028060008381526001602052604090206006015460ff166002811115610f4157fe5b14610f5e5760405162461bcd60e51b815260040161066990613299565b6000838152600160205260409020610f75846117b3565b336000908152600482016020526040902054610fa35760405162461bcd60e51b8152600401610669906131d2565b33600090815260058201602052604090205460ff1615610fd55760405162461bcd60e51b81526004016106699061318b565b6000610fe085611aa9565b33600090815260048401602052604081205491925090670de0b6b3a76400009061101190849063ffffffff61232c16565b8161101857fe5b049050808360010154101561103f5760405162461bcd60e51b815260040161066990612ff1565b6001830154611054908263ffffffff61230416565b600184810191909155336000818152600580870160209081526040808420805460ff19169096179095556004880190528382205493518a94919392600080516020613454833981519152926110ac9288904290612d8f565b60405180910390a4604051339082156108fc029083906000818181858888f193505050501580156110e1573d6000803e3d6000fd5b50505050505050565b8060028060008381526001602052604090206006015460ff16600281111561110e57fe5b1461112b5760405162461bcd60e51b815260040161066990613299565b600083815260016020908152604080832060088101548452600e81018352818420338552600481019093529220546111755760405162461bcd60e51b815260040161066990612f02565b33600090815260058201602052604090205460ff16156111a75760405162461bcd60e51b8152600401610669906130b2565b33600090815260048201602052604090205460018301548111156111dd5760405162461bcd60e51b815260040161066990612ff1565b60018301546111f2908263ffffffff61230416565b6001808501919091553360009081526005840160205260409020805460ff191690911790558560046008850154336000818152600487016020526040908190205490519192600080516020613454833981519152926110ac929088904290612d8f565b6004546001600160a01b031681565b600080600061127284611aa9565b61127d85600061129b565b61128886600161129b565b9250925092509193909250565b60025481565b6000828152600160209081526040808320848452600e810190925282206002600683015460ff1660028111156112cd57fe5b1480156112e057506112de85610e3d565b155b1561130a57600882015484146112f7576000611301565b670de0b6b3a76400005b92505050611355565b60038083015490820154611350919061134490670de0b6b3a76400009061133890849063ffffffff61230416565b9063ffffffff61232c16565b9063ffffffff6129c416565b925050505b92915050565b600082815260016020526040902054829042118015611397575060008181526001602052604081206006015460ff16600281111561139557fe5b145b156113a5576113a581612172565b8260008060008381526001602052604090206006015460ff1660028111156113c957fe5b146113e65760405162461bcd60e51b815260040161066990613299565b600085815260016020908152604080832033845260048101909252909120548511156114245760405162461bcd60e51b815260040161066990613258565b61142d866117b3565b611439868660036129e5565b50606061144587612556565b905060608151604051908082528060200260200182016040528015611474578160200160208202803883390190505b50905060001960005b83518110156114b357600084828151811061149457fe5b60200260200101519050808311156114aa578092505b5060010161147d565b5060028401546000906114d0906113448b8563ffffffff61232c16565b905060005b845181101561156e5785600201546115098b8784815181106114f357fe5b602002602001015161232c90919063ffffffff16565b8161151057fe5b0484828151811061151d57fe5b60200260200101818152505061154f8285838151811061153957fe5b602002602001015161230490919063ffffffff16565b84828151811061155b57fe5b60209081029190910101526001016114d5565b506115798a8261238b565b600285015461158e908a63ffffffff61230416565b60028601553360009081526004860160205260409020546115b5908a63ffffffff61230416565b3360009081526004870160205260408120919091555b84518110156116b65760008482815181106115e257fe5b602002602001015111156116ae576003808701546000838152600e89016020526040902090910154855161162f9033908f9086908a908290811061162257fe5b60200260200101516124c7565b8c6000336001600160a01b0316600080516020613454833981519152868a888151811061165857fe5b60200260200101516116928e600301546113448e8c8151811061167757fe5b60200260200101516113388b8d61230490919063ffffffff16565b426040516116a39493929190612d8f565b60405180910390a450505b6001016115cb565b50604051339082156108fc029083906000818181858888f193505050501580156116e4573d6000803e3d6000fd5b50896003336001600160a01b031660008051602061345483398151915260008d86426040516117169493929190612d8f565b60405180910390a489600080516020613474833981519152866002015461173c8d611aa9565b4260405161174c939291906133f6565b60405180910390a250505050505050505050565b600082815260016020908152604080832060028101546001600160a01b0386168552600482019093529083205490916117ab9161134490670de0b6b3a764000063ffffffff61232c16565b949350505050565b6000818152600160205260408120906117cc83336120cc565b9050801561183857336000908152600c830160205260409020546117f6908263ffffffff61236616565b336000818152600c85016020526040808220939093559151909183156108fc02918491818181858888f19350505050158015611836573d6000803e3d6000fd5b505b8260063360008181526004860160205260408082205490516000805160206134548339815191529261186f92909188904290612d8f565b60405180910390a4505050565b60009182526001602081815260408085206001600160a01b03949094168086526004808601845282872054878052600e9096018085528388208389528201855283882054958852845282872091875201909152909220549092565b60008181526001602052604081206002600682015460ff1660028111156118fa57fe5b1461190a576000199150506108a8565b6008015492915050565b6000818152600160208190526040822060068101548154600283015493830154600384015486958695869586958695929460ff90921693909290916119588d6118d7565b949d939c50919a509850965090945092505050565b670de0b6b3a764000081565b6000828152600160205260408120606061199285612556565b600a8301549091506000906119b690670de0b6b3a76400009063ffffffff61230416565b6119ce88670de0b6b3a764000063ffffffff61232c16565b816119d557fe5b04905060008286815181106119e657fe5b602002602001015190506000611a0d670de0b6b3a76400008361232c90919063ffffffff16565b905060005b8451811015611a5c57878114611a54576000858281518110611a3057fe5b60200260200101519050611a50610d9b868361230490919063ffffffff16565b9250505b600101611a12565b5060008111611a7d5760405162461bcd60e51b815260040161066990612dfc565b610e1b82610e0f611a9c84670de0b6b3a764000063ffffffff6125e916565b869063ffffffff61236616565b60008181526001602052604081206002600682015460ff166002811115611acc57fe5b148015611adf5750611add83610e3d565b155b15611b2757600281015460088201546000908152600e83016020526040902060030154611b1f919061134490670de0b6b3a764000063ffffffff61232c16565b9150506108a8565b6003810154600d8201546002830154611b5592916113449190670de0b6b3a76400000263ffffffff61232c16565b9392505050565b60035481565b60606000805480602002602001604051908101604052809291908181526020018280548015611bb057602002820191906000526020600020905b815481526020019060010190808311611b9c575b5050505050905090565b8160028060008381526001602052604090206006015460ff166002811115611bde57fe5b14611bfb5760405162461bcd60e51b815260040161066990613299565b6000848152600160209081526040808320868452600e8101835281842033855260048101909352922054611c415760405162461bcd60e51b815260040161066990612e60565b33600090815260068201602052604090205460ff1615611c735760405162461bcd60e51b8152600401610669906133b3565b6000611c7f878761129b565b33600090815260048401602052604081205491925090611cb490670de0b6b3a76400009061134490859063ffffffff61232c16565b90508084600101541015611cda5760405162461bcd60e51b815260040161066990612ff1565b6001840154611cef908263ffffffff61230416565b6001808601919091553360009081526006850160205260409020805460ff191690911790558760073360008181526004870160205260409081902054905160008051602061345483398151915291611d4d918d919088904290612d8f565b60405180910390a4604051339082156108fc029083906000818181858888f19350505050158015611d82573d6000803e3d6000fd5b505050505050505050565b6007546006546040516370a0823160e01b8152600092916001600160a01b0316906370a0823190611dc2903390600401612cc5565b60206040518083038186803b158015611dda57600080fd5b505afa158015611dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e129190810190612b32565b1015611e305760405162461bcd60e51b815260040161066990613068565b60025460008054600181810183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639091018390558282526020526040902034611e8c5760405162461bcd60e51b815260040161066990612e31565b428611611eab5760405162461bcd60e51b815260040161066990613141565b6001600160a01b038516611ed15760405162461bcd60e51b815260040161066990613312565b83600214611ef15760405162461bcd60e51b815260040161066990612f4c565b85815560068101805460ff19169055600354600a820155600019600882015560005b84811015611f5557600d820180546001818101835560009283526020808420909201849055838352600e85019091526040909120848155810182905501611f13565b506000600460009054906101000a90046001600160a01b03169050806001600160a01b031663d4876b9f60028d8d8a6005548d6000806040518963ffffffff1660e01b8152600401611fae989796959493929190612daa565b602060405180830381600087803b158015611fc857600080fd5b505af1158015611fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120009190810190612b32565b600983015561200f8334612619565b612018836121c2565b82336001600160a01b03167f928446b14f4c661d8499681f1d2eb118eb6e89066877a7d43e0672a27cc63a32878e8e8e8e60405161205a95949392919061340c565b60405180910390a3505060028054600101905598975050505050505050565b6000828152600160209081526040808320848452600e81019092528220829182916120a4878761129b565b6003820154600290920154909891975095509350505050565b6006546001600160a01b031681565b600082815260016020908152604080832060028101546001600160a01b03861685526004820190935290832054600b8201549192849261211692611344919063ffffffff61232c16565b6001600160a01b0385166000908152600c8401602052604090205490915081101561214657600092505050611355565b6001600160a01b0384166000908152600c8301602052604090205461135090829063ffffffff61230416565b6000818152600160205260409020600681015460ff16600281111561219357fe5b60010160028111156121a157fe5b60068201805460ff191660018360028111156121b957fe5b02179055505050565b6000818152600160205260408120905b600d82015481101561222a5780837f8270f0a0534b13b7f92d1dbd58aa75c5207b40c55fefa7a17110c6136ad7270b61220b868561129b565b4260405161221a929190613445565b60405180910390a36001016121d2565b5081600080516020613474833981519152826002015461224985611aa9565b42604051612259939291906133f6565b60405180910390a25050565b6000838152600160209081526040808320858452600e810183528184206001600160a01b0389168552600481019093529220546122a8908463ffffffff61230416565b6001600160a01b038716600090815260048301602052604090205560038101546122d8908463ffffffff61236616565b6003808301919091558201546122f4908463ffffffff61236616565b8260030181905550505050505050565b6000828211156123265760405162461bcd60e51b815260040161066990612fba565b50900390565b60008261233b57506000611355565b8282028284828161234857fe5b0414611b555760405162461bcd60e51b815260040161066990613100565b600082820183811015611b555760405162461bcd60e51b815260040161066990612ea1565b6000828152600160205260408120905b600d82015481101561240e576000818152600e83016020526040902060038101546123cc908563ffffffff61230416565b600382015560028101546123e6908563ffffffff61230416565b60028201556003830154612400908563ffffffff61230416565b60038401555060010161239b565b506001810154612424908363ffffffff61230416565b6001909101555050565b6000828152600160205260408120905b600d8201548110156124b1576000818152600e830160205260409020600381015461246f908563ffffffff61236616565b60038201556002810154612489908563ffffffff61236616565b600282015560038301546124a3908563ffffffff61236616565b60038401555060010161243e565b506001810154612424908363ffffffff61236616565b6000838152600160209081526040808320858452600e810183528184206001600160a01b03891685526004810190935292205461250a908463ffffffff61236616565b6001600160a01b0387166000908152600483016020526040902055600381015461253a908463ffffffff61230416565b6003808301919091558201546122f4908463ffffffff61230416565b600081815260016020908152604091829020600d8101548351818152818402810190930190935260609290918391801561259a578160200160208202803883390190505b50905060005b600d8301548110156125e1576000818152600e8401602052604090206003015482518390839081106125ce57fe5b60209081029190910101526001016125a0565b509392505050565b60008215612608578160018403816125fd57fe5b046001019050611355565b81838161261157fe5b049392505050565b600082815260016020526040902054829042118015612655575060008181526001602052604081206006015460ff16600281111561265357fe5b145b156126635761266381612172565b8260008060008381526001602052604090206006015460ff16600281111561268757fe5b146126a45760405162461bcd60e51b815260040161066990613299565b6000858152600160205260409020846126cf5760405162461bcd60e51b815260040161066990612f83565b600060606126dc88612556565b90506060815160405190808252806020026020018201604052801561270b578160200160208202803883390190505b506002850154909150600090156127fa5760005b835181101561275557600084828151811061273657fe5b602002602001015190508083101561274c578092505b5060010161271f565b5060005b83518110156127c55760008261278b86848151811061277457fe5b60200260200101518d61232c90919063ffffffff16565b8161279257fe5b0490506127a58b8263ffffffff61230416565b8483815181106127b157fe5b602090810291909101015250600101612759565b50806127de86600201548b61232c90919063ffffffff16565b816127e557fe5b0493506127f48a8560026129e5565b506127fe565b8893505b6002850154612813908563ffffffff61236616565b600286015533600090815260048601602052604090205461283a908563ffffffff61236616565b3360009081526004870160205260409020556128568a8a61242e565b60005b825181101561291c57600083828151811061287057fe5b60200260200101511115612914576003808701546000838152600e8901602052604090209091015484516128b09033908f90869089908290811061162257fe5b8c6000336001600160a01b0316600080516020613454833981519152868988815181106128d957fe5b60200260200101516128f88e600301546113448d8c8151811061167757fe5b426040516129099493929190612d8f565b60405180910390a450505b600101612859565b5060006129288b611aa9565b90506000670de0b6b3a7640000612945838863ffffffff61232c16565b8161294c57fe5b0490508b6002336001600160a01b031660008051602061345483398151915260008a86426040516129809493929190612d8f565b60405180910390a48b600080516020613474833981519152886002015484426040516129ae939291906133f6565b60405180910390a2505050505050505050505050565b60008082116126085760405162461bcd60e51b815260040161066990613034565b60008381526001602052604081206002810154600b8201548391612a149161134490889063ffffffff61232c16565b90506002846007811115612a2457fe5b1415612a7d57600b820154612a3f908263ffffffff61236616565b600b830155336000908152600c83016020526040902054612a66908263ffffffff61236616565b336000908152600c84016020526040902055612acc565b600b820154612a92908263ffffffff61230416565b600b830155336000908152600c83016020526040902054612ab9908263ffffffff61230416565b336000908152600c840160205260409020555b50509392505050565b80356001600160a01b038116811461135557600080fd5b60008083601f840112612afd578182fd5b5081356001600160401b03811115612b13578182fd5b602083019150836020828501011115612b2b57600080fd5b9250929050565b600060208284031215612b43578081fd5b5051919050565b600080600080600080600060a0888a031215612b64578283fd5b87356001600160401b0380821115612b7a578485fd5b612b868b838c01612aec565b909950975060208a0135915080821115612b9e578485fd5b50612bab8a828b01612aec565b90965094505060408801359250612bc58960608a01612ad5565b91506080880135905092959891949750929550565b600060208284031215612beb578081fd5b5035919050565b60008060408385031215612c04578182fd5b82359150612c158460208501612ad5565b90509250929050565b60008060408385031215612c30578182fd5b50508035926020909101359150565b600080600060608486031215612c53578283fd5b505081359360208301359350604090920135919050565b60008060008060808587031215612c7f578384fd5b5050823594602084013594506040840135936060013592509050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b81811015612d1157835183529284019291840191600101612cf5565b50909695505050505050565b901515815260200190565b94151585529215156020850152901515604084015215156060830152608082015260a00190565b90815260200190565b60c0810160038810612d6657fe5b968152602081019590955260408501939093526060840191909152608083015260a09091015290565b93845260208401929092526040830152606082015260800190565b600089825260e06020830152612dc460e08301898b612c9b565b6001600160a01b039790971660408301525063ffffffff948516606082015292909316608083015260a082015260c001529392505050565b6020808252601b908201527a6d7573742068617665206e6f6e2d7a65726f2062616c616e63657360281b604082015260600190565b60208082526015908201527407374616b65206e6565647320746f206265203e203605c1b604082015260600190565b60208082526021908201527f7573657220646f6573206e6f7420686f6c64206f7574636f6d652073686172656040820152607360f81b606082015260800190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b602080825260129082015271073686172657320616d6f756e7420697320360741b604082015260600190565b6020808252602a908201527f7573657220646f6573206e6f7420686f6c64207265736f6c766564206f7574636040820152696f6d652073686172657360b01b606082015260800190565b6020808252601e908201527f6e756d626572206f66206f7574636f6d65732068617320746f20626520320000604082015260600190565b6020808252601f908201527f7374616b652068617320746f2062652067726561746572207468616e20302e00604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526023908201527f4d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b6020808252601a9082015279536166654d6174683a206469766973696f6e206279207a65726f60301b604082015260600190565b6020808252602a908201527f6d73672e73656e646572206d75737420686f6c64206d696e696d756d2065726360408201526932302062616c616e636560b01b606082015260800190565b6020808252602e908201527f7573657220616c726561647920636c61696d6564207265736f6c766564206f7560408201526d74636f6d652077696e6e696e677360901b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602a908201527f6d61726b6574206d757374207265736f6c7665206166746572207468652063756040820152697272656e74206461746560b01b606082015260800190565b60208082526027908201527f7573657220616c726561647920636c61696d6564206c69717569646974792077604082015266696e6e696e677360c81b606082015260800190565b60208082526023908201527f7573657220646f6573206e6f7420686f6c64206c69717569646974792073686160408201526272657360e81b606082015260800190565b60208082526023908201527f6d61726b657420646f6573206e6f74206861766520656e6f7567682062616c616040820152626e636560e81b606082015260800190565b60208082526021908201527f7573657220646f6573206e6f74206861766520656e6f7567682062616c616e636040820152606560f81b606082015260800190565b6020808252601990820152784d61726b657420696e20696e636f727265637420737461746560381b604082015260600190565b60208082526026908201527f6f7574636f6d652073686172657320706f6f6c2062616c616e636520697320746040820152656f6f206c6f7760d01b606082015260800190565b6020808252601a9082015279696e76616c69642061726269747261746f72206164647265737360301b604082015260600190565b6020808252601e908201527f6d696e696d756d2062757920616d6f756e74206e6f7420726561636865640000604082015260600190565b6020808252601c908201527b1b585e1a5b5d5b481cd95b1b08185b5bdd5b9d08195e18d95959195960221b604082015260600190565b60208082526023908201527f7573657220616c726561647920636c61696d6564206f7574636f6d652073686160408201526272657360e81b606082015260800190565b9283526020830191909152604082015260600190565b600086825260606020830152613426606083018688612c9b565b8281036040840152613439818587612c9b565b98975050505050505050565b91825260208201526040019056fe9dcabe311735ed0d65f0c22c5425d1f17331f94c9d0767f59e58473cf95ada611eca98f266e5348ae38d5d057a4d8e451e76672f69ac6ba4b0e3b31ea9c7eb2ba26469706673582212209a05a587712745fd0a97aa37b7f385f4630d7eefab295188f89f8ce263f95ce064736f6c63430006020033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000008b29344f368b5fa35595325903fe0eaab70c8e1f00000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000083d3f4769a19f1b43337888b0290f5473cf508b2000000000000000000000000000000000000000000000000000000000003f480
-----Decoded View---------------
Arg [0] : _fee (uint256): 20000000000000000
Arg [1] : _token (address): 0x8b29344f368b5FA35595325903fE0eAab70C8E1F
Arg [2] : _requiredBalance (uint256): 1000000000000000000000
Arg [3] : _realitioAddress (address): 0x83d3f4769A19F1B43337888B0290F5473cf508b2
Arg [4] : _realitioTimeout (uint256): 259200
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000470de4df820000
Arg [1] : 0000000000000000000000008b29344f368b5fa35595325903fe0eaab70c8e1f
Arg [2] : 00000000000000000000000000000000000000000000003635c9adc5dea00000
Arg [3] : 00000000000000000000000083d3f4769a19f1b43337888b0290f5473cf508b2
Arg [4] : 000000000000000000000000000000000000000000000000000000000003f480
Deployed Bytecode Sourcemap
49503:31034:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52508:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52508:30:0;;;:::i;:::-;;;;;;;;;;;;;;;;76919:298;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;76919:298:0;;;;;;;;:::i;:::-;;;;;;;;;;65912:643;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65912:643:0;;;;;;;;:::i;75017:712::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;75017:712:0;;;;;;;;:::i;:::-;;;;;;;;;;;;79060:173;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;79060:173:0;;;;;;;;:::i;:::-;;;;;;;;59201:1320;;;;;;;;;:::i;:::-;;50431:117;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50431:117:0;;;:::i;52383:30::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52383:30:0;;;:::i;57972:1179::-;;;;;;;;;:::i;55988:903::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;55988:903:0;;;;;;;;:::i;77223:177::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;77223:177:0;;;;;;;;:::i;78623:393::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;78623:393:0;;;;;;;;:::i;:::-;;;;;;;;60577:188;;;;;;;;;:::i;68948:1063::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68948:1063:0;;;;;;;;:::i;66634:1038::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;66634:1038:0;;;;;;;;:::i;52348:30::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52348:30:0;;;:::i;:::-;;;;;;;;77406:266;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;77406:266:0;;;;;;;;:::i;52214:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52214:26:0;;;:::i;79239:527::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;79239:527:0;;;;;;;;:::i;63403:2429::-;;;;;;;;;:::i;75735:228::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;75735:228:0;;;;;;;;:::i;70097:545::-;;;;;;;;;:::i;74644:367::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74644:367:0;;;;;;;;:::i;78305:312::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;78305:312:0;;;;;;;;:::i;76472:441::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;76472:441:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;50555:36;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50555:36:0;;;:::i;56999:924::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;56999:924:0;;;;;;;;:::i;77678:621::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;77678:621:0;;;;;;;;:::i;52264:18::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52264:18:0;;;:::i;76374:92::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;76374:92:0;;;:::i;67753:1106::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;67753:1106:0;;;;;;;;:::i;54189:1720::-;;;;;;;;;:::i;79772:390::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;79772:390:0;;;;;;;;:::i;52440:19::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52440:19:0;;;:::i;75969:399::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;75969:399:0;;;;;;;;:::i;52508:30::-;;;;:::o;76919:298::-;77009:7;77090:17;;;:7;:17;;;;;77124:11;;;:17;77143:28;;;;;77124:17;;77143:28;;76919:298::o;65912:643::-;66092:7;52791:17;;;:7;:17;;;;;:35;65995:8;;52785:3;:41;:88;;;;-1:-1:-1;52857:16:0;52830:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;52785:88;52781:130;;;52884:19;52894:8;52884:9;:19::i;:::-;66018:8;66028:18:::1;::::0;52999:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;52991:70;;;;-1:-1:-1::0;;;52991:70:0::1;;;;;;;;;;;;;;;;;66111:21:::3;66135:17:::0;;;:7:::3;:17;::::0;;;;;66200:15:::3;::::0;;66317:28;;;;66298:48;;-1:-1:-1;;;66298:48:0;;66068:8;;66135:17;;-1:-1:-1;;;;;66200:15:0;;::::3;::::0;66111:21;66200:15;;66298:18:::3;::::0;:48:::3;::::0;::::3;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::3;5:2;66298:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::3;77:16;74:1;67:27;5:2;66298: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;66298:48:0;;;;;;;;;66356:27:::0;;;:39;;;66409:52:::3;::::0;66290:57;;-1:-1:-1;66436:8:0;;66424:10:::3;::::0;66409:52:::3;::::0;::::3;::::0;66290:57;;66457:3:::3;::::0;66409:52:::3;;;;;;;;;;66468:38;66497:8;66468:28;:38::i;:::-;-1:-1:-1::0;;66522:27:0;;;;-1:-1:-1;53292:19:0::2;53302:8;53292:9;:19::i;:::-;53068:1;52917::::1;;65912:643:::0;;;;:::o;75017:712::-;75123:4;75224:17;;;:7;:17;;;;;75123:4;;;;;;;;75304:20;75288:12;;;;;;:36;;;;;;;;;75284:132;;75343:5;75350;75357;75364;75371:36;75392:8;75402:4;75371:20;:36::i;:::-;75335:73;;;;;;;;;;;;;75284:132;75472:27;;;;75424:29;75456:44;;;:15;;;:44;;;;;;;;-1:-1:-1;;;;;75525:28:0;;;;:22;;;;:28;;;;;;75566:21;;;;:27;;;;;;75602:22;;;:28;;;;;;75643:22;;;:28;;;;;;;;75456:44;;75525:32;;;;75566:27;;;;;75602:32;;;;75643:28;75680:36;75701:8;75548:4;75680:20;:36::i;:::-;75509:214;;;;;;;;;;;;75017:712;;;;;;;;;:::o;79060:173::-;79155:21;79179:17;;;:7;:17;;;;;;;;;79210;;;79203:24;;;;;;;;;;;;;;;;;79130:16;;79179:17;;79203:24;;79210:17;79203:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79060:173;;;;:::o;59201:1320::-;52791:17;;;;:7;:17;;;;;:35;59357:8;;52785:3;:41;:88;;;;-1:-1:-1;52857:16:0;52830:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;52785:88;52781:130;;;52884:19;52894:8;52884:9;:19::i;:::-;59375:8;59385:16:::1;::::0;52999:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;52991:70;;;;-1:-1:-1::0;;;52991:70:0::1;;;;;;;;;59410:21:::2;59434:17:::0;;;:7:::2;:17;::::0;;;;;;;59490:26;;;:15:::2;::::0;::::2;:26:::0;;;;;59434:17;;59542:42:::2;59557:5:::0;59442:8;59506:9;59542:14:::2;:42::i;:::-;59525:59;;59611:22;59601:6;:32;;59593:73;;;;-1:-1:-1::0;;;59593:73:0::2;;;;;;;;;59690:1;59681:6;:10;59673:41;;;;-1:-1:-1::0;;;59673:41:0::2;;;;;;;;;59752:10;59729:34;::::0;;;:22;;;:34:::2;::::0;;;;;:44;-1:-1:-1;59729:44:0::2;59721:90;;;;-1:-1:-1::0;;;59721:90:0::2;;;;;;;;;59820:68;59848:10;59860:8;59870:9;59881:6;59820:27;:68::i;:::-;59937:17;59989:12;59997:3;;50585:6;59989:7;;:12;;;;:::i;:::-;59967:11;::::0;::::2;:17:::0;59957:28:::2;::::0;:5;;:28:::2;:9;:28;:::i;:::-;:45;;;;;60034:22:::0;;;;59957:45;;::::2;::::0;-1:-1:-1;60034:37:0::2;::::0;59957:45;60034:37:::2;:26;:37;:::i;:::-;60009:22:::0;;;:62;60078:21:::2;60102:20;:5:::0;60112:9;60102:20:::2;:9;:20;:::i;:::-;60078:44;;60157:13;60139:6;:14;;;:31;;60131:79;;;;-1:-1:-1::0;;;60131:79:0::2;;;;;;;;;60253:47;60276:8;60286:13;60253:22;:47::i;:::-;60344:26;::::0;:10:::2;::::0;:26;::::2;;;::::0;60364:5;;60344:26:::2;::::0;;;60364:5;60344:10;:26;::::2;;;;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;-1:-1:::0;60430:8:0;60411:17:::2;60399:10;-1:-1:-1::0;;;;;60384:86:0::2;-1:-1:-1::0;;;;;;;;;;;60440:9:0::2;60451:6;60459:5;60466:3;60384:86;;;;;;;;;;;;;;;;;;60477:38;60506:8;60477:28;:38::i;:::-;53068:1;;;;;52917::::1;;59201:1320:::0;;;;;:::o;50431:117::-;-1:-1:-1;;50431:117:0;:::o;52383:30::-;;;;:::o;57972:1179::-;52791:17;;;;:7;:17;;;;;:35;58106:8;;52785:3;:41;:88;;;;-1:-1:-1;52857:16:0;52830:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;52785:88;52781:130;;;52884:19;52894:8;52884:9;:19::i;:::-;58124:8;58134:16:::1;::::0;52999:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;52991:70;;;;-1:-1:-1::0;;;52991:70:0::1;;;;;;;;;58159:21:::2;58183:17:::0;;;:7:::2;:17;::::0;;;;;58225:9:::2;::::0;58258:41:::2;58225:9:::0;58191:8;58289:9;58258:13:::2;:41::i;:::-;58241:58;;58324:21;58314:6;:31;;58306:74;;;;-1:-1:-1::0;;;58306:74:0::2;;;;;;;;;58404:1;58395:6;:10;58387:41;;;;-1:-1:-1::0;;;58387:41:0::2;;;;;;;;;58514:11;::::0;::::2;:17:::0;58484::::2;::::0;50585:6:::2;::::0;58504:28:::2;::::0;:5;;:28:::2;:9;:28;:::i;:::-;:34;;;;;58570:22:::0;;;;58504:34;;::::2;::::0;-1:-1:-1;58570:37:0::2;::::0;58504:34;58570:37:::2;:26;:37;:::i;:::-;58545:22:::0;;;:62;58614:22:::2;58639:20;:5:::0;58649:9;58639:20:::2;:9;:20;:::i;:::-;58668:29;58700:26:::0;;;:15:::2;::::0;::::2;:26;::::0;;;;58614:45;;-1:-1:-1;58785:43:0::2;58803:8:::0;58614:45;58785:17:::2;:43::i;:::-;58845:24:::0;;;;:34;-1:-1:-1;58845:34:0::2;58837:85;;;;-1:-1:-1::0;;;58837:85:0::2;;;;;;;;;58931:70;58961:10;58973:8;58983:9;58994:6;58931:29;:70::i;:::-;59060:8:::0;59042:16:::2;59030:10;-1:-1:-1::0;;;;;59015:85:0::2;-1:-1:-1::0;;;;;;;;;;;59070:9:0::2;59081:6;59089:5;59096:3;59015:85;;;;;;;;;;55988:903:::0;56105:7;56145:17;;;:7;:17;;;;;56171:31;56205:33;56153:8;56205:23;:33::i;:::-;56171:67;;56245:23;56271:47;50585:6;56282:29;56293:6;:11;;:17;;;56282:6;:10;;:29;;;;:::i;:::-;:35;;;;;56271:6;;56282:35;;56271:47;:10;:47;:::i;:::-;56245:73;;56325:27;56355:14;56370:9;56355:25;;;;;;;;;;;;;;56325:55;;56387:28;56418;50585:6;56418:19;:23;;:28;;;;:::i;:::-;56387:59;-1:-1:-1;56458:9:0;56453:267;56477:14;:21;56473:1;:25;56453:267;;;56523:9;56518:1;:14;56514:199;;56545:21;56569:14;56584:1;56569:17;;;;;;;;;;;;;;56545:41;;56620:83;56668:34;56686:15;56668:13;:17;;:34;;;;:::i;:::-;56620:39;:20;56645:13;56620:39;:24;:39;:::i;:::-;:47;:83;:47;:83;:::i;:::-;56597:106;;56514:199;;56500:3;;56453:267;;;;56757:1;56734:20;:24;56726:64;;;;-1:-1:-1;;;56726:64:0;;;;;;;;;56806:79;56851:33;:20;50585:6;56851:33;:28;:33;:::i;:::-;56806:40;:19;56830:15;56806:40;:23;:40;:::i;:::-;:44;:79;:44;:79;:::i;:::-;56799:86;55988:903;-1:-1:-1;;;;;;;;;55988:903:0:o;77223:177::-;77291:7;77331:17;;;:7;:17;;;;;77365:28;;;;77223:177::o;78623:393::-;78686:4;78723:17;;;:7;:17;;;;;78825:20;78809:12;;;;;;:36;;;;;;;;;78805:71;;78863:5;78856:12;;;;;78805:71;78986:17;;;:24;78955:27;;;;;:55;;;78623:393;-1:-1:-1;;78623:393:0:o;60577:188::-;52791:17;;;;:7;:17;;;;;:35;60665:8;;52785:3;:41;:88;;;;-1:-1:-1;52857:16:0;52830:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;52785:88;52781:130;;;52884:19;52894:8;52884:9;:19::i;:::-;60688:8;60698:16:::1;::::0;52999:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;52991:70;;;;-1:-1:-1::0;;;52991:70:0::1;;;;;;;;;60726:33:::2;60739:8;60749:9;60726:12;:33::i;:::-;52917:1:::1;;60577:188:::0;;:::o;68948:1063::-;69007:8;69017:20;;52999:17;;;;:7;:17;;;;;:23;;;;;:32;;;;;;;;;52991:70;;;;-1:-1:-1;;;52991:70:0;;;;;;;;;69046:21:::1;69070:17:::0;;;:7:::1;:17;::::0;;;;69130:19:::1;69078:8:::0;69130:9:::1;:19::i;:::-;69189:10;69203:1;69166:34:::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;69158:86:::1;;;;-1:-1:-1::0;;;69158:86:0::1;;;;;;;;;69282:10;69259:34;::::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;::::1;;:43;69251:95;;;;-1:-1:-1::0;;;69251:95:0::1;;;;;;;;;69423:22;69448:33;69472:8;69448:23;:33::i;:::-;69546:10;69488:13;69523:34:::0;;;:22:::1;::::0;::::1;:34;::::0;;;;;69423:58;;-1:-1:-1;69488:13:0;50585:6:::1;::::0;69504:54:::1;::::0;69423:58;;69504:54:::1;:18;:54;:::i;:::-;:60;;;;;;69488:76;;69640:5;69622:6;:14;;;:23;;69614:71;;;;-1:-1:-1::0;;;69614:71:0::1;;;;;;;;;69711:14;::::0;::::1;::::0;:25:::1;::::0;69730:5;69711:25:::1;:18;:25;:::i;:::-;69694:14;::::0;;::::1;:42:::0;;;;69766:10:::1;69743:34;::::0;;;:22:::1;::::0;;::::1;:34;::::0;;;;;;;:41;;-1:-1:-1;;69743:41:0::1;::::0;;::::1;::::0;;;69903:22:::1;::::0;::::1;:34:::0;;;;;;69798:172;;69876:8;;69743:22;;69766:10;-1:-1:-1;;;;;;;;;;;69798:172:0;::::1;::::0;69946:5;;69960:3:::1;::::0;69798:172:::1;;;;;;;;;;69979:26;::::0;:10:::1;::::0;:26;::::1;;;::::0;69999:5;;69979:26:::1;::::0;;;69999:5;69979:10;:26;::::1;;;;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;69979:26:0;53068:1;;;68948:1063:::0;;;:::o;66634:1038::-;66692:8;66702:20;;52999:17;;;;:7;:17;;;;;:23;;;;;:32;;;;;;;;;52991:70;;;;-1:-1:-1;;;52991:70:0;;;;;;;;;66731:21:::1;66755:17:::0;;;:7:::1;:17;::::0;;;;;;;66835:27;;;;66819:44;;:15:::1;::::0;::::1;:44:::0;;;;;66911:10:::1;66880:42:::0;;:30;;;:42;;;;;;66872:101:::1;;;;-1:-1:-1::0;;;66872:101:0::1;;;;;;;;;67018:10;66988:41;::::0;;;:29;;;:41:::1;::::0;;;;;::::1;;:50;66980:109;;;;-1:-1:-1::0;;;66980:109:0::1;;;;;;;;;67174:10;67127:13;67143:42:::0;;;:30;;;:42:::1;::::0;;;;;67243:14:::1;::::0;::::1;::::0;:23;-1:-1:-1;67243:23:0::1;67235:71;;;;-1:-1:-1::0;;;67235:71:0::1;;;;;;;;;67332:14;::::0;::::1;::::0;:25:::1;::::0;67351:5;67332:25:::1;:18;:25;:::i;:::-;67315:14;::::0;;::::1;:42:::0;;;;67394:10:::1;67364:41;::::0;;;:29;;;:41:::1;::::0;;;;:48;;-1:-1:-1;;67364:48:0::1;::::0;;::::1;::::0;;67503:8;67468:26:::1;67520:27:::0;;;;67449:10:::1;67556:42;::::0;;;:30;;;:42:::1;::::0;;;;;;;67426:205;;67449:10;;-1:-1:-1;;;;;;;;;;;67426:205:0;::::1;::::0;67556:42;67607:5;;67621:3:::1;::::0;67426:205:::1;;52348:30:::0;;;-1:-1:-1;;;;;52348:30:0;;:::o;77406:266::-;77495:7;77511;77527;77560:33;77584:8;77560:23;:33::i;:::-;77595:34;77617:8;77627:1;77595:21;:34::i;:::-;77631;77653:8;77663:1;77631:21;:34::i;:::-;77552:114;;;;;;77406:266;;;;;:::o;52214:26::-;;;;:::o;79239:527::-;79328:7;79368:17;;;:7;:17;;;;;;;;79424:26;;;:15;;;:26;;;;;79479:20;79463:12;;;;;;:36;;;;;;;;;:65;;;;;79504:24;79519:8;79504:14;:24::i;:::-;79503:25;79463:65;79459:195;;;79609:27;;;;79596:40;;:50;;79645:1;79596:50;;;50585:6;79596:50;79589:57;;;;;;79459:195;79737:22;;;;;79697:24;;;;79669:91;;79737:22;79669:63;;50585:6;;79670:52;;79737:22;;79670:52;:26;:52;:::i;:::-;79669:58;:63;:58;:63;:::i;:::-;:67;:91;:67;:91;:::i;:::-;79662:98;;;;79239:527;;;;;:::o;63403:2429::-;52791:17;;;;:7;:17;;;;;:35;63510:8;;52785:3;:41;:88;;;;-1:-1:-1;52857:16:0;52830:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;52785:88;52781:130;;;52884:19;52894:8;52884:9;:19::i;:::-;63533:8;63543:16:::1;::::0;52999:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;52991:70;;;;-1:-1:-1::0;;;52991:70:0::1;;;;;;;;;63571:21:::2;63595:17:::0;;;:7:::2;:17;::::0;;;;;;;63652:10:::2;63629:34:::0;;:22:::2;::::0;::::2;:34:::0;;;;;;;:44;-1:-1:-1;63629:44:0::2;63621:90;;;;-1:-1:-1::0;;;63621:90:0::2;;;;;;;;;63752:19;63762:8;63752:9;:19::i;:::-;63811:65;63829:8;63839:6;63847:28;63811:17;:65::i;:::-;;63885:31;63919:33;63943:8;63919:23;:33::i;:::-;63885:67;;63959:28;64004:14;:21;63990:36;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;::::0;-1:-1;63990:36:0::2;-1:-1:-1::0;63959:67:0;-1:-1:-1;;;64033:18:0::2;64163:177;64187:14;:21;64183:1;:25;64163:177;;;64224:21;64248:14;64263:1;64248:17;;;;;;;;;;;;;;64224:41;;64291:13;64278:10;:26;64274:58;;;64319:13;64306:26;;64274:58;-1:-1:-1::0;64210:3:0::2;;64163:177;;;-1:-1:-1::0;64401:16:0::2;::::0;::::2;::::0;64348:23:::2;::::0;64374:44:::2;::::0;:22:::2;:6:::0;64385:10;64374:22:::2;:10;:22;:::i;:44::-;64348:70:::0;-1:-1:-1;64432:9:0::2;64427:195;64451:14;:21;64447:1;:25;64427:195;;;64537:6;:16;;;64505:29;64527:6;64505:14;64520:1;64505:17;;;;;;;;;;;;;;:21;;:29;;;;:::i;:::-;:48;;;;;;64488:11;64500:1;64488:14;;;;;;;;;;;;;:65;;;::::0;::::2;64579:35;64598:15;64579:11;64591:1;64579:14;;;;;;;;;;;;;;:18;;:35;;;;:::i;:::-;64562:11;64574:1;64562:14;;;;;;;;;::::0;;::::2;::::0;;;;;:52;64474:3:::2;;64427:195;;;;64669:49;64692:8;64702:15;64669:22;:49::i;:::-;64744:16;::::0;::::2;::::0;:28:::2;::::0;64765:6;64744:28:::2;:20;:28;:::i;:::-;64725:16;::::0;::::2;:47:::0;64893:10:::2;64870:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;;:46:::2;::::0;64909:6;64870:46:::2;:38;:46;:::i;:::-;64856:10;64833:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;:83;;;;64925:594:::2;64949:14;:21;64945:1;:25;64925:594;;;65007:1;64990:11;65002:1;64990:14;;;;;;;;;;;;;;:18;64986:526;;;65044:22;::::0;;::::2;::::0;65021:20:::2;65101:18:::0;;;:15:::2;::::0;::::2;:18;::::0;;;;:35;;;;65204:14;;65149:70:::2;::::0;65179:10:::2;::::0;65191:8;;65117:1;;65204:11;;65117:1;;65204:14;::::2;;;;;;;;;;;65149:29;:70::i;:::-;65314:8:::0;65285:16:::2;65262:10;-1:-1:-1::0;;;;;65235:267:0::2;-1:-1:-1::0;;;;;;;;;;;65335:1:0::2;65349:11;65361:1;65349:14;;;;;;;;;;;;;;65376:81;65434:6;:22;;;65376:53;65414:11;65426:1;65414:14;;;;;;;;;;;;;;65377:31;65394:13;65377:12;:16;;:31;;;;:::i;65376:81::-;65488:3;65235:267;;;;;;;;;;;;;;;;;;64986:526;;;64972:3;;64925:594;;;-1:-1:-1::0;65582:36:0::2;::::0;:10:::2;::::0;:36;::::2;;;::::0;65602:15;;65582:36:::2;::::0;;;65602:15;65582:10;:36;::::2;;;;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;-1:-1:::0;65689:8:0;65659:28:::2;65647:10;-1:-1:-1::0;;;;;65632:99:0::2;-1:-1:-1::0;;;;;;;;;;;65699:1:0::2;65702:6;65710:15;65727:3;65632:99;;;;;;;;;;;;;;;;;;65759:8;-1:-1:-1::0;;;;;;;;;;;65769:6:0::2;:16;;;65787:33;65811:8;65787:23;:33::i;:::-;65822:3;65743:83;;;;;;;;;;;;;;;;;53068:1;;;;;52917::::1;;63403:2429:::0;;;:::o;75735:228::-;75825:7;75865:17;;;:7;:17;;;;;;;;75940:16;;;;-1:-1:-1;;;;;75898:28:0;;;;:22;;;:28;;;;;;;75865:17;;75898:59;;:37;;50585:6;75898:37;:32;:37;:::i;:59::-;75891:66;75735:228;-1:-1:-1;;;;75735:228:0:o;70097:545::-;70156:21;70180:17;;;:7;:17;;;;;;70230:42;70188:8;70261:10;70230:20;:42::i;:::-;70206:66;-1:-1:-1;70285:17:0;;70281:167;;70367:10;70347:31;;;;:19;;;:31;;;;;;:50;;70383:13;70347:50;:35;:50;:::i;:::-;70333:10;70313:31;;;;:19;;;:31;;;;;;:84;;;;70406:34;;70333:10;;70406:34;;;;;70426:13;;70406:34;70313:31;70406:34;70426:13;70333:10;70406:34;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70406:34:0;70281:167;70534:8;70503:22;70484:10;70551:1;70561:34;;;:22;;;:34;;;;;;;70461:175;;-1:-1:-1;;;;;;;;;;;70461:175:0;;;70551:1;;70604:13;;70626:3;;70461:175;;;;;;;;;;70097:545;;;:::o;74644:367::-;74751:7;74832:17;;;:7;:17;;;;;;;;-1:-1:-1;;;;;74874:28:0;;;;;;;:22;;;;:28;;;;;;74911:18;;;:15;;;;:18;;;;;;:39;;;:33;;:39;;;;;;74959:18;;;;;;;;:39;;;:33;:39;;;;;;;74874:28;;74644:367::o;78305:312::-;78378:6;78417:17;;;:7;:17;;;;;78513:20;78497:12;;;;;;:36;;;;;;;;;78493:68;;-1:-1:-1;;78544:9:0;;;;;78493:68;78583:27;;;;78305:312;-1:-1:-1;;78305:312:0:o;76472:441::-;76559:11;76691:17;;;:7;:17;;;;;;;76733:12;;;;76754:24;;76787:16;;;;76812:14;;;;76835:22;;;;76559:11;;;;;;;;;;76691:17;;76733:12;;;;;76754:24;;76787:16;;76866:34;76699:8;76866:24;:34::i;:::-;76717:190;;;;-1:-1:-1;76717:190:0;;-1:-1:-1;76717:190:0;-1:-1:-1;76717:190:0;-1:-1:-1;76717:190:0;;-1:-1:-1;76472:441:0;-1:-1:-1;;;76472:441:0:o;50555:36::-;50585:6;50555:36;:::o;56999:924::-;57117:30;57180:17;;;:7;:17;;;;;57206:31;57240:33;57188:8;57240:23;:33::i;:::-;57331:11;;;:17;57206:67;;-1:-1:-1;57280:22:0;;57323:26;;50585:6;;57323:26;:7;:26;:::i;:::-;57305:15;:6;50585;57305:15;:10;:15;:::i;:::-;:44;;;;;;57280:69;;57356:28;57387:14;57402:9;57387:25;;;;;;;;;;;;;;57356:56;;57419:28;57450:29;50585:6;57450:20;:24;;:29;;;;:::i;:::-;57419:60;-1:-1:-1;57491:9:0;57486:266;57510:14;:21;57506:1;:25;57486:266;;;57556:9;57551:1;:14;57547:198;;57578:21;57602:14;57617:1;57602:17;;;;;;;;;;;;;;57578:41;;57653:82;57701:33;57719:14;57701:13;:17;;:33;;;;:::i;57653:82::-;57630:105;;57547:198;;57533:3;;57486:266;;;;57789:1;57766:20;:24;57758:64;;;;-1:-1:-1;;;57758:64:0;;;;;;;;;57838:79;57896:20;57838:53;57857:33;:20;50585:6;57857:33;:28;:33;:::i;:::-;57838:14;;:53;:18;:53;:::i;77678:621::-;77750:7;77790:17;;;:7;:17;;;;;77836:20;77820:12;;;;;;:36;;;;;;;;;:65;;;;;77861:24;77876:8;77861:14;:24::i;:::-;77860:25;77820:65;77816:305;;;78096:16;;;;78037:27;;;;78021:44;;;;:15;;;:44;;;;;:61;;;:92;;78096:16;78021:70;;50585:6;78021:70;:65;:70;:::i;:92::-;78014:99;;;;;77816:305;78270:22;;;;78240:17;;;:24;78213:16;;;;:80;;78270:22;78213:52;;:16;50585:6;78234:30;78213:52;:20;:52;:::i;:80::-;78206:87;77678:621;-1:-1:-1;;;77678:621:0:o;52264:18::-;;;;:::o;76374:92::-;76419:16;76451:9;76444:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76374:92;:::o;67753:1106::-;67851:8;67861:20;;52999:17;;;;:7;:17;;;;;:23;;;;;:32;;;;;;;;;52991:70;;;;-1:-1:-1;;;52991:70:0;;;;;;;;;67893:21:::1;67917:17:::0;;;:7:::1;:17;::::0;;;;;;;67973:26;;;:15:::1;::::0;::::1;:26:::0;;;;;68039:10:::1;68016:34:::0;;:22;;;:34;;;;;;68008:84:::1;;;;-1:-1:-1::0;;;68008:84:0::1;;;;;;;;;68135:10;68107:39;::::0;;;:27;;;:39:::1;::::0;;;;;::::1;;:48;68099:96;;;;-1:-1:-1::0;;;68099:96:0::1;;;;;;;;;68267:13;68283:42;68305:8;68315:9;68283:21;:42::i;:::-;68381:10;68332:13;68358:34:::0;;;:22;;;:34:::1;::::0;;;;;68267:58;;-1:-1:-1;68332:13:0;68348:54:::1;::::0;50585:6:::1;::::0;68348:45:::1;::::0;68267:58;;68348:45:::1;:9;:45;:::i;:54::-;68332:70;;68478:5;68460:6;:14;;;:23;;68452:71;;;;-1:-1:-1::0;;;68452:71:0::1;;;;;;;;;68549:14;::::0;::::1;::::0;:25:::1;::::0;68568:5;68549:25:::1;:18;:25;:::i;:::-;68532:14;::::0;;::::1;:42:::0;;;;68609:10:::1;68581:39;::::0;;;:27;;;:39:::1;::::0;;;;:46;;-1:-1:-1;;68581:46:0::1;::::0;;::::1;::::0;;68716:8;68683:24:::1;68664:10;68751:34;::::0;;;:22;;;:34:::1;::::0;;;;;;;68641:177;;-1:-1:-1;;;;;;;;;;;68641:177:0;::::1;::::0;68733:9;;68751:34;68794:5;;68808:3:::1;::::0;68641:177:::1;;;;;;;;;;68827:26;::::0;:10:::1;::::0;:26;::::1;;;::::0;68847:5;;68827:26:::1;::::0;;;68847:5;68827:10;:26;::::1;;;;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;68827:26:0;53068:1;;;;67753:1106:::0;;;;:::o;54189:1720::-;53404:15;;53373:5;;:27;;-1:-1:-1;;;53373:27:0;;54398:7;;53404:15;-1:-1:-1;;;;;53373:5:0;;:15;;:27;;53389:10;;53373:27;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53373:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53373:27: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;53373:27:0;;;;;;;;;:46;;53365:101;;;;-1:-1:-1;;;53365:101:0;;;;;;;;;54433:11:::1;::::0;54414:16:::1;27:10:-1::0;;39:1:::1;23:18:::0;;::::1;45:23:::0;;54451:24:0;;;::::1;::::0;;;54508:17;;;54451:24:::1;54508:17:::0;;;;54542:9:::1;54534:47;;;;-1:-1:-1::0;;;54534:47:0::1;;;;;;;;;54607:3;54596:8;:14;54588:69;;;;-1:-1:-1::0;;;54588:69:0::1;;;;;;;;;-1:-1:-1::0;;;;;54672:24:0;::::1;54664:63;;;;-1:-1:-1::0;;;54664:63:0::1;;;;;;;;;54775:8;54787:1;54775:13;54767:56;;;;-1:-1:-1::0;;;54767:56:0::1;;;;;;;;;54832:35:::0;;;54874:12:::1;::::0;::::1;:31:::0;;-1:-1:-1;;54874:31:0::1;::::0;;54932:3:::1;::::0;54912:11:::1;::::0;::::1;:23:::0;-1:-1:-1;;55020:27:0;;;:42;54832:24:::1;55104:201;55128:8;55124:1;:12;55104:201;;;55152:17;::::0;::::1;27:10:-1::0;;39:1:::1;23:18:::0;;::::1;45:23:::0;;-1:-1;55152:25:0;;;::::1;::::0;;;;;::::1;::::0;;;55218:18;;;:15:::1;::::0;::::1;:18:::0;;;;;;;55247:27;;;55283:10;::::1;:14:::0;;;55138:3:::1;55104:201;;;;55351:22;55390:15;;;;;;;;;-1:-1:-1::0;;;;;55390:15:0::1;55351:55;;55446:8;-1:-1:-1::0;;;;;55446:25:0::1;;55480:1;55490:8;;55507:10;55533:15;;55565:8;55583:1;55593::::0;55446:155:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;55446:155:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;55446:155: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;55446:155:0;;;;;;;;;55415:28:::0;;;:186;55610:33:::1;55623:8:::0;55633:9:::1;55610:12;:33::i;:::-;55689:38;55718:8;55689:28;:38::i;:::-;55765:8;55753:10;-1:-1:-1::0;;;;;55739:62:0::1;;55775:8;55785;;55795:5;;55739:62;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;55864:11:0::1;::::0;;55878:1:::1;55864:15;55850:29:::0;;55895:8;54189:1720;-1:-1:-1;;;;;;;;54189:1720:0:o;79772:390::-;79885:7;79966:17;;;:7;:17;;;;;;;;80022:26;;;:15;;;:26;;;;;79885:7;;;;80065:42;79974:8;80038:9;80065:21;:42::i;:::-;80109:24;;;;:14;;;;80135:20;80057:99;;80109:24;;-1:-1:-1;80135:20:0;-1:-1:-1;79772:390:0;-1:-1:-1;;;;79772:390:0:o;52440:19::-;;;-1:-1:-1;;;;;52440:19:0;;:::o;75969:399::-;76052:7;76092:17;;;:7;:17;;;;;;;;76199:16;;;;-1:-1:-1;;;;;76165:28:0;;;;:22;;;:28;;;;;;;76138:22;;;;76092:17;;76052:7;;76138:78;;:56;;:22;:56;:26;:56;:::i;:78::-;-1:-1:-1;;;;;76259:25:0;;;;;;:19;;;:25;;;;;;76118:98;;-1:-1:-1;76259:37:0;-1:-1:-1;76255:51:0;;;76305:1;76298:8;;;;;;76255:51;-1:-1:-1;;;;;76336:25:0;;;;;;:19;;;:25;;;;;;76322:40;;:9;;:40;:13;:40;:::i;71470:159::-;71522:21;71546:17;;;:7;:17;;;;;71605:12;;;;;;71597:21;;;;;;;;71621:1;71597:25;71585:38;;;;;;;;71570:12;;;:53;;-1:-1:-1;;71570:53:0;;;;;;;;;;;;;;;;71470:159;;:::o;71693:415::-;71764:21;71788:17;;;:7;:17;;;;;;71814:149;71838:17;;;:24;71834:28;;71814:149;;;71912:1;71902:8;71883:72;71915:34;71937:8;71947:1;71915:21;:34::i;:::-;71951:3;71883:72;;;;;;;;;;;;;;;;71864:3;;71814:149;;;;72035:8;-1:-1:-1;;;;;;;;;;;72045:6:0;:16;;;72063:33;72087:8;72063:23;:33::i;:::-;72098:3;72019:83;;;;;;;;;;;;;;;;;71693:415;;:::o;74060:507::-;74204:21;74228:17;;;:7;:17;;;;;;;;74284:26;;;:15;;;:26;;;;;-1:-1:-1;;;;;74385:28:0;;;;:22;;;:28;;;;;;:40;;74418:6;74385:40;:32;:40;:::i;:::-;-1:-1:-1;;;;;74354:28:0;;;;;;:22;;;:28;;;;;:71;74459:24;;;;:36;;74488:6;74459:36;:28;:36;:::i;:::-;74432:24;;;;:63;;;;74527:22;;;:34;;74554:6;74527:34;:26;:34;:::i;:::-;74502:6;:22;;:59;;;;74060:507;;;;;;:::o;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;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;;;;;;;;44471:179;44529:7;44561:5;;;44585:6;;;;44577:46;;;;-1:-1:-1;;;44577:46:0;;;;;;;;72800:593;72881:21;72905:17;;;:7;:17;;;;;;72931:405;72955:17;;;:24;72951:28;;72931:405;;;72995:29;73027:18;;;:15;;;:18;;;;;73083:24;;;;:36;;73112:6;73083:36;:28;:36;:::i;:::-;73056:24;;;:63;:14;;;73151:20;:32;;73176:6;73151:32;:24;:32;:::i;:::-;73128:14;;;:55;73294:22;;;;:34;;73321:6;73294:34;:26;:34;:::i;:::-;73269:22;;;:59;-1:-1:-1;72981:3:0;;72931:405;;;-1:-1:-1;73361:14:0;;;;:26;;73380:6;73361:26;:18;:26;:::i;:::-;73344:14;;;;:43;-1:-1:-1;;72800:593:0:o;72161:581::-;72237:21;72261:17;;;:7;:17;;;;;;72287:398;72311:17;;;:24;72307:28;;72287:398;;;72351:29;72383:18;;;:15;;;:18;;;;;72439:24;;;;:36;;72468:6;72439:36;:28;:36;:::i;:::-;72412:24;;;:63;:14;;;72507:20;:32;;72532:6;72507:32;:24;:32;:::i;:::-;72484:14;;;:55;72643:22;;;;:34;;72670:6;72643:34;:26;:34;:::i;:::-;72618:22;;;:59;-1:-1:-1;72337:3:0;;72287:398;;;-1:-1:-1;72710:14:0;;;;:26;;72729:6;72710:26;:18;:26;:::i;73461:526::-;73607:21;73631:17;;;:7;:17;;;;;;;;73687:26;;;:15;;;:26;;;;;-1:-1:-1;;;;;73805:28:0;;;;:22;;;:28;;;;;;:40;;73838:6;73805:40;:32;:40;:::i;:::-;-1:-1:-1;;;;;73774:28:0;;;;;;:22;;;:28;;;;;:71;73879:24;;;;:36;;73908:6;73879:36;:28;:36;:::i;:::-;73852:24;;;;:63;;;;73947:22;;;:34;;73974:6;73947:34;:26;:34;:::i;80168:366::-;80266:21;80290:17;;;:7;:17;;;;;;;;;80356;;;:24;80342:39;;;;;;;;;;;;;;;;80241:16;;80290:17;;80241:16;;80342:39;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;80342:39:0;-1:-1:-1;80316:65:0;-1:-1:-1;80393:9:0;80388:119;80412:17;;;:24;80408:28;;80388:119;;;80464:18;;;;:15;;;:18;;;;;:35;;;80452:9;;:6;;80480:1;;80452:9;;;;;;;;;;;;;;;:47;80438:3;;80388:119;;;-1:-1:-1;80522:6:0;80168:366;-1:-1:-1;;;80168:366:0:o;49322:138::-;49384:7;49404:5;;49400:35;;49429:1;49424;49420;:5;49419:11;;;;;;49434:1;49418:17;49411:24;;;;49400:35;49453:1;49449;:5;;;;;;;49322:138;-1:-1:-1;;;49322:138:0:o;60839:2505::-;52791:17;;;;:7;:17;;;;;:35;60928:8;;52785:3;:41;:88;;;;-1:-1:-1;52857:16:0;52830:17;;;:7;:17;;;;;:23;;;;;:43;;;;;;;;;52785:88;52781:130;;;52884:19;52894:8;52884:9;:19::i;:::-;60951:8;60961:16:::1;::::0;52999:17:::1;::::0;;;:7:::1;:17;::::0;;;;:23:::1;;::::0;::::1;;:32;::::0;::::1;;;;;;;52991:70;;;;-1:-1:-1::0;;;52991:70:0::1;;;;;;;;;60989:21:::2;61013:17:::0;;;:7:::2;:17;::::0;;;;61047:9;61039:53:::2;;;;-1:-1:-1::0;;;61039:53:0::2;;;;;;;;;61101:23;61133:31;61167:33;61191:8;61167:23;:33::i;:::-;61133:67;;61207:32;61256:14;:21;61242:36;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;::::0;-1:-1;61242:36:0::2;-1:-1:-1::0;61320:16:0::2;::::0;::::2;::::0;61207:71;;-1:-1:-1;61285:18:0::2;::::0;61320:20;61316:784:::2;;61446:9;61441:183;61465:14;:21;61461:1;:25;61441:183;;;61504:21;61528:14;61543:1;61528:17;;;;;;;;;;;;;;61504:41;;61573:13;61560:10;:26;61556:58;;;61601:13;61588:26;;61556:58;-1:-1:-1::0;61488:3:0::2;;61441:183;;;-1:-1:-1::0;61639:9:0::2;61634:186;61658:14;:21;61654:1;:25;61634:186;;;61697:17;61748:10;61717:28;61727:14;61742:1;61727:17;;;;;;;;;;;;;;61717:5;:9;;:28;;;;:::i;:::-;:41;;;;;;::::0;-1:-1:-1;61790:20:0::2;:5:::0;61717:41;61790:20:::2;:9;:20;:::i;:::-;61769:15;61785:1;61769:18;;;;;;;;;::::0;;::::2;::::0;;;;;:41;-1:-1:-1;61681:3:0::2;;61634:186;;;;61878:10;61848:27;61858:6;:16;;;61848:5;:9;;:27;;;;:::i;:::-;:40;;;;;;61830:58;;61932:71;61950:8;61960:15;61977:25;61932:17;:71::i;:::-;;61316:784;;;62087:5;62069:23;;61316:784;62150:16;::::0;::::2;::::0;:37:::2;::::0;62171:15;62150:37:::2;:20;:37;:::i;:::-;62131:16;::::0;::::2;:56:::0;62254:10:::2;62231:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;;:55:::2;::::0;62270:15;62231:55:::2;:38;:55;:::i;:::-;62217:10;62194:34;::::0;;;:22:::2;::::0;::::2;:34;::::0;;;;:92;62295:34:::2;62313:8:::0;62323:5;62295:17:::2;:34::i;:::-;62403:9;62398:609;62422:15;:22;62418:1;:26;62398:609;;;62485:1;62464:15;62480:1;62464:18;;;;;;;;;;;;;;:22;62460:540;;;62522:22;::::0;;::::2;::::0;62499:20:::2;62579:18:::0;;;:15:::2;::::0;::::2;:18;::::0;;;;:35;;;;62680:18;;62625:74:::2;::::0;62655:10:::2;::::0;62667:8;;62595:1;;62680:15;;62595:1;;62680:18;::::2;;;;62625:74;62794:8:::0;62765:16:::2;62742:10;-1:-1:-1::0;;;;;62715:275:0::2;-1:-1:-1::0;;;;;;;;;;;62815:1:0::2;62829:15;62845:1;62829:18;;;;;;;;;;;;;;62860:85;62922:6;:22;;;62860:57;62898:15;62914:1;62898:18;;;;;;;62860:85;62976:3;62715:275;;;;;;;;;;;;;;;;;;62460:540;;;62446:3;;62398:609;;;;63015:22;63040:33;63064:8;63040:23;:33::i;:::-;63015:58:::0;-1:-1:-1;63080:22:0::2;50585:6;63105:35;63015:58:::0;63124:15;63105:35:::2;:18;:35;:::i;:::-;:41;;;;;;::::0;-1:-1:-1;63212:8:0;63185:25:::2;63173:10;-1:-1:-1::0;;;;;63158:104:0::2;-1:-1:-1::0;;;;;;;;;;;63222:1:0::2;63225:15;63242:14;63258:3;63158:104;;;;;;;;;;;;;;;;;;63290:8;-1:-1:-1::0;;;;;;;;;;;63300:6:0::2;:16;;;63318:14;63334:3;63274:64;;;;;;;;;;;;;;;;;53068:1;;;;;;;52917::::1;;60839:2505:::0;;;:::o;46048:153::-;46106:7;46138:1;46134;:5;46126:44;;;;-1:-1:-1;;;46126:44:0;;;;;;;;70738:681;70866:7;70906:17;;;:7;:17;;;;;71001:16;;;;70973:22;;;;70866:7;;70953:65;;:43;;:15;;:43;:19;:43;:::i;:65::-;70932:86;-1:-1:-1;71041:25:0;71031:6;:35;;;;;;;;;71027:387;;;71102:22;;;;:38;;71129:10;71102:38;:26;:38;:::i;:::-;71077:22;;;:63;71203:10;71183:31;;;;:19;;;:31;;;;;;:47;;71219:10;71183:47;:35;:47;:::i;:::-;71169:10;71149:31;;;;:19;;;:31;;;;;:81;71027:387;;;71278:22;;;;:38;;71305:10;71278:38;:26;:38;:::i;:::-;71253:22;;;:63;71379:10;71359:31;;;;:19;;;:31;;;;;;:47;;71395:10;71359:47;:35;:47;:::i;:::-;71345:10;71325:31;;;;:19;;;:31;;;;;:81;71027:387;70738:681;;;;;;;:::o;5:130:-1:-;72:20;;-1:-1;;;;;35487:54;;37211:35;;37201:2;;37260:1;;37250:12;298:337;;;413:3;406:4;398:6;394:17;390:27;380:2;;-1:-1;;421:12;380:2;-1:-1;451:20;;-1:-1;;;;;480:30;;477:2;;;-1:-1;;513:12;477:2;557:4;549:6;545:17;533:29;;608:3;557:4;588:17;549:6;574:32;;571:41;568:2;;;625:1;;615:12;568:2;373:262;;;;;;921:263;;1036:2;1024:9;1015:7;1011:23;1007:32;1004:2;;;-1:-1;;1042:12;1004:2;-1:-1;220:13;;998:186;-1:-1;998:186;1191:995;;;;;;;;1403:3;1391:9;1382:7;1378:23;1374:33;1371:2;;;-1:-1;;1410:12;1371:2;1455:31;;-1:-1;;;;;1495:30;;;1492:2;;;-1:-1;;1528:12;1492:2;1566:65;1623:7;1614:6;1603:9;1599:22;1566:65;;;1556:75;;-1:-1;1556:75;-1:-1;1696:2;1681:18;;1668:32;;-1:-1;1709:30;;;1706:2;;;-1:-1;;1742:12;1706:2;;1780:65;1837:7;1828:6;1817:9;1813:22;1780:65;;;1770:75;;-1:-1;1770:75;-1:-1;;1882:2;1921:22;;710:20;;-1:-1;2008:53;2053:7;1990:2;2029:22;;2008:53;;;1998:63;;2098:3;2142:9;2138:22;710:20;2107:63;;1365:821;;;;;;;;;;;2193:241;;2297:2;2285:9;2276:7;2272:23;2268:32;2265:2;;;-1:-1;;2303:12;2265:2;-1:-1;710:20;;2259:175;-1:-1;2259:175;2711:366;;;2832:2;2820:9;2811:7;2807:23;2803:32;2800:2;;;-1:-1;;2838:12;2800:2;723:6;710:20;2890:63;;3008:53;3053:7;2990:2;3033:9;3029:22;3008:53;;;2998:63;;2794:283;;;;;;3084:366;;;3205:2;3193:9;3184:7;3180:23;3176:32;3173:2;;;-1:-1;;3211:12;3173:2;-1:-1;;710:20;;;3363:2;3402:22;;;710:20;;-1:-1;3167:283;3457:491;;;;3595:2;3583:9;3574:7;3570:23;3566:32;3563:2;;;-1:-1;;3601:12;3563:2;-1:-1;;710:20;;;3753:2;3792:22;;710:20;;-1:-1;3861:2;3900:22;;;710:20;;3557:391;-1:-1;3557:391;3955:617;;;;;4110:3;4098:9;4089:7;4085:23;4081:33;4078:2;;;-1:-1;;4117:12;4078:2;-1:-1;;710:20;;;4269:2;4308:22;;710:20;;-1:-1;4377:2;4416:22;;710:20;;4485:2;4524:22;710:20;;-1:-1;4072:500;-1:-1;4072:500;6750:300;;34705:6;34700:3;34693:19;36861:6;36856:3;34742:4;34737:3;34733:14;36838:30;-1:-1;34742:4;36908:6;34737:3;36899:16;;36892:27;34742:4;37017:7;;37021:2;7036:6;37001:14;36997:28;34737:3;7005:39;;6998:46;;6852:198;;;;;;16418:213;-1:-1;;;;;35487:54;;;;4981:37;;16536:2;16521:18;;16507:124;16874:361;17042:2;17056:47;;;34418:12;;17027:18;;;34693:19;;;16874:361;;17042:2;34272:14;;;;34733;;;;16874:361;5469:260;5494:6;5491:1;5488:13;5469:260;;;5555:13;;5941:37;;34548:14;;;;4733;;;;5516:1;5509:9;5469:260;;;-1:-1;17109:116;;17013:222;-1:-1;;;;;;17013:222;17242:201;35097:13;;35090:21;5824:34;;17354:2;17339:18;;17325:118;17450:611;35097:13;;35090:21;5824:34;;35097:13;;35090:21;17809:2;17794:18;;5824:34;35097:13;;35090:21;17886:2;17871:18;;5824:34;35097:13;35090:21;17963:2;17948:18;;5824:34;18046:3;18031:19;;5941:37;17656:3;17641:19;;17627:434;18068:213;5941:37;;;18186:2;18171:18;;18157:124;18534:795;18804:3;18789:19;;37123:1;37113:12;;37103:2;;37129:9;37103:2;6234:64;;;18983:2;18968:18;;5941:37;;;;19066:2;19051:18;;5941:37;;;;19149:2;19134:18;;5941:37;;;;19232:3;19217:19;;5941:37;19314:3;19299:19;;;5941:37;18775:554;;19552:563;6506:58;;;19935:2;19920:18;;5941:37;;;;20018:2;20003:18;;5941:37;20101:2;20086:18;;5941:37;19762:3;19747:19;;19733:382;20122:1031;;36377:24;6513:3;6506:58;20458:3;20585:2;20574:9;20570:18;20563:48;20625:88;20458:3;20447:9;20443:19;20699:6;20691;20625:88;;;-1:-1;;;;;35487:54;;;;20792:2;20777:18;;4981:37;-1:-1;35704:10;35693:22;;;20873:2;20858:18;;16370:36;35693:22;;;;20954:3;20939:19;;16370:36;35498:42;21031:19;;6506:58;21138:3;21123:19;6506:58;20617:96;20429:724;-1:-1;;;20429:724;21160:407;21351:2;21365:47;;;7283:2;21336:18;;;34693:19;-1:-1;;;34733:14;;;7299:50;7368:12;;;21322:245;21574:407;21765:2;21779:47;;;7619:2;21750:18;;;34693:19;-1:-1;;;34733:14;;;7635:44;7698:12;;;21736:245;21988:407;22179:2;22193:47;;;7949:2;22164:18;;;34693:19;7985:34;34733:14;;;7965:55;-1:-1;;;8040:12;;;8033:25;8077:12;;;22150:245;22402:407;22593:2;22607:47;;;8328:2;22578:18;;;34693:19;-1:-1;;;34733:14;;;8344:50;8413:12;;;22564:245;22816:407;23007:2;23021:47;;;8664:2;22992:18;;;34693:19;-1:-1;;;34733:14;;;8680:41;8740:12;;;22978:245;23230:407;23421:2;23435:47;;;8991:2;23406:18;;;34693:19;9027:34;34733:14;;;9007:55;-1:-1;;;9082:12;;;9075:34;9128:12;;;23392:245;23644:407;23835:2;23849:47;;;9379:2;23820:18;;;34693:19;9415:32;34733:14;;;9395:53;9467:12;;;23806:245;24058:407;24249:2;24263:47;;;9718:2;24234:18;;;34693:19;9754:33;34733:14;;;9734:54;9807:12;;;24220:245;24472:407;24663:2;24677:47;;;10058:2;24648:18;;;34693:19;10094:32;34733:14;;;10074:53;10146:12;;;24634:245;24886:407;25077:2;25091:47;;;10397:2;25062:18;;;34693:19;10433:34;34733:14;;;10413:55;-1:-1;;;10488:12;;;10481:27;10527:12;;;25048:245;25300:407;25491:2;25505:47;;;10778:2;25476:18;;;34693:19;-1:-1;;;34733:14;;;10794:49;10862:12;;;25462:245;25714:407;25905:2;25919:47;;;11113:2;25890:18;;;34693:19;11149:34;34733:14;;;11129:55;-1:-1;;;11204:12;;;11197:34;11250:12;;;25876:245;26128:407;26319:2;26333:47;;;11501:2;26304:18;;;34693:19;11537:34;34733:14;;;11517:55;-1:-1;;;11592:12;;;11585:38;11642:12;;;26290:245;26542:407;26733:2;26747:47;;;11893:2;26718:18;;;34693:19;11929:34;34733:14;;;11909:55;-1:-1;;;11984:12;;;11977:25;12021:12;;;26704:245;26956:407;27147:2;27161:47;;;12272:2;27132:18;;;34693:19;12308:34;34733:14;;;12288:55;-1:-1;;;12363:12;;;12356:34;12409:12;;;27118:245;27370:407;27561:2;27575:47;;;12660:2;27546:18;;;34693:19;12696:34;34733:14;;;12676:55;-1:-1;;;12751:12;;;12744:31;12794:12;;;27532:245;27784:407;27975:2;27989:47;;;13045:2;27960:18;;;34693:19;13081:34;34733:14;;;13061:55;-1:-1;;;13136:12;;;13129:27;13175:12;;;27946:245;28198:407;28389:2;28403:47;;;13426:2;28374:18;;;34693:19;13462:34;34733:14;;;13442:55;-1:-1;;;13517:12;;;13510:27;13556:12;;;28360:245;28612:407;28803:2;28817:47;;;13807:2;28788:18;;;34693:19;13843:34;34733:14;;;13823:55;-1:-1;;;13898:12;;;13891:25;13935:12;;;28774:245;29026:407;29217:2;29231:47;;;14186:2;29202:18;;;34693:19;-1:-1;;;34733:14;;;14202:48;14269:12;;;29188:245;29440:407;29631:2;29645:47;;;14520:2;29616:18;;;34693:19;14556:34;34733:14;;;14536:55;-1:-1;;;14611:12;;;14604:30;14653:12;;;29602:245;29854:407;30045:2;30059:47;;;14904:2;30030:18;;;34693:19;-1:-1;;;34733:14;;;14920:49;14988:12;;;30016:245;30268:407;30459:2;30473:47;;;15239:2;30444:18;;;34693:19;15275:32;34733:14;;;15255:53;15327:12;;;30430:245;30682:407;30873:2;30887:47;;;15578:2;30858:18;;;34693:19;-1:-1;;;34733:14;;;15594:51;15664:12;;;30844:245;31096:407;31287:2;31301:47;;;15915:2;31272:18;;;34693:19;15951:34;34733:14;;;15931:55;-1:-1;;;16006:12;;;15999:27;16045:12;;;31258:245;31730:435;5941:37;;;32068:2;32053:18;;5941:37;;;;32151:2;32136:18;;5941:37;31904:2;31889:18;;31875:290;32172:651;;5971:5;5948:3;5941:37;32406:2;32524;32513:9;32509:18;32502:48;32564:88;32406:2;32395:9;32391:18;32638:6;32630;32564:88;;;32700:9;32694:4;32690:20;32685:2;32674:9;32670:18;32663:48;32725:88;32808:4;32799:6;32791;32725:88;;;32717:96;32377:446;-1:-1;;;;;;;;32377:446;32830:324;5941:37;;;33140:2;33125:18;;5941:37;32976:2;32961:18;;32947:207
Swarm Source
ipfs://9a05a587712745fd0a97aa37b7f385f4630d7eefab295188f89f8ce263f95ce0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 24 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
MOVR | 100.00% | $21.55 | 0.25 | $5.39 |
[ Download: CSV Export ]
[ 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.