ETH Price: $2,624.65 (+5.69%)
Gas: 5 Gwei

Contract

0x03b1565e070df392e48e7a8e01798C4B00E534A5
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Add Savings Prox...92399412020-01-08 12:14:411675 days ago1578485681IN
0x03b1565e...B00E534A5
0 ETH0.000179624.1
0x6080604092357852020-01-07 20:54:441675 days ago1578430484IN
 Create: DydxSavingsProtocol
0 ETH0.009325244.1

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DydxSavingsProtocol

Compiler Version
v0.5.7+commit.6da8b019

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-01-08
*/

pragma solidity ^0.5.0;

contract ProtocolInterface {

    function deposit(address _user, uint _amount) public;
    function withdraw(address _user, uint _amount) public;
}

/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/


pragma experimental ABIEncoderV2;

pragma solidity ^0.5.0;

/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {
    /**
    * @dev Multiplies two unsigned integers, reverts on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
    * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
    * @dev Adds two unsigned integers, reverts on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
    * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}


/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity 0.5.7;


/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity 0.5.7;


/**
 * @title Require
 * @author dYdX
 *
 * Stringifies parameters to pretty-print revert messages. Costs more gas than regular require()
 */
library Require {

    // ============ Constants ============

    uint256 constant ASCII_ZERO = 48; // '0'
    uint256 constant ASCII_RELATIVE_ZERO = 87; // 'a' - 10
    uint256 constant ASCII_LOWER_EX = 120; // 'x'
    bytes2 constant COLON = 0x3a20; // ': '
    bytes2 constant COMMA = 0x2c20; // ', '
    bytes2 constant LPAREN = 0x203c; // ' <'
    byte constant RPAREN = 0x3e; // '>'
    uint256 constant FOUR_BIT_MASK = 0xf;

    // ============ Library Functions ============

    function that(
        bool must,
        bytes32 file,
        bytes32 reason
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason)
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        uint256 payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        uint256 payloadA,
        uint256 payloadB
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA,
        uint256 payloadB
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA,
        uint256 payloadB,
        uint256 payloadC
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        COMMA,
                        stringify(payloadC),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        bytes32 payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        bytes32 payloadA,
        uint256 payloadB,
        uint256 payloadC
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        COMMA,
                        stringify(payloadC),
                        RPAREN
                    )
                )
            );
        }
    }

    // ============ Private Functions ============

    function stringifyTruncated(
        bytes32 input
    )
        private
        pure
        returns (bytes memory)
    {
        // put the input bytes into the result
        bytes memory result = abi.encodePacked(input);

        // determine the length of the input by finding the location of the last non-zero byte
        for (uint256 i = 32; i > 0; ) {
            // reverse-for-loops with unsigned integer
            /* solium-disable-next-line security/no-modify-for-iter-var */
            i--;

            // find the last non-zero byte in order to determine the length
            if (result[i] != 0) {
                uint256 length = i + 1;

                /* solium-disable-next-line security/no-inline-assembly */
                assembly {
                    mstore(result, length) // r.length = length;
                }

                return result;
            }
        }

        // all bytes are zero
        return new bytes(0);
    }

    function stringify(
        uint256 input
    )
        private
        pure
        returns (bytes memory)
    {
        if (input == 0) {
            return "0";
        }

        // get the final string length
        uint256 j = input;
        uint256 length;
        while (j != 0) {
            length++;
            j /= 10;
        }

        // allocate the string
        bytes memory bstr = new bytes(length);

        // populate the string starting with the least-significant character
        j = input;
        for (uint256 i = length; i > 0; ) {
            // reverse-for-loops with unsigned integer
            /* solium-disable-next-line security/no-modify-for-iter-var */
            i--;

            // take last decimal digit
            bstr[i] = byte(uint8(ASCII_ZERO + (j % 10)));

            // remove the last decimal digit
            j /= 10;
        }

        return bstr;
    }

    function stringify(
        address input
    )
        private
        pure
        returns (bytes memory)
    {
        uint256 z = uint256(input);

        // addresses are "0x" followed by 20 bytes of data which take up 2 characters each
        bytes memory result = new bytes(42);

        // populate the result with "0x"
        result[0] = byte(uint8(ASCII_ZERO));
        result[1] = byte(uint8(ASCII_LOWER_EX));

        // for each byte (starting from the lowest byte), populate the result with two characters
        for (uint256 i = 0; i < 20; i++) {
            // each byte takes two characters
            uint256 shift = i * 2;

            // populate the least-significant character
            result[41 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;

            // populate the most-significant character
            result[40 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;
        }

        return result;
    }

    function stringify(
        bytes32 input
    )
        private
        pure
        returns (bytes memory)
    {
        uint256 z = uint256(input);

        // bytes32 are "0x" followed by 32 bytes of data which take up 2 characters each
        bytes memory result = new bytes(66);

        // populate the result with "0x"
        result[0] = byte(uint8(ASCII_ZERO));
        result[1] = byte(uint8(ASCII_LOWER_EX));

        // for each byte (starting from the lowest byte), populate the result with two characters
        for (uint256 i = 0; i < 32; i++) {
            // each byte takes two characters
            uint256 shift = i * 2;

            // populate the least-significant character
            result[65 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;

            // populate the most-significant character
            result[64 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;
        }

        return result;
    }

    function char(
        uint256 input
    )
        private
        pure
        returns (byte)
    {
        // return ASCII digit (0-9)
        if (input < 10) {
            return byte(uint8(input + ASCII_ZERO));
        }

        // return ASCII letter (a-f)
        return byte(uint8(input + ASCII_RELATIVE_ZERO));
    }
}


/**
 * @title Math
 * @author dYdX
 *
 * Library for non-standard Math functions
 */
library Math {
    using SafeMath for uint256;

    // ============ Constants ============

    bytes32 constant FILE = "Math";

    // ============ Library Functions ============

    /*
     * Return target * (numerator / denominator).
     */
    function getPartial(
        uint256 target,
        uint256 numerator,
        uint256 denominator
    )
        internal
        pure
        returns (uint256)
    {
        return target.mul(numerator).div(denominator);
    }

    /*
     * Return target * (numerator / denominator), but rounded up.
     */
    function getPartialRoundUp(
        uint256 target,
        uint256 numerator,
        uint256 denominator
    )
        internal
        pure
        returns (uint256)
    {
        if (target == 0 || numerator == 0) {
            // SafeMath will check for zero denominator
            return SafeMath.div(0, denominator);
        }
        return target.mul(numerator).sub(1).div(denominator).add(1);
    }

    function to128(
        uint256 number
    )
        internal
        pure
        returns (uint128)
    {
        uint128 result = uint128(number);
        Require.that(
            result == number,
            FILE,
            "Unsafe cast to uint128"
        );
        return result;
    }

    function to96(
        uint256 number
    )
        internal
        pure
        returns (uint96)
    {
        uint96 result = uint96(number);
        Require.that(
            result == number,
            FILE,
            "Unsafe cast to uint96"
        );
        return result;
    }

    function to32(
        uint256 number
    )
        internal
        pure
        returns (uint32)
    {
        uint32 result = uint32(number);
        Require.that(
            result == number,
            FILE,
            "Unsafe cast to uint32"
        );
        return result;
    }

    function min(
        uint256 a,
        uint256 b
    )
        internal
        pure
        returns (uint256)
    {
        return a < b ? a : b;
    }

    function max(
        uint256 a,
        uint256 b
    )
        internal
        pure
        returns (uint256)
    {
        return a > b ? a : b;
    }
}


/**
 * @title Actions
 * @author dYdX
 *
 * Library that defines and parses valid Actions
 */
library Actions {

    // ============ Constants ============

    bytes32 constant FILE = "Actions";

    // ============ Enums ============

    enum ActionType {
        Deposit,   // supply tokens
        Withdraw,  // borrow tokens
        Transfer,  // transfer balance between accounts
        Buy,       // buy an amount of some token (externally)
        Sell,      // sell an amount of some token (externally)
        Trade,     // trade tokens against another account
        Liquidate, // liquidate an undercollateralized or expiring account
        Vaporize,  // use excess tokens to zero-out a completely negative account
        Call       // send arbitrary data to an address
    }

    enum AccountLayout {
        OnePrimary,
        TwoPrimary,
        PrimaryAndSecondary
    }

    enum MarketLayout {
        ZeroMarkets,
        OneMarket,
        TwoMarkets
    }

    // ============ Structs ============

    /*
     * Arguments that are passed to Solo in an ordered list as part of a single operation.
     * Each ActionArgs has an actionType which specifies which action struct that this data will be
     * parsed into before being processed.
     */
    struct ActionArgs {
        ActionType actionType;
        uint256 accountId;
        Types.AssetAmount amount;
        uint256 primaryMarketId;
        uint256 secondaryMarketId;
        address otherAddress;
        uint256 otherAccountId;
        bytes data;
    }

    // ============ Action Types ============

    /*
     * Moves tokens from an address to Solo. Can either repay a borrow or provide additional supply.
     */
    struct DepositArgs {
        Types.AssetAmount amount;
        Account.Info account;
        uint256 market;
        address from;
    }

    /*
     * Moves tokens from Solo to another address. Can either borrow tokens or reduce the amount
     * previously supplied.
     */
    struct WithdrawArgs {
        Types.AssetAmount amount;
        Account.Info account;
        uint256 market;
        address to;
    }

    /*
     * Transfers balance between two accounts. The msg.sender must be an operator for both accounts.
     * The amount field applies to accountOne.
     * This action does not require any token movement since the trade is done internally to Solo.
     */
    struct TransferArgs {
        Types.AssetAmount amount;
        Account.Info accountOne;
        Account.Info accountTwo;
        uint256 market;
    }

    /*
     * Acquires a certain amount of tokens by spending other tokens. Sends takerMarket tokens to the
     * specified exchangeWrapper contract and expects makerMarket tokens in return. The amount field
     * applies to the makerMarket.
     */
    struct BuyArgs {
        Types.AssetAmount amount;
        Account.Info account;
        uint256 makerMarket;
        uint256 takerMarket;
        address exchangeWrapper;
        bytes orderData;
    }

    /*
     * Spends a certain amount of tokens to acquire other tokens. Sends takerMarket tokens to the
     * specified exchangeWrapper and expects makerMarket tokens in return. The amount field applies
     * to the takerMarket.
     */
    struct SellArgs {
        Types.AssetAmount amount;
        Account.Info account;
        uint256 takerMarket;
        uint256 makerMarket;
        address exchangeWrapper;
        bytes orderData;
    }

    /*
     * Trades balances between two accounts using any external contract that implements the
     * AutoTrader interface. The AutoTrader contract must be an operator for the makerAccount (for
     * which it is trading on-behalf-of). The amount field applies to the makerAccount and the
     * inputMarket. This proposed change to the makerAccount is passed to the AutoTrader which will
     * quote a change for the makerAccount in the outputMarket (or will disallow the trade).
     * This action does not require any token movement since the trade is done internally to Solo.
     */
    struct TradeArgs {
        Types.AssetAmount amount;
        Account.Info takerAccount;
        Account.Info makerAccount;
        uint256 inputMarket;
        uint256 outputMarket;
        address autoTrader;
        bytes tradeData;
    }

    /*
     * Each account must maintain a certain margin-ratio (specified globally). If the account falls
     * below this margin-ratio, it can be liquidated by any other account. This allows anyone else
     * (arbitrageurs) to repay any borrowed asset (owedMarket) of the liquidating account in
     * exchange for any collateral asset (heldMarket) of the liquidAccount. The ratio is determined
     * by the price ratio (given by the oracles) plus a spread (specified globally). Liquidating an
     * account also sets a flag on the account that the account is being liquidated. This allows
     * anyone to continue liquidating the account until there are no more borrows being taken by the
     * liquidating account. Liquidators do not have to liquidate the entire account all at once but
     * can liquidate as much as they choose. The liquidating flag allows liquidators to continue
     * liquidating the account even if it becomes collateralized through partial liquidation or
     * price movement.
     */
    struct LiquidateArgs {
        Types.AssetAmount amount;
        Account.Info solidAccount;
        Account.Info liquidAccount;
        uint256 owedMarket;
        uint256 heldMarket;
    }

    /*
     * Similar to liquidate, but vaporAccounts are accounts that have only negative balances
     * remaining. The arbitrageur pays back the negative asset (owedMarket) of the vaporAccount in
     * exchange for a collateral asset (heldMarket) at a favorable spread. However, since the
     * liquidAccount has no collateral assets, the collateral must come from Solo's excess tokens.
     */
    struct VaporizeArgs {
        Types.AssetAmount amount;
        Account.Info solidAccount;
        Account.Info vaporAccount;
        uint256 owedMarket;
        uint256 heldMarket;
    }

    /*
     * Passes arbitrary bytes of data to an external contract that implements the Callee interface.
     * Does not change any asset amounts. This function may be useful for setting certain variables
     * on layer-two contracts for certain accounts without having to make a separate Ethereum
     * transaction for doing so. Also, the second-layer contracts can ensure that the call is coming
     * from an operator of the particular account.
     */
    struct CallArgs {
        Account.Info account;
        address callee;
        bytes data;
    }

    // ============ Helper Functions ============

    function getMarketLayout(
        ActionType actionType
    )
        internal
        pure
        returns (MarketLayout)
    {
        if (
            actionType == Actions.ActionType.Deposit
            || actionType == Actions.ActionType.Withdraw
            || actionType == Actions.ActionType.Transfer
        ) {
            return MarketLayout.OneMarket;
        }
        else if (actionType == Actions.ActionType.Call) {
            return MarketLayout.ZeroMarkets;
        }
        return MarketLayout.TwoMarkets;
    }

    function getAccountLayout(
        ActionType actionType
    )
        internal
        pure
        returns (AccountLayout)
    {
        if (
            actionType == Actions.ActionType.Transfer
            || actionType == Actions.ActionType.Trade
        ) {
            return AccountLayout.TwoPrimary;
        } else if (
            actionType == Actions.ActionType.Liquidate
            || actionType == Actions.ActionType.Vaporize
        ) {
            return AccountLayout.PrimaryAndSecondary;
        }
        return AccountLayout.OnePrimary;
    }

    // ============ Parsing Functions ============

    function parseDepositArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (DepositArgs memory)
    {
        assert(args.actionType == ActionType.Deposit);
        return DepositArgs({
            amount: args.amount,
            account: accounts[args.accountId],
            market: args.primaryMarketId,
            from: args.otherAddress
        });
    }

    function parseWithdrawArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (WithdrawArgs memory)
    {
        assert(args.actionType == ActionType.Withdraw);
        return WithdrawArgs({
            amount: args.amount,
            account: accounts[args.accountId],
            market: args.primaryMarketId,
            to: args.otherAddress
        });
    }

    function parseTransferArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (TransferArgs memory)
    {
        assert(args.actionType == ActionType.Transfer);
        return TransferArgs({
            amount: args.amount,
            accountOne: accounts[args.accountId],
            accountTwo: accounts[args.otherAccountId],
            market: args.primaryMarketId
        });
    }

    function parseBuyArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (BuyArgs memory)
    {
        assert(args.actionType == ActionType.Buy);
        return BuyArgs({
            amount: args.amount,
            account: accounts[args.accountId],
            makerMarket: args.primaryMarketId,
            takerMarket: args.secondaryMarketId,
            exchangeWrapper: args.otherAddress,
            orderData: args.data
        });
    }

    function parseSellArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (SellArgs memory)
    {
        assert(args.actionType == ActionType.Sell);
        return SellArgs({
            amount: args.amount,
            account: accounts[args.accountId],
            takerMarket: args.primaryMarketId,
            makerMarket: args.secondaryMarketId,
            exchangeWrapper: args.otherAddress,
            orderData: args.data
        });
    }

    function parseTradeArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (TradeArgs memory)
    {
        assert(args.actionType == ActionType.Trade);
        return TradeArgs({
            amount: args.amount,
            takerAccount: accounts[args.accountId],
            makerAccount: accounts[args.otherAccountId],
            inputMarket: args.primaryMarketId,
            outputMarket: args.secondaryMarketId,
            autoTrader: args.otherAddress,
            tradeData: args.data
        });
    }

    function parseLiquidateArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (LiquidateArgs memory)
    {
        assert(args.actionType == ActionType.Liquidate);
        return LiquidateArgs({
            amount: args.amount,
            solidAccount: accounts[args.accountId],
            liquidAccount: accounts[args.otherAccountId],
            owedMarket: args.primaryMarketId,
            heldMarket: args.secondaryMarketId
        });
    }

    function parseVaporizeArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (VaporizeArgs memory)
    {
        assert(args.actionType == ActionType.Vaporize);
        return VaporizeArgs({
            amount: args.amount,
            solidAccount: accounts[args.accountId],
            vaporAccount: accounts[args.otherAccountId],
            owedMarket: args.primaryMarketId,
            heldMarket: args.secondaryMarketId
        });
    }

    function parseCallArgs(
        Account.Info[] memory accounts,
        ActionArgs memory args
    )
        internal
        pure
        returns (CallArgs memory)
    {
        assert(args.actionType == ActionType.Call);
        return CallArgs({
            account: accounts[args.accountId],
            callee: args.otherAddress,
            data: args.data
        });
    }
}

/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/





/**
 * @title Account
 * @author dYdX
 *
 * Library of structs and functions that represent an account
 */
library Account {
    // ============ Enums ============

    /*
     * Most-recently-cached account status.
     *
     * Normal: Can only be liquidated if the account values are violating the global margin-ratio.
     * Liquid: Can be liquidated no matter the account values.
     *         Can be vaporized if there are no more positive account values.
     * Vapor:  Has only negative (or zeroed) account values. Can be vaporized.
     *
     */
    enum Status {
        Normal,
        Liquid,
        Vapor
    }

    // ============ Structs ============

    // Represents the unique key that specifies an account
    struct Info {
        address owner;  // The address that owns the account
        uint256 number; // A nonce that allows a single address to control many accounts
    }

    // The complete storage for any account
    struct Storage {
        mapping (uint256 => Types.Par) balances; // Mapping from marketId to principal
        Status status;
    }

    // ============ Library Functions ============

    function equals(
        Info memory a,
        Info memory b
    )
        internal
        pure
        returns (bool)
    {
        return a.owner == b.owner && a.number == b.number;
    }
}

/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/





/**
 * @title Types
 * @author dYdX
 *
 * Library for interacting with the basic structs used in Solo
 */
library Types {
    using Math for uint256;

    // ============ AssetAmount ============

    enum AssetDenomination {
        Wei, // the amount is denominated in wei
        Par  // the amount is denominated in par
    }

    enum AssetReference {
        Delta, // the amount is given as a delta from the current value
        Target // the amount is given as an exact number to end up at
    }

    struct AssetAmount {
        bool sign; // true if positive
        AssetDenomination denomination;
        AssetReference ref;
        uint256 value;
    }

    // ============ Par (Principal Amount) ============

    // Total borrow and supply values for a market
    struct TotalPar {
        uint128 borrow;
        uint128 supply;
    }

    // Individual principal amount for an account
    struct Par {
        bool sign; // true if positive
        uint128 value;
    }

    function zeroPar()
        internal
        pure
        returns (Par memory)
    {
        return Par({
            sign: false,
            value: 0
        });
    }

    function sub(
        Par memory a,
        Par memory b
    )
        internal
        pure
        returns (Par memory)
    {
        return add(a, negative(b));
    }

    function add(
        Par memory a,
        Par memory b
    )
        internal
        pure
        returns (Par memory)
    {
        Par memory result;
        if (a.sign == b.sign) {
            result.sign = a.sign;
            result.value = SafeMath.add(a.value, b.value).to128();
        } else {
            if (a.value >= b.value) {
                result.sign = a.sign;
                result.value = SafeMath.sub(a.value, b.value).to128();
            } else {
                result.sign = b.sign;
                result.value = SafeMath.sub(b.value, a.value).to128();
            }
        }
        return result;
    }

    function equals(
        Par memory a,
        Par memory b
    )
        internal
        pure
        returns (bool)
    {
        if (a.value == b.value) {
            if (a.value == 0) {
                return true;
            }
            return a.sign == b.sign;
        }
        return false;
    }

    function negative(
        Par memory a
    )
        internal
        pure
        returns (Par memory)
    {
        return Par({
            sign: !a.sign,
            value: a.value
        });
    }

    function isNegative(
        Par memory a
    )
        internal
        pure
        returns (bool)
    {
        return !a.sign && a.value > 0;
    }

    function isPositive(
        Par memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.sign && a.value > 0;
    }

    function isZero(
        Par memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.value == 0;
    }

    // ============ Wei (Token Amount) ============

    // Individual token amount for an account
    struct Wei {
        bool sign; // true if positive
        uint256 value;
    }

    function zeroWei()
        internal
        pure
        returns (Wei memory)
    {
        return Wei({
            sign: false,
            value: 0
        });
    }

    function sub(
        Wei memory a,
        Wei memory b
    )
        internal
        pure
        returns (Wei memory)
    {
        return add(a, negative(b));
    }

    function add(
        Wei memory a,
        Wei memory b
    )
        internal
        pure
        returns (Wei memory)
    {
        Wei memory result;
        if (a.sign == b.sign) {
            result.sign = a.sign;
            result.value = SafeMath.add(a.value, b.value);
        } else {
            if (a.value >= b.value) {
                result.sign = a.sign;
                result.value = SafeMath.sub(a.value, b.value);
            } else {
                result.sign = b.sign;
                result.value = SafeMath.sub(b.value, a.value);
            }
        }
        return result;
    }

    function equals(
        Wei memory a,
        Wei memory b
    )
        internal
        pure
        returns (bool)
    {
        if (a.value == b.value) {
            if (a.value == 0) {
                return true;
            }
            return a.sign == b.sign;
        }
        return false;
    }

    function negative(
        Wei memory a
    )
        internal
        pure
        returns (Wei memory)
    {
        return Wei({
            sign: !a.sign,
            value: a.value
        });
    }

    function isNegative(
        Wei memory a
    )
        internal
        pure
        returns (bool)
    {
        return !a.sign && a.value > 0;
    }

    function isPositive(
        Wei memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.sign && a.value > 0;
    }

    function isZero(
        Wei memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.value == 0;
    }
}






contract ISoloMargin {
    struct OperatorArg {
        address operator;
        bool trusted;
    }

    function operate(
        Account.Info[] memory accounts,
        Actions.ActionArgs[] memory actions
    ) public;

    function getAccountBalances(
        Account.Info memory account
    ) public view returns (
        address[] memory,
        Types.Par[] memory,
        Types.Wei[] memory
    );

    function setOperators(
        OperatorArg[] memory args
    ) public;
}

interface ERC20 {
    function totalSupply() external view returns (uint supply);
    function balanceOf(address _owner) external view returns (uint balance);
    function transfer(address _to, uint _value) external returns (bool success);
    function transferFrom(address _from, address _to, uint _value) external returns (bool success);
    function approve(address _spender, uint _value) external returns (bool success);
    function allowance(address _owner, address _spender) external view returns (uint remaining);
    function decimals() external view returns(uint digits);
    event Approval(address indexed _owner, address indexed _spender, uint _value);
}

contract ConstantAddressesMainnet {
    address public constant MAKER_DAI_ADDRESS = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359;
    address public constant IDAI_ADDRESS = 0x14094949152EDDBFcd073717200DA82fEd8dC960;
    address public constant SOLO_MARGIN_ADDRESS = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e;
    address public constant CDAI_ADDRESS = 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC;
    address public constant KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    address public constant MKR_ADDRESS = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;
    address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address public constant VOX_ADDRESS = 0x9B0F70Df76165442ca6092939132bBAEA77f2d7A;
    address public constant PETH_ADDRESS = 0xf53AD2c6851052A81B42133467480961B2321C09;
    address public constant TUB_ADDRESS = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3;
    address payable public constant WALLET_ID = 0x322d58b9E75a6918f7e7849AEe0fF09369977e08;
    address public constant LOGGER_ADDRESS = 0xeCf88e1ceC2D2894A0295DB3D86Fe7CE4991E6dF;
    address public constant OTC_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
    address public constant DISCOUNT_ADDRESS = 0x1b14E8D511c9A4395425314f849bD737BAF8208F;

    address public constant KYBER_WRAPPER = 0x8F337bD3b7F2b05d9A8dC8Ac518584e833424893;
    address public constant UNISWAP_WRAPPER = 0x1e30124FDE14533231216D95F7798cD0061e5cf8;
    address public constant ETH2DAI_WRAPPER = 0xd7BBB1777E13b6F535Dec414f575b858ed300baF;
    address public constant OASIS_WRAPPER = 0x9aBE2715D2d99246269b8E17e9D1b620E9bf6558;

    address public constant KYBER_INTERFACE = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755;
    address public constant UNISWAP_FACTORY = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
    address public constant FACTORY_ADDRESS = 0x5a15566417e6C1c9546523066500bDDBc53F88C7;
    address public constant PIP_INTERFACE_ADDRESS = 0x729D19f657BD0614b4985Cf1D82531c67569197B;

    address public constant PROXY_REGISTRY_INTERFACE_ADDRESS = 0x4678f0a6958e4D2Bc4F1BAF7Bc52E8F3564f3fE4;
    address public constant GAS_TOKEN_INTERFACE_ADDRESS = 0x0000000000b3F879cb30FE243b4Dfee438691c04;

    address public constant SAVINGS_LOGGER_ADDRESS = 0x89b3635BD2bAD145C6f92E82C9e83f06D5654984;

    address public constant SAVER_EXCHANGE_ADDRESS = 0x865B41584A22F8345Fca4B71c42a1E7aBcD67eCB;

    // Kovan addresses, not used on mainnet
    address public constant COMPOUND_DAI_ADDRESS = 0x25a01a05C188DaCBCf1D61Af55D4a5B4021F7eeD;
    address public constant STUPID_EXCHANGE = 0x863E41FE88288ebf3fcd91d8Dbb679fb83fdfE17;

    // new MCD contracts
    address public constant MANAGER_ADDRESS = 0x5ef30b9986345249bc32d8928B7ee64DE9435E39;
    address public constant VAT_ADDRESS = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B;
    address public constant SPOTTER_ADDRESS = 0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3;
    address public constant PROXY_ACTIONS = 0x82ecD135Dce65Fbc6DbdD0e4237E0AF93FFD5038;

    address public constant JUG_ADDRESS = 0x19c0976f590D67707E62397C87829d896Dc0f1F1;
    address public constant DAI_JOIN_ADDRESS = 0x9759A6Ac90977b93B58547b4A71c78317f391A28;
    address public constant ETH_JOIN_ADDRESS = 0x2F0b23f53734252Bda2277357e97e1517d6B042A;
    address public constant MIGRATION_ACTIONS_PROXY = 0xe4B22D484958E582098A98229A24e8A43801b674;

    address public constant SAI_ADDRESS = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359;
    address public constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;

    address payable public constant SCD_MCD_MIGRATION = 0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849;

    // Our contracts
    address public constant SUBSCRIPTION_ADDRESS = 0x83152CAA0d344a2Fd428769529e2d490A88f4393;
    address public constant MONITOR_ADDRESS = 0x3F4339816EDEF8D3d3970DB2993e2e0Ec6010760;

    address public constant NEW_CDAI_ADDRESS = 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643;
    address public constant NEW_IDAI_ADDRESS = 0x493C57C4763932315A328269E1ADaD09653B9081;

}

contract ConstantAddressesKovan {
    address public constant KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    address public constant WETH_ADDRESS = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
    address public constant MAKER_DAI_ADDRESS = 0xC4375B7De8af5a38a93548eb8453a498222C4fF2;
    address public constant MKR_ADDRESS = 0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD;
    address public constant VOX_ADDRESS = 0xBb4339c0aB5B1d9f14Bd6e3426444A1e9d86A1d9;
    address public constant PETH_ADDRESS = 0xf4d791139cE033Ad35DB2B2201435fAd668B1b64;
    address public constant TUB_ADDRESS = 0xa71937147b55Deb8a530C7229C442Fd3F31b7db2;
    address public constant LOGGER_ADDRESS = 0x32d0e18f988F952Eb3524aCE762042381a2c39E5;
    address payable public  constant WALLET_ID = 0x54b44C6B18fc0b4A1010B21d524c338D1f8065F6;
    address public constant OTC_ADDRESS = 0x4A6bC4e803c62081ffEbCc8d227B5a87a58f1F8F;
    address public constant COMPOUND_DAI_ADDRESS = 0x25a01a05C188DaCBCf1D61Af55D4a5B4021F7eeD;
    address public constant SOLO_MARGIN_ADDRESS = 0x4EC3570cADaAEE08Ae384779B0f3A45EF85289DE;
    address public constant IDAI_ADDRESS = 0xA1e58F3B1927743393b25f261471E1f2D3D9f0F6;
    address public constant CDAI_ADDRESS = 0xb6b09fBffBa6A5C4631e5F7B2e3Ee183aC259c0d;
    address public constant STUPID_EXCHANGE = 0x863E41FE88288ebf3fcd91d8Dbb679fb83fdfE17;
    address public constant DISCOUNT_ADDRESS = 0x1297c1105FEDf45E0CF6C102934f32C4EB780929;
    address public constant SAI_SAVER_PROXY = 0xADB7c74bCe932fC6C27ddA3Ac2344707d2fBb0E6;

    address public constant KYBER_WRAPPER = 0x68c56FF0E7BBD30AF9Ad68225479449869fC1bA0;
    address public constant UNISWAP_WRAPPER = 0x2A4ee140F05f1Ba9A07A020b07CCFB76CecE4b43;
    address public constant ETH2DAI_WRAPPER = 0x823cde416973a19f98Bb9C96d97F4FE6C9A7238B;
    address public constant OASIS_WRAPPER = 0x0257Ba4876863143bbeDB7847beC583e4deb6fE6;

    address public constant SAVER_EXCHANGE_ADDRESS = 0xACA7d11e3f482418C324aAC8e90AaD0431f692A6;


    address public constant FACTORY_ADDRESS = 0xc72E74E474682680a414b506699bBcA44ab9a930;
    //
    address public constant PIP_INTERFACE_ADDRESS = 0xA944bd4b25C9F186A846fd5668941AA3d3B8425F;
    address public constant PROXY_REGISTRY_INTERFACE_ADDRESS = 0x64A436ae831C1672AE81F674CAb8B6775df3475C;
    address public constant GAS_TOKEN_INTERFACE_ADDRESS = 0x0000000000170CcC93903185bE5A2094C870Df62;
    address public constant KYBER_INTERFACE = 0x692f391bCc85cefCe8C237C01e1f636BbD70EA4D;

    address public constant SAVINGS_LOGGER_ADDRESS = 0x2aa889D809B29c608dA99767837D189dAe12a874;

    // Rinkeby, when no Kovan
    address public constant UNISWAP_FACTORY = 0xf5D915570BC477f9B8D6C0E980aA81757A3AaC36;

    // new MCD contracts
    address public constant MANAGER_ADDRESS = 0x1476483dD8C35F25e568113C5f70249D3976ba21;
    address public constant VAT_ADDRESS = 0xbA987bDB501d131f766fEe8180Da5d81b34b69d9;
    address public constant SPOTTER_ADDRESS = 0x3a042de6413eDB15F2784f2f97cC68C7E9750b2D;

    address public constant JUG_ADDRESS = 0xcbB7718c9F39d05aEEDE1c472ca8Bf804b2f1EaD;
    address public constant DAI_JOIN_ADDRESS = 0x5AA71a3ae1C0bd6ac27A1f28e1415fFFB6F15B8c;
    address public constant ETH_JOIN_ADDRESS = 0x775787933e92b709f2a3C70aa87999696e74A9F8;
    address public constant MIGRATION_ACTIONS_PROXY = 0x433870076aBd08865f0e038dcC4Ac6450e313Bd8;
    address public constant PROXY_ACTIONS = 0xd1D24637b9109B7f61459176EdcfF9Be56283a7B;

    address public constant SAI_ADDRESS = 0xC4375B7De8af5a38a93548eb8453a498222C4fF2;
    address public constant DAI_ADDRESS = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;

    address payable public constant SCD_MCD_MIGRATION = 0x411B2Faa662C8e3E5cF8f01dFdae0aeE482ca7b0;

    // Our contracts
    address public constant SUBSCRIPTION_ADDRESS = 0xFC41f79776061a396635aD0b9dF7a640A05063C1;
    address public constant MONITOR_ADDRESS = 0xfC1Fc0502e90B7A3766f93344E1eDb906F8A75DD;
}

contract ConstantAddresses is ConstantAddressesMainnet {
}

contract DSAuthority {
    function canCall(
        address src, address dst, bytes4 sig
    ) public view returns (bool);
}

contract DSAuthEvents {
    event LogSetAuthority (address indexed authority);
    event LogSetOwner     (address indexed owner);
}

contract DSAuth is DSAuthEvents {
    DSAuthority  public  authority;
    address      public  owner;

    constructor() public {
        owner = msg.sender;
        emit LogSetOwner(msg.sender);
    }

    function setOwner(address owner_)
        public
        auth
    {
        owner = owner_;
        emit LogSetOwner(owner);
    }

    function setAuthority(DSAuthority authority_)
        public
        auth
    {
        authority = authority_;
        emit LogSetAuthority(address(authority));
    }

    modifier auth {
        require(isAuthorized(msg.sender, msg.sig));
        _;
    }

    function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
        if (src == address(this)) {
            return true;
        } else if (src == owner) {
            return true;
        } else if (authority == DSAuthority(0)) {
            return false;
        } else {
            return authority.canCall(src, address(this), sig);
        }
    }
}








contract DydxSavingsProtocol is ProtocolInterface, ConstantAddresses, DSAuth {


    ISoloMargin public soloMargin;
    address public savingsProxy;

    uint daiMarketId = 3;

    constructor() public {
        soloMargin = ISoloMargin(SOLO_MARGIN_ADDRESS);
    }

    function addSavingsProxy(address _savingsProxy) public auth {
        savingsProxy = _savingsProxy;
    }

    function deposit(address _user, uint _amount) public {
        require(msg.sender == _user);

        Account.Info[] memory accounts = new Account.Info[](1);
        accounts[0] = getAccount(_user, 0);

        Actions.ActionArgs[] memory actions = new Actions.ActionArgs[](1);
        Types.AssetAmount memory amount = Types.AssetAmount({
            sign: true,
            denomination: Types.AssetDenomination.Wei,
            ref: Types.AssetReference.Delta,
            value: _amount
        });

        actions[0] = Actions.ActionArgs({
            actionType: Actions.ActionType.Deposit,
            accountId: 0,
            amount: amount,
            primaryMarketId: daiMarketId,
            otherAddress: _user,
            secondaryMarketId: 0, //not used
            otherAccountId: 0, //not used
            data: "" //not used
        });

        soloMargin.operate(accounts, actions);
    }

    function withdraw(address _user, uint _amount) public {
        require(msg.sender == _user);

        Account.Info[] memory accounts = new Account.Info[](1);
        accounts[0] = getAccount(_user, 0);

        Actions.ActionArgs[] memory actions = new Actions.ActionArgs[](1);
        Types.AssetAmount memory amount = Types.AssetAmount({
            sign: false,
            denomination: Types.AssetDenomination.Wei,
            ref: Types.AssetReference.Delta,
            value: _amount
        });

        actions[0] = Actions.ActionArgs({
            actionType: Actions.ActionType.Withdraw,
            accountId: 0,
            amount: amount,
            primaryMarketId: daiMarketId,
            otherAddress: _user,
            secondaryMarketId: 0, //not used
            otherAccountId: 0, //not used
            data: "" //not used
        });

        soloMargin.operate(accounts, actions);
    }

    function getWeiBalance(address _user, uint _index) public view returns(Types.Wei memory) {

        Types.Wei[] memory weiBalances;
        (,,weiBalances) = soloMargin.getAccountBalances(getAccount(_user, _index));

        return weiBalances[daiMarketId];
    }

    function getParBalance(address _user, uint _index) public view returns(Types.Par memory) {
        Types.Par[] memory parBalances;
        (,parBalances,) = soloMargin.getAccountBalances(getAccount(_user, _index));

        return parBalances[daiMarketId];
    }

    function getAccount(address _user, uint _index) public view returns(Account.Info memory) {
        Account.Info memory account = Account.Info({
            owner: _user,
            number: _index
        });

        return account;
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"WETH_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CDAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SAVINGS_LOGGER_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_savingsProxy","type":"address"}],"name":"addSavingsProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"soloMargin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"PIP_INTERFACE_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KYBER_ETH_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"OTC_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"IDAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"GAS_TOKEN_INTERFACE_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOX_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGER_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MONITOR_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ETH2DAI_WRAPPER","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_user","type":"address"},{"name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"STUPID_EXCHANGE","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIGRATION_ACTIONS_PROXY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_user","type":"address"},{"name":"_index","type":"uint256"}],"name":"getAccount","outputs":[{"components":[{"name":"owner","type":"address"},{"name":"number","type":"uint256"}],"name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SPOTTER_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PROXY_REGISTRY_INTERFACE_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_user","type":"address"},{"name":"_index","type":"uint256"}],"name":"getParBalance","outputs":[{"components":[{"name":"sign","type":"bool"},{"name":"value","type":"uint128"}],"name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"PROXY_ACTIONS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MKR_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FACTORY_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LOGGER_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SAVER_EXCHANGE_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAKER_DAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DISCOUNT_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"savingsProxy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"JUG_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NEW_CDAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KYBER_WRAPPER","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SUBSCRIPTION_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NEW_IDAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COMPOUND_DAI_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UNISWAP_FACTORY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"OASIS_WRAPPER","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PETH_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KYBER_INTERFACE","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VAT_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DAI_JOIN_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WALLET_ID","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SOLO_MARGIN_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UNISWAP_WRAPPER","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_user","type":"address"},{"name":"_index","type":"uint256"}],"name":"getWeiBalance","outputs":[{"components":[{"name":"sign","type":"bool"},{"name":"value","type":"uint256"}],"name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"TUB_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ETH_JOIN_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_user","type":"address"},{"name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SCD_MCD_MIGRATION","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

6080604052600360045534801561001557600080fd5b5033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9460405160405180910390a2731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612702806100fe6000396000f3fe608060405234801561001057600080fd5b506004361061035d5760003560e01c80638823151b116101d3578063c74c0fac11610104578063d36b907d116100a2578063f0d405e51161007c578063f0d405e51461098a578063f1d25396146109a8578063f3fef3a3146109c6578063f8352472146109e25761035d565b8063d36b907d1461091e578063ddaa293c1461093c578063eef1bbda1461095a5761035d565b8063ce9bde1d116100de578063ce9bde1d146108a6578063cf786f8f146108c4578063cfac57c7146108e2578063d3661fa5146109005761035d565b8063c74c0fac1461084c578063c917c2d31461086a578063c9fde270146108885761035d565b8063acbeba6111610171578063bc17effa1161014b578063bc17effa146107d4578063bf42d947146107f2578063bf7e214f14610810578063c16921b71461082e5761035d565b8063acbeba611461077a578063ad7359c914610798578063b175afa1146107b65761035d565b806394f0eb3d116101ad57806394f0eb3d146107025780639da779e914610720578063a46a66c91461073e578063a683668c1461075c5761035d565b80638823151b146106a85780638da5cb5b146106c657806394bfbe74146106e45761035d565b806336e6da11116102ad578063670079eb1161024b5780637800a0f6116102255780637800a0f6146106205780637a9e5e4b14610650578063819854e71461066c578063825ffd921461068a5761035d565b8063670079eb146105b45780636738929f146105e4578063728c0092146106025761035d565b806343fb75e81161028757806343fb75e81461053e57806347e7ef241461055c578063502237d71461057857806362da5d90146105965761035d565b806336e6da11146104e4578063380d42441461050257806342c1eb4e146105205761035d565b806313af40351161031a5780632a441f05116102f45780632a441f051461046c5780632a4c0a1a1461048a5780632d5eeb3f146104a857806332ac5cd2146104c65761035d565b806313af4035146104145780631dab52b01461043057806329f7fc9e1461044e5761035d565b8063040141e5146103625780630531b2ad1461038057806308204ea31461039e5780630b6cd37e146103bc5780630bd4a73e146103d8578063134f6d3a146103f6575b600080fd5b61036a610a00565b604051610377919061225a565b60405180910390f35b610388610a18565b604051610395919061225a565b60405180910390f35b6103a6610a30565b6040516103b3919061225a565b60405180910390f35b6103d660048036036103d19190810190611d64565b610a48565b005b6103e0610ac3565b6040516103ed919061225a565b60405180910390f35b6103fe610adb565b60405161040b9190612319565b60405180910390f35b61042e60048036036104299190810190611d64565b610b01565b005b610438610be1565b604051610445919061225a565b60405180910390f35b610456610bf9565b604051610463919061225a565b60405180910390f35b610474610c11565b604051610481919061225a565b60405180910390f35b610492610c29565b60405161049f919061225a565b60405180910390f35b6104b0610c41565b6040516104bd919061225a565b60405180910390f35b6104ce610c59565b6040516104db919061225a565b60405180910390f35b6104ec610c6c565b6040516104f9919061225a565b60405180910390f35b61050a610c84565b604051610517919061225a565b60405180910390f35b610528610c9c565b604051610535919061225a565b60405180910390f35b610546610cb4565b604051610553919061225a565b60405180910390f35b61057660048036036105719190810190611d8d565b610ccc565b005b610580610f0b565b60405161058d919061225a565b60405180910390f35b61059e610f23565b6040516105ab919061225a565b60405180910390f35b6105ce60048036036105c99190810190611d8d565b610f3b565b6040516105db9190612334565b60405180910390f35b6105ec610f82565b6040516105f9919061225a565b60405180910390f35b61060a610f9a565b604051610617919061225a565b60405180910390f35b61063a60048036036106359190810190611d8d565b610fb2565b604051610647919061234f565b60405180910390f35b61066a60048036036106659190810190611e89565b61109c565b005b61067461117a565b604051610681919061225a565b60405180910390f35b610692611192565b60405161069f919061225a565b60405180910390f35b6106b06111aa565b6040516106bd919061225a565b60405180910390f35b6106ce6111c2565b6040516106db919061225a565b60405180910390f35b6106ec6111e8565b6040516106f9919061225a565b60405180910390f35b61070a611200565b604051610717919061225a565b60405180910390f35b610728611218565b604051610735919061225a565b60405180910390f35b610746611230565b604051610753919061225a565b60405180910390f35b610764611248565b604051610771919061225a565b60405180910390f35b61078261126e565b60405161078f919061225a565b60405180910390f35b6107a0611286565b6040516107ad919061225a565b60405180910390f35b6107be61129e565b6040516107cb919061225a565b60405180910390f35b6107dc6112b6565b6040516107e9919061225a565b60405180910390f35b6107fa6112ce565b604051610807919061225a565b60405180910390f35b6108186112e6565b60405161082591906122fe565b60405180910390f35b61083661130b565b604051610843919061225a565b60405180910390f35b610854611323565b604051610861919061225a565b60405180910390f35b61087261133b565b60405161087f919061225a565b60405180910390f35b610890611353565b60405161089d919061225a565b60405180910390f35b6108ae61136b565b6040516108bb919061225a565b60405180910390f35b6108cc611383565b6040516108d9919061225a565b60405180910390f35b6108ea61139b565b6040516108f7919061225a565b60405180910390f35b6109086113b3565b6040516109159190612275565b60405180910390f35b6109266113cb565b604051610933919061225a565b60405180910390f35b6109446113e3565b604051610951919061225a565b60405180910390f35b610974600480360361096f9190810190611d8d565b6113fb565b604051610981919061236a565b60405180910390f35b6109926114e6565b60405161099f919061225a565b60405180910390f35b6109b06114fe565b6040516109bd919061225a565b60405180910390f35b6109e060048036036109db9190810190611d8d565b611516565b005b6109ea611755565b6040516109f79190612275565b60405180910390f35b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b73f5dce57282a584d2746faf1593d3121fcac444dc81565b7389b3635bd2bad145c6f92e82c9e83f06d565498481565b610a76336000357fffffffff000000000000000000000000000000000000000000000000000000001661176d565b610a7f57600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7389d24a6b4ccb1b6faa2625fe562bdd9a2326035981565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610b2f336000357fffffffff000000000000000000000000000000000000000000000000000000001661176d565b610b3857600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9460405160405180910390a250565b73729d19f657bd0614b4985cf1d82531c67569197b81565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b7339755357759ce0d7f32dc8dc45414cca409ae24e81565b736b175474e89094c44da98b954eedeac495271d0f81565b7314094949152eddbfcd073717200da82fed8dc96081565b6eb3f879cb30fe243b4dfee438691c0481565b739b0f70df76165442ca6092939132bbaea77f2d7a81565b735ef30b9986345249bc32d8928b7ee64de9435e3981565b733f4339816edef8d3d3970db2993e2e0ec601076081565b73d7bbb1777e13b6f535dec414f575b858ed300baf81565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d0457600080fd5b60606001604051908082528060200260200182016040528015610d4157816020015b610d2e611921565b815260200190600190039081610d265790505b509050610d4f836000610f3b565b81600081518110610d5c57fe5b602002602001018190525060606001604051908082528060200260200182016040528015610da457816020015b610d91611951565b815260200190600190039081610d895790505b509050610daf6119bd565b604051806080016040528060011515815260200160006001811115610dd057fe5b815260200160006001811115610de257fe5b815260200185815250905060405180610100016040528060006008811115610e0657fe5b8152602001600081526020018281526020016004548152602001600081526020018673ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016040518060200160405280600081525081525082600081518110610e6a57fe5b6020026020010181905250600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a67a6a4584846040518363ffffffff1660e01b8152600401610ed29291906122c7565b600060405180830381600087803b158015610eec57600080fd5b505af1158015610f00573d6000803e3d6000fd5b505050505050505050565b73863e41fe88288ebf3fcd91d8dbb679fb83fdfe1781565b73e4b22d484958e582098a98229a24e8a43801b67481565b610f436119fd565b610f4b6119fd565b60405180604001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018481525090508091505092915050565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b734678f0a6958e4d2bc4f1baf7bc52e8f3564f3fe481565b610fba611a2d565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a8194e76110048686610f3b565b6040518263ffffffff1660e01b81526004016110209190612334565b60006040518083038186803b15801561103857600080fd5b505afa15801561104c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506110759190810190611dc9565b9091505080915050806004548151811061108b57fe5b602002602001015191505092915050565b6110ca336000357fffffffff000000000000000000000000000000000000000000000000000000001661176d565b6110d357600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada460405160405180910390a250565b7382ecd135dce65fbc6dbdd0e4237e0af93ffd503881565b739f8f72aa9304c8b593d555f12ef6589cc3a579a281565b735a15566417e6c1c9546523066500bddbc53f88c781565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73ecf88e1cec2d2894a0295db3d86fe7ce4991e6df81565b73865b41584a22f8345fca4b71c42a1e7abcd67ecb81565b7389d24a6b4ccb1b6faa2625fe562bdd9a2326035981565b731b14e8d511c9a4395425314f849bd737baf8208f81565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7319c0976f590d67707e62397c87829d896dc0f1f181565b735d3a536e4d6dbd6114cc1ead35777bab948e364381565b738f337bd3b7f2b05d9a8dc8ac518584e83342489381565b7383152caa0d344a2fd428769529e2d490a88f439381565b73493c57c4763932315a328269e1adad09653b908181565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7325a01a05c188dacbcf1d61af55d4a5b4021f7eed81565b73c0a47dfe034b400b47bdad5fecda2621de6c4d9581565b739abe2715d2d99246269b8e17e9d1b620e9bf655881565b73f53ad2c6851052a81b42133467480961b2321c0981565b73818e6fecd516ecc3849daf6845e3ec868087b75581565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b739759a6ac90977b93b58547b4a71c78317f391a2881565b73322d58b9e75a6918f7e7849aee0ff09369977e0881565b731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e81565b731e30124fde14533231216d95f7798cd0061e5cf881565b611403611a5b565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a8194e761144d8686610f3b565b6040518263ffffffff1660e01b81526004016114699190612334565b60006040518083038186803b15801561148157600080fd5b505afa158015611495573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506114be9190810190611dc9565b90915090508091505080600454815181106114d557fe5b602002602001015191505092915050565b73448a5065aebb8e423f0896e6c5d525c040f59af381565b732f0b23f53734252bda2277357e97e1517d6b042a81565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154e57600080fd5b6060600160405190808252806020026020018201604052801561158b57816020015b611578611921565b8152602001906001900390816115705790505b509050611599836000610f3b565b816000815181106115a657fe5b6020026020010181905250606060016040519080825280602002602001820160405280156115ee57816020015b6115db611951565b8152602001906001900390816115d35790505b5090506115f96119bd565b60405180608001604052806000151581526020016000600181111561161a57fe5b81526020016000600181111561162c57fe5b81526020018581525090506040518061010001604052806001600881111561165057fe5b8152602001600081526020018281526020016004548152602001600081526020018673ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160405180602001604052806000815250815250826000815181106116b457fe5b6020026020010181905250600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a67a6a4584846040518363ffffffff1660e01b815260040161171c9291906122c7565b600060405180830381600087803b15801561173657600080fd5b505af115801561174a573d6000803e3d6000fd5b505050505050505050565b73c73e0383f3aff3215e6f04b0331d58cecf0ab84981565b60003073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156117ac576001905061191b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561180b576001905061191b565b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561186a576000905061191b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b70096138430856040518463ffffffff1660e01b81526004016118c893929190612290565b60206040518083038186803b1580156118e057600080fd5b505afa1580156118f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119189190810190611e60565b90505b92915050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6040518061016001604052806000600881111561196a57fe5b81526020016000815260200161197e611a77565b81526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001606081525090565b6040518060800160405280600015158152602001600060018111156119de57fe5b8152602001600060018111156119f057fe5b8152602001600081525090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b604051806040016040528060001515815260200160006fffffffffffffffffffffffffffffffff1681525090565b6040518060400160405280600015158152602001600081525090565b604051806080016040528060001515815260200160006001811115611a9857fe5b815260200160006001811115611aaa57fe5b8152602001600081525090565b6000611ac38235612590565b905092915050565b6000611ad78251612590565b905092915050565b600082601f830112611af057600080fd5b8151611b03611afe826123b2565b612385565b91508181835260208401935060208101905083856020840282011115611b2857600080fd5b60005b83811015611b585781611b3e8882611acb565b845260208401935060208301925050600181019050611b2b565b5050505092915050565b600082601f830112611b7357600080fd5b8151611b86611b81826123da565b612385565b91508181835260208401935060208101905083856040840282011115611bab57600080fd5b60005b83811015611bdb5781611bc18882611c90565b845260208401935060408301925050600181019050611bae565b5050505092915050565b600082601f830112611bf657600080fd5b8151611c09611c0482612402565b612385565b91508181835260208401935060208101905083856040840282011115611c2e57600080fd5b60005b83811015611c5e5781611c448882611cdc565b845260208401935060408301925050600181019050611c31565b5050505092915050565b6000611c7482516125a2565b905092915050565b6000611c8882356125ae565b905092915050565b600060408284031215611ca257600080fd5b611cac6040612385565b90506000611cbc84828501611c68565b6000830152506020611cd084828501611d28565b60208301525092915050565b600060408284031215611cee57600080fd5b611cf86040612385565b90506000611d0884828501611c68565b6000830152506020611d1c84828501611d50565b60208301525092915050565b6000611d3482516125c0565b905092915050565b6000611d4882356125fc565b905092915050565b6000611d5c82516125fc565b905092915050565b600060208284031215611d7657600080fd5b6000611d8484828501611ab7565b91505092915050565b60008060408385031215611da057600080fd5b6000611dae85828601611ab7565b9250506020611dbf85828601611d3c565b9150509250929050565b600080600060608486031215611dde57600080fd5b600084015167ffffffffffffffff811115611df857600080fd5b611e0486828701611adf565b935050602084015167ffffffffffffffff811115611e2157600080fd5b611e2d86828701611b62565b925050604084015167ffffffffffffffff811115611e4a57600080fd5b611e5686828701611be5565b9150509250925092565b600060208284031215611e7257600080fd5b6000611e8084828501611c68565b91505092915050565b600060208284031215611e9b57600080fd5b6000611ea984828501611c7c565b91505092915050565b6000611ebe8383612078565b905092915050565b6000611ed283836121af565b60408301905092915050565b611ee7816124c4565b82525050565b611ef6816124b2565b82525050565b611f05816124b2565b82525050565b6000611f1682612444565b611f20818561247f565b935083602082028501611f328561242a565b60005b84811015611f6b578383038852611f4d838351611eb2565b9250611f5882612465565b9150602088019750600181019050611f35565b508196508694505050505092915050565b6000611f878261244f565b611f918185612490565b9350611f9c83612437565b60005b82811015611fca57611fb2868351611ec6565b9550611fbd82612472565b9150600181019050611f9f565b50849250505092915050565b611fdf816124d6565b82525050565b611fee816124e2565b82525050565b6000611fff8261245a565b61200981856124a1565b9350612019818560208601612684565b612022816126b7565b840191505092915050565b61203681612606565b82525050565b6120458161262a565b82525050565b6120548161264e565b82525050565b61206381612660565b82525050565b61207281612672565b82525050565b600061016083016000830151612091600086018261204b565b5060208301516120a4602086018261224b565b5060408301516120b7604086018261212b565b5060608301516120ca60c086018261224b565b5060808301516120dd60e086018261224b565b5060a08301516120f1610100860182611eed565b5060c083015161210561012086018261224b565b5060e083015184820361014086015261211e8282611ff4565b9150508091505092915050565b6080820160008201516121416000850182611fd6565b506020820151612154602085018261205a565b5060408201516121676040850182612069565b50606082015161217a606085018261224b565b50505050565b6040820160008201516121966000850182611eed565b5060208201516121a9602085018261224b565b50505050565b6040820160008201516121c56000850182611eed565b5060208201516121d8602085018261224b565b50505050565b6040820160008201516121f46000850182611fd6565b506020820151612207602085018261223c565b50505050565b6040820160008201516122236000850182611fd6565b506020820151612236602085018261224b565b50505050565b6122458161254a565b82525050565b61225481612586565b82525050565b600060208201905061226f6000830184611efc565b92915050565b600060208201905061228a6000830184611ede565b92915050565b60006060820190506122a56000830186611efc565b6122b26020830185611efc565b6122bf6040830184611fe5565b949350505050565b600060408201905081810360008301526122e18185611f7c565b905081810360208301526122f58184611f0b565b90509392505050565b6000602082019050612313600083018461202d565b92915050565b600060208201905061232e600083018461203c565b92915050565b60006040820190506123496000830184612180565b92915050565b600060408201905061236460008301846121de565b92915050565b600060408201905061237f600083018461220d565b92915050565b6000604051905081810181811067ffffffffffffffff821117156123a857600080fd5b8060405250919050565b600067ffffffffffffffff8211156123c957600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156123f157600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561241957600080fd5b602082029050602081019050919050565b6000602082019050919050565b6000602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006124bd82612566565b9050919050565b60006124cf82612566565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006009821061251a57fe5b819050919050565b60006002821061252e57fe5b819050919050565b60006002821061254257fe5b819050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061259b826125dc565b9050919050565b60008115159050919050565b60006125b982612590565b9050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061261182612618565b9050919050565b600061262382612566565b9050919050565b60006126358261263c565b9050919050565b600061264782612566565b9050919050565b60006126598261250e565b9050919050565b600061266b82612522565b9050919050565b600061267d82612536565b9050919050565b60005b838110156126a2578082015181840152602081019050612687565b838111156126b1576000848401525b50505050565b6000601f19601f830116905091905056fea265627a7a7230582013febd37d3e0aebf89825e0fa2db31962f7ff39217fd49fe9165ed7d06a07db56c6578706572696d656e74616cf50037

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061035d5760003560e01c80638823151b116101d3578063c74c0fac11610104578063d36b907d116100a2578063f0d405e51161007c578063f0d405e51461098a578063f1d25396146109a8578063f3fef3a3146109c6578063f8352472146109e25761035d565b8063d36b907d1461091e578063ddaa293c1461093c578063eef1bbda1461095a5761035d565b8063ce9bde1d116100de578063ce9bde1d146108a6578063cf786f8f146108c4578063cfac57c7146108e2578063d3661fa5146109005761035d565b8063c74c0fac1461084c578063c917c2d31461086a578063c9fde270146108885761035d565b8063acbeba6111610171578063bc17effa1161014b578063bc17effa146107d4578063bf42d947146107f2578063bf7e214f14610810578063c16921b71461082e5761035d565b8063acbeba611461077a578063ad7359c914610798578063b175afa1146107b65761035d565b806394f0eb3d116101ad57806394f0eb3d146107025780639da779e914610720578063a46a66c91461073e578063a683668c1461075c5761035d565b80638823151b146106a85780638da5cb5b146106c657806394bfbe74146106e45761035d565b806336e6da11116102ad578063670079eb1161024b5780637800a0f6116102255780637800a0f6146106205780637a9e5e4b14610650578063819854e71461066c578063825ffd921461068a5761035d565b8063670079eb146105b45780636738929f146105e4578063728c0092146106025761035d565b806343fb75e81161028757806343fb75e81461053e57806347e7ef241461055c578063502237d71461057857806362da5d90146105965761035d565b806336e6da11146104e4578063380d42441461050257806342c1eb4e146105205761035d565b806313af40351161031a5780632a441f05116102f45780632a441f051461046c5780632a4c0a1a1461048a5780632d5eeb3f146104a857806332ac5cd2146104c65761035d565b806313af4035146104145780631dab52b01461043057806329f7fc9e1461044e5761035d565b8063040141e5146103625780630531b2ad1461038057806308204ea31461039e5780630b6cd37e146103bc5780630bd4a73e146103d8578063134f6d3a146103f6575b600080fd5b61036a610a00565b604051610377919061225a565b60405180910390f35b610388610a18565b604051610395919061225a565b60405180910390f35b6103a6610a30565b6040516103b3919061225a565b60405180910390f35b6103d660048036036103d19190810190611d64565b610a48565b005b6103e0610ac3565b6040516103ed919061225a565b60405180910390f35b6103fe610adb565b60405161040b9190612319565b60405180910390f35b61042e60048036036104299190810190611d64565b610b01565b005b610438610be1565b604051610445919061225a565b60405180910390f35b610456610bf9565b604051610463919061225a565b60405180910390f35b610474610c11565b604051610481919061225a565b60405180910390f35b610492610c29565b60405161049f919061225a565b60405180910390f35b6104b0610c41565b6040516104bd919061225a565b60405180910390f35b6104ce610c59565b6040516104db919061225a565b60405180910390f35b6104ec610c6c565b6040516104f9919061225a565b60405180910390f35b61050a610c84565b604051610517919061225a565b60405180910390f35b610528610c9c565b604051610535919061225a565b60405180910390f35b610546610cb4565b604051610553919061225a565b60405180910390f35b61057660048036036105719190810190611d8d565b610ccc565b005b610580610f0b565b60405161058d919061225a565b60405180910390f35b61059e610f23565b6040516105ab919061225a565b60405180910390f35b6105ce60048036036105c99190810190611d8d565b610f3b565b6040516105db9190612334565b60405180910390f35b6105ec610f82565b6040516105f9919061225a565b60405180910390f35b61060a610f9a565b604051610617919061225a565b60405180910390f35b61063a60048036036106359190810190611d8d565b610fb2565b604051610647919061234f565b60405180910390f35b61066a60048036036106659190810190611e89565b61109c565b005b61067461117a565b604051610681919061225a565b60405180910390f35b610692611192565b60405161069f919061225a565b60405180910390f35b6106b06111aa565b6040516106bd919061225a565b60405180910390f35b6106ce6111c2565b6040516106db919061225a565b60405180910390f35b6106ec6111e8565b6040516106f9919061225a565b60405180910390f35b61070a611200565b604051610717919061225a565b60405180910390f35b610728611218565b604051610735919061225a565b60405180910390f35b610746611230565b604051610753919061225a565b60405180910390f35b610764611248565b604051610771919061225a565b60405180910390f35b61078261126e565b60405161078f919061225a565b60405180910390f35b6107a0611286565b6040516107ad919061225a565b60405180910390f35b6107be61129e565b6040516107cb919061225a565b60405180910390f35b6107dc6112b6565b6040516107e9919061225a565b60405180910390f35b6107fa6112ce565b604051610807919061225a565b60405180910390f35b6108186112e6565b60405161082591906122fe565b60405180910390f35b61083661130b565b604051610843919061225a565b60405180910390f35b610854611323565b604051610861919061225a565b60405180910390f35b61087261133b565b60405161087f919061225a565b60405180910390f35b610890611353565b60405161089d919061225a565b60405180910390f35b6108ae61136b565b6040516108bb919061225a565b60405180910390f35b6108cc611383565b6040516108d9919061225a565b60405180910390f35b6108ea61139b565b6040516108f7919061225a565b60405180910390f35b6109086113b3565b6040516109159190612275565b60405180910390f35b6109266113cb565b604051610933919061225a565b60405180910390f35b6109446113e3565b604051610951919061225a565b60405180910390f35b610974600480360361096f9190810190611d8d565b6113fb565b604051610981919061236a565b60405180910390f35b6109926114e6565b60405161099f919061225a565b60405180910390f35b6109b06114fe565b6040516109bd919061225a565b60405180910390f35b6109e060048036036109db9190810190611d8d565b611516565b005b6109ea611755565b6040516109f79190612275565b60405180910390f35b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b73f5dce57282a584d2746faf1593d3121fcac444dc81565b7389b3635bd2bad145c6f92e82c9e83f06d565498481565b610a76336000357fffffffff000000000000000000000000000000000000000000000000000000001661176d565b610a7f57600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7389d24a6b4ccb1b6faa2625fe562bdd9a2326035981565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610b2f336000357fffffffff000000000000000000000000000000000000000000000000000000001661176d565b610b3857600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9460405160405180910390a250565b73729d19f657bd0614b4985cf1d82531c67569197b81565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b7339755357759ce0d7f32dc8dc45414cca409ae24e81565b736b175474e89094c44da98b954eedeac495271d0f81565b7314094949152eddbfcd073717200da82fed8dc96081565b6eb3f879cb30fe243b4dfee438691c0481565b739b0f70df76165442ca6092939132bbaea77f2d7a81565b735ef30b9986345249bc32d8928b7ee64de9435e3981565b733f4339816edef8d3d3970db2993e2e0ec601076081565b73d7bbb1777e13b6f535dec414f575b858ed300baf81565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d0457600080fd5b60606001604051908082528060200260200182016040528015610d4157816020015b610d2e611921565b815260200190600190039081610d265790505b509050610d4f836000610f3b565b81600081518110610d5c57fe5b602002602001018190525060606001604051908082528060200260200182016040528015610da457816020015b610d91611951565b815260200190600190039081610d895790505b509050610daf6119bd565b604051806080016040528060011515815260200160006001811115610dd057fe5b815260200160006001811115610de257fe5b815260200185815250905060405180610100016040528060006008811115610e0657fe5b8152602001600081526020018281526020016004548152602001600081526020018673ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016040518060200160405280600081525081525082600081518110610e6a57fe5b6020026020010181905250600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a67a6a4584846040518363ffffffff1660e01b8152600401610ed29291906122c7565b600060405180830381600087803b158015610eec57600080fd5b505af1158015610f00573d6000803e3d6000fd5b505050505050505050565b73863e41fe88288ebf3fcd91d8dbb679fb83fdfe1781565b73e4b22d484958e582098a98229a24e8a43801b67481565b610f436119fd565b610f4b6119fd565b60405180604001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018481525090508091505092915050565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b734678f0a6958e4d2bc4f1baf7bc52e8f3564f3fe481565b610fba611a2d565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a8194e76110048686610f3b565b6040518263ffffffff1660e01b81526004016110209190612334565b60006040518083038186803b15801561103857600080fd5b505afa15801561104c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506110759190810190611dc9565b9091505080915050806004548151811061108b57fe5b602002602001015191505092915050565b6110ca336000357fffffffff000000000000000000000000000000000000000000000000000000001661176d565b6110d357600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada460405160405180910390a250565b7382ecd135dce65fbc6dbdd0e4237e0af93ffd503881565b739f8f72aa9304c8b593d555f12ef6589cc3a579a281565b735a15566417e6c1c9546523066500bddbc53f88c781565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73ecf88e1cec2d2894a0295db3d86fe7ce4991e6df81565b73865b41584a22f8345fca4b71c42a1e7abcd67ecb81565b7389d24a6b4ccb1b6faa2625fe562bdd9a2326035981565b731b14e8d511c9a4395425314f849bd737baf8208f81565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7319c0976f590d67707e62397c87829d896dc0f1f181565b735d3a536e4d6dbd6114cc1ead35777bab948e364381565b738f337bd3b7f2b05d9a8dc8ac518584e83342489381565b7383152caa0d344a2fd428769529e2d490a88f439381565b73493c57c4763932315a328269e1adad09653b908181565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7325a01a05c188dacbcf1d61af55d4a5b4021f7eed81565b73c0a47dfe034b400b47bdad5fecda2621de6c4d9581565b739abe2715d2d99246269b8e17e9d1b620e9bf655881565b73f53ad2c6851052a81b42133467480961b2321c0981565b73818e6fecd516ecc3849daf6845e3ec868087b75581565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b739759a6ac90977b93b58547b4a71c78317f391a2881565b73322d58b9e75a6918f7e7849aee0ff09369977e0881565b731e0447b19bb6ecfdae1e4ae1694b0c3659614e4e81565b731e30124fde14533231216d95f7798cd0061e5cf881565b611403611a5b565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a8194e761144d8686610f3b565b6040518263ffffffff1660e01b81526004016114699190612334565b60006040518083038186803b15801561148157600080fd5b505afa158015611495573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506114be9190810190611dc9565b90915090508091505080600454815181106114d557fe5b602002602001015191505092915050565b73448a5065aebb8e423f0896e6c5d525c040f59af381565b732f0b23f53734252bda2277357e97e1517d6b042a81565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154e57600080fd5b6060600160405190808252806020026020018201604052801561158b57816020015b611578611921565b8152602001906001900390816115705790505b509050611599836000610f3b565b816000815181106115a657fe5b6020026020010181905250606060016040519080825280602002602001820160405280156115ee57816020015b6115db611951565b8152602001906001900390816115d35790505b5090506115f96119bd565b60405180608001604052806000151581526020016000600181111561161a57fe5b81526020016000600181111561162c57fe5b81526020018581525090506040518061010001604052806001600881111561165057fe5b8152602001600081526020018281526020016004548152602001600081526020018673ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160405180602001604052806000815250815250826000815181106116b457fe5b6020026020010181905250600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a67a6a4584846040518363ffffffff1660e01b815260040161171c9291906122c7565b600060405180830381600087803b15801561173657600080fd5b505af115801561174a573d6000803e3d6000fd5b505050505050505050565b73c73e0383f3aff3215e6f04b0331d58cecf0ab84981565b60003073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156117ac576001905061191b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561180b576001905061191b565b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561186a576000905061191b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b70096138430856040518463ffffffff1660e01b81526004016118c893929190612290565b60206040518083038186803b1580156118e057600080fd5b505afa1580156118f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119189190810190611e60565b90505b92915050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6040518061016001604052806000600881111561196a57fe5b81526020016000815260200161197e611a77565b81526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001606081525090565b6040518060800160405280600015158152602001600060018111156119de57fe5b8152602001600060018111156119f057fe5b8152602001600081525090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b604051806040016040528060001515815260200160006fffffffffffffffffffffffffffffffff1681525090565b6040518060400160405280600015158152602001600081525090565b604051806080016040528060001515815260200160006001811115611a9857fe5b815260200160006001811115611aaa57fe5b8152602001600081525090565b6000611ac38235612590565b905092915050565b6000611ad78251612590565b905092915050565b600082601f830112611af057600080fd5b8151611b03611afe826123b2565b612385565b91508181835260208401935060208101905083856020840282011115611b2857600080fd5b60005b83811015611b585781611b3e8882611acb565b845260208401935060208301925050600181019050611b2b565b5050505092915050565b600082601f830112611b7357600080fd5b8151611b86611b81826123da565b612385565b91508181835260208401935060208101905083856040840282011115611bab57600080fd5b60005b83811015611bdb5781611bc18882611c90565b845260208401935060408301925050600181019050611bae565b5050505092915050565b600082601f830112611bf657600080fd5b8151611c09611c0482612402565b612385565b91508181835260208401935060208101905083856040840282011115611c2e57600080fd5b60005b83811015611c5e5781611c448882611cdc565b845260208401935060408301925050600181019050611c31565b5050505092915050565b6000611c7482516125a2565b905092915050565b6000611c8882356125ae565b905092915050565b600060408284031215611ca257600080fd5b611cac6040612385565b90506000611cbc84828501611c68565b6000830152506020611cd084828501611d28565b60208301525092915050565b600060408284031215611cee57600080fd5b611cf86040612385565b90506000611d0884828501611c68565b6000830152506020611d1c84828501611d50565b60208301525092915050565b6000611d3482516125c0565b905092915050565b6000611d4882356125fc565b905092915050565b6000611d5c82516125fc565b905092915050565b600060208284031215611d7657600080fd5b6000611d8484828501611ab7565b91505092915050565b60008060408385031215611da057600080fd5b6000611dae85828601611ab7565b9250506020611dbf85828601611d3c565b9150509250929050565b600080600060608486031215611dde57600080fd5b600084015167ffffffffffffffff811115611df857600080fd5b611e0486828701611adf565b935050602084015167ffffffffffffffff811115611e2157600080fd5b611e2d86828701611b62565b925050604084015167ffffffffffffffff811115611e4a57600080fd5b611e5686828701611be5565b9150509250925092565b600060208284031215611e7257600080fd5b6000611e8084828501611c68565b91505092915050565b600060208284031215611e9b57600080fd5b6000611ea984828501611c7c565b91505092915050565b6000611ebe8383612078565b905092915050565b6000611ed283836121af565b60408301905092915050565b611ee7816124c4565b82525050565b611ef6816124b2565b82525050565b611f05816124b2565b82525050565b6000611f1682612444565b611f20818561247f565b935083602082028501611f328561242a565b60005b84811015611f6b578383038852611f4d838351611eb2565b9250611f5882612465565b9150602088019750600181019050611f35565b508196508694505050505092915050565b6000611f878261244f565b611f918185612490565b9350611f9c83612437565b60005b82811015611fca57611fb2868351611ec6565b9550611fbd82612472565b9150600181019050611f9f565b50849250505092915050565b611fdf816124d6565b82525050565b611fee816124e2565b82525050565b6000611fff8261245a565b61200981856124a1565b9350612019818560208601612684565b612022816126b7565b840191505092915050565b61203681612606565b82525050565b6120458161262a565b82525050565b6120548161264e565b82525050565b61206381612660565b82525050565b61207281612672565b82525050565b600061016083016000830151612091600086018261204b565b5060208301516120a4602086018261224b565b5060408301516120b7604086018261212b565b5060608301516120ca60c086018261224b565b5060808301516120dd60e086018261224b565b5060a08301516120f1610100860182611eed565b5060c083015161210561012086018261224b565b5060e083015184820361014086015261211e8282611ff4565b9150508091505092915050565b6080820160008201516121416000850182611fd6565b506020820151612154602085018261205a565b5060408201516121676040850182612069565b50606082015161217a606085018261224b565b50505050565b6040820160008201516121966000850182611eed565b5060208201516121a9602085018261224b565b50505050565b6040820160008201516121c56000850182611eed565b5060208201516121d8602085018261224b565b50505050565b6040820160008201516121f46000850182611fd6565b506020820151612207602085018261223c565b50505050565b6040820160008201516122236000850182611fd6565b506020820151612236602085018261224b565b50505050565b6122458161254a565b82525050565b61225481612586565b82525050565b600060208201905061226f6000830184611efc565b92915050565b600060208201905061228a6000830184611ede565b92915050565b60006060820190506122a56000830186611efc565b6122b26020830185611efc565b6122bf6040830184611fe5565b949350505050565b600060408201905081810360008301526122e18185611f7c565b905081810360208301526122f58184611f0b565b90509392505050565b6000602082019050612313600083018461202d565b92915050565b600060208201905061232e600083018461203c565b92915050565b60006040820190506123496000830184612180565b92915050565b600060408201905061236460008301846121de565b92915050565b600060408201905061237f600083018461220d565b92915050565b6000604051905081810181811067ffffffffffffffff821117156123a857600080fd5b8060405250919050565b600067ffffffffffffffff8211156123c957600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156123f157600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561241957600080fd5b602082029050602081019050919050565b6000602082019050919050565b6000602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006124bd82612566565b9050919050565b60006124cf82612566565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006009821061251a57fe5b819050919050565b60006002821061252e57fe5b819050919050565b60006002821061254257fe5b819050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061259b826125dc565b9050919050565b60008115159050919050565b60006125b982612590565b9050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061261182612618565b9050919050565b600061262382612566565b9050919050565b60006126358261263c565b9050919050565b600061264782612566565b9050919050565b60006126598261250e565b9050919050565b600061266b82612522565b9050919050565b600061267d82612536565b9050919050565b60005b838110156126a2578082015181840152602081019050612687565b838111156126b1576000848401525b50505050565b6000601f19601f830116905091905056fea265627a7a7230582013febd37d3e0aebf89825e0fa2db31962f7ff39217fd49fe9165ed7d06a07db56c6578706572696d656e74616cf50037

Deployed Bytecode Sourcemap

48110:3091:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48110:3091:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39198:81;;;:::i;:::-;;;;;;;;;;;;;;;;38930;;;:::i;:::-;;;;;;;;;;;;;;;;40859:91;;;:::i;:::-;;;;;;;;;;;;;;;;48392:107;;;;;;;;;;;;;;;;:::i;:::-;;42051:80;;;:::i;:::-;;;;;;;;;;;;;;;;48198:29;;;:::i;:::-;;;;;;;;;;;;;;;;47289:136;;;;;;;;;;;;;;;;:::i;:::-;;40547:90;;;:::i;:::-;;;;;;;;;;;;;;;;39018:86;;;:::i;:::-;;;;;;;;;;;;;;;;39731:80;;;:::i;:::-;;;;;;;;;;;;;;;;42138;;;:::i;:::-;;;;;;;;;;;;;;;;38747:81;;;:::i;:::-;;;;;;;;;;;;;;;;40754:96;;;:::i;:::-;;;;;;;;;;;;;;;;39286:80;;;:::i;:::-;;;;;;;;;;;;;;;;41319:84;;;:::i;:::-;;;;;;;;;;;;;;;;42448;;;:::i;:::-;;;;;;;;;;;;;;;;40092;;;:::i;:::-;;;;;;;;;;;;;;;;48507:937;;;;;;;;;;;;;;;;:::i;:::-;;41200:84;;;:::i;:::-;;;;;;;;;;;;;;;;41950:92;;;:::i;:::-;;;;;;;;;;;;;;;;50952:246;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;41497:84;;;:::i;:::-;;;;;;;;;;;;;;;;40646:101;;;:::i;:::-;;;;;;;;;;;;;;;;50677:267;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;47433:173;;;;;;;;;;;;;;;;:::i;:::-;;41588:82;;;:::i;:::-;;;;;;;;;;;;;;;;39111:80;;;:::i;:::-;;;;;;;;;;;;;;;;40456:84;;;:::i;:::-;;;;;;;;;;;;;;;;47149:26;;;:::i;:::-;;;;;;;;;;;;;;;;39641:83;;;:::i;:::-;;;;;;;;;;;;;;;;40959:91;;;:::i;:::-;;;;;;;;;;;;;;;;38654:86;;;:::i;:::-;;;;;;;;;;;;;;;;39818:85;;;:::i;:::-;;;;;;;;;;;;;;;;48234:27;;;:::i;:::-;;;;;;;;;;;;;;;;41679:80;;;:::i;:::-;;;;;;;;;;;;;;;;42541:85;;;:::i;:::-;;;;;;;;;;;;;;;;39912:82;;;:::i;:::-;;;;;;;;;;;;;;;;42352:89;;;:::i;:::-;;;;;;;;;;;;;;;;42633:85;;;:::i;:::-;;;;;;;;;;;;;;;;47112:30;;;:::i;:::-;;;;;;;;;;;;;;;;41104:89;;;:::i;:::-;;;;;;;;;;;;;;;;40365:84;;;:::i;:::-;;;;;;;;;;;;;;;;40183:82;;;:::i;:::-;;;;;;;;;;;;;;;;39373:81;;;:::i;:::-;;;;;;;;;;;;;;;;40274:84;;;:::i;:::-;;;;;;;;;;;;;;;;41410:80;;;:::i;:::-;;;;;;;;;;;;;;;;41766:85;;;:::i;:::-;;;;;;;;;;;;;;;;39548:86;;;:::i;:::-;;;;;;;;;;;;;;;;38835:88;;;:::i;:::-;;;;;;;;;;;;;;;;40001:84;;;:::i;:::-;;;;;;;;;;;;;;;;50400:269;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;39461:80;;;:::i;:::-;;;;;;;;;;;;;;;;41858:85;;;:::i;:::-;;;;;;;;;;;;;;;;49452:940;;;;;;;;;;;;;;;;:::i;:::-;;42227:94;;;:::i;:::-;;;;;;;;;;;;;;;;39198:81;39237:42;39198:81;:::o;38930:::-;38969:42;38930:81;:::o;40859:91::-;40908:42;40859:91;:::o;48392:107::-;47647:33;47660:10;47672:7;;;;47647:12;:33::i;:::-;47639:42;;;;;;48478:13;48463:12;;:28;;;;;;;;;;;;;;;;;;48392:107;:::o;42051:80::-;42089:42;42051:80;:::o;48198:29::-;;;;;;;;;;;;;:::o;47289:136::-;47647:33;47660:10;47672:7;;;;47647:12;:33::i;:::-;47639:42;;;;;;47377:6;47369:5;;:14;;;;;;;;;;;;;;;;;;47411:5;;;;;;;;;;;47399:18;;;;;;;;;;;;47289:136;:::o;40547:90::-;40595:42;40547:90;:::o;39018:86::-;39062:42;39018:86;:::o;39731:80::-;39769:42;39731:80;:::o;42138:::-;42176:42;42138:80;:::o;38747:81::-;38786:42;38747:81;:::o;40754:96::-;40808:42;40754:96;:::o;39286:80::-;39324:42;39286:80;:::o;41319:84::-;41361:42;41319:84;:::o;42448:::-;42490:42;42448:84;:::o;40092:::-;40134:42;40092:84;:::o;48507:937::-;48593:5;48579:19;;:10;:19;;;48571:28;;;;;;48612:30;48664:1;48645:21;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;48612:54;;48691:20;48702:5;48709:1;48691:10;:20::i;:::-;48677:8;48686:1;48677:11;;;;;;;;;;;;;:34;;;;48724:35;48787:1;48762:27;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;48724:65;;48800:31;;:::i;:::-;48834:186;;;;;;;;48873:4;48834:186;;;;;;48906:27;48834:186;;;;;;;;;;;;48953:26;48834:186;;;;;;;;;;;;49001:7;48834:186;;;48800:220;;49046:340;;;;;;;;49092:26;49046:340;;;;;;;;;;;;49144:1;49046:340;;;;49168:6;49046:340;;;;49206:11;;49046:340;;;;49285:1;49046:340;;;;49246:5;49046:340;;;;;;49328:1;49046:340;;;;;;;;;;;;;;;;;;;49033:7;49041:1;49033:10;;;;;;;;;;;;;:353;;;;49399:10;;;;;;;;;;;:18;;;49418:8;49428:7;49399:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49399:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49399:37:0;;;;48507:937;;;;;:::o;41200:84::-;41242:42;41200:84;:::o;41950:92::-;42000:42;41950:92;:::o;50952:246::-;51020:19;;:::i;:::-;51052:27;;:::i;:::-;51082:81;;;;;;;;51117:5;51082:81;;;;;;51145:6;51082:81;;;51052:111;;51183:7;51176:14;;;50952:246;;;;:::o;41497:84::-;41539:42;41497:84;:::o;40646:101::-;40705:42;40646:101;:::o;50677:267::-;50748:16;;:::i;:::-;50777:30;50836:10;;;;;;;;;;;:29;;;50866:25;50877:5;50884:6;50866:10;:25::i;:::-;50836:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50836:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50836:56:0;;;;;;39:16:-1;36:1;17:17;2:54;50836:56:0;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;50836:56:0;;;;;;;;;50818:74;;;;;;;;50912:11;50924;;50912:24;;;;;;;;;;;;;;50905:31;;;50677:267;;;;:::o;47433:173::-;47647:33;47660:10;47672:7;;;;47647:12;:33::i;:::-;47639:42;;;;;;47537:10;47525:9;;:22;;;;;;;;;;;;;;;;;;47587:9;;;;;;;;;;;47563:35;;;;;;;;;;;;47433:173;:::o;41588:82::-;41628:42;41588:82;:::o;39111:80::-;39149:42;39111:80;:::o;40456:84::-;40498:42;40456:84;:::o;47149:26::-;;;;;;;;;;;;;:::o;39641:83::-;39682:42;39641:83;:::o;40959:91::-;41008:42;40959:91;:::o;38654:86::-;38698:42;38654:86;:::o;39818:85::-;39861:42;39818:85;:::o;48234:27::-;;;;;;;;;;;;;:::o;41679:80::-;41717:42;41679:80;:::o;42541:85::-;42584:42;42541:85;:::o;39912:82::-;39952:42;39912:82;:::o;42352:89::-;42399:42;42352:89;:::o;42633:85::-;42676:42;42633:85;:::o;47112:30::-;;;;;;;;;;;;;:::o;41104:89::-;41151:42;41104:89;:::o;40365:84::-;40407:42;40365:84;:::o;40183:82::-;40223:42;40183:82;:::o;39373:81::-;39412:42;39373:81;:::o;40274:84::-;40316:42;40274:84;:::o;41410:80::-;41448:42;41410:80;:::o;41766:85::-;41809:42;41766:85;:::o;39548:86::-;39592:42;39548:86;:::o;38835:88::-;38881:42;38835:88;:::o;40001:84::-;40043:42;40001:84;:::o;50400:269::-;50471:16;;:::i;:::-;50502:30;50561:10;;;;;;;;;;;:29;;;50591:25;50602:5;50609:6;50591:10;:25::i;:::-;50561:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50561:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50561:56:0;;;;;;39:16:-1;36:1;17:17;2:54;50561:56:0;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;50561:56:0;;;;;;;;;50543:74;;;;;;;;;50637:11;50649;;50637:24;;;;;;;;;;;;;;50630:31;;;50400:269;;;;:::o;39461:80::-;39499:42;39461:80;:::o;41858:85::-;41901:42;41858:85;:::o;49452:940::-;49539:5;49525:19;;:10;:19;;;49517:28;;;;;;49558:30;49610:1;49591:21;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;49558:54;;49637:20;49648:5;49655:1;49637:10;:20::i;:::-;49623:8;49632:1;49623:11;;;;;;;;;;;;;:34;;;;49670:35;49733:1;49708:27;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;49670:65;;49746:31;;:::i;:::-;49780:187;;;;;;;;49819:5;49780:187;;;;;;49853:27;49780:187;;;;;;;;;;;;49900:26;49780:187;;;;;;;;;;;;49948:7;49780:187;;;49746:221;;49993:341;;;;;;;;50039:27;49993:341;;;;;;;;;;;;50092:1;49993:341;;;;50116:6;49993:341;;;;50154:11;;49993:341;;;;50233:1;49993:341;;;;50194:5;49993:341;;;;;;50276:1;49993:341;;;;;;;;;;;;;;;;;;;49980:7;49988:1;49980:10;;;;;;;;;;;;;:354;;;;50347:10;;;;;;;;;;;:18;;;50366:8;50376:7;50347:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50347:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50347:37:0;;;;49452:940;;;;;:::o;42227:94::-;42279:42;42227:94;:::o;47709:380::-;47779:4;47815;47800:20;;:3;:20;;;47796:286;;;47844:4;47837:11;;;;47796:286;47877:5;;;;;;;;;;;47870:12;;:3;:12;;;47866:216;;;47906:4;47899:11;;;;47866:216;47957:1;47932:27;;:9;;;;;;;;;;;:27;;;47928:154;;;47983:5;47976:12;;;;47928:154;48028:9;;;;;;;;;;;:17;;;48046:3;48059:4;48066:3;48028:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48028:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48028:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;48028:42:0;;;;;;;;;48021:49;;47709:380;;;;;:::o;48110:3091::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;;57:66;;;;;130:122;;208:39;239:6;233:13;208:39;;;199:48;;193:59;;;;;277:722;;405:3;398:4;390:6;386:17;382:27;372:2;;423:1;420;413:12;372:2;453:6;447:13;475:80;490:64;547:6;490:64;;;475:80;;;466:89;;572:5;597:6;590:5;583:21;627:4;619:6;615:17;605:27;;649:4;644:3;640:14;633:21;;702:6;749:3;741:4;733:6;729:17;724:3;720:27;717:36;714:2;;;766:1;763;756:12;714:2;791:1;776:217;801:6;798:1;795:13;776:217;;;859:3;881:48;925:3;913:10;881:48;;;876:3;869:61;953:4;948:3;944:14;937:21;;981:4;976:3;972:14;965:21;;833:160;823:1;820;816:9;811:14;;776:217;;;780:14;365:634;;;;;;;;1034:773;;1179:3;1172:4;1164:6;1160:17;1156:27;1146:2;;1197:1;1194;1187:12;1146:2;1227:6;1221:13;1249:97;1264:81;1338:6;1264:81;;;1249:97;;;1240:106;;1363:5;1388:6;1381:5;1374:21;1418:4;1410:6;1406:17;1396:27;;1440:4;1435:3;1431:14;1424:21;;1493:6;1540:3;1532:4;1524:6;1520:17;1515:3;1511:27;1508:36;1505:2;;;1557:1;1554;1547:12;1505:2;1582:1;1567:234;1592:6;1589:1;1586:13;1567:234;;;1650:3;1672:65;1733:3;1721:10;1672:65;;;1667:3;1660:78;1761:4;1756:3;1752:14;1745:21;;1789:4;1784:3;1780:14;1773:21;;1624:177;1614:1;1611;1607:9;1602:14;;1567:234;;;1571:14;1139:668;;;;;;;;1842:773;;1987:3;1980:4;1972:6;1968:17;1964:27;1954:2;;2005:1;2002;1995:12;1954:2;2035:6;2029:13;2057:97;2072:81;2146:6;2072:81;;;2057:97;;;2048:106;;2171:5;2196:6;2189:5;2182:21;2226:4;2218:6;2214:17;2204:27;;2248:4;2243:3;2239:14;2232:21;;2301:6;2348:3;2340:4;2332:6;2328:17;2323:3;2319:27;2316:36;2313:2;;;2365:1;2362;2355:12;2313:2;2390:1;2375:234;2400:6;2397:1;2394:13;2375:234;;;2458:3;2480:65;2541:3;2529:10;2480:65;;;2475:3;2468:78;2569:4;2564:3;2560:14;2553:21;;2597:4;2592:3;2588:14;2581:21;;2432:177;2422:1;2419;2415:9;2410:14;;2375:234;;;2379:14;1947:668;;;;;;;;2623:116;;2698:36;2726:6;2720:13;2698:36;;;2689:45;;2683:56;;;;;2746:158;;2833:66;2891:6;2878:20;2833:66;;;2824:75;;2818:86;;;;;2934:489;;3051:4;3039:9;3034:3;3030:19;3026:30;3023:2;;;3069:1;3066;3059:12;3023:2;3087:20;3102:4;3087:20;;;3078:29;;3157:1;3188:57;3241:3;3232:6;3221:9;3217:22;3188:57;;;3182:3;3175:5;3171:15;3164:82;3117:140;3308:2;3341:60;3397:3;3388:6;3377:9;3373:22;3341:60;;;3334:4;3327:5;3323:16;3316:86;3267:146;3017:406;;;;;3453:489;;3570:4;3558:9;3553:3;3549:19;3545:30;3542:2;;;3588:1;3585;3578:12;3542:2;3606:20;3621:4;3606:20;;;3597:29;;3676:1;3707:57;3760:3;3751:6;3740:9;3736:22;3707:57;;;3701:3;3694:5;3690:15;3683:82;3636:140;3827:2;3860:60;3916:3;3907:6;3896:9;3892:22;3860:60;;;3853:4;3846:5;3842:16;3835:86;3786:146;3536:406;;;;;3949:122;;4027:39;4058:6;4052:13;4027:39;;;4018:48;;4012:59;;;;;4078:118;;4145:46;4183:6;4170:20;4145:46;;;4136:55;;4130:66;;;;;4203:122;;4281:39;4312:6;4306:13;4281:39;;;4272:48;;4266:59;;;;;4332:241;;4436:2;4424:9;4415:7;4411:23;4407:32;4404:2;;;4452:1;4449;4442:12;4404:2;4487:1;4504:53;4549:7;4540:6;4529:9;4525:22;4504:53;;;4494:63;;4466:97;4398:175;;;;;4580:366;;;4701:2;4689:9;4680:7;4676:23;4672:32;4669:2;;;4717:1;4714;4707:12;4669:2;4752:1;4769:53;4814:7;4805:6;4794:9;4790:22;4769:53;;;4759:63;;4731:97;4859:2;4877:53;4922:7;4913:6;4902:9;4898:22;4877:53;;;4867:63;;4838:98;4663:283;;;;;;4953:990;;;;5211:2;5199:9;5190:7;5186:23;5182:32;5179:2;;;5227:1;5224;5217:12;5179:2;5283:1;5272:9;5268:17;5262:24;5306:18;5298:6;5295:30;5292:2;;;5338:1;5335;5328:12;5292:2;5358:89;5439:7;5430:6;5419:9;5415:22;5358:89;;;5348:99;;5241:212;5505:2;5494:9;5490:18;5484:25;5529:18;5521:6;5518:30;5515:2;;;5561:1;5558;5551:12;5515:2;5581:106;5679:7;5670:6;5659:9;5655:22;5581:106;;;5571:116;;5463:230;5745:2;5734:9;5730:18;5724:25;5769:18;5761:6;5758:30;5755:2;;;5801:1;5798;5791:12;5755:2;5821:106;5919:7;5910:6;5899:9;5895:22;5821:106;;;5811:116;;5703:230;5173:770;;;;;;5950:257;;6062:2;6050:9;6041:7;6037:23;6033:32;6030:2;;;6078:1;6075;6068:12;6030:2;6113:1;6130:61;6183:7;6174:6;6163:9;6159:22;6130:61;;;6120:71;;6092:105;6024:183;;;;;6214:281;;6338:2;6326:9;6317:7;6313:23;6309:32;6306:2;;;6354:1;6351;6344:12;6306:2;6389:1;6406:73;6471:7;6462:6;6451:9;6447:22;6406:73;;;6396:83;;6368:117;6300:195;;;;;6503:253;;6652:98;6746:3;6738:6;6652:98;;;6638:112;;6631:125;;;;;6765:249;;6888:86;6970:3;6962:6;6888:86;;;7003:4;6998:3;6994:14;6980:28;;6881:133;;;;;7022:144;7121:39;7154:5;7121:39;;;7116:3;7109:52;7103:63;;;7173:110;7246:31;7271:5;7246:31;;;7241:3;7234:44;7228:55;;;7290:120;7373:31;7398:5;7373:31;;;7368:3;7361:44;7355:55;;;7484:971;;7677:78;7749:5;7677:78;;;7768:110;7871:6;7866:3;7768:110;;;7761:117;;7901:3;7943:4;7935:6;7931:17;7926:3;7922:27;7969:80;8043:5;7969:80;;;8070:1;8055:361;8080:6;8077:1;8074:13;8055:361;;;8142:9;8136:4;8132:20;8127:3;8120:33;8168:112;8275:4;8266:6;8260:13;8168:112;;;8160:120;;8297:84;8374:6;8297:84;;;8287:94;;8404:4;8399:3;8395:14;8388:21;;8102:1;8099;8095:9;8090:14;;8055:361;;;8059:14;8429:4;8422:11;;8446:3;8439:10;;7656:799;;;;;;;;;8518:765;;8699:72;8765:5;8699:72;;;8784:104;8881:6;8876:3;8784:104;;;8777:111;;8908:74;8976:5;8908:74;;;9003:1;8988:273;9013:6;9010:1;9007:13;8988:273;;;9060:99;9155:3;9146:6;9140:13;9060:99;;;9053:106;;9176:78;9247:6;9176:78;;;9166:88;;9035:1;9032;9028:9;9023:14;;8988:273;;;8992:14;9274:3;9267:10;;8678:605;;;;;;;9291:101;9358:28;9380:5;9358:28;;;9353:3;9346:41;9340:52;;;9399:117;9480:30;9504:5;9480:30;;;9475:3;9468:43;9462:54;;;9523:315;;9619:34;9647:5;9619:34;;;9665:60;9718:6;9713:3;9665:60;;;9658:67;;9730:52;9775:6;9770:3;9763:4;9756:5;9752:16;9730:52;;;9803:29;9825:6;9803:29;;;9798:3;9794:39;9787:46;;9599:239;;;;;;9845:166;9948:57;9999:5;9948:57;;;9943:3;9936:70;9930:81;;;10018:166;10121:57;10172:5;10121:57;;;10116:3;10109:70;10103:81;;;10191:142;10277:50;10321:5;10277:50;;;10272:3;10265:63;10259:74;;;10340:156;10433:57;10484:5;10433:57;;;10428:3;10421:70;10415:81;;;10503:150;10593:54;10641:5;10593:54;;;10588:3;10581:67;10575:78;;;10721:1589;;10864:5;10859:3;10855:15;10953:3;10946:5;10942:15;10936:22;10964:74;11033:3;11028;11024:13;11011:11;10964:74;;;10885:159;11121:4;11114:5;11110:16;11104:23;11133:62;11189:4;11184:3;11180:14;11167:11;11133:62;;;11054:147;11275:4;11268:5;11264:16;11258:23;11287:116;11397:4;11392:3;11388:14;11375:11;11287:116;;;11211:198;11492:4;11485:5;11481:16;11475:23;11504:62;11560:4;11555:3;11551:14;11538:11;11504:62;;;11419:153;11657:4;11650:5;11646:16;11640:23;11669:62;11725:4;11720:3;11716:14;11703:11;11669:62;;;11582:155;11817:4;11810:5;11806:16;11800:23;11829:63;11885:5;11880:3;11876:15;11863:11;11829:63;;;11747:151;11980:4;11973:5;11969:16;11963:23;11992:63;12048:5;12043:3;12039:15;12026:11;11992:63;;;11908:153;12133:4;12126:5;12122:16;12116:23;12186:3;12180:4;12176:14;12168:5;12163:3;12159:15;12152:39;12206:66;12267:4;12254:11;12206:66;;;12198:74;;12071:213;12301:4;12294:11;;10837:1473;;;;;;12376:807;12513:4;12508:3;12504:14;12595:3;12588:5;12584:15;12578:22;12606:55;12656:3;12651;12647:13;12634:11;12606:55;;;12533:134;12747:4;12740:5;12736:16;12730:23;12759:82;12835:4;12830:3;12826:14;12813:11;12759:82;;;12677:170;12918:4;12911:5;12907:16;12901:23;12930:79;13003:4;12998:3;12994:14;12981:11;12930:79;;;12857:158;13088:4;13081:5;13077:16;13071:23;13100:62;13156:4;13151:3;13147:14;13134:11;13100:62;;;13025:143;12486:697;;;;13239:467;13376:4;13371:3;13367:14;13459:3;13452:5;13448:15;13442:22;13470:61;13526:3;13521;13517:13;13504:11;13470:61;;;13396:141;13611:4;13604:5;13600:16;13594:23;13623:62;13679:4;13674:3;13670:14;13657:11;13623:62;;;13547:144;13349:357;;;;13762:453;13885:4;13880:3;13876:14;13968:3;13961:5;13957:15;13951:22;13979:61;14035:3;14030;14026:13;14013:11;13979:61;;;13905:141;14120:4;14113:5;14109:16;14103:23;14132:62;14188:4;14183:3;14179:14;14166:11;14132:62;;;14056:144;13858:357;;;;14265:457;14400:4;14395:3;14391:14;14482:3;14475:5;14471:15;14465:22;14493:55;14543:3;14538;14534:13;14521:11;14493:55;;;14420:134;14627:4;14620:5;14616:16;14610:23;14639:62;14695:4;14690:3;14686:14;14673:11;14639:62;;;14564:143;14373:349;;;;14772:457;14907:4;14902:3;14898:14;14989:3;14982:5;14978:15;14972:22;15000:55;15050:3;15045;15041:13;15028:11;15000:55;;;14927:134;15134:4;15127:5;15123:16;15117:23;15146:62;15202:4;15197:3;15193:14;15180:11;15146:62;;;15071:143;14880:349;;;;15236:110;15309:31;15334:5;15309:31;;;15304:3;15297:44;15291:55;;;15353:110;15426:31;15451:5;15426:31;;;15421:3;15414:44;15408:55;;;15470:213;;15588:2;15577:9;15573:18;15565:26;;15602:71;15670:1;15659:9;15655:17;15646:6;15602:71;;;15559:124;;;;;15690:245;;15824:2;15813:9;15809:18;15801:26;;15838:87;15922:1;15911:9;15907:17;15898:6;15838:87;;;15795:140;;;;;15942:431;;16114:2;16103:9;16099:18;16091:26;;16128:71;16196:1;16185:9;16181:17;16172:6;16128:71;;;16210:72;16278:2;16267:9;16263:18;16254:6;16210:72;;;16293:70;16359:2;16348:9;16344:18;16335:6;16293:70;;;16085:288;;;;;;;16380:788;;16710:2;16699:9;16695:18;16687:26;;16760:9;16754:4;16750:20;16746:1;16735:9;16731:17;16724:47;16785:144;16924:4;16915:6;16785:144;;;16777:152;;16977:9;16971:4;16967:20;16962:2;16951:9;16947:18;16940:48;17002:156;17153:4;17144:6;17002:156;;;16994:164;;16681:487;;;;;;17175:253;;17313:2;17302:9;17298:18;17290:26;;17327:91;17415:1;17404:9;17400:17;17391:6;17327:91;;;17284:144;;;;;17435:253;;17573:2;17562:9;17558:18;17550:26;;17587:91;17675:1;17664:9;17660:17;17651:6;17587:91;;;17544:144;;;;;17695:301;;17857:2;17846:9;17842:18;17834:26;;17871:115;17983:1;17972:9;17968:17;17959:6;17871:115;;;17828:168;;;;;18003:297;;18163:2;18152:9;18148:18;18140:26;;18177:113;18287:1;18276:9;18272:17;18263:6;18177:113;;;18134:166;;;;;18307:297;;18467:2;18456:9;18452:18;18444:26;;18481:113;18591:1;18580:9;18576:17;18567:6;18481:113;;;18438:166;;;;;18611:256;;18673:2;18667:9;18657:19;;18711:4;18703:6;18699:17;18810:6;18798:10;18795:22;18774:18;18762:10;18759:34;18756:62;18753:2;;;18831:1;18828;18821:12;18753:2;18851:10;18847:2;18840:22;18651:216;;;;;18874:258;;19033:18;19025:6;19022:30;19019:2;;;19065:1;19062;19055:12;19019:2;19094:4;19086:6;19082:17;19074:25;;19122:4;19116;19112:15;19104:23;;18956:176;;;;19139:275;;19315:18;19307:6;19304:30;19301:2;;;19347:1;19344;19337:12;19301:2;19376:4;19368:6;19364:17;19356:25;;19404:4;19398;19394:15;19386:23;;19238:176;;;;19421:275;;19597:18;19589:6;19586:30;19583:2;;;19629:1;19626;19619:12;19583:2;19658:4;19650:6;19646:17;19638:25;;19686:4;19680;19676:15;19668:23;;19520:176;;;;19705:145;;19838:4;19830:6;19826:17;19815:28;;19807:43;;;;19861:139;;19988:4;19980:6;19976:17;19965:28;;19957:43;;;;20009:131;;20129:5;20123:12;20113:22;;20107:33;;;;20147:125;;20261:5;20255:12;20245:22;;20239:33;;;;20279:87;;20355:5;20349:12;20339:22;;20333:33;;;;20374:146;;20509:4;20501:6;20497:17;20486:28;;20479:41;;;;20529:140;;20658:4;20650:6;20646:17;20635:28;;20628:41;;;;20678:202;;20832:6;20827:3;20820:19;20869:4;20864:3;20860:14;20845:29;;20813:67;;;;;20889:196;;21037:6;21032:3;21025:19;21074:4;21069:3;21065:14;21050:29;;21018:67;;;;;21094:152;;21198:6;21193:3;21186:19;21235:4;21230:3;21226:14;21211:29;;21179:67;;;;;21254:105;;21323:31;21348:5;21323:31;;;21312:42;;21306:53;;;;21366:113;;21443:31;21468:5;21443:31;;;21432:42;;21426:53;;;;21486:92;;21566:5;21559:13;21552:21;21541:32;;21535:43;;;;21585:151;;21664:66;21657:5;21653:78;21642:89;;21636:100;;;;21743:132;;21836:1;21829:5;21826:12;21816:2;;21842:9;21816:2;21865:5;21854:16;;21810:65;;;;21882:139;;21982:1;21975:5;21972:12;21962:2;;21988:9;21962:2;22011:5;22000:16;;21956:65;;;;22028:136;;22125:1;22118:5;22115:12;22105:2;;22131:9;22105:2;22154:5;22143:16;;22099:65;;;;22171:120;;22251:34;22244:5;22240:46;22229:57;;22223:68;;;;22298:128;;22378:42;22371:5;22367:54;22356:65;;22350:76;;;;22433:79;;22502:5;22491:16;;22485:27;;;;22519:105;;22588:31;22613:5;22588:31;;;22577:42;;22571:53;;;;22631:92;;22711:5;22704:13;22697:21;22686:32;;22680:43;;;;22730:125;;22819:31;22844:5;22819:31;;;22808:42;;22802:53;;;;22862:120;;22942:34;22935:5;22931:46;22920:57;;22914:68;;;;22989:128;;23069:42;23062:5;23058:54;23047:65;;23041:76;;;;23124:79;;23193:5;23182:16;;23176:27;;;;23210:161;;23309:57;23360:5;23309:57;;;23296:70;;23290:81;;;;23378:135;;23477:31;23502:5;23477:31;;;23464:44;;23458:55;;;;23520:161;;23619:57;23670:5;23619:57;;;23606:70;;23600:81;;;;23688:135;;23787:31;23812:5;23787:31;;;23774:44;;23768:55;;;;23830:143;;23922:46;23962:5;23922:46;;;23909:59;;23903:70;;;;23980:157;;24079:53;24126:5;24079:53;;;24066:66;;24060:77;;;;24144:151;;24240:50;24284:5;24240:50;;;24227:63;;24221:74;;;;24303:268;24368:1;24375:101;24389:6;24386:1;24383:13;24375:101;;;24465:1;24460:3;24456:11;24450:18;24446:1;24441:3;24437:11;24430:39;24411:2;24408:1;24404:10;24399:15;;24375:101;;;24491:6;24488:1;24485:13;24482:2;;;24556:1;24547:6;24542:3;24538:16;24531:27;24482:2;24352:219;;;;;24579:97;;24667:2;24663:7;24658:2;24651:5;24647:14;24643:28;24633:38;;24627:49;;;

Swarm Source

bzzr://13febd37d3e0aebf89825e0fa2db31962f7ff39217fd49fe9165ed7d06a07db5

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.