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