ETH Price: $2,542.40 (-4.50%)
Gas: 2 Gwei

Contract

0x8888888883585b9a8202Db34D8b09d7252bfc61C
 
Transaction Hash
Method
Block
From
To
Claim204841402024-08-08 13:23:113 days ago1723123391IN
0x88888888...252bfc61C
0 ETH0.001251569.55687813
Claim204076782024-07-28 21:15:5914 days ago1722201359IN
0x88888888...252bfc61C
0 ETH0.000268822.05244248
Claim204076732024-07-28 21:14:5914 days ago1722201299IN
0x88888888...252bfc61C
0 ETH0.000255371.94992104
Claim203151192024-07-15 23:14:1127 days ago1721085251IN
0x88888888...252bfc61C
0 ETH0.001127038.6047986
Claim203137412024-07-15 18:36:3527 days ago1721068595IN
0x88888888...252bfc61C
0 ETH0.0025457819.43761317
Trade203078392024-07-14 22:50:3528 days ago1720997435IN
0x88888888...252bfc61C
0 ETH0.000323872.17580816
Trade203078342024-07-14 22:49:3528 days ago1720997375IN
0x88888888...252bfc61C
0 ETH0.000325392.18582515
Claim203074962024-07-14 21:41:4728 days ago1720993307IN
0x88888888...252bfc61C
0 ETH0.000521463.98223335
Trade203074942024-07-14 21:41:2328 days ago1720993283IN
0x88888888...252bfc61C
0 ETH0.000590213.963561
Claim203070602024-07-14 20:14:1128 days ago1720988051IN
0x88888888...252bfc61C
0 ETH0.000393223.00234776
Claim203070582024-07-14 20:13:4728 days ago1720988027IN
0x88888888...252bfc61C
0 ETH0.000400333.05678347
Trade203066102024-07-14 18:43:2328 days ago1720982603IN
0x88888888...252bfc61C
0 ETH0.000293424.55160847
Trade203066082024-07-14 18:42:5928 days ago1720982579IN
0x88888888...252bfc61C
0 ETH0.000691434.64433018
Trade203054862024-07-14 14:57:4728 days ago1720969067IN
0x88888888...252bfc61C
0 ETH0.000768885.16342352
Trade203053932024-07-14 14:39:1128 days ago1720967951IN
0x88888888...252bfc61C
0 ETH0.000726434.87857512
Claim203053712024-07-14 14:34:3528 days ago1720967675IN
0x88888888...252bfc61C
0 ETH0.000614964.69519019
Claim203014932024-07-14 1:35:1129 days ago1720920911IN
0x88888888...252bfc61C
0 ETH0.00054674.174034
Claim203014902024-07-14 1:34:3529 days ago1720920875IN
0x88888888...252bfc61C
0 ETH0.000533074.07034097
Claim203014752024-07-14 1:31:3529 days ago1720920695IN
0x88888888...252bfc61C
0 ETH0.000598594.57025434
Claim203014712024-07-14 1:30:4729 days ago1720920647IN
0x88888888...252bfc61C
0 ETH0.000578564.41745018
Claim203014672024-07-14 1:29:5929 days ago1720920599IN
0x88888888...252bfc61C
0 ETH0.000544934.16053596
Claim203014612024-07-14 1:28:4729 days ago1720920527IN
0x88888888...252bfc61C
0 ETH0.000598624.57088852
Claim203014552024-07-14 1:27:3529 days ago1720920455IN
0x88888888...252bfc61C
0 ETH0.000605724.62551823
Claim203014512024-07-14 1:26:4729 days ago1720920407IN
0x88888888...252bfc61C
0 ETH0.000611754.67111594
Trade203012982024-07-14 0:55:5929 days ago1720918559IN
0x88888888...252bfc61C
0 ETH0.001080097.25362082
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
204841402024-08-08 13:23:113 days ago1723123391
0x88888888...252bfc61C
0 ETH
204841402024-08-08 13:23:113 days ago1723123391
0x88888888...252bfc61C
0 ETH
204841402024-08-08 13:23:113 days ago1723123391
0x88888888...252bfc61C
0 ETH
204076782024-07-28 21:15:5914 days ago1722201359
0x88888888...252bfc61C
0 ETH
204076782024-07-28 21:15:5914 days ago1722201359
0x88888888...252bfc61C
0 ETH
204076782024-07-28 21:15:5914 days ago1722201359
0x88888888...252bfc61C
0 ETH
204076732024-07-28 21:14:5914 days ago1722201299
0x88888888...252bfc61C
0 ETH
204076732024-07-28 21:14:5914 days ago1722201299
0x88888888...252bfc61C
0 ETH
204076732024-07-28 21:14:5914 days ago1722201299
0x88888888...252bfc61C
0 ETH
203151192024-07-15 23:14:1127 days ago1721085251
0x88888888...252bfc61C
0 ETH
203151192024-07-15 23:14:1127 days ago1721085251
0x88888888...252bfc61C
0 ETH
203151192024-07-15 23:14:1127 days ago1721085251
0x88888888...252bfc61C
0 ETH
203137412024-07-15 18:36:3527 days ago1721068595
0x88888888...252bfc61C
0 ETH
203137412024-07-15 18:36:3527 days ago1721068595
0x88888888...252bfc61C
0 ETH
203137412024-07-15 18:36:3527 days ago1721068595
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078392024-07-14 22:50:3528 days ago1720997435
0x88888888...252bfc61C
0 ETH
203078342024-07-14 22:49:3528 days ago1720997375
0x88888888...252bfc61C
0 ETH
203078342024-07-14 22:49:3528 days ago1720997375
0x88888888...252bfc61C
0 ETH
203078342024-07-14 22:49:3528 days ago1720997375
0x88888888...252bfc61C
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Degens

Compiler Version
v0.5.12+commit.7709ece9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-11-05
*/

// Degens Protocol (C) degens.com

pragma solidity ^0.5.10;

interface IERC20Token {
    function balanceOf(address tokenOwner) external view returns (uint balance);
    function allowance(address tokenOwner, address spender) external view returns (uint remaining);
    function transfer(address to, uint tokens) external returns (bool success);
    function transferFrom(address from, address to, uint tokens) external returns (bool success);
}

contract Degens {
    // Constants

    uint private constant MAX_SANE_AMOUNT = (2**128) - 1;
    uint private constant MIN_SANE_AMOUNT = 2;
    uint private constant MAX_PRICE = 1000000000;

    bytes32 private constant EIP712_DOMAIN = keccak256(abi.encode(
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
        keccak256("Degens"),
        keccak256("1.0"),
        uint256(1), // set chainId at deployment
        address(0x8888888883585b9a8202Db34D8b09d7252bfc61C) // set contractAddr at deployment
    ));


    // Events

    event LogRequestTrade(address indexed sender);
    event LogRequestMatchOrders(address indexed sender);
    event LogRequestClaim(address indexed sender);
    event LogRequestRecoverFunds(address indexed sender);

    event LogTrade(
        address indexed takerAccount,
        address indexed makerAccount,
        uint indexed matchId,
        address token,
        uint orderFillHash,
        uint8 orderDirection,
        uint32 price,
        uint longAmount,
        int newLongPosition,
        uint shortAmount,
        int newShortPosition,
        int longBalanceDelta,
        int shortBalanceDelta
    );

    event LogTradeError(
        address indexed takerAccount,
        address indexed makerAccount,
        uint indexed matchId,
        address token,
        uint orderFillHash,
        uint16 status
    );

    event LogCancel(
        address indexed account,
        address token,
        uint amount,
        uint orderGroup
    );

    event LogCancelAll(
        address indexed account,
        uint timestamp
    );

    event LogFinalizeMatch(
        uint indexed matchId,
        uint32 finalPrice
    );

    event LogClaim(
        address indexed account,
        uint indexed matchId,
        address indexed token,
        uint amount,
        uint graderFee
    );


    // Storage

    struct Match {
        mapping(address => mapping(address => int)) positions; // account => token => position
        bool finalized;
        uint32 finalPrice;
        uint32 graderFee;
        address[] graders;
    }

    mapping(uint => Match) private matches;
    mapping(uint => uint) private filledAmounts;
    mapping(address => uint) private cancelTimestamps;


    // Order

    struct Order {
        address maker;
        address taker;
        address token;
        uint matchId;
        uint amount;
        uint32 price;
        uint8 direction;
        uint expiry;
        uint timestamp;
        uint orderGroup;

        uint fillHash;
    }

    bytes32 private constant EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked(
        "Order(",
            "address maker,",
            "address taker,",
            "address token,",
            "uint256 matchId,",
            "uint256 amount,",
            "uint256 price,",
            "uint256 direction,",
            "uint256 expiry,",
            "uint256 timestamp,",
            "uint256 orderGroup",
        ")"
    ));

    function unpackShared(uint[4] memory packed, Order memory o) private view {
        o.maker = address(packed[0] >> (12*8));
        o.taker = packed[0] & (0x01 << (11*8)) == 0 ? address(0) : msg.sender;
        o.amount = packed[1] >> (16*8);
        o.price = uint32(packed[1] >> uint32((12*8)) & 0xFFFFFFFF);
        o.direction = uint8((packed[0] >> (10*8)) & 0xFF);
        o.expiry = (packed[0] >> (5*8)) & 0xFFFFFFFFFF;
        o.timestamp = packed[0] & 0xFFFFFFFFFF;
        o.orderGroup = packed[1] & 0xFFFFFFFFFFFFFFFFFFFFFFFF;
    }

    function computeFillHash(Order memory o) private pure {
        o.fillHash = uint(keccak256(abi.encodePacked(o.maker, o.token, o.amount, o.orderGroup)));
    }

    function unpackOrder(uint matchId, address token, uint[4] memory packed) private view returns(Order memory o) {
        unpackShared(packed, o);

        o.token = token;
        o.matchId = matchId;

        computeFillHash(o);

        bytes32 signatureHash = keccak256(abi.encodePacked(
            "\x19\x01",
            EIP712_DOMAIN,
            keccak256(abi.encode(
                EIP712_ORDER_SCHEMA_HASH,
                o.maker,
                o.taker,
                o.token,
                o.matchId,
                o.amount,
                uint(o.price),
                uint(o.direction),
                o.expiry,
                o.timestamp,
                o.orderGroup
            ))
        ));

        if ((packed[0] & (0x02 << (11*8))) != 0) signatureHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", signatureHash));

        require(ecrecoverPacked(signatureHash, packed[2], packed[3]) == o.maker, "DERR_INVALID_ORDER_SIGNATURE");
        require(o.taker == address(0) || o.taker == msg.sender, "DERR_INVALID_TAKER"); // not reachable
        require(o.price > 0 && o.price < MAX_PRICE, "DERR_INVALID_PRICE");
        require(o.direction < 2, "DERR_INVALID_DIRECTION");
    }

    function unpackOrderForQuery(uint[4] memory packed) private view returns(Order memory o) {
        unpackShared(packed, o);

        o.matchId = packed[2];
        o.token = address(packed[3]);
        o.taker = address(0);

        computeFillHash(o);
    }


    // Trade

    enum TradeStatus {
        INVALID,
        OK,

        TAKER_NO_BALANCE,
        TRADE_EXPIRED,
        MATCH_FINALIZED,
        TRADE_TOO_SMALL,

        ORDER_NO_BALANCE,
        ORDER_EXPIRED,
        ORDER_CANCELLED,

        AMOUNT_MALFORMED,
        SELF_TRADE
    }

    struct Trade {
        TradeStatus status;
        address longAddr;
        address shortAddr;
        int newLongPosition;
        int newShortPosition;
        int longBalanceDelta;
        int shortBalanceDelta;
        uint shortAmount;
        uint longAmount;
        uint takerAmount;
        uint makerAmount;
    }


    // External interface

    function() external payable {
        revert("DERR_UNKNOWN_METHOD");
    }

    function trade(uint amount, uint expiry, uint matchId, address token, uint[4][] calldata packedOrders) external {
        emit LogRequestTrade(msg.sender);

        if (expiry != 0 && block.timestamp >= expiry) {
            emit LogTradeError(msg.sender, address(0), matchId, token, 0, uint16(TradeStatus.TRADE_EXPIRED));
            return;
        }

        require(packedOrders.length > 0, "DERR_EMPTY_PACKEDORDERS");

        uint amountRemaining = amount;

        for (uint i = 0; i < packedOrders.length; i++) {
            Order memory o = unpackOrder(matchId, token, packedOrders[i]);

            Trade memory t = tradeCore(amountRemaining, o, false);

            if (t.status == TradeStatus.OK) {
                applyTradePositions(o, t);
                applyTradeBalances(o, t);
                applyTradeLog(o, t);
                amountRemaining = safeSub(amountRemaining, t.takerAmount);
            } else {
                emit LogTradeError(msg.sender, o.maker, o.matchId, o.token, o.fillHash, uint16(t.status));
            }

            if (amountRemaining < MIN_SANE_AMOUNT) break;
        }
    }

    function matchOrders(uint matchId, address token, uint[4] calldata packedLeftOrder, uint[4][] calldata packedRightOrders) external {
        emit LogRequestMatchOrders(msg.sender);

        require(packedRightOrders.length > 0, "DERR_EMPTY_PACKEDRIGHTORDERS");

        Order memory leftOrder = unpackOrder(matchId, token, packedLeftOrder);

        for (uint i = 0; i < packedRightOrders.length; i++) {
            Order memory rightOrder = unpackOrder(matchId, token, packedRightOrders[i]);

            require(leftOrder.maker != rightOrder.maker, "DERR_SAME_MAKER");
            require(rightOrder.direction != leftOrder.direction, "DERR_SAME_DIRECTION");


            (uint leftMaxPosition, uint leftAmount) = computeMaxPosition(leftOrder);
            (uint rightMaxPosition, uint rightAmount) = computeMaxPosition(rightOrder);

            if (leftMaxPosition > rightMaxPosition) {
                leftAmount = uint(priceDivide(int(rightMaxPosition), leftOrder.direction == 1 ? (MAX_PRICE - leftOrder.price) : leftOrder.price));
            } else {
                rightAmount = uint(priceDivide(int(leftMaxPosition), leftOrder.direction == 1 ? rightOrder.price : (MAX_PRICE - rightOrder.price)));
            }


            Trade memory rightTrade = tradeCore(rightAmount, rightOrder, true);

            if (rightTrade.status != TradeStatus.OK) {
                emit LogTradeError(msg.sender, rightOrder.maker, rightOrder.matchId, rightOrder.token, rightOrder.fillHash, uint16(rightTrade.status));
                continue;
            }

            applyTradePositions(rightOrder, rightTrade);

            Trade memory leftTrade = tradeCore(leftAmount, leftOrder, true);

            require(leftTrade.status == TradeStatus.OK, "DERR_LEFT_TRADE_FAIL");

            applyTradePositions(leftOrder, leftTrade);


            int takerBalanceDelta = 0;

            if (leftOrder.direction == 1) {
                takerBalanceDelta = leftTrade.shortBalanceDelta + rightTrade.longBalanceDelta;
                leftTrade.shortBalanceDelta = rightTrade.longBalanceDelta = 0;
            } else {
                takerBalanceDelta = leftTrade.longBalanceDelta + rightTrade.shortBalanceDelta;
                leftTrade.longBalanceDelta = rightTrade.shortBalanceDelta = 0;
            }


            if (takerBalanceDelta < 0) adjustBalance(leftOrder.token, msg.sender, takerBalanceDelta);

            if (leftTrade.shortBalanceDelta + leftTrade.longBalanceDelta < rightTrade.shortBalanceDelta + rightTrade.longBalanceDelta) {
                applyTradeBalances(leftOrder, leftTrade);
                applyTradeBalances(rightOrder, rightTrade);
            } else {
                applyTradeBalances(rightOrder, rightTrade);
                applyTradeBalances(leftOrder, leftTrade);
            }

            if (takerBalanceDelta > 0) adjustBalance(leftOrder.token, msg.sender, takerBalanceDelta);


            applyTradeLog(rightOrder, rightTrade);
            applyTradeLog(leftOrder, leftTrade);
        }
    }

    function cancel(address token, uint amount, uint orderGroup) external {
        require(orderGroup <= 0xFFFFFFFFFFFFFFFFFFFFFFFF, "DERR_BAD_ORDERGROUP");
        uint fillHash = uint(keccak256(abi.encodePacked(msg.sender, token, amount, orderGroup)));
        filledAmounts[fillHash] = uint(-1);
        emit LogCancel(msg.sender, token, amount, orderGroup);
    }

    function cancelAll() external {
        cancelTimestamps[msg.sender] = block.timestamp;
        emit LogCancelAll(msg.sender, block.timestamp);
    }

    function claim(bytes32 witness, uint256 graderQuorum, uint256 graderFee, address[] calldata graders, uint32 finalPrice, uint256[2][] calldata sigs, uint256[] calldata targets) external {
        emit LogRequestClaim(msg.sender);

        uint matchId = uint(keccak256(abi.encodePacked(witness, graderQuorum, graderFee, graders)));

        Match storage m = matches[matchId];

        if (!m.finalized) {
            require(graderQuorum > 0, "DERR_ZERO_GRADER_QUORUM");
            require(sigs.length == graders.length, "DERR_INVALID_NUM_SIGS");
            require(graderFee <= MAX_PRICE, "DERR_INVALID_GRADERFEE");

            bytes32 messageHash = keccak256(abi.encodePacked(
                                      "\x19Ethereum Signed Message:\n32",
                                      keccak256(abi.encodePacked(address(this), matchId, finalPrice))
                                  ));

            uint validated = 0;

            for (uint i = 0; i < graders.length; i++) {
                if (sigs[i][0] != 0) {
                    address signer = ecrecoverPacked(messageHash, sigs[i][0], sigs[i][1]);
                    require(signer == graders[i], "DERR_BAD_GRADER_SIG");
                    m.graders.push(graders[i]);
                    validated++;
                }
            }

            require(validated >= graderQuorum, "DERR_INSUFFICIENT_GRADERS");

            bool waiveFees = (finalPrice & 0x80000000) != 0;
            uint32 maskedPrice = finalPrice & 0x7fffffff;

            m.finalized = true;
            m.finalPrice = maskedPrice;
            m.graderFee = waiveFees ? 0 : uint32(graderFee);

            require(m.finalPrice <= MAX_PRICE, "DERR_BAD_FINALPRICE");

            emit LogFinalizeMatch(matchId, finalPrice);
        }

        processClaims(matchId, targets);
    }

    function claimFinalized(uint matchId, uint256[] calldata targets) external {
        emit LogRequestClaim(msg.sender);

        Match storage m = matches[matchId];

        require(m.finalized, "DERR_MATCH_NOT_FINALIZED");

        processClaims(matchId, targets);
    }

    function recoverFunds(uint256 detailsHash, uint256 recoveryTime, uint256 cancelPrice, uint256 graderQuorum, uint256 graderFee, address[] calldata graders) external {
        emit LogRequestRecoverFunds(msg.sender);

        bytes32 witness = keccak256(abi.encodePacked(detailsHash, recoveryTime, cancelPrice));
        uint matchId = uint(keccak256(abi.encodePacked(witness, graderQuorum, graderFee, graders)));

        Match storage m = matches[matchId];

        require(!m.finalized, "DERR_MATCH_IS_FINALIZED");
        require(recoveryTime < block.timestamp, "DERR_TOO_SOON_TO_RECOVER");
        require(cancelPrice <= MAX_PRICE, "DERR_INVALID_CANCELPRICE");

        m.finalized = true;
        m.finalPrice = uint32(cancelPrice);
        m.graderFee = 0;

        emit LogFinalizeMatch(matchId, uint32(cancelPrice));
    }


    // External read-only interface

    function getPosition(uint matchId, address account, address token) external view returns(int) {
        return matches[matchId].positions[account][token];
    }

    function getFinalizedStatus(uint matchId) external view returns(bool, uint32, uint32, address[] memory graders) {
        Match storage m = matches[matchId];
        return (m.finalized, m.finalPrice, m.graderFee, m.graders);
    }

    function getFilledAmount(bytes32 fillHash) external view returns(uint) {
        return filledAmounts[uint(fillHash)];
    }

    function getCancelTimestamp(address account) external view returns(uint) {
        return cancelTimestamps[account];
    }

    function testOrder(uint[4] calldata packed) external view returns(uint256, uint256) {
        Order memory o = unpackOrderForQuery(packed);
        return (getOrderAmount(o), filledAmounts[o.fillHash]);
    }


    // Utilities that modify storage

    function adjustBalance(address token, address addr, int delta) private {
        if (delta > 0) {
            require(IERC20Token(token).transfer(addr, uint(delta)), "DERR_TOKEN_TRANSFER_FAIL");
        } else if (delta < 0) {
            require(IERC20Token(token).transferFrom(addr, address(this), uint(-1 * delta)), "DERR_TOKEN_TRANSFERFROM_FAIL");
        }
    }

    function applyTradePositions(Order memory o, Trade memory t) private {
        assert(t.status == TradeStatus.OK);

        Match storage m = matches[o.matchId];

        m.positions[t.longAddr][o.token] = t.newLongPosition;
        m.positions[t.shortAddr][o.token] = t.newShortPosition;
    }

    function applyTradeBalances(Order memory o, Trade memory t) private {
        assert(t.status == TradeStatus.OK);

        if (t.longBalanceDelta < t.shortBalanceDelta) {
            adjustBalance(o.token, t.longAddr, t.longBalanceDelta);
            adjustBalance(o.token, t.shortAddr, t.shortBalanceDelta);
        } else {
            adjustBalance(o.token, t.shortAddr, t.shortBalanceDelta);
            adjustBalance(o.token, t.longAddr, t.longBalanceDelta);
        }

        filledAmounts[o.fillHash] += (o.direction == 0 ? t.shortAmount : t.longAmount);
    }

    function applyTradeLog(Order memory o, Trade memory t) private {
        emit LogTrade(msg.sender, o.maker, o.matchId, o.token, o.fillHash, o.direction, o.price, t.longAmount, t.newLongPosition, t.shortAmount, t.newShortPosition, t.longBalanceDelta, t.shortBalanceDelta);
    }

    function processClaims(uint matchId, uint256[] memory targets) private {
        Match storage m = matches[matchId];
        assert(m.finalized);
        assert(m.graderFee <= MAX_PRICE);

        for (uint i = 0; i < targets.length;) {
            address token = address(targets[i] & 0x00ffffffffffffffffffffffffffffffffffffffff);
            int totalFee = 0;

            for (i++; i < targets.length && (targets[i] & (1<<255)) == 0; i++) {
                address addr = address(targets[i]);
                int delta = 0;
                int targetPosition = m.positions[addr][token];

                if (targetPosition > 0) {
                    delta = priceDivide(targetPosition, m.finalPrice);
                } else if (targetPosition < 0) {
                    delta = priceDivide(-targetPosition, MAX_PRICE - m.finalPrice);
                } else {
                    continue;
                }

                assert(delta >= 0);

                int fee = priceDivide(delta, m.graderFee);
                assert(fee >= 0);

                delta -= fee;
                totalFee += fee;

                assert(delta >= 0);

                m.positions[addr][token] = 0;
                adjustBalance(token, addr, delta);

                emit LogClaim(addr, matchId, token, uint(delta), uint(fee));
            }

            if (m.graderFee == 0 || totalFee == 0) continue;

            int feePerGrader = totalFee / int(m.graders.length);

            for (uint j = 0; j < m.graders.length - 1; j++) {
                totalFee -= feePerGrader;
                adjustBalance(token, m.graders[j], feePerGrader);
            }

            adjustBalance(token, m.graders[m.graders.length - 1], totalFee);
        }
    }


    // Utilities that read from storage

    function lookupBalance(address token, address addr) private view returns(uint) {
        uint balance = minu256(IERC20Token(token).balanceOf(addr), IERC20Token(token).allowance(addr, address(this)));
        require(balance <= MAX_SANE_AMOUNT, "DERR_BALANCE_INSANE");

        return balance;
    }

    function tradeCore(uint amount, Order memory o, bool takerUnlimitedBalance) private view returns(Trade memory t) {
        t.status = TradeStatus.INVALID;

        if (block.timestamp >= o.expiry) {
            t.status = TradeStatus.ORDER_EXPIRED;
            return t;
        }

        uint orderFilledAmount = filledAmounts[o.fillHash];

        if (cancelTimestamps[o.maker] >= o.timestamp || orderFilledAmount == uint(-1)) {
            t.status = TradeStatus.ORDER_CANCELLED;
            return t;
        }

        if (msg.sender == o.maker) {
            t.status = TradeStatus.SELF_TRADE;
            return t;
        }

        if (amount > MAX_SANE_AMOUNT) {
            t.status = TradeStatus.AMOUNT_MALFORMED;
            return t;
        }

        Match storage m = matches[o.matchId];

        if (m.finalized) {
            t.status = TradeStatus.MATCH_FINALIZED;
            return t;
        }


        uint longAmount;
        uint shortAmount;
        uint longBalance;
        uint shortBalance;

        if (o.direction == 0) {
            // maker short, taker long
            t.longAddr = msg.sender;
            longAmount = amount;

            t.shortAddr = o.maker;
            shortAmount = safeSub(o.amount, orderFilledAmount);

            longBalance = takerUnlimitedBalance ? MAX_SANE_AMOUNT : lookupBalance(o.token, t.longAddr);
            shortBalance = lookupBalance(o.token, t.shortAddr);
        } else {
            // maker long, taker short
            t.longAddr = o.maker;
            longAmount = safeSub(o.amount, orderFilledAmount);

            t.shortAddr = msg.sender;
            shortAmount = amount;

            longBalance = lookupBalance(o.token, t.longAddr);
            shortBalance = takerUnlimitedBalance ? MAX_SANE_AMOUNT : lookupBalance(o.token, t.shortAddr);
        }

        int oldLongPosition = m.positions[t.longAddr][o.token];
        int oldShortPosition = m.positions[t.shortAddr][o.token];

        longAmount = minu256(longAmount, computeEffectiveBalance(longBalance, oldLongPosition, o.price, true));
        shortAmount = minu256(shortAmount, computeEffectiveBalance(shortBalance, oldShortPosition, o.price, false));

        if (longAmount < MIN_SANE_AMOUNT) {
            t.status = o.direction == 0 ? TradeStatus.TAKER_NO_BALANCE : TradeStatus.ORDER_NO_BALANCE;
            return t;
        }

        if (shortAmount < MIN_SANE_AMOUNT) {
            t.status = o.direction == 0 ? TradeStatus.ORDER_NO_BALANCE : TradeStatus.TAKER_NO_BALANCE;
            return t;
        }

        (longAmount, shortAmount) = computePriceWeightedAmounts(longAmount, shortAmount, o.price);

        if (longAmount < MIN_SANE_AMOUNT || shortAmount < MIN_SANE_AMOUNT) {
            t.status = TradeStatus.TRADE_TOO_SMALL;
            return t;
        }

        int newLongPosition = oldLongPosition + (int(longAmount) + int(shortAmount));
        int newShortPosition = oldShortPosition - (int(longAmount) + int(shortAmount));


        t.longBalanceDelta = 0;
        t.shortBalanceDelta = 0;

        if (oldLongPosition < 0) t.longBalanceDelta += priceDivide(-oldLongPosition + min256(0, newLongPosition), MAX_PRICE - o.price);
        if (newLongPosition > 0) t.longBalanceDelta -= priceDivide(newLongPosition - max256(0, oldLongPosition), o.price);

        if (oldShortPosition > 0) t.shortBalanceDelta += priceDivide(oldShortPosition - max256(0, newShortPosition), o.price);
        if (newShortPosition < 0) t.shortBalanceDelta -= priceDivide(-newShortPosition + min256(0, oldShortPosition), MAX_PRICE - o.price);

        int exposureDelta = computeExposureDelta(t.longBalanceDelta, t.shortBalanceDelta, oldLongPosition, newLongPosition, oldShortPosition, newShortPosition);

        if (exposureDelta != 0) {
            if (exposureDelta == 1) {
                newLongPosition--;
                newShortPosition++;
            } else if (exposureDelta == -1) {
                t.longBalanceDelta++; // one left-over wei: arbitrarily give it to long
            } else {
                assert(false);
            }

            exposureDelta = computeExposureDelta(t.longBalanceDelta, t.shortBalanceDelta, oldLongPosition, newLongPosition, oldShortPosition, newShortPosition);
            assert(exposureDelta == 0);
        }


        t.status = TradeStatus.OK;
        t.newLongPosition = newLongPosition;
        t.newShortPosition = newShortPosition;
        t.shortAmount = shortAmount;
        t.longAmount = longAmount;

        if (o.direction == 0) {
            t.takerAmount = t.longAmount;
            t.makerAmount = t.shortAmount;
        } else {
            t.takerAmount = t.shortAmount;
            t.makerAmount = t.longAmount;
        }

        return t;
    }

    function getOrderAmount(Order memory o) private view returns(uint) {
        if (block.timestamp >= o.expiry || cancelTimestamps[o.maker] >= o.timestamp) return 0;

        uint filled = filledAmounts[o.fillHash];
        if (filled == uint(-1)) return 0;

        Match storage m = matches[o.matchId];

        uint amount = safeSub(o.amount, filled);
        int position = m.positions[o.maker][o.token];

        return minu256(amount, computeEffectiveBalance(lookupBalance(o.token, o.maker), position, o.price, o.direction == 1));
    }

    function computeMaxPosition(Order memory o) private view returns(uint, uint) {
        if (o.direction == 1) {
            (uint longAmount, uint shortAmount) = computePriceWeightedAmounts(getOrderAmount(o), MAX_SANE_AMOUNT, o.price);

            return (longAmount + shortAmount, shortAmount);
        } else {
            (uint longAmount, uint shortAmount) = computePriceWeightedAmounts(MAX_SANE_AMOUNT, getOrderAmount(o), o.price);

            return (longAmount + shortAmount, longAmount);
        }
    }


    // Pure utilities

    function ecrecoverPacked(bytes32 hash, uint r, uint sv) private pure returns (address) {
        return ecrecover(hash, uint8(27 + (sv >> 255)), bytes32(r), bytes32(sv & ((1<<255) - 1)));
    }

    function priceDivide(int amount, uint price) private pure returns(int) {
        assert(amount >= 0);
        return int(safeMul(uint(amount), price) / MAX_PRICE);
    }

    function computeEffectiveBalance(uint balance, int position, uint price, bool isLong) private pure returns(uint) {
        uint effectiveBalance = balance;

        if (isLong) {
            if (position < 0) effectiveBalance += uint(priceDivide(-position, price));
        } else {
            if (position > 0) effectiveBalance += uint(priceDivide(position, MAX_PRICE - price));
        }

        return effectiveBalance;
    }

    function computePriceWeightedAmounts(uint longAmount, uint shortAmount, uint price) private pure returns(uint, uint) {
        uint totalLongAmount = longAmount + (safeMul(longAmount, MAX_PRICE - price) / price);
        uint totalShortAmount = shortAmount + (safeMul(shortAmount, price) / (MAX_PRICE - price));

        if (totalLongAmount > totalShortAmount) {
            return (totalShortAmount - shortAmount, shortAmount);
        } else {
            return (longAmount, totalLongAmount - longAmount);
        }
    }

    function computeExposureDelta(int longBalanceDelta, int shortBalanceDelta, int oldLongPosition, int newLongPosition, int oldShortPosition, int newShortPosition) private pure returns(int) {
        int positionDelta = 0;
        if (newLongPosition > 0) positionDelta += newLongPosition - max256(0, oldLongPosition);
        if (oldShortPosition > 0) positionDelta -= oldShortPosition - max256(0, newShortPosition);

        return positionDelta + longBalanceDelta + shortBalanceDelta;
    }

    function safeMul(uint a, uint b) private pure returns(uint) {
        uint c = a * b;
        assert(a == 0 || c / a == b);
        return c;
    }

    function safeSub(uint a, uint b) private pure returns(uint) {
        assert(b <= a);
        return a - b;
    }

    function minu256(uint a, uint b) private pure returns(uint) {
        return a < b ? a : b;
    }

    function max256(int a, int b) private pure returns(int) {
        return a >= b ? a : b;
    }

    function min256(int a, int b) private pure returns(int) {
        return a < b ? a : b;
    }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderGroup","type":"uint256"}],"name":"LogCancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"LogCancelAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"matchId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"graderFee","type":"uint256"}],"name":"LogClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"matchId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"finalPrice","type":"uint32"}],"name":"LogFinalizeMatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"LogRequestClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"LogRequestMatchOrders","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"LogRequestRecoverFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"LogRequestTrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"takerAccount","type":"address"},{"indexed":true,"internalType":"address","name":"makerAccount","type":"address"},{"indexed":true,"internalType":"uint256","name":"matchId","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderFillHash","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"orderDirection","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"price","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"longAmount","type":"uint256"},{"indexed":false,"internalType":"int256","name":"newLongPosition","type":"int256"},{"indexed":false,"internalType":"uint256","name":"shortAmount","type":"uint256"},{"indexed":false,"internalType":"int256","name":"newShortPosition","type":"int256"},{"indexed":false,"internalType":"int256","name":"longBalanceDelta","type":"int256"},{"indexed":false,"internalType":"int256","name":"shortBalanceDelta","type":"int256"}],"name":"LogTrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"takerAccount","type":"address"},{"indexed":true,"internalType":"address","name":"makerAccount","type":"address"},{"indexed":true,"internalType":"uint256","name":"matchId","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderFillHash","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"status","type":"uint16"}],"name":"LogTradeError","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"orderGroup","type":"uint256"}],"name":"cancel","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"cancelAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"witness","type":"bytes32"},{"internalType":"uint256","name":"graderQuorum","type":"uint256"},{"internalType":"uint256","name":"graderFee","type":"uint256"},{"internalType":"address[]","name":"graders","type":"address[]"},{"internalType":"uint32","name":"finalPrice","type":"uint32"},{"internalType":"uint256[2][]","name":"sigs","type":"uint256[2][]"},{"internalType":"uint256[]","name":"targets","type":"uint256[]"}],"name":"claim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"matchId","type":"uint256"},{"internalType":"uint256[]","name":"targets","type":"uint256[]"}],"name":"claimFinalized","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCancelTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"fillHash","type":"bytes32"}],"name":"getFilledAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"matchId","type":"uint256"}],"name":"getFinalizedStatus","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address[]","name":"graders","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"matchId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getPosition","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"matchId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256[4]","name":"packedLeftOrder","type":"uint256[4]"},{"internalType":"uint256[4][]","name":"packedRightOrders","type":"uint256[4][]"}],"name":"matchOrders","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"detailsHash","type":"uint256"},{"internalType":"uint256","name":"recoveryTime","type":"uint256"},{"internalType":"uint256","name":"cancelPrice","type":"uint256"},{"internalType":"uint256","name":"graderQuorum","type":"uint256"},{"internalType":"uint256","name":"graderFee","type":"uint256"},{"internalType":"address[]","name":"graders","type":"address[]"}],"name":"recoverFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256[4]","name":"packed","type":"uint256[4]"}],"name":"testOrder","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"matchId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256[4][]","name":"packedOrders","type":"uint256[4][]"}],"name":"trade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506130b8806100206000396000f3fe6080604052600436106100a75760003560e01c806344ae7b671161006457806344ae7b67146102fa578063a49a408814610390578063a981848f146104c8578063c3908f9714610507578063cc527775146105a1578063e156d58e146105cb576100a7565b806301ba4a36146100ea57806313e3dcf21461019957806316b7218f1461021d57806318cb2b18146102625780632f1ae7ab146102775780633c186ff3146102b9575b6040805162461bcd60e51b81526020600482015260136024820152721111549497d55392d393d5d397d351551213d1606a1b604482015290519081900360640190fd5b3480156100f657600080fd5b506101146004803603602081101561010d57600080fd5b5035610667565b60405180851515151581526020018463ffffffff1663ffffffff1681526020018363ffffffff1663ffffffff16815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561018257818101518382015260200161016a565b505050509050019550505050505060405180910390f35b3480156101a557600080fd5b5061021b600480360360408110156101bc57600080fd5b81359190810190604081016020820135600160201b8111156101dd57600080fd5b8201836020820111156101ef57600080fd5b803590602001918460208302840111600160201b8311171561021057600080fd5b509092509050610709565b005b34801561022957600080fd5b506102506004803603602081101561024057600080fd5b50356001600160a01b03166107de565b60408051918252519081900360200190f35b34801561026e57600080fd5b5061021b6107fd565b34801561028357600080fd5b506102a06004803603608081101561029a57600080fd5b50610848565b6040805192835260208301919091528051918290030190f35b3480156102c557600080fd5b50610250600480360360608110156102dc57600080fd5b508035906001600160a01b03602082013581169160400135166108ad565b34801561030657600080fd5b5061021b600480360360e081101561031d57600080fd5b8135916001600160a01b036020820135169160408201919081019060e0810160c0820135600160201b81111561035257600080fd5b82018360208201111561036457600080fd5b803590602001918460808302840111600160201b8311171561038557600080fd5b5090925090506108e2565b34801561039c57600080fd5b5061021b600480360360e08110156103b357600080fd5b81359160208101359160408201359190810190608081016060820135600160201b8111156103e057600080fd5b8201836020820111156103f257600080fd5b803590602001918460208302840111600160201b8311171561041357600080fd5b9193909263ffffffff83351692604081019060200135600160201b81111561043a57600080fd5b82018360208201111561044c57600080fd5b803590602001918460408302840111600160201b8311171561046d57600080fd5b919390929091602081019035600160201b81111561048a57600080fd5b82018360208201111561049c57600080fd5b803590602001918460208302840111600160201b831117156104bd57600080fd5b509092509050610d77565b3480156104d457600080fd5b5061021b600480360360608110156104eb57600080fd5b506001600160a01b03813516906020810135906040013561127e565b34801561051357600080fd5b5061021b600480360360c081101561052a57600080fd5b8135916020810135916040820135916060810135916080820135919081019060c0810160a0820135600160201b81111561056357600080fd5b82018360208201111561057557600080fd5b803590602001918460208302840111600160201b8311171561059657600080fd5b50909250905061138e565b3480156105ad57600080fd5b50610250600480360360208110156105c457600080fd5b50356115d2565b3480156105d757600080fd5b5061021b600480360360a08110156105ee57600080fd5b8135916020810135916040820135916001600160a01b036060820135169181019060a081016080820135600160201b81111561062957600080fd5b82018360208201111561063b57600080fd5b803590602001918460808302840111600160201b8311171561065c57600080fd5b5090925090506115e4565b6000818152602081815260408083206001810154600282018054845181870281018701909552808552869586956060959460ff81169463ffffffff6101008304811695600160281b909304169390929183918301828280156106f257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106d4575b505050505090509450945094509450509193509193565b60405133907f902f1762b5131108c2ffa49e43791cce17fc79e78815dc0aa308c1fda0d0517990600090a26000838152602081905260409020600181015460ff1661079b576040805162461bcd60e51b815260206004820152601860248201527f444552525f4d415443485f4e4f545f46494e414c495a45440000000000000000604482015290519081900360640190fd5b6107d8848484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506117fa92505050565b50505050565b6001600160a01b0381166000908152600260205260409020545b919050565b336000818152600260209081526040918290204290819055825190815291517ff741d0ba71da7949fae818df4044531f78c6303a239319d2f9e2ede16cbe2d199281900390910190a2565b600080610853612f46565b6040805160808181019092526108819186906004908390839080828437600092019190915250611acc915050565b905061088c81611b0d565b6101409091015160009081526001602052604090205490925090505b915091565b6000838152602081815260408083206001600160a01b03808716855290835281842090851684529091529020545b9392505050565b60405133907fa3b0991678c175443e6e8f8d87bb0590aff251acaca153680f0b6a64868ef36f90600090a28061095f576040805162461bcd60e51b815260206004820152601c60248201527f444552525f454d5054595f5041434b454452494748544f524445525300000000604482015290519081900360640190fd5b610967612f46565b61099b8686866004806020026040519081016040528092919082600460200280828437600092019190915250611c0e915050565b905060005b82811015610d6e576109b0612f46565b6109f588888787868181106109c157fe5b9050608002016004806020026040519081016040528092919082600460200280828437600092019190915250611c0e915050565b805184519192506001600160a01b0391821691161415610a4e576040805162461bcd60e51b815260206004820152600f60248201526e2222a9292fa9a0a6a2afa6a0a5a2a960891b604482015290519081900360640190fd5b8260c0015160ff168160c0015160ff161415610aa7576040805162461bcd60e51b81526020600482015260136024820152722222a9292fa9a0a6a2afa224a922a1aa24a7a760691b604482015290519081900360640190fd5b600080610ab385612185565b91509150600080610ac385612185565b9150915081841115610b1057610b09828860c0015160ff16600114610af2578860a0015163ffffffff16610b04565b8860a0015163ffffffff16633b9aca00035b612203565b9250610b4c565b610b49848860c0015160ff16600114610b39578660a0015163ffffffff16633b9aca0003610b04565b8660a0015163ffffffff16612203565b90505b610b54612fc4565b610b608287600161222d565b905060018151600a811115610b7157fe5b14610c0557856060015186600001516001600160a01b0316336001600160a01b03167fc18d9b605d704a457c4e1843595120a6722eb9b31b859ec775262189d62f04b789604001518a61014001518660000151600a811115610bcf57fe5b604080516001600160a01b039094168452602084019290925261ffff1682820152519081900360600190a4505050505050610d66565b610c0f8682612710565b610c17612fc4565b610c23858a600161222d565b905060018151600a811115610c3457fe5b14610c7d576040805162461bcd60e51b81526020600482015260146024820152731111549497d311519517d51490511157d190525360621b604482015290519081900360640190fd5b610c878982612710565b60008090508960c0015160ff1660011415610cb8575060a08201805160c08301805160009384905292905201610cd0565b5060c08201805160a083018051600093849052929052015b6000811215610ce857610ce88a60400151338361278d565b8260a001518360c00151018260a001518360c00151011215610d1d57610d0e8a83612960565b610d188884612960565b610d31565b610d278884612960565b610d318a83612960565b6000811315610d4957610d498a60400151338361278d565b610d538884612a25565b610d5d8a83612a25565b50505050505050505b6001016109a0565b50505050505050565b60405133907f902f1762b5131108c2ffa49e43791cce17fc79e78815dc0aa308c1fda0d0517990600090a260008a8a8a8a8a604051602001808681526020018581526020018481526020018383602002808284376040805191909301818103601f1901825283528051602091820120600081815291829052929020600181015492995097505060ff16945061123393505050505760008b11610e60576040805162461bcd60e51b815260206004820152601760248201527f444552525f5a45524f5f4752414445525f51554f52554d000000000000000000604482015290519081900360640190fd5b848814610eac576040805162461bcd60e51b8152602060048201526015602482015274444552525f494e56414c49445f4e554d5f5349475360581b604482015290519081900360640190fd5b633b9aca008a1115610efe576040805162461bcd60e51b8152602060048201526016602482015275444552525f494e56414c49445f47524144455246454560501b604482015290519081900360640190fd5b604080513060601b602080830191909152603482018590526001600160e01b031960e08b901b166054830152825160388184030181526058830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060788401526094808401919091528351808403909101815260b490920190925280519101206000805b8a8110156110df57888882818110610f9e57fe5b905060400201600060028110610fb057fe5b6020020135156110d757600061100b848b8b85818110610fcc57fe5b905060400201600060028110610fde57fe5b60200201358c8c86818110610fef57fe5b90506040020160016002811061100157fe5b6020020135612b13565b90508c8c8381811061101957fe5b905060200201356001600160a01b03166001600160a01b0316816001600160a01b031614611084576040805162461bcd60e51b8152602060048201526013602482015272444552525f4241445f4752414445525f53494760681b604482015290519081900360640190fd5b846002018d8d8481811061109457fe5b835460018082018655600095865260209586902090910180549290950293909301356001600160a01b03166001600160a01b031990911617909255939093019250505b600101610f8a565b508c811015611135576040805162461bcd60e51b815260206004820152601960248201527f444552525f494e53554646494349454e545f4752414445525300000000000000604482015290519081900360640190fd5b6001838101805460ff191690911764ffffffff001916637fffffff8b1661010081029190911790915563800000008a1615159081611173578d611176565b60005b60018601805468ffffffff00000000001916600160281b63ffffffff938416021790819055633b9aca0061010090910490911611156111f2576040805162461bcd60e51b8152602060048201526013602482015272444552525f4241445f46494e414c505249434560681b604482015290519081900360640190fd5b6040805163ffffffff8d168152905187917f5b7dd90e5b4429f4065b72413fa0e6b3e94d240f37f15738c63219cf4d1d29a3919081900360200190a2505050505b611270828585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506117fa92505050565b505050505050505050505050565b6bffffffffffffffffffffffff8111156112d5576040805162461bcd60e51b81526020600482015260136024820152720444552525f4241445f4f5244455247524f555606c1b604482015290519081900360640190fd5b6040805133606081811b6020808501919091526bffffffffffffffffffffffff199188901b9190911660348401526048830186905260688084018690528451808503909101815260888401808652815191830191909120600081815260019093529185902060001990556001600160a01b038816905260a8830186905260c88301859052925190917f1430a8409c73700eb66d67441f57646f38f97871d4ef568e9891000cfbc542da919081900360e80190a250505050565b60405133907fa612fa9d5f4626cdfb0059745f5452d35b60fb0038b98a8c90da902a4508c55f90600090a2600087878760405160200180848152602001838152602001828152602001935050505060405160208183030381529060405280519060200120905060008186868686604051602001808681526020018581526020018481526020018383602002808284376040805191909301818103601f1901825283528051602091820120600081815291829052929020600181015492995097505060ff161594506114ab9350505050576040805162461bcd60e51b815260206004820152601760248201527f444552525f4d415443485f49535f46494e414c495a4544000000000000000000604482015290519081900360640190fd5b4289106114ff576040805162461bcd60e51b815260206004820152601860248201527f444552525f544f4f5f534f4f4e5f544f5f5245434f5645520000000000000000604482015290519081900360640190fd5b633b9aca00881115611558576040805162461bcd60e51b815260206004820152601860248201527f444552525f494e56414c49445f43414e43454c50524943450000000000000000604482015290519081900360640190fd5b6001818101805460ff191690911764ffffffff00191661010063ffffffff8b169081029190911768ffffffff00000000001916909155604080519182525183917f5b7dd90e5b4429f4065b72413fa0e6b3e94d240f37f15738c63219cf4d1d29a3916020918190039190910190a250505050505050505050565b60009081526001602052604090205490565b60405133907f320f4f18680fd8cde0c2d93327e7e10359f46608ea9b09689bcad9298ffaabf690600090a2841580159061161e5750844210155b1561167857604080516001600160a01b0385168152600060208201819052600382840152915186929133917fc18d9b605d704a457c4e1843595120a6722eb9b31b859ec775262189d62f04b79181900360600190a46117f2565b806116ca576040805162461bcd60e51b815260206004820152601760248201527f444552525f454d5054595f5041434b45444f5244455253000000000000000000604482015290519081900360640190fd5b8560005b828110156117ef576116de612f46565b6116ef87878787868181106109c157fe5b90506116f9612fc4565b6117058483600061222d565b905060018151600a81111561171657fe5b1415611750576117268282612710565b6117308282612960565b61173a8282612a25565b61174984826101200151612b8b565b93506117d5565b816060015182600001516001600160a01b0316336001600160a01b03167fc18d9b605d704a457c4e1843595120a6722eb9b31b859ec775262189d62f04b785604001518661014001518660000151600a8111156117a957fe5b604080516001600160a01b039094168452602084019290925261ffff1682820152519081900360600190a45b60028410156117e55750506117ef565b50506001016116ce565b50505b505050505050565b6000828152602081905260409020600181015460ff1661181657fe5b6001810154633b9aca00600160281b90910463ffffffff16111561183657fe5b60005b82518110156107d857600083828151811061185057fe5b60209081029190910101516001909201916001600160a01b0316905060005b845183108015611898575084838151811061188657fe5b6020026020010151600160ff1b166000145b15611a1f5760008584815181106118ab57fe5b6020908102919091018101516001600160a01b038082166000908152888452604080822092881682529190935282205490925081811315611908576001870154611901908290610100900463ffffffff16612203565b915061193e565b600081121561193657600187015461190190600083900390610100900463ffffffff16633b9aca0003612203565b505050611a14565b600082121561194957fe5b6001870154600090611969908490600160281b900463ffffffff16612203565b9050600081121561197657fe5b938401939182900391600083121561198a57fe5b6001600160a01b03808516600090815260208a81526040808320938a168352929052908120556119bb86858561278d565b856001600160a01b03168a856001600160a01b03167f34b19d4ab39b572df0255e6c74331cd56f42aff855508021d664cd2be29b3ff88685604051808381526020018281526020019250505060405180910390a4505050505b60019092019161186f565b6001840154600160281b900463ffffffff161580611a3b575080155b15611a47575050611ac7565b60028401546000908281611a5757fe5b05905060005b600286015460001901811015611aa8578183039250611aa084876002018381548110611a8557fe5b6000918252602090912001546001600160a01b03168461278d565b600101611a5d565b50600285018054611ac39185916000198101908110611a8557fe5b5050505b611839565b611ad4612f46565b611ade8282612b9d565b6040808301516060838101919091528301516001600160a01b031690820152600060208201526107f881612c2d565b60008160e0015142101580611b40575061010082015182516001600160a01b031660009081526002602052604090205410155b15611b4d575060006107f8565b610140820151600090815260016020526040902054600019811415611b765760009150506107f8565b606083015160009081526020819052604081206080850151909190611b9b9084612b8b565b85516001600160a01b03908116600090815260208581526040808320818b0180519095168452909152902054905187519293509091611c04918491611bff91611be391612c9d565b848a60a0015163ffffffff168b60c0015160ff16600114612dfa565b612e44565b9695505050505050565b611c16612f46565b611c208282612b9d565b6001600160a01b038316604082015260608101849052611c3f81612c2d565b600060405180806130326052913960520190506040518091039020604051808065446567656e7360d01b815250600601905060405180910390206040518080620312e360ec1b815250600301905060405180910390206001738888888883585b9a8202db34d8b09d7252bfc61c60405160200180868152602001858152602001848152602001838152602001826001600160a01b03166001600160a01b03168152602001955050505050506040516020818303038152906040528051906020012060405160200180806509ee4c8cae4560d31b815250600601806d1859191c995cdcc81b585ad95c8b60921b815250600e01806d1859191c995cdcc81d185ad95c8b60921b815250600e01806d1859191c995cdcc81d1bdad95b8b60921b815250600e01806f1d5a5b9d0c8d4d881b585d18da12590b60821b815250601001806e1d5a5b9d0c8d4d88185b5bdd5b9d0b608a1b815250600f01806d1d5a5b9d0c8d4d881c1c9a58d94b60921b815250600e0180711d5a5b9d0c8d4d88191a5c9958dd1a5bdb8b60721b815250601201806e1d5a5b9d0c8d4d88195e1c1a5c9e4b608a1b815250600f0180711d5a5b9d0c8d4d881d1a5b595cdd185b5c0b60721b8152506012018071075696e74323536206f7264657247726f75760741b81525060120180602960f81b815250600101905060405160208183030381529060405280519060200120836000015184602001518560400151866060015187608001518860a0015163ffffffff168960c0015160ff168a60e001518b61010001518c6101200151604051602001808c81526020018b6001600160a01b03166001600160a01b031681526020018a6001600160a01b03166001600160a01b03168152602001896001600160a01b03166001600160a01b031681526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019b50505050505050505050505060405160208183030381529060405280519060200120604051602001808061190160f01b8152506002018381526020018281526020019250505060405160208183030381529060405280519060200120905082600060048110611f6e57fe5b6020020151600160591b1615611fd0578060405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012090505b81516001600160a01b0316611ff48285600260200201518660036020020151612b13565b6001600160a01b03161461204f576040805162461bcd60e51b815260206004820152601c60248201527f444552525f494e56414c49445f4f524445525f5349474e415455524500000000604482015290519081900360640190fd5b60208201516001600160a01b03161580612075575060208201516001600160a01b031633145b6120bb576040805162461bcd60e51b81526020600482015260126024820152712222a9292fa4a72b20a624a22faa20a5a2a960711b604482015290519081900360640190fd5b60008260a0015163ffffffff161180156120e25750633b9aca008260a0015163ffffffff16105b612128576040805162461bcd60e51b8152602060048201526012602482015271444552525f494e56414c49445f505249434560701b604482015290519081900360640190fd5b60028260c0015160ff161061217d576040805162461bcd60e51b81526020600482015260166024820152752222a9292fa4a72b20a624a22fa224a922a1aa24a7a760511b604482015290519081900360640190fd5b509392505050565b6000808260c0015160ff16600114156121ce576000806121bf6121a786611b0d565b6001600160801b038760a0015163ffffffff16612e5a565b908101945092506108a8915050565b6000806121f56001600160801b036121e587611b0d565b8760a0015163ffffffff16612e5a565b8101945092506108a8915050565b60008083121561220f57fe5b633b9aca0061221e8484612ec4565b8161222557fe5b049392505050565b612235612fc4565b6000815260e0830151421061224d57600781526108db565b61014083015160009081526001602090815260408083205461010087015187516001600160a01b03168552600290935292205410158061228e575060001981145b156122ae578160085b9081600a8111156122a457fe5b9052506108db9050565b83516001600160a01b03163314156122c85781600a612297565b6001600160801b038511156122df57816009612297565b60608401516000908152602081905260409020600181015460ff161561230a575050600481526108db565b6000806000808860c0015160ff166000141561238a5733602088015288516001600160a01b0316604088015260808901518a94506123489087612b8b565b9250876123665761236189604001518860200151612c9d565b61236f565b6001600160801b035b915061238389604001518860400151612c9d565b90506123f4565b88516001600160a01b0316602088015260808901516123a99087612b8b565b336040808a01919091528a015160208901519195508b94506123ca91612c9d565b9150876123e8576123e389604001518860400151612c9d565b6123f1565b6001600160801b035b90505b6020808801516001600160a01b03908116600090815287835260408082208d820180518516845290855281832054828d0151851684528a865282842091519094168352909352919091205460a08b015161245f908790611bff908790869063ffffffff166001612dfa565b955061247c85611bff85848f60a0015163ffffffff166000612dfa565b945060028610156124c95760c08b015160ff161561249b57600661249e565b60025b8990600a8111156124ab57fe5b9081600a8111156124b857fe5b9052506108db975050505050505050565b60028510156124ee5760c08b015160ff16156124e657600261249e565b8860066124ab565b61250386868d60a0015163ffffffff16612e5a565b909650945060028610806125175750600285105b15612524578860056124ab565b600060a08a0181905260c08a01819052868601838101919083039084121561257b5761256f612554600084612ee4565b85600003018e60a0015163ffffffff16633b9aca0003612203565b60a08c01805190910190525b60008213156125b1576125a4612592600086612ef3565b83038e60a0015163ffffffff16612203565b60a08c0180519190910390525b60008313156125e6576125da6125c8600083612ef3565b84038e60a0015163ffffffff16612203565b60c08c01805190910190525b6000811215612625576126186125fd600085612ee4565b82600003018e60a0015163ffffffff16633b9aca0003612203565b60c08c0180519190910390525b600061263d8c60a001518d60c0015187868887612f03565b9050801561269d57806001141561266157600019909201916001919091019061267d565b80600019141561267b5760a08c018051600101905261267d565bfe5b6126938c60a001518d60c0015187868887612f03565b9050801561269d57fe5b60018c5260608c0183905260808c0182905260e08c018890526101008c0189905260c08e015160ff166126e6576101008c01516101208d015260e08c01516101408d01526126fe565b60e08c01516101208d01526101008c01516101408d01525b50505050505050505050509392505050565b60018151600a81111561271f57fe5b1461272657fe5b60608083015160009081526020818152604080832093850151858301516001600160a01b0390811685528584528285209783018051821686529784528285209190915560808601519582015181168452938252808320955190931682529390935290912055565b600081131561287857826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156127f657600080fd5b505af115801561280a573d6000803e3d6000fd5b505050506040513d602081101561282057600080fd5b5051612873576040805162461bcd60e51b815260206004820152601860248201527f444552525f544f4b454e5f5452414e534645525f4641494c0000000000000000604482015290519081900360640190fd5b61295b565b600081121561295b57604080516323b872dd60e01b81526001600160a01b038481166004830152306024830152600084810360448401529251908616926323b872dd92606480820193602093909283900390910190829087803b1580156128de57600080fd5b505af11580156128f2573d6000803e3d6000fd5b505050506040513d602081101561290857600080fd5b505161295b576040805162461bcd60e51b815260206004820152601c60248201527f444552525f544f4b454e5f5452414e5346455246524f4d5f4641494c00000000604482015290519081900360640190fd5b505050565b60018151600a81111561296f57fe5b1461297657fe5b8060c001518160a0015112156129b95761299d826040015182602001518360a0015161278d565b6129b4826040015182604001518360c0015161278d565b6129e7565b6129d0826040015182604001518360c0015161278d565b6129e7826040015182602001518360a0015161278d565b60c082015160ff16156129ff57806101000151612a05565b8060e001515b610140909201516000908152600160205260409020805490920190915550565b816060015182600001516001600160a01b0316336001600160a01b03167fdc13589835b7bdc7ff3bbf712a59927511e18e82e9ec9231372692090e1c09f185604001518661014001518760c001518860a0015188610100015189606001518a60e001518b608001518c60a001518d60c00151604051808b6001600160a01b03166001600160a01b031681526020018a81526020018960ff1660ff1681526020018863ffffffff1663ffffffff1681526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a45050565b604080516000808252602080830180855287905260ff85811c601b011683850152606083018690526001600160ff1b03851660808401529251909260019260a080820193601f1981019281900390910190855afa158015612b78573d6000803e3d6000fd5b5050604051601f19015195945050505050565b600082821115612b9757fe5b50900390565b815160601c81528151600160581b1615612bb75733612bba565b60005b6001600160a01b031660208281019190915282018051608090811c90830152805160601c63ffffffff1660a0830152825160501c60ff1660c0830152825160281c64ffffffffff90811660e0840152925190921661010082015290516bffffffffffffffffffffffff1661012090910152565b8051604080830151608084015161012085015183516bffffffffffffffffffffffff19606096871b81166020808401919091529490961b90951660348601526048850191909152606880850191909152825180850390910181526088909301909152815191012061014090910152565b600080612da6846001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612cf957600080fd5b505afa158015612d0d573d6000803e3d6000fd5b505050506040513d6020811015612d2357600080fd5b505160408051636eb1769f60e11b81526001600160a01b03878116600483015230602483015291519188169163dd62ed3e91604480820192602092909190829003018186803b158015612d7557600080fd5b505afa158015612d89573d6000803e3d6000fd5b505050506040513d6020811015612d9f57600080fd5b5051612e44565b90506001600160801b038111156108db576040805162461bcd60e51b8152602060048201526013602482015272444552525f42414c414e43455f494e53414e4560681b604482015290519081900360640190fd5b6000848215612e20576000851215612e1b57612e198560000385612203565b015b612e3b565b6000851315612e3b57612e398585633b9aca0003612203565b015b95945050505050565b6000818310612e5357816108db565b5090919050565b600080600083612e708786633b9aca0003612ec4565b81612e7757fe5b0486019050600084633b9aca0003612e8f8787612ec4565b81612e9657fe5b048601905080821115612eb25785810386935093505050612ebc565b5085925082900390505b935093915050565b6000828202831580612ede575082848281612edb57fe5b04145b6108db57fe5b6000818312612e5357816108db565b600081831215612e5357816108db565b60008080851315612f1d57612f19600087612ef3565b8503015b6000841315612f3657612f31600084612ef3565b840390035b8701860190509695505050505050565b60405180610160016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600063ffffffff168152602001600060ff168152602001600081526020016000815260200160008152602001600081525090565b604080516101608101909152806000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a265627a7a72315820b605f651f6cf04bb6fcbe5454668200c9c33798c9b1f98d8215326c9dcd925da64736f6c634300050c0032

Deployed Bytecode

0x6080604052600436106100a75760003560e01c806344ae7b671161006457806344ae7b67146102fa578063a49a408814610390578063a981848f146104c8578063c3908f9714610507578063cc527775146105a1578063e156d58e146105cb576100a7565b806301ba4a36146100ea57806313e3dcf21461019957806316b7218f1461021d57806318cb2b18146102625780632f1ae7ab146102775780633c186ff3146102b9575b6040805162461bcd60e51b81526020600482015260136024820152721111549497d55392d393d5d397d351551213d1606a1b604482015290519081900360640190fd5b3480156100f657600080fd5b506101146004803603602081101561010d57600080fd5b5035610667565b60405180851515151581526020018463ffffffff1663ffffffff1681526020018363ffffffff1663ffffffff16815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561018257818101518382015260200161016a565b505050509050019550505050505060405180910390f35b3480156101a557600080fd5b5061021b600480360360408110156101bc57600080fd5b81359190810190604081016020820135600160201b8111156101dd57600080fd5b8201836020820111156101ef57600080fd5b803590602001918460208302840111600160201b8311171561021057600080fd5b509092509050610709565b005b34801561022957600080fd5b506102506004803603602081101561024057600080fd5b50356001600160a01b03166107de565b60408051918252519081900360200190f35b34801561026e57600080fd5b5061021b6107fd565b34801561028357600080fd5b506102a06004803603608081101561029a57600080fd5b50610848565b6040805192835260208301919091528051918290030190f35b3480156102c557600080fd5b50610250600480360360608110156102dc57600080fd5b508035906001600160a01b03602082013581169160400135166108ad565b34801561030657600080fd5b5061021b600480360360e081101561031d57600080fd5b8135916001600160a01b036020820135169160408201919081019060e0810160c0820135600160201b81111561035257600080fd5b82018360208201111561036457600080fd5b803590602001918460808302840111600160201b8311171561038557600080fd5b5090925090506108e2565b34801561039c57600080fd5b5061021b600480360360e08110156103b357600080fd5b81359160208101359160408201359190810190608081016060820135600160201b8111156103e057600080fd5b8201836020820111156103f257600080fd5b803590602001918460208302840111600160201b8311171561041357600080fd5b9193909263ffffffff83351692604081019060200135600160201b81111561043a57600080fd5b82018360208201111561044c57600080fd5b803590602001918460408302840111600160201b8311171561046d57600080fd5b919390929091602081019035600160201b81111561048a57600080fd5b82018360208201111561049c57600080fd5b803590602001918460208302840111600160201b831117156104bd57600080fd5b509092509050610d77565b3480156104d457600080fd5b5061021b600480360360608110156104eb57600080fd5b506001600160a01b03813516906020810135906040013561127e565b34801561051357600080fd5b5061021b600480360360c081101561052a57600080fd5b8135916020810135916040820135916060810135916080820135919081019060c0810160a0820135600160201b81111561056357600080fd5b82018360208201111561057557600080fd5b803590602001918460208302840111600160201b8311171561059657600080fd5b50909250905061138e565b3480156105ad57600080fd5b50610250600480360360208110156105c457600080fd5b50356115d2565b3480156105d757600080fd5b5061021b600480360360a08110156105ee57600080fd5b8135916020810135916040820135916001600160a01b036060820135169181019060a081016080820135600160201b81111561062957600080fd5b82018360208201111561063b57600080fd5b803590602001918460808302840111600160201b8311171561065c57600080fd5b5090925090506115e4565b6000818152602081815260408083206001810154600282018054845181870281018701909552808552869586956060959460ff81169463ffffffff6101008304811695600160281b909304169390929183918301828280156106f257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106d4575b505050505090509450945094509450509193509193565b60405133907f902f1762b5131108c2ffa49e43791cce17fc79e78815dc0aa308c1fda0d0517990600090a26000838152602081905260409020600181015460ff1661079b576040805162461bcd60e51b815260206004820152601860248201527f444552525f4d415443485f4e4f545f46494e414c495a45440000000000000000604482015290519081900360640190fd5b6107d8848484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506117fa92505050565b50505050565b6001600160a01b0381166000908152600260205260409020545b919050565b336000818152600260209081526040918290204290819055825190815291517ff741d0ba71da7949fae818df4044531f78c6303a239319d2f9e2ede16cbe2d199281900390910190a2565b600080610853612f46565b6040805160808181019092526108819186906004908390839080828437600092019190915250611acc915050565b905061088c81611b0d565b6101409091015160009081526001602052604090205490925090505b915091565b6000838152602081815260408083206001600160a01b03808716855290835281842090851684529091529020545b9392505050565b60405133907fa3b0991678c175443e6e8f8d87bb0590aff251acaca153680f0b6a64868ef36f90600090a28061095f576040805162461bcd60e51b815260206004820152601c60248201527f444552525f454d5054595f5041434b454452494748544f524445525300000000604482015290519081900360640190fd5b610967612f46565b61099b8686866004806020026040519081016040528092919082600460200280828437600092019190915250611c0e915050565b905060005b82811015610d6e576109b0612f46565b6109f588888787868181106109c157fe5b9050608002016004806020026040519081016040528092919082600460200280828437600092019190915250611c0e915050565b805184519192506001600160a01b0391821691161415610a4e576040805162461bcd60e51b815260206004820152600f60248201526e2222a9292fa9a0a6a2afa6a0a5a2a960891b604482015290519081900360640190fd5b8260c0015160ff168160c0015160ff161415610aa7576040805162461bcd60e51b81526020600482015260136024820152722222a9292fa9a0a6a2afa224a922a1aa24a7a760691b604482015290519081900360640190fd5b600080610ab385612185565b91509150600080610ac385612185565b9150915081841115610b1057610b09828860c0015160ff16600114610af2578860a0015163ffffffff16610b04565b8860a0015163ffffffff16633b9aca00035b612203565b9250610b4c565b610b49848860c0015160ff16600114610b39578660a0015163ffffffff16633b9aca0003610b04565b8660a0015163ffffffff16612203565b90505b610b54612fc4565b610b608287600161222d565b905060018151600a811115610b7157fe5b14610c0557856060015186600001516001600160a01b0316336001600160a01b03167fc18d9b605d704a457c4e1843595120a6722eb9b31b859ec775262189d62f04b789604001518a61014001518660000151600a811115610bcf57fe5b604080516001600160a01b039094168452602084019290925261ffff1682820152519081900360600190a4505050505050610d66565b610c0f8682612710565b610c17612fc4565b610c23858a600161222d565b905060018151600a811115610c3457fe5b14610c7d576040805162461bcd60e51b81526020600482015260146024820152731111549497d311519517d51490511157d190525360621b604482015290519081900360640190fd5b610c878982612710565b60008090508960c0015160ff1660011415610cb8575060a08201805160c08301805160009384905292905201610cd0565b5060c08201805160a083018051600093849052929052015b6000811215610ce857610ce88a60400151338361278d565b8260a001518360c00151018260a001518360c00151011215610d1d57610d0e8a83612960565b610d188884612960565b610d31565b610d278884612960565b610d318a83612960565b6000811315610d4957610d498a60400151338361278d565b610d538884612a25565b610d5d8a83612a25565b50505050505050505b6001016109a0565b50505050505050565b60405133907f902f1762b5131108c2ffa49e43791cce17fc79e78815dc0aa308c1fda0d0517990600090a260008a8a8a8a8a604051602001808681526020018581526020018481526020018383602002808284376040805191909301818103601f1901825283528051602091820120600081815291829052929020600181015492995097505060ff16945061123393505050505760008b11610e60576040805162461bcd60e51b815260206004820152601760248201527f444552525f5a45524f5f4752414445525f51554f52554d000000000000000000604482015290519081900360640190fd5b848814610eac576040805162461bcd60e51b8152602060048201526015602482015274444552525f494e56414c49445f4e554d5f5349475360581b604482015290519081900360640190fd5b633b9aca008a1115610efe576040805162461bcd60e51b8152602060048201526016602482015275444552525f494e56414c49445f47524144455246454560501b604482015290519081900360640190fd5b604080513060601b602080830191909152603482018590526001600160e01b031960e08b901b166054830152825160388184030181526058830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060788401526094808401919091528351808403909101815260b490920190925280519101206000805b8a8110156110df57888882818110610f9e57fe5b905060400201600060028110610fb057fe5b6020020135156110d757600061100b848b8b85818110610fcc57fe5b905060400201600060028110610fde57fe5b60200201358c8c86818110610fef57fe5b90506040020160016002811061100157fe5b6020020135612b13565b90508c8c8381811061101957fe5b905060200201356001600160a01b03166001600160a01b0316816001600160a01b031614611084576040805162461bcd60e51b8152602060048201526013602482015272444552525f4241445f4752414445525f53494760681b604482015290519081900360640190fd5b846002018d8d8481811061109457fe5b835460018082018655600095865260209586902090910180549290950293909301356001600160a01b03166001600160a01b031990911617909255939093019250505b600101610f8a565b508c811015611135576040805162461bcd60e51b815260206004820152601960248201527f444552525f494e53554646494349454e545f4752414445525300000000000000604482015290519081900360640190fd5b6001838101805460ff191690911764ffffffff001916637fffffff8b1661010081029190911790915563800000008a1615159081611173578d611176565b60005b60018601805468ffffffff00000000001916600160281b63ffffffff938416021790819055633b9aca0061010090910490911611156111f2576040805162461bcd60e51b8152602060048201526013602482015272444552525f4241445f46494e414c505249434560681b604482015290519081900360640190fd5b6040805163ffffffff8d168152905187917f5b7dd90e5b4429f4065b72413fa0e6b3e94d240f37f15738c63219cf4d1d29a3919081900360200190a2505050505b611270828585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506117fa92505050565b505050505050505050505050565b6bffffffffffffffffffffffff8111156112d5576040805162461bcd60e51b81526020600482015260136024820152720444552525f4241445f4f5244455247524f555606c1b604482015290519081900360640190fd5b6040805133606081811b6020808501919091526bffffffffffffffffffffffff199188901b9190911660348401526048830186905260688084018690528451808503909101815260888401808652815191830191909120600081815260019093529185902060001990556001600160a01b038816905260a8830186905260c88301859052925190917f1430a8409c73700eb66d67441f57646f38f97871d4ef568e9891000cfbc542da919081900360e80190a250505050565b60405133907fa612fa9d5f4626cdfb0059745f5452d35b60fb0038b98a8c90da902a4508c55f90600090a2600087878760405160200180848152602001838152602001828152602001935050505060405160208183030381529060405280519060200120905060008186868686604051602001808681526020018581526020018481526020018383602002808284376040805191909301818103601f1901825283528051602091820120600081815291829052929020600181015492995097505060ff161594506114ab9350505050576040805162461bcd60e51b815260206004820152601760248201527f444552525f4d415443485f49535f46494e414c495a4544000000000000000000604482015290519081900360640190fd5b4289106114ff576040805162461bcd60e51b815260206004820152601860248201527f444552525f544f4f5f534f4f4e5f544f5f5245434f5645520000000000000000604482015290519081900360640190fd5b633b9aca00881115611558576040805162461bcd60e51b815260206004820152601860248201527f444552525f494e56414c49445f43414e43454c50524943450000000000000000604482015290519081900360640190fd5b6001818101805460ff191690911764ffffffff00191661010063ffffffff8b169081029190911768ffffffff00000000001916909155604080519182525183917f5b7dd90e5b4429f4065b72413fa0e6b3e94d240f37f15738c63219cf4d1d29a3916020918190039190910190a250505050505050505050565b60009081526001602052604090205490565b60405133907f320f4f18680fd8cde0c2d93327e7e10359f46608ea9b09689bcad9298ffaabf690600090a2841580159061161e5750844210155b1561167857604080516001600160a01b0385168152600060208201819052600382840152915186929133917fc18d9b605d704a457c4e1843595120a6722eb9b31b859ec775262189d62f04b79181900360600190a46117f2565b806116ca576040805162461bcd60e51b815260206004820152601760248201527f444552525f454d5054595f5041434b45444f5244455253000000000000000000604482015290519081900360640190fd5b8560005b828110156117ef576116de612f46565b6116ef87878787868181106109c157fe5b90506116f9612fc4565b6117058483600061222d565b905060018151600a81111561171657fe5b1415611750576117268282612710565b6117308282612960565b61173a8282612a25565b61174984826101200151612b8b565b93506117d5565b816060015182600001516001600160a01b0316336001600160a01b03167fc18d9b605d704a457c4e1843595120a6722eb9b31b859ec775262189d62f04b785604001518661014001518660000151600a8111156117a957fe5b604080516001600160a01b039094168452602084019290925261ffff1682820152519081900360600190a45b60028410156117e55750506117ef565b50506001016116ce565b50505b505050505050565b6000828152602081905260409020600181015460ff1661181657fe5b6001810154633b9aca00600160281b90910463ffffffff16111561183657fe5b60005b82518110156107d857600083828151811061185057fe5b60209081029190910101516001909201916001600160a01b0316905060005b845183108015611898575084838151811061188657fe5b6020026020010151600160ff1b166000145b15611a1f5760008584815181106118ab57fe5b6020908102919091018101516001600160a01b038082166000908152888452604080822092881682529190935282205490925081811315611908576001870154611901908290610100900463ffffffff16612203565b915061193e565b600081121561193657600187015461190190600083900390610100900463ffffffff16633b9aca0003612203565b505050611a14565b600082121561194957fe5b6001870154600090611969908490600160281b900463ffffffff16612203565b9050600081121561197657fe5b938401939182900391600083121561198a57fe5b6001600160a01b03808516600090815260208a81526040808320938a168352929052908120556119bb86858561278d565b856001600160a01b03168a856001600160a01b03167f34b19d4ab39b572df0255e6c74331cd56f42aff855508021d664cd2be29b3ff88685604051808381526020018281526020019250505060405180910390a4505050505b60019092019161186f565b6001840154600160281b900463ffffffff161580611a3b575080155b15611a47575050611ac7565b60028401546000908281611a5757fe5b05905060005b600286015460001901811015611aa8578183039250611aa084876002018381548110611a8557fe5b6000918252602090912001546001600160a01b03168461278d565b600101611a5d565b50600285018054611ac39185916000198101908110611a8557fe5b5050505b611839565b611ad4612f46565b611ade8282612b9d565b6040808301516060838101919091528301516001600160a01b031690820152600060208201526107f881612c2d565b60008160e0015142101580611b40575061010082015182516001600160a01b031660009081526002602052604090205410155b15611b4d575060006107f8565b610140820151600090815260016020526040902054600019811415611b765760009150506107f8565b606083015160009081526020819052604081206080850151909190611b9b9084612b8b565b85516001600160a01b03908116600090815260208581526040808320818b0180519095168452909152902054905187519293509091611c04918491611bff91611be391612c9d565b848a60a0015163ffffffff168b60c0015160ff16600114612dfa565b612e44565b9695505050505050565b611c16612f46565b611c208282612b9d565b6001600160a01b038316604082015260608101849052611c3f81612c2d565b600060405180806130326052913960520190506040518091039020604051808065446567656e7360d01b815250600601905060405180910390206040518080620312e360ec1b815250600301905060405180910390206001738888888883585b9a8202db34d8b09d7252bfc61c60405160200180868152602001858152602001848152602001838152602001826001600160a01b03166001600160a01b03168152602001955050505050506040516020818303038152906040528051906020012060405160200180806509ee4c8cae4560d31b815250600601806d1859191c995cdcc81b585ad95c8b60921b815250600e01806d1859191c995cdcc81d185ad95c8b60921b815250600e01806d1859191c995cdcc81d1bdad95b8b60921b815250600e01806f1d5a5b9d0c8d4d881b585d18da12590b60821b815250601001806e1d5a5b9d0c8d4d88185b5bdd5b9d0b608a1b815250600f01806d1d5a5b9d0c8d4d881c1c9a58d94b60921b815250600e0180711d5a5b9d0c8d4d88191a5c9958dd1a5bdb8b60721b815250601201806e1d5a5b9d0c8d4d88195e1c1a5c9e4b608a1b815250600f0180711d5a5b9d0c8d4d881d1a5b595cdd185b5c0b60721b8152506012018071075696e74323536206f7264657247726f75760741b81525060120180602960f81b815250600101905060405160208183030381529060405280519060200120836000015184602001518560400151866060015187608001518860a0015163ffffffff168960c0015160ff168a60e001518b61010001518c6101200151604051602001808c81526020018b6001600160a01b03166001600160a01b031681526020018a6001600160a01b03166001600160a01b03168152602001896001600160a01b03166001600160a01b031681526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019b50505050505050505050505060405160208183030381529060405280519060200120604051602001808061190160f01b8152506002018381526020018281526020019250505060405160208183030381529060405280519060200120905082600060048110611f6e57fe5b6020020151600160591b1615611fd0578060405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012090505b81516001600160a01b0316611ff48285600260200201518660036020020151612b13565b6001600160a01b03161461204f576040805162461bcd60e51b815260206004820152601c60248201527f444552525f494e56414c49445f4f524445525f5349474e415455524500000000604482015290519081900360640190fd5b60208201516001600160a01b03161580612075575060208201516001600160a01b031633145b6120bb576040805162461bcd60e51b81526020600482015260126024820152712222a9292fa4a72b20a624a22faa20a5a2a960711b604482015290519081900360640190fd5b60008260a0015163ffffffff161180156120e25750633b9aca008260a0015163ffffffff16105b612128576040805162461bcd60e51b8152602060048201526012602482015271444552525f494e56414c49445f505249434560701b604482015290519081900360640190fd5b60028260c0015160ff161061217d576040805162461bcd60e51b81526020600482015260166024820152752222a9292fa4a72b20a624a22fa224a922a1aa24a7a760511b604482015290519081900360640190fd5b509392505050565b6000808260c0015160ff16600114156121ce576000806121bf6121a786611b0d565b6001600160801b038760a0015163ffffffff16612e5a565b908101945092506108a8915050565b6000806121f56001600160801b036121e587611b0d565b8760a0015163ffffffff16612e5a565b8101945092506108a8915050565b60008083121561220f57fe5b633b9aca0061221e8484612ec4565b8161222557fe5b049392505050565b612235612fc4565b6000815260e0830151421061224d57600781526108db565b61014083015160009081526001602090815260408083205461010087015187516001600160a01b03168552600290935292205410158061228e575060001981145b156122ae578160085b9081600a8111156122a457fe5b9052506108db9050565b83516001600160a01b03163314156122c85781600a612297565b6001600160801b038511156122df57816009612297565b60608401516000908152602081905260409020600181015460ff161561230a575050600481526108db565b6000806000808860c0015160ff166000141561238a5733602088015288516001600160a01b0316604088015260808901518a94506123489087612b8b565b9250876123665761236189604001518860200151612c9d565b61236f565b6001600160801b035b915061238389604001518860400151612c9d565b90506123f4565b88516001600160a01b0316602088015260808901516123a99087612b8b565b336040808a01919091528a015160208901519195508b94506123ca91612c9d565b9150876123e8576123e389604001518860400151612c9d565b6123f1565b6001600160801b035b90505b6020808801516001600160a01b03908116600090815287835260408082208d820180518516845290855281832054828d0151851684528a865282842091519094168352909352919091205460a08b015161245f908790611bff908790869063ffffffff166001612dfa565b955061247c85611bff85848f60a0015163ffffffff166000612dfa565b945060028610156124c95760c08b015160ff161561249b57600661249e565b60025b8990600a8111156124ab57fe5b9081600a8111156124b857fe5b9052506108db975050505050505050565b60028510156124ee5760c08b015160ff16156124e657600261249e565b8860066124ab565b61250386868d60a0015163ffffffff16612e5a565b909650945060028610806125175750600285105b15612524578860056124ab565b600060a08a0181905260c08a01819052868601838101919083039084121561257b5761256f612554600084612ee4565b85600003018e60a0015163ffffffff16633b9aca0003612203565b60a08c01805190910190525b60008213156125b1576125a4612592600086612ef3565b83038e60a0015163ffffffff16612203565b60a08c0180519190910390525b60008313156125e6576125da6125c8600083612ef3565b84038e60a0015163ffffffff16612203565b60c08c01805190910190525b6000811215612625576126186125fd600085612ee4565b82600003018e60a0015163ffffffff16633b9aca0003612203565b60c08c0180519190910390525b600061263d8c60a001518d60c0015187868887612f03565b9050801561269d57806001141561266157600019909201916001919091019061267d565b80600019141561267b5760a08c018051600101905261267d565bfe5b6126938c60a001518d60c0015187868887612f03565b9050801561269d57fe5b60018c5260608c0183905260808c0182905260e08c018890526101008c0189905260c08e015160ff166126e6576101008c01516101208d015260e08c01516101408d01526126fe565b60e08c01516101208d01526101008c01516101408d01525b50505050505050505050509392505050565b60018151600a81111561271f57fe5b1461272657fe5b60608083015160009081526020818152604080832093850151858301516001600160a01b0390811685528584528285209783018051821686529784528285209190915560808601519582015181168452938252808320955190931682529390935290912055565b600081131561287857826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156127f657600080fd5b505af115801561280a573d6000803e3d6000fd5b505050506040513d602081101561282057600080fd5b5051612873576040805162461bcd60e51b815260206004820152601860248201527f444552525f544f4b454e5f5452414e534645525f4641494c0000000000000000604482015290519081900360640190fd5b61295b565b600081121561295b57604080516323b872dd60e01b81526001600160a01b038481166004830152306024830152600084810360448401529251908616926323b872dd92606480820193602093909283900390910190829087803b1580156128de57600080fd5b505af11580156128f2573d6000803e3d6000fd5b505050506040513d602081101561290857600080fd5b505161295b576040805162461bcd60e51b815260206004820152601c60248201527f444552525f544f4b454e5f5452414e5346455246524f4d5f4641494c00000000604482015290519081900360640190fd5b505050565b60018151600a81111561296f57fe5b1461297657fe5b8060c001518160a0015112156129b95761299d826040015182602001518360a0015161278d565b6129b4826040015182604001518360c0015161278d565b6129e7565b6129d0826040015182604001518360c0015161278d565b6129e7826040015182602001518360a0015161278d565b60c082015160ff16156129ff57806101000151612a05565b8060e001515b610140909201516000908152600160205260409020805490920190915550565b816060015182600001516001600160a01b0316336001600160a01b03167fdc13589835b7bdc7ff3bbf712a59927511e18e82e9ec9231372692090e1c09f185604001518661014001518760c001518860a0015188610100015189606001518a60e001518b608001518c60a001518d60c00151604051808b6001600160a01b03166001600160a01b031681526020018a81526020018960ff1660ff1681526020018863ffffffff1663ffffffff1681526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a45050565b604080516000808252602080830180855287905260ff85811c601b011683850152606083018690526001600160ff1b03851660808401529251909260019260a080820193601f1981019281900390910190855afa158015612b78573d6000803e3d6000fd5b5050604051601f19015195945050505050565b600082821115612b9757fe5b50900390565b815160601c81528151600160581b1615612bb75733612bba565b60005b6001600160a01b031660208281019190915282018051608090811c90830152805160601c63ffffffff1660a0830152825160501c60ff1660c0830152825160281c64ffffffffff90811660e0840152925190921661010082015290516bffffffffffffffffffffffff1661012090910152565b8051604080830151608084015161012085015183516bffffffffffffffffffffffff19606096871b81166020808401919091529490961b90951660348601526048850191909152606880850191909152825180850390910181526088909301909152815191012061014090910152565b600080612da6846001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612cf957600080fd5b505afa158015612d0d573d6000803e3d6000fd5b505050506040513d6020811015612d2357600080fd5b505160408051636eb1769f60e11b81526001600160a01b03878116600483015230602483015291519188169163dd62ed3e91604480820192602092909190829003018186803b158015612d7557600080fd5b505afa158015612d89573d6000803e3d6000fd5b505050506040513d6020811015612d9f57600080fd5b5051612e44565b90506001600160801b038111156108db576040805162461bcd60e51b8152602060048201526013602482015272444552525f42414c414e43455f494e53414e4560681b604482015290519081900360640190fd5b6000848215612e20576000851215612e1b57612e198560000385612203565b015b612e3b565b6000851315612e3b57612e398585633b9aca0003612203565b015b95945050505050565b6000818310612e5357816108db565b5090919050565b600080600083612e708786633b9aca0003612ec4565b81612e7757fe5b0486019050600084633b9aca0003612e8f8787612ec4565b81612e9657fe5b048601905080821115612eb25785810386935093505050612ebc565b5085925082900390505b935093915050565b6000828202831580612ede575082848281612edb57fe5b04145b6108db57fe5b6000818312612e5357816108db565b600081831215612e5357816108db565b60008080851315612f1d57612f19600087612ef3565b8503015b6000841315612f3657612f31600084612ef3565b840390035b8701860190509695505050505050565b60405180610160016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600063ffffffff168152602001600060ff168152602001600081526020016000815260200160008152602001600081525090565b604080516101608101909152806000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a265627a7a72315820b605f651f6cf04bb6fcbe5454668200c9c33798c9b1f98d8215326c9dcd925da64736f6c634300050c0032

Deployed Bytecode Sourcemap

458:27188:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6605:29;;;-1:-1:-1;;;6605:29:0;;;;;;;;;;;;-1:-1:-1;;;6605:29:0;;;;;;;;;;;;;;14672:234;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14672:234:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14672:234:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;14672:234:0;;;;;;;;;;;;;;;;;;;;13321:278;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13321:278:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;13321:278:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;13321:278:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;13321:278:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;13321:278:0;;-1:-1:-1;13321:278:0;-1:-1:-1;13321:278:0;:::i;:::-;;15048:124;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15048:124:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15048:124:0;-1:-1:-1;;;;;15048:124:0;;:::i;:::-;;;;;;;;;;;;;;;;11289:152;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11289:152:0;;;:::i;15180:211::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15180:211:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;15180:211:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;14502:162;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14502:162:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14502:162:0;;;-1:-1:-1;;;;;14502:162:0;;;;;;;;;;;;:::i;7810:3094::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7810:3094:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;7810:3094:0;;;-1:-1:-1;;;;;7810:3094:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;7810:3094:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;7810:3094:0;;;;;;102:9:-1;95:3;81:12;77:22;67:8;63:37;60:52;-1:-1;;;25:12;22:29;11:109;8:2;;;133:1;130;123:12;8:2;-1:-1;7810:3094:0;;-1:-1:-1;7810:3094:0;-1:-1:-1;7810:3094:0;:::i;11449:1864::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11449:1864:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;11449:1864:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;11449:1864:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;11449:1864:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;11449:1864:0;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;11449:1864:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;11449:1864:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;11449:1864:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;11449:1864:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;11449:1864:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;11449:1864:0;;-1:-1:-1;11449:1864:0;-1:-1:-1;11449:1864:0;:::i;10912:369::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10912:369:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;10912:369:0;;;;;;;;;;;;;:::i;13607:846::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13607:846:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;13607:846:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;13607:846:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;13607:846:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;13607:846:0;;-1:-1:-1;13607:846:0;-1:-1:-1;13607:846:0;:::i;14914:126::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14914:126:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14914:126:0;;:::i;6650:1152::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6650:1152:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;6650:1152:0;;;;;;;;;;;;;-1:-1:-1;;;;;6650:1152:0;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;6650:1152:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;6650:1152:0;;;;;;102:9:-1;95:3;81:12;77:22;67:8;63:37;60:52;-1:-1;;;25:12;22:29;11:109;8:2;;;133:1;130;123:12;8:2;-1:-1;6650:1152:0;;-1:-1:-1;6650:1152:0;-1:-1:-1;6650:1152:0;:::i;14672:234::-;14736:4;14813:16;;;;;;;;;;;14848:11;;;;14888:9;;;14840:58;;;;;;;;;;;;;;;;;14736:4;;;;14758:24;;14813:16;14848:11;;;;14861:12;14848:11;14861:12;;;;;-1:-1:-1;;;14875:11:0;;;;;14888:9;;14840:58;14888:9;;14840:58;;14888:9;14840:58;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14840:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14672:234;;;;;:::o;13321:278::-;13412:27;;13428:10;;13412:27;;;;;13452:15;13470:16;;;;;;;;;;13507:11;;;;;;13499:48;;;;;-1:-1:-1;;;13499:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;13560:31;13574:7;13583;;13560:31;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;13560:13:0;;-1:-1:-1;;;13560:31:0:i;:::-;13321:278;;;;:::o;15048:124::-;-1:-1:-1;;;;;15139:25:0;;15115:4;15139:25;;;:16;:25;;;;;;15048:124;;;;:::o;11289:152::-;11347:10;11330:28;;;;:16;:28;;;;;;;;;11361:15;11330:46;;;;11392:41;;;;;;;;;;;;;;;;;11289:152::o;15180:211::-;15246:7;15255;15275:14;;:::i;:::-;15292:27;;;;;;;;;;;;15312:6;;15292:27;;;;15312:6;;15292:27;15312:6;15292:27;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;15292:19:0;;-1:-1:-1;;15292:27:0:i;:::-;15275:44;;15338:17;15353:1;15338:14;:17::i;:::-;15371:10;;;;;15357:25;;;;:13;:25;;;;;;15330:53;;-1:-1:-1;15357:25:0;-1:-1:-1;15180:211:0;;;;:::o;14502:162::-;14591:3;14614:16;;;;;;;;;;;-1:-1:-1;;;;;14614:35:0;;;;;;;;;;;:42;;;;;;;;;;;14502:162;;;;;;:::o;7810:3094::-;7957:33;;7979:10;;7957:33;;;;;8011:28;8003:69;;;;;-1:-1:-1;;;8003:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;8085:22;;:::i;:::-;8110:44;8122:7;8131:5;8138:15;8110:44;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;8110:11:0;;-1:-1:-1;;8110:44:0:i;:::-;8085:69;-1:-1:-1;8172:6:0;8167:2730;8184:28;;;8167:2730;;;8234:23;;:::i;:::-;8260:49;8272:7;8281:5;8288:17;;8306:1;8288:20;;;;;;;;;;;;8260:49;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;8260:11:0;;-1:-1:-1;;8260:49:0:i;:::-;8353:16;;8334:15;;8234:75;;-1:-1:-1;;;;;;8334:35:0;;;;;;;8326:63;;;;;-1:-1:-1;;;8326:63:0;;;;;;;;;;;;-1:-1:-1;;;8326:63:0;;;;;;;;;;;;;;;8436:9;:19;;;8412:43;;:10;:20;;;:43;;;;8404:75;;;;;-1:-1:-1;;;8404:75:0;;;;;;;;;;;;-1:-1:-1;;;8404:75:0;;;;;;;;;;;;;;;8499:20;8521:15;8540:29;8559:9;8540:18;:29::i;:::-;8498:71;;;;8585:21;8608:16;8628:30;8647:10;8628:18;:30::i;:::-;8584:74;;;;8697:16;8679:15;:34;8675:376;;;8752:110;8768:16;8787:9;:19;;;:24;;8810:1;8787:24;:74;;8846:9;:15;;;8787:74;;;;;8827:9;:15;;;8815:27;;642:10;8815:27;8787:74;8752:11;:110::i;:::-;8734:129;;8675:376;;;8923:111;8939:15;8957:9;:19;;;:24;;8980:1;8957:24;:76;;9016:10;:16;;;9004:28;;642:10;9004:28;8957:76;;;8984:10;:16;;;8957:76;;8923:11;:111::i;:::-;8904:131;;8675:376;9069:23;;:::i;:::-;9095:40;9105:11;9118:10;9130:4;9095:9;:40::i;:::-;9069:66;-1:-1:-1;9177:14:0;9156:17;;:35;;;;;;;;;9152:237;;9261:10;:18;;;9243:10;:16;;;-1:-1:-1;;;;;9217:129:0;9231:10;-1:-1:-1;;;;;9217:129:0;;9281:10;:16;;;9299:10;:19;;;9327:10;:17;;;9320:25;;;;;;;;9217:129;;;-1:-1:-1;;;;;9217:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;9365:8;;;;;;;;9152:237;9405:43;9425:10;9437;9405:19;:43::i;:::-;9465:22;;:::i;:::-;9490:38;9500:10;9512:9;9523:4;9490:9;:38::i;:::-;9465:63;-1:-1:-1;9573:14:0;9553:16;;:34;;;;;;;;;9545:67;;;;;-1:-1:-1;;;9545:67:0;;;;;;;;;;;;-1:-1:-1;;;9545:67:0;;;;;;;;;;;;;;;9629:41;9649:9;9660;9629:19;:41::i;:::-;9689:21;9713:1;9689:25;;9735:9;:19;;;:24;;9758:1;9735:24;9731:420;;;-1:-1:-1;9830:27:0;;;;;9800;;;;;9936:1;9906:31;;;;9876:61;;;9800:57;9731:420;;;-1:-1:-1;10027:28:0;;;;;9998:26;;;;;10134:1;10103:32;;;;10074:61;;;9998:57;9731:420;10193:1;10173:17;:21;10169:88;;;10196:61;10210:9;:15;;;10227:10;10239:17;10196:13;:61::i;:::-;10368:10;:27;;;10337:10;:28;;;:58;10308:9;:26;;;10278:9;:27;;;:56;:117;10274:401;;;10416:40;10435:9;10446;10416:18;:40::i;:::-;10475:42;10494:10;10506;10475:18;:42::i;:::-;10274:401;;;10558:42;10577:10;10589;10558:18;:42::i;:::-;10619:40;10638:9;10649;10619:18;:40::i;:::-;10715:1;10695:17;:21;10691:88;;;10718:61;10732:9;:15;;;10749:10;10761:17;10718:13;:61::i;:::-;10798:37;10812:10;10824;10798:13;:37::i;:::-;10850:35;10864:9;10875;10850:13;:35::i;:::-;8167:2730;;;;;;;;;8214:3;;8167:2730;;;;7810:3094;;;;;;:::o;11449:1864::-;11650:27;;11666:10;;11650:27;;;;;11690:12;11737:7;11746:12;11760:9;11771:7;;11720:59;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;11720:59:0;;;45:16:-1;;;;26:21;;;-1:-1;;22:32;6:49;;11720:59:0;;11710:70;;49:4:-1;11710:70:0;;;;11705:76;11812:16;;;;;;;;;;11846:11;;;;11710:70;;-1:-1:-1;11812:16:0;-1:-1:-1;;11846:11:0;;;-1:-1:-1;11841:1421:0;;-1:-1:-1;;;;11841:1421:0;11897:1;11882:12;:16;11874:52;;;;;-1:-1:-1;;;11874:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;11949:29;;;11941:63;;;;;-1:-1:-1;;;11941:63:0;;;;;;;;;;;;-1:-1:-1;;;11941:63:0;;;;;;;;;;;;;;;642:10;12027:9;:22;;12019:57;;;;;-1:-1:-1;;;12019:57:0;;;;;;;;;;;;-1:-1:-1;;;12019:57:0;;;;;;;;;;;;;;;12267:52;;;12292:4;12267:52;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;12267:52:0;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;12267:52:0;;;;;12257:63;;;;;;12125:232;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12125:232:0;;;;;;;12115:243;;;;;12093:19;;12410:367;12427:18;;;12410:367;;;12475:4;;12480:1;12475:7;;;;;;;;;;;;12483:1;12475:10;;;;;;;;;;;:15;12471:291;;12515:14;12532:52;12548:11;12561:4;;12566:1;12561:7;;;;;;;;;;;;12569:1;12561:10;;;;;;;;;;;12573:4;;12578:1;12573:7;;;;;;;;;;;;12581:1;12573:10;;;;;;;;;;;12532:15;:52::i;:::-;12515:69;;12625:7;;12633:1;12625:10;;;;;;;;;;;;;-1:-1:-1;;;;;12625:10:0;-1:-1:-1;;;;;12615:20:0;:6;-1:-1:-1;;;;;12615:20:0;;12607:52;;;;;-1:-1:-1;;;12607:52:0;;;;;;;;;;;;-1:-1:-1;;;12607:52:0;;;;;;;;;;;;;;;12682:1;:9;;12697:7;;12705:1;12697:10;;;;;;;27::-1;;39:1;23:18;;;45:23;;-1:-1;12682:26:0;;;12697:10;12682:26;;;;;;;;;12697:10;;;;;;;;;-1:-1:-1;;;;;12697:10:0;-1:-1:-1;;;;;;12682:26:0;;;;;;;12731:11;;;;;-1:-1:-1;;12471:291:0;12447:3;;12410:367;;;;12814:12;12801:9;:25;;12793:63;;;;;-1:-1:-1;;;12793:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;13010:4;12996:11;;;:18;;-1:-1:-1;;12996:18:0;;;;-1:-1:-1;;13029:26:0;12969:10;12956:23;;12996:18;13029:26;;;;;;;;;12904:10;12891:23;;12890:30;;;;13084:33;;13107:9;13084:33;;;13096:1;13084:33;13070:11;;;:47;;-1:-1:-1;;13070:47:0;-1:-1:-1;;;13070:47:0;;;;;;;;;;642:10;13070:47;13142:12;;;;;;:25;;13134:57;;;;;-1:-1:-1;;;13134:57:0;;;;;;;;;;;;-1:-1:-1;;;13134:57:0;;;;;;;;;;;;;;;13213:37;;;;;;;;;;13230:7;;13213:37;;;;;;;;;;11841:1421;;;;;13274:31;13288:7;13297;;13274:31;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;13274:13:0;;-1:-1:-1;;;13274:31:0:i;:::-;11449:1864;;;;;;;;;;;;:::o;10912:369::-;11015:26;11001:10;:40;;10993:72;;;;;-1:-1:-1;;;10993:72:0;;;;;;;;;;;;-1:-1:-1;;;10993:72:0;;;;;;;;;;;;;;;11107:55;;;11124:10;11107:55;;;;;;;;;;;;-1:-1:-1;;11107:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;11107:55:0;;;;;;11097:66;;;;;;;;;11076:13;11175:23;;;:13;:23;;;;;;;-1:-1:-1;;11175:34:0;;-1:-1:-1;;;;;11107:55:0;;11225:48;;;;;;;;;;;;;;;;11124:10;;11225:48;;;;;;;;;;10912:369;;;;:::o;13607:846::-;13787:34;;13810:10;;13787:34;;;;;13834:15;13879:11;13892:12;13906:11;13862:56;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;13862:56:0;;;13852:67;;;;;;13834:85;;13930:12;13977:7;13986:12;14000:9;14011:7;;13960:59;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;13960:59:0;;;45:16:-1;;;;26:21;;;-1:-1;;22:32;6:49;;13960:59:0;;13950:70;;49:4:-1;13950:70:0;;;;13945:76;14052:16;;;;;;;;;;14090:11;;;;13950:70;;-1:-1:-1;14052:16:0;-1:-1:-1;;14090:11:0;;14089:12;;-1:-1:-1;14081:48:0;;-1:-1:-1;;;;14081:48:0;;;;-1:-1:-1;;;14081:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14163:15;14148:12;:30;14140:67;;;;;-1:-1:-1;;;14140:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;642:10;14226:11;:24;;14218:61;;;;;-1:-1:-1;;;14218:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14306:4;14292:11;;;:18;;-1:-1:-1;;14292:18:0;;;;-1:-1:-1;;14321:34:0;14292:18;14321:34;;;;;;;;;;-1:-1:-1;;14366:15:0;;;;14399:46;;;;;;;14416:7;;14399:46;;;;;;;;;;;;;13607:846;;;;;;;;;;:::o;14914:126::-;14979:4;15003:29;;;:13;:29;;;;;;;14914:126::o;6650:1152::-;6778:27;;6794:10;;6778:27;;;;;6822:11;;;;;:40;;;6856:6;6837:15;:25;;6822:40;6818:190;;;6884:91;;;-1:-1:-1;;;;;6884:91:0;;;;6918:1;6884:91;;;;;;6948:25;6884:91;;;;;;6922:7;;6918:1;6898:10;;6884:91;;;;;;;;;6990:7;;6818:190;7028:23;7020:59;;;;;-1:-1:-1;;;7020:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;7115:6;7092:20;7134:661;7151:23;;;7134:661;;;7196:14;;:::i;:::-;7213:44;7225:7;7234:5;7241:12;;7254:1;7241:15;;;;;;7213:44;7196:61;;7274:14;;:::i;:::-;7291:36;7301:15;7318:1;7321:5;7291:9;:36::i;:::-;7274:53;-1:-1:-1;7360:14:0;7348:8;;:26;;;;;;;;;7344:379;;;7395:25;7415:1;7418;7395:19;:25::i;:::-;7439:24;7458:1;7461;7439:18;:24::i;:::-;7482:19;7496:1;7499;7482:13;:19::i;:::-;7538:39;7546:15;7563:1;:13;;;7538:7;:39::i;:::-;7520:57;;7344:379;;;7658:1;:9;;;7649:1;:7;;;-1:-1:-1;;;;;7623:84:0;7637:10;-1:-1:-1;;;;;7623:84:0;;7669:1;:7;;;7678:1;:10;;;7697:1;:8;;;7690:16;;;;;;;;7623:84;;;-1:-1:-1;;;;;7623:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;7344:379;600:1;7743:15;:33;7739:44;;;7778:5;;;;7739:44;-1:-1:-1;;7176:3:0;;7134:661;;;;6650:1152;;;;;;;;:::o;17006:1788::-;17088:15;17106:16;;;;;;;;;;17140:11;;;;;;17133:19;;;;17170:11;;;;642:10;-1:-1:-1;;;17170:11:0;;;;;:24;;17163:32;;;;17213:6;17208:1579;17229:7;:14;17225:1;:18;17208:1579;;;17261:13;17285:7;17293:1;17285:10;;;;;;;;;;;;;;;;;;17396:3;;;;;-1:-1:-1;;;;;17285:57:0;;-1:-1:-1;17358:12:0;17391:983;17405:7;:14;17401:1;:18;:50;;;;;17424:7;17432:1;17424:10;;;;;;;;;;;;;;-1:-1:-1;;;17424:21:0;17450:1;17423:28;17401:50;17391:983;;;17477:12;17500:7;17508:1;17500:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17583:17:0;;;17530:9;17583:17;;;;;;;;;;:24;;;;;;;;;;;;17500:10;;-1:-1:-1;17632:18:0;;;17628:308;;;17711:12;;;;17683:41;;17695:14;;17711:12;;;;;17683:11;:41::i;:::-;17675:49;;17628:308;;;17771:1;17754:14;:18;17750:186;;;17846:12;;;;17805:54;;17817:15;;;;;17846:12;;;;;642:10;17834:24;17805:11;:54::i;17750:186::-;17908:8;;;;;17750:186;17972:1;17963:5;:10;;17956:18;;;;18024:11;;;;17995:7;;18005:31;;18017:5;;-1:-1:-1;;;18024:11:0;;;;18005;:31::i;:::-;17995:41;;18069:1;18062:3;:8;;18055:16;;;;18123:15;;;;18092:12;;;;;18175:1;18166:10;;;18159:18;;;;-1:-1:-1;;;;;18198:17:0;;;18225:1;18198:17;;;;;;;;;;;:24;;;;;;;;;;;:28;18245:33;18216:5;18210:4;18272:5;18245:13;:33::i;:::-;18328:5;-1:-1:-1;;;;;18304:54:0;18319:7;18313:4;-1:-1:-1;;;;;18304:54:0;;18340:5;18353:3;18304:54;;;;;;;;;;;;;;;;;;;;;;;;17391:983;;;;;17453:3;;;;;17391:983;;;18394:11;;;;-1:-1:-1;;;18394:11:0;;;;:16;;:33;;-1:-1:-1;18414:13:0;;18394:33;18390:47;;;18429:8;;;;18390:47;18488:9;;;:16;18454;;18473:8;18488:16;18473:32;;;;;;-1:-1:-1;18527:6:0;18522:174;18543:9;;;:16;-1:-1:-1;;18543:20:0;18539:24;;18522:174;;;18601:12;18589:24;;;;18632:48;18646:5;18653:1;:9;;18663:1;18653:12;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18653:12:0;18667;18632:13;:48::i;:::-;18565:3;;18522:174;;;-1:-1:-1;18733:9:0;;;18743:16;;18712:63;;18726:5;;-1:-1:-1;;18743:20:0;;;18733:31;;;;;18712:63;17208:1579;;;;;;5602:266;5675:14;;:::i;:::-;5702:23;5715:6;5723:1;5702:12;:23::i;:::-;5750:9;;;;;5738;;;;:21;;;;5788:9;;;-1:-1:-1;;;;;5770:28:0;:7;;;:28;-1:-1:-1;5750:9:0;5809:7;;:20;5842:18;5738:9;5842:15;:18::i;24061:552::-;24122:4;24162:1;:8;;;24143:15;:27;;:71;;;-1:-1:-1;24203:11:0;;;;24191:7;;-1:-1:-1;;;;;24174:25:0;;;;;:16;:25;;;;;;:40;;24143:71;24139:85;;;-1:-1:-1;24223:1:0;24216:8;;24139:85;24265:10;;;;24237:11;24251:25;;;:13;:25;;;;;;-1:-1:-1;;24291:18:0;;24287:32;;;24318:1;24311:8;;;;;24287:32;24358:9;;;;24332:15;24350:18;;;;;;;;;;24403:8;;;;24350:18;;24332:15;24395:25;;24413:6;24395:7;:25::i;:::-;24458:7;;-1:-1:-1;;;;;24446:20:0;;;24431:12;24446:20;;;;;;;;;;;24467:7;;;;;24446:29;;;;;;;;;;;24549:7;;24558;;24381:39;;-1:-1:-1;24446:29:0;;24495:110;;24381:39;;24511:93;;24535:31;;:13;:31::i;:::-;24568:8;24578:1;:7;;;24511:93;;24587:1;:11;;;:16;;24602:1;24587:16;24511:23;:93::i;:::-;24495:7;:110::i;:::-;24488:117;24061:552;-1:-1:-1;;;;;;24061:552:0:o;4335:1259::-;4429:14;;:::i;:::-;4456:23;4469:6;4477:1;4456:12;:23::i;:::-;-1:-1:-1;;;;;4492:15:0;;:7;;;:15;4518:9;;;:19;;;4550:18;4492:1;4550:15;:18::i;:::-;4581:21;733:95;;;;;;;;;;;;;;;;;;;839:19;;;;-1:-1:-1;;;839:19:0;;;;;;;;;;;;;;869:16;;;;-1:-1:-1;;;869:16:0;;;;;;;;;;;;;;904:1;954:42;712:326;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;712:326:0;-1:-1:-1;;;;;712:326:0;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;712:326:0;;;702:337;;;;;;3215:382;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;-1:-1:-1;;;3215:382:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3215:382:0;;;3205:393;;;;;;4781:1;:7;;;4807:1;:7;;;4833:1;:7;;;4859:1;:9;;;4887:1;:8;;;4919:1;:7;;;4914:13;;4951:1;:11;;;4946:17;;4982:1;:8;;;5009:1;:11;;;5039:1;:12;;;4709:357;;;;;;;;;;;-1:-1:-1;;;;;4709:357:0;-1:-1:-1;;;;;4709:357:0;;;;;;-1:-1:-1;;;;;4709:357:0;-1:-1:-1;;;;;4709:357:0;;;;;;-1:-1:-1;;;;;4709:357:0;-1:-1:-1;;;;;4709:357:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4709:357:0;;;4699:368;;;;;;4615:463;;;;;;-1:-1:-1;;;4615:463:0;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4615:463:0;;;4605:474;;;;;;4581:498;;5097:6;5104:1;5097:9;;;;;;;;;;;-1:-1:-1;;;5097:28:0;5096:35;5092:135;;5212:13;5159:67;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;5159:67:0;;;5149:78;;;;;;5133:94;;5092:135;5304:7;;-1:-1:-1;;;;;5248:63:0;:52;5264:13;5279:6;5286:1;5279:9;;;;5290:6;5297:1;5290:9;;;;5248:15;:52::i;:::-;-1:-1:-1;;;;;5248:63:0;;5240:104;;;;;-1:-1:-1;;;5240:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5363:7;;;;-1:-1:-1;;;;;5363:21:0;;;:46;;-1:-1:-1;5388:7:0;;;;-1:-1:-1;;;;;5388:21:0;5399:10;5388:21;5363:46;5355:77;;;;;-1:-1:-1;;;5355:77:0;;;;;;;;;;;;-1:-1:-1;;;5355:77:0;;;;;;;;;;;;;;;5478:1;5468;:7;;;:11;;;:34;;;;;642:10;5483:1;:7;;;:19;;;5468:34;5460:65;;;;;-1:-1:-1;;;5460:65:0;;;;;;;;;;;;-1:-1:-1;;;5460:65:0;;;;;;;;;;;;;;;5558:1;5544;:11;;;:15;;;5536:50;;;;;-1:-1:-1;;;5536:50:0;;;;;;;;;;;;-1:-1:-1;;;5536:50:0;;;;;;;;;;;;;;;4335:1259;;;;;;:::o;24621:522::-;24686:4;24692;24713:1;:11;;;:16;;24728:1;24713:16;24709:427;;;24747:15;24764:16;24784:72;24812:17;24827:1;24812:14;:17::i;:::-;-1:-1:-1;;;;;24848:1:0;:7;;;24784:72;;:27;:72::i;:::-;24881:24;;;;-1:-1:-1;24746:110:0;-1:-1:-1;24873:46:0;;-1:-1:-1;;24873:46:0;24709:427;24953:15;24970:16;24990:72;-1:-1:-1;;;;;25035:17:0;25050:1;25035:14;:17::i;:::-;25054:1;:7;;;24990:72;;:27;:72::i;:::-;25087:24;;;-1:-1:-1;24952:110:0;-1:-1:-1;25079:45:0;;-1:-1:-1;;25079:45:0;25381:172;25447:3;25480:1;25470:6;:11;;25463:19;;;;642:10;25504:28;25517:6;25526:5;25504:7;:28::i;:::-;:40;;;;;;;25381:172;-1:-1:-1;;;25381:172:0:o;19158:4895::-;19255:14;;:::i;:::-;19293:19;19282:30;;19348:8;;;;19329:15;:27;19325:119;;19384:25;19373:36;;19424:8;;19325:119;19495:10;;;;19456:22;19481:25;;;:13;:25;;;;;;;;;19552:11;;;;19540:7;;-1:-1:-1;;;;;19523:25:0;;;:16;:25;;;;;;:40;;;:73;;;-1:-1:-1;;19567:17:0;:29;19523:73;19519:167;;;19613:1;19624:27;19613:38;;;;;;;;;;;;;-1:-1:-1;19666:8:0;;-1:-1:-1;19666:8:0;19519:167;19716:7;;-1:-1:-1;;;;;19702:21:0;:10;:21;19698:110;;;19740:1;19751:22;19740:33;;19698:110;-1:-1:-1;;;;;19824:6:0;:24;19820:119;;;19865:1;19876:28;19865:39;;19820:119;19977:9;;;;19951:15;19969:18;;;;;;;;;;20004:11;;;;;;20000:105;;;-1:-1:-1;;20043:27:0;20032:38;;20085:8;;20000:105;20119:15;20145:16;20172;20199:17;20233:1;:11;;;:16;;20248:1;20233:16;20229:826;;;20319:10;20306;;;:23;20394:7;;-1:-1:-1;;;;;20380:21:0;:11;;;:21;20438:8;;;;20357:6;;-1:-1:-1;20430:36:0;;20448:17;20430:7;:36::i;:::-;20416:50;;20497:21;:76;;20539:34;20553:1;:7;;;20562:1;:10;;;20539:13;:34::i;:::-;20497:76;;;-1:-1:-1;;;;;20497:76:0;20483:90;;20603:35;20617:1;:7;;;20626:1;:11;;;20603:13;:35::i;:::-;20588:50;;20229:826;;;20724:7;;-1:-1:-1;;;;;20711:20:0;:10;;;:20;20767:8;;;;20759:36;;20777:17;20759:7;:36::i;:::-;20826:10;20812:11;;;;:24;;;;20916:7;;;20925:10;;;;20746:49;;-1:-1:-1;20865:6:0;;-1:-1:-1;20902:34:0;;:13;:34::i;:::-;20888:48;;20966:21;:77;;21008:35;21022:1;:7;;;21031:1;:11;;;21008:13;:35::i;:::-;20966:77;;;-1:-1:-1;;;;;20966:77:0;20951:92;;20229:826;21101:10;;;;;-1:-1:-1;;;;;21089:23:0;;;21067:19;21089:23;;;;;;;;;;21113:7;;;;;21089:32;;;;;;;;;;;21167:11;;;;21155:24;;;;;;;;;;21180:7;;21155:33;;;;;;;;;;;;;21288:7;;;;21214:89;;21222:10;;21234:68;;21258:11;;21089:32;;21234:68;;21297:4;21234:23;:68::i;21214:89::-;21201:102;;21328:93;21336:11;21349:71;21373:12;21387:16;21405:1;:7;;;21349:71;;21414:5;21349:23;:71::i;21328:93::-;21314:107;;600:1;21438:10;:28;21434:173;;;21494:11;;;;:16;;;:78;;21544:28;21494:78;;;21513:28;21494:78;21483:1;;:89;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21587:8:0;;-1:-1:-1;;;;;;;;21587:8:0;21434:173;600:1;21623:11;:29;21619:174;;;21680:11;;;;:16;;;:78;;21730:28;21680:78;;;21669:1;21699:28;21669:89;;21619:174;21833:61;21861:10;21873:11;21886:1;:7;;;21833:61;;:27;:61::i;:::-;21805:89;;-1:-1:-1;21805:89:0;-1:-1:-1;600:1:0;21911:28;;;:61;;;600:1;21943:11;:29;21911:61;21907:155;;;21989:1;22000:27;21989:38;;21907:155;22074:19;22254:18;;;:22;;;22287:19;;;:23;;;22115:34;;;22096:54;;;;22184:55;;;;22327:19;;22323:126;;;22370:79;22401:26;22408:1;22411:15;22401:6;:26::i;:::-;22383:15;22382:16;;:45;22441:1;:7;;;22429:19;;642:10;22429:19;22370:11;:79::i;:::-;22348:18;;;:101;;;;;;;22323:126;22482:1;22464:15;:19;22460:113;;;22507:66;22537:26;22544:1;22547:15;22537:6;:26::i;:::-;22519:15;:44;22565:1;:7;;;22507:66;;:11;:66::i;:::-;22485:18;;;:88;;;;;;;;22460:113;22609:1;22590:16;:20;22586:117;;;22635:68;22666:27;22673:1;22676:16;22666:6;:27::i;:::-;22647:16;:46;22695:1;:7;;;22635:68;;:11;:68::i;:::-;22612:19;;;:91;;;;;;;22586:117;22737:1;22718:16;:20;22714:130;;;22763:81;22795:27;22802:1;22805:16;22795:6;:27::i;:::-;22776:16;22775:17;;:47;22836:1;:7;;;22824:19;;642:10;22824:19;22763:11;:81::i;:::-;22740:19;;;:104;;;;;;;;22714:130;22857:17;22877:131;22898:1;:18;;;22918:1;:19;;;22939:15;22956;22973:16;22991;22877:20;:131::i;:::-;22857:151;-1:-1:-1;23025:18:0;;23021:558;;23064:13;23081:1;23064:18;23060:303;;;-1:-1:-1;;23103:17:0;;;;;23139:18;;;;;23060:303;;;23183:13;-1:-1:-1;;23183:19:0;23179:184;;;23223:18;;;:20;;;;;;23179:184;;;23334:13;;23395:131;23416:1;:18;;;23436:1;:19;;;23457:15;23474;23491:16;23509;23395:20;:131::i;:::-;23379:147;-1:-1:-1;23548:18:0;;23541:26;;;;23604:14;23593:25;;23629:17;;;:35;;;23675:18;;;:37;;;23723:13;;;:27;;;23761:12;;;:25;;;23803:11;;;;:16;;23799:226;;23852:12;;;;23836:13;;;:28;23895:13;;;;23879;;;:29;23799:226;;;23957:13;;;;23941;;;:29;24001:12;;;;23985:13;;;:28;23799:226;-1:-1:-1;;;;;;;;;;;19158:4895:0;;;;;:::o;15822:301::-;15921:14;15909:8;;:26;;;;;;;;;15902:34;;;;15975:9;;;;;15949:15;15967:18;;;;;;;;;;;16033:17;;;;16010:10;;;;-1:-1:-1;;;;;15998:23:0;;;;;;;;;;;16022:7;;;;;15998:32;;;;;;;;;;:52;;;;16097:18;;;;16073:11;;;;16061:24;;;;;;;;;;16086:7;;16061:33;;;;;;;;;;;;:54;15822:301::o;15441:373::-;15535:1;15527:5;:9;15523:284;;;15573:5;-1:-1:-1;;;;;15561:27:0;;15589:4;15600:5;15561:46;;;;;;;;;;;;;-1:-1:-1;;;;;15561:46:0;-1:-1:-1;;;;;15561:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15561:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15561:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15561:46:0;15553:83;;;;;-1:-1:-1;;;15553:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;15523:284;;;15666:1;15658:5;:9;15654:153;;;15692:70;;;-1:-1:-1;;;15692:70:0;;-1:-1:-1;;;;;15692:70:0;;;;;;;15738:4;15692:70;;;;15750:10;;;;15692:70;;;;;;:31;;;;;;:70;;;;;;;;;;;;;;;;;;:31;:70;;;5:2:-1;;;;30:1;27;20:12;5:2;15692:70:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15692:70:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15692:70:0;15684:111;;;;;-1:-1:-1;;;15684:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;15441:373;;;:::o;16131:580::-;16229:14;16217:8;;:26;;;;;;;;;16210:34;;;;16282:1;:19;;;16261:1;:18;;;:40;16257:356;;;16318:54;16332:1;:7;;;16341:1;:10;;;16353:1;:18;;;16318:13;:54::i;:::-;16387:56;16401:1;:7;;;16410:1;:11;;;16423:1;:19;;;16387:13;:56::i;:::-;16257:356;;;16476:56;16490:1;:7;;;16499:1;:11;;;16512:1;:19;;;16476:13;:56::i;:::-;16547:54;16561:1;:7;;;16570:1;:10;;;16582:1;:18;;;16547:13;:54::i;:::-;16655:11;;;;:16;;;:47;;16690:1;:12;;;16655:47;;;16674:1;:13;;;16655:47;16639:10;;;;;16625:25;;;;:13;:25;;;;;:78;;;;;;;;-1:-1:-1;16131:580:0:o;16719:279::-;16828:1;:9;;;16819:1;:7;;;-1:-1:-1;;;;;16798:192:0;16807:10;-1:-1:-1;;;;;16798:192:0;;16839:1;:7;;;16848:1;:10;;;16860:1;:11;;;16873:1;:7;;;16882:1;:12;;;16896:1;:17;;;16915:1;:13;;;16930:1;:18;;;16950:1;:18;;;16970:1;:19;;;16798:192;;;;-1:-1:-1;;;;;16798:192:0;-1:-1:-1;;;;;16798:192:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16719:279;;:::o;25178:195::-;25283:82;;;25256:7;25283:82;;;;;;;;;;;;;25317:3;25311:9;;;25305:2;:16;25283:82;;;;;;;;;;;-1:-1:-1;;;;;25344:19:0;;25283:82;;;;;;25256:7;;25283:82;;;;;;;-1:-1:-1;;25283:82:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;25283:82:0;;-1:-1:-1;;25283:82:0;;;25178:195;-1:-1:-1;;;;;25178:195:0:o;27213:116::-;27267:4;27296:1;27291;:6;;27284:14;;;;-1:-1:-1;27316:5:0;;;27213:116::o;3607:551::-;3710:9;;3724:4;3710:19;3692:38;;3751:9;;-1:-1:-1;;;3751:28:0;:33;:59;;3800:10;3751:59;;;3795:1;3751:59;-1:-1:-1;;;;;3741:69:0;:7;;;;:69;;;;3832:9;;;;3846:4;3832:19;;;3821:8;;;:30;3879:9;;3900:4;3879:27;3909:10;3879:40;3862:7;;;:58;3952:9;;3966:4;3952:19;3975:4;3951:28;3931:11;;;:49;4003:9;;4017:3;4003:18;4025:12;4002:35;;;3991:8;;;:46;4062:9;;:24;;;4048:11;;;:38;4112:9;;4124:26;4112:38;4097:12;;;;:53;3607:551::o;4166:161::-;4276:7;;4285;;;;;4294:8;;;;4304:12;;;;4259:58;;-1:-1:-1;;4259:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;4259:58:0;;;;;;;4249:69;;;;;4231:10;;;;:88;4166:161::o;18847:303::-;18920:4;18937:12;18952:94;18972:5;-1:-1:-1;;;;;18960:28:0;;18989:4;18960:34;;;;;;;;;;;;;-1:-1:-1;;;;;18960:34:0;-1:-1:-1;;;;;18960:34:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18960:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18960:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18960:34:0;18996:49;;;-1:-1:-1;;;18996:49:0;;-1:-1:-1;;;;;18996:49:0;;;;;;;19039:4;18996:49;;;;;;:28;;;;;;:49;;;;;18960:34;;18996:49;;;;;;;;:28;:49;;;5:2:-1;;;;30:1;27;20:12;5:2;18996:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18996:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18996:49:0;18952:7;:94::i;:::-;18937:109;;-1:-1:-1;;;;;19065:7:0;:26;;19057:58;;;;;-1:-1:-1;;;19057:58:0;;;;;;;;;;;;-1:-1:-1;;;19057:58:0;;;;;;;;;;;;;;25561:440;25668:4;25709:7;25729:229;;;;25771:1;25760:8;:12;25756:73;;;25799:29;25812:8;25811:9;;25822:5;25799:11;:29::i;:::-;25774:55;25756:73;25729:229;;;25877:1;25866:8;:12;25862:84;;;25905:40;25917:8;25939:5;642:10;25927:17;25905:11;:40::i;:::-;25880:66;25862:84;25977:16;25561:440;-1:-1:-1;;;;;25561:440:0:o;27337:99::-;27391:4;27419:1;27415;:5;:13;;27427:1;27415:13;;;-1:-1:-1;27423:1:0;;27408:20;-1:-1:-1;27337:99:0:o;26009:533::-;26114:4;26120;26137:20;26215:5;26174:38;26182:10;26206:5;642:10;26194:17;26174:7;:38::i;:::-;:46;;;;;;26160:10;:61;26137:84;;26232:21;26314:5;642:10;26302:17;26271:27;26279:11;26292:5;26271:7;:27::i;:::-;:49;;;;;;26256:11;:65;26232:89;;26356:16;26338:15;:34;26334:201;;;26416:11;26397:16;:30;26429:11;26389:52;;;;;;;;26334:201;-1:-1:-1;26482:10:0;;-1:-1:-1;26494:28:0;;;;-1:-1:-1;26009:533:0;;;;;;;:::o;27054:151::-;27108:4;27134:5;;;27157:6;;;:20;;;27176:1;27171;27167;:5;;;;;;:10;27157:20;27150:28;;;27548:95;27599:3;27626:1;27622;:5;:13;;27634:1;27622:13;;27444:96;27495:3;27523:1;27518;:6;;:14;;27531:1;27518:14;;26550:496;26732:3;;26784:19;;;26780:86;;;26840:26;26847:1;26850:15;26840:6;:26::i;:::-;26822:44;;26805:61;26780:86;26900:1;26881:16;:20;26877:89;;;26939:27;26946:1;26949:16;26939:6;:27::i;:::-;26920:46;;26903:63;;26877:89;26986:32;;:52;;;-1:-1:-1;26550:496:0;;;;;;;;:::o;458:27188::-;;;;;;;;;;-1:-1:-1;;;;;458:27188:0;;;;;;-1:-1:-1;;;;;458:27188:0;;;;;;-1:-1:-1;;;;;458:27188:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;458:27188:0;;;;;-1:-1:-1;;;;;458:27188:0;;;;;;-1:-1:-1;;;;;458:27188:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

bzzr://b605f651f6cf04bb6fcbe5454668200c9c33798c9b1f98d8215326c9dcd925da

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.