ETH Price: $2,744.41 (+2.83%)

Token

CounterDAO (++)
 

Overview

Max Total Supply

0 ++

Holders

19

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
*esk🙂️🙃️.eth
Balance
1 ++
0x57e73D0d9224f89eb4eE8c5D44932523A8c4339e
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
DSSToken

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 12 : token.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

// token.sol -- I frobbed an inc and all I got was this lousy token

// Copyright (C) 2022 Horsefacts <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

pragma solidity ^0.8.15;

import {DSSLike} from "dss/dss.sol";
import {DSNote} from "ds-note/note.sol";
import {ERC721} from "solmate/tokens/ERC721.sol";
import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";

import {Render, DataURI} from "./render.sol";

interface SumLike {
    function incs(address)
        external
        view
        returns (uint256, uint256, uint256, uint256, uint256);
}

interface CTRLike {
    function balanceOf(address) external view returns (uint256);
    function push(address, uint256) external;
}

struct Inc {
    address guy;
    uint256 net;
    uint256 tab;
    uint256 tax;
    uint256 num;
    uint256 hop;
}

contract DSSToken is ERC721, DSNote {
    using FixedPointMathLib for uint256;
    using DataURI for string;

    error WrongPayment(uint256 sent, uint256 cost);
    error Forbidden();
    error PullFailed();

    uint256 constant WAD        = 1    ether;
    uint256 constant BASE_PRICE = 0.01 ether;
    uint256 constant INCREASE   = 1.1  ether;

    DSSLike public immutable dss;   // DSS module
    DSSLike public immutable coins; // Token ID counter
    DSSLike public immutable price; // Token price counter
    CTRLike public immutable ctr;   // CTR token

    address public owner;

    modifier auth() {
        if (msg.sender != owner) revert Forbidden();
        _;
    }

    modifier owns(uint256 tokenId) {
        if (msg.sender != ownerOf(tokenId)) revert Forbidden();
        _;
    }

    modifier exists(uint256 tokenId) {
        ownerOf(tokenId);
        _;
    }

    constructor(address _dss, address _ctr) ERC721("CounterDAO", "++") {
        owner = msg.sender;

        dss = DSSLike(_dss);
        ctr = CTRLike(_ctr);

        // Build a counter to track token IDs.
        coins = DSSLike(dss.build("coins", address(0)));

        // Build a counter to track token price.
        price = DSSLike(dss.build("price", address(0)));

        // Authorize core dss modules.
        coins.bless();
        price.bless();

        // Initialize counters.
        coins.use();
        price.use();
    }

    /// @notice Mint a dss-token to caller. Must send ether equal to
    /// current `cost`. Distributes 100 CTR to caller if a sufficient
    /// balance is available in the contract.
    function mint() external payable note {
        uint256 _cost = cost();
        if (msg.value != _cost) {
            revert WrongPayment(msg.value, _cost);
        }

        // Increment token ID.
        coins.hit();
        uint256 id = coins.see();

        // Build and initialize a counter associated with this token.
        DSSLike _count = DSSLike(dss.build(bytes32(id), address(0)));
        _count.bless();
        _count.use();

        // Distribute 100 CTR to caller.
        _give(msg.sender, 100 * WAD);
        _safeMint(msg.sender, id);
    }

    /// @notice Increase `cost` by 10%. Distributes 10 CTR to caller
    /// if a sufficient balance is available in the contract.
    function hike() external note {
        if (price.see() < 100) {
            // Increment price counter.
            price.hit();
            _give(msg.sender, 10 * WAD);
        }
    }

    /// @notice Decrease `cost` by 10%. Distributes 10 CTR to caller
    /// if a sufficient balance is available in the contract.
    function drop() external note {
        if (price.see() > 0) {
            // Decrement price counter.
            price.dip();
            _give(msg.sender, 10 * WAD);
        }
    }

    /// @notice Get cost to `mint` a dss-token.
    /// @return Current `mint` price in wei.
    function cost() public view returns (uint256) {
        return cost(price.see());
    }

    /// @notice Get cost to `mint` a dss-token for a given value
    /// of the `price` counter.
    /// @param net Value of the `price` counter.
    /// @return `mint` price in wei.
    function cost(uint256 net) public pure returns (uint256) {
        // Calculate cost to mint based on price counter value.
        // Price increases by 10% for each counter increment, i.e.:
        //
        // cost = 0.01 ether * 1.01 ether ^ (counter value)

        return BASE_PRICE.mulWadUp(INCREASE.rpow(net, WAD));
    }

    /// @notice Increment a token's counter. Only token owner.
    /// @param tokenId dss-token ID.
    function hit(uint256 tokenId) external owns(tokenId) note {
        count(tokenId).hit();
    }

    /// @notice Decrement a token's counter. Only token owner.
    /// @param tokenId dss-token ID
    function dip(uint256 tokenId) external owns(tokenId) note {
        count(tokenId).dip();
    }

    /// @notice Withdraw ether balance from contract. Only contract owner.
    /// @param dst Destination address.
    function pull(address dst) external auth note {
        (bool ok,) = payable(dst).call{ value: address(this).balance }("");
        if (!ok) revert PullFailed();
    }

    /// @notice Change contract owner. Only contract owner.
    /// @param guy New contract owner.
    function swap(address guy) external auth note {
        owner = guy;
    }

    /// @notice Read a token's counter value.
    /// @param tokenId dss-token ID.
    function see(uint256 tokenId) external view returns (uint256) {
        return count(tokenId).see();
    }

    /// @notice Get the DSSProxy for a token's counter.
    /// @param tokenId dss-token ID.
    function count(uint256 tokenId) public view returns (DSSLike) {
        // dss.scry returns the deterministic address of a DSSProxy contract for
        // a given deployer, salt, and owner. Since we know these values, we
        // don't need to write the counter address to storage.
        return DSSLike(dss.scry(address(this), bytes32(tokenId), address(0)));
    }

    /// @notice Get the Inc for a DSSProxy address.
    /// @param guy DSSProxy address.
    function inc(address guy) public view returns (Inc memory) {
        // Get low level counter information from the Sum.
        SumLike sum = SumLike(dss.sum());
        (uint256 net, uint256 tab, uint256 tax, uint256 num, uint256 hop) =
            sum.incs(guy);
        return Inc(guy, net, tab, tax, num, hop);
    }

    /// @notice Get URI for a dss-token.
    /// @param tokenId dss-token ID.
    /// @return base64 encoded Data URI string.
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        exists(tokenId)
        returns (string memory)
    {
        return tokenJSON(tokenId).toDataURI("application/json");
    }

    /// @notice Get JSON metadata for a dss-token.
    /// @param tokenId dss-token ID.
    /// @return JSON metadata string.
    function tokenJSON(uint256 tokenId)
        public
        view
        exists(tokenId)
        returns (string memory)
    {
        Inc memory countInc = inc(address(count(tokenId)));
        return Render.json(tokenId, tokenSVG(tokenId).toDataURI("image/svg+xml"), countInc);
    }

    /// @notice Get SVG image for a dss-token.
    /// @param tokenId dss-token ID.
    /// @return SVG image string.
    function tokenSVG(uint256 tokenId)
        public
        view
        exists(tokenId)
        returns (string memory)
    {
        Inc memory countInc = inc(address(count(tokenId)));
        Inc memory priceInc = inc(address(price));
        return Render.image(tokenId, coins.see(), countInc, priceInc);
    }

    function _give(address dst, uint256 wad) internal {
        if (ctr.balanceOf(address(this)) >= wad) ctr.push(dst, wad);
    }
}

File 2 of 12 : dss.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

/// dss.sol -- Decentralized Summation System

// Copyright (C) 2022 Horsefacts <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

pragma solidity ^0.8.15;

import {DSSProxy} from "./proxy/proxy.sol";

interface DSSLike {
    function sum() external view returns(address);
    function use() external;
    function see() external view returns (uint256);
    function hit() external;
    function dip() external;
    function nil() external;
    function hope(address) external;
    function nope(address) external;
    function bless() external;
    function build(bytes32 wit, address god) external returns (address);
    function scry(address guy, bytes32 wit, address god) external view returns (address);
}

interface SumLike {
    function hope(address) external;
    function nope(address) external;
}

interface UseLike {
    function use() external;
}

interface SpyLike {
    function see() external view returns (uint256);
}

interface HitterLike {
    function hit() external;
}

interface DipperLike {
    function dip() external;
}

interface NilLike {
    function nil() external;
}

contract DSS {
    // --- Data ---
    address immutable public sum;
    address immutable public _use;
    address immutable public _spy;
    address immutable public _hitter;
    address immutable public _dipper;
    address immutable public _nil;

    // --- Init ---
    constructor(
        address sum_,
        address use_,
        address spy_,
        address hitter_,
        address dipper_,
        address nil_)
    {
        sum     = sum_;     // Core ICV engine
        _use    = use_;     // Creation module
        _spy    = spy_;     // Read module
        _hitter = hitter_;  // Increment module
        _dipper = dipper_;  // Decrement module
        _nil    = nil_;     // Reset module
    }

    // --- DSS Operations ---
    function use() external {
        UseLike(_use).use();
    }

    function see() external view returns (uint256) {
        return SpyLike(_spy).see();
    }

    function hit() external {
        HitterLike(_hitter).hit();
    }

    function dip() external {
        DipperLike(_dipper).dip();
    }

    function nil() external {
        NilLike(_nil).nil();
    }

    function hope(address usr) external {
        SumLike(sum).hope(usr);
    }

    function nope(address usr) external {
        SumLike(sum).nope(usr);
    }

    function bless() external {
        SumLike(sum).hope(_use);
        SumLike(sum).hope(_hitter);
        SumLike(sum).hope(_dipper);
        SumLike(sum).hope(_nil);
    }

    function build(bytes32 wit, address god) external returns (address proxy) {
        proxy = address(new DSSProxy{ salt: wit }(address(this), msg.sender, god));
    }

    function scry(address guy, bytes32 wit, address god) external view returns (address) {
        address me = address(this);
        return address(uint160(uint256(keccak256(
            abi.encodePacked(
                bytes1(0xff),
                me,
                wit,
                keccak256(
                    abi.encodePacked(
                        type(DSSProxy).creationCode,
                        abi.encode(me),
                        abi.encode(guy),
                        abi.encode(god)
                    )
                )
            )
        ))));
    }
}

File 3 of 12 : note.sol
/// note.sol -- the `note' modifier, for logging calls as events

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.4.23;

contract DSNote {
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  guy,
        bytes32  indexed  foo,
        bytes32  indexed  bar,
        uint256           wad,
        bytes             fax
    ) anonymous;

    modifier note {
        bytes32 foo;
        bytes32 bar;
        uint256 wad;

        assembly {
            foo := calldataload(4)
            bar := calldataload(36)
            wad := callvalue()
        }

        _;

        emit LogNote(msg.sig, msg.sender, foo, bar, wad, msg.data);
    }
}

File 4 of 12 : ERC721.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /*//////////////////////////////////////////////////////////////
                         METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                         ERC721 APPROVAL STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];

        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }
}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}

File 5 of 12 : FixedPointMathLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        assembly {
            // Start off with z at 1.
            z := 1

            // Used below to help find a nearby power of 2.
            let y := x

            // Find the lowest power of 2 that is at least sqrt(x).
            if iszero(lt(y, 0x100000000000000000000000000000000)) {
                y := shr(128, y) // Like dividing by 2 ** 128.
                z := shl(64, z) // Like multiplying by 2 ** 64.
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z) // Like multiplying by 2 ** 32.
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z) // Like multiplying by 2 ** 16.
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z) // Like multiplying by 2 ** 8.
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z) // Like multiplying by 2 ** 4.
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z) // Like multiplying by 2 ** 2.
            }
            if iszero(lt(y, 0x8)) {
                // Equivalent to 2 ** z.
                z := shl(1, z)
            }

            // Shifting right by 1 is like dividing by 2.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // Compute a rounded down version of z.
            let zRoundDown := div(x, z)

            // If zRoundDown is smaller, use it.
            if lt(zRoundDown, z) {
                z := zRoundDown
            }
        }
    }
}

File 6 of 12 : render.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

// render.sol -- DSSToken render module

// Copyright (C) 2022 Horsefacts <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
pragma solidity ^0.8.15;

import {svg} from "hot-chain-svg/SVG.sol";
import {utils} from "hot-chain-svg/Utils.sol";
import {Base64} from "openzeppelin-contracts/contracts/utils/Base64.sol";
import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol";

import {Inc} from "./token.sol";

library DataURI {
    function toDataURI(string memory data, string memory mimeType)
        internal
        pure
        returns (string memory)
    {
        return string.concat(
            "data:", mimeType, ";base64,", Base64.encode(abi.encodePacked(data))
        );
    }
}

library Render {
    function json(uint256 _tokenId, string memory _svg, Inc memory _count)
        internal
        pure
        returns (string memory)
    {
        return string.concat(
            '{"name": "CounterDAO',
            " #",
            utils.uint2str(_tokenId),
            '", "description": "I frobbed an inc and all I got was this lousy dss-token", "image": "',
            _svg,
            '", "attributes": ',
            attributes(_count),
            '}'
        );
    }

    function attributes(Inc memory inc) internal pure returns (string memory) {
        return string.concat(
            "[",
            attribute("net", inc.net),
            ",",
            attribute("tab", inc.tab),
            ",",
            attribute("tax", inc.tax),
            ",",
            attribute("num", inc.num),
            ",",
            attribute("hop", inc.hop),
            "]"
        );
    }

    function attribute(string memory name, uint256 value)
        internal
        pure
        returns (string memory)
    {
        return string.concat(
            '{"trait_type": "',
            name,
            '", "value": "',
            utils.uint2str(value),
            '", "display_type": "number"}'
        );
    }

    function image(
        uint256 _tokenId,
        uint256 _supply,
        Inc memory _count,
        Inc memory _price
    )
        internal
        pure
        returns (string memory)
    {
        return string.concat(
            '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" style="background:#7CC3B3;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;">',
            svg.el(
                "path",
                string.concat(
                    svg.prop("id", "top"),
                    svg.prop(
                        "d",
                        "M 10 10 H 280 a10,10 0 0 1 10,10 V 280 a10,10 0 0 1 -10,10 H 20 a10,10 0 0 1 -10,-10 V 10 z"
                    ),
                    svg.prop("fill", "#7CC3B3")
                ),
                ""
            ),
            svg.el(
                "path",
                string.concat(
                    svg.prop("id", "bottom"),
                    svg.prop(
                        "d",
                        "M 290 290 H 20 a10,10 0 0 1 -10,-10 V 20 a10,10 0 0 1 10,-10 H 280 a10,10 0 0 1 10,10 V 290 z"
                    ),
                    svg.prop("fill", "#7CC3B3")
                ),
                ""
            ),
            svg.text(
                string.concat(
                    svg.prop("dominant-baseline", "middle"),
                    svg.prop("font-family", "Menlo, monospace"),
                    svg.prop("font-size", "9"),
                    svg.prop("fill", "white")
                ),
                string.concat(
                    svg.el(
                        "textPath",
                        string.concat(svg.prop("href", "#top")),
                        string.concat(
                            formatInc(_count),
                            svg.el(
                                "animate",
                                string.concat(
                                    svg.prop("attributeName", "startOffset"),
                                    svg.prop("from", "0%"),
                                    svg.prop("to", "100%"),
                                    svg.prop("dur", "120s"),
                                    svg.prop("begin", "0s"),
                                    svg.prop("repeatCount", "indefinite")
                                ),
                                ""
                            )
                        )
                    )
                )
            ),
            svg.text(
                string.concat(
                    svg.prop("x", "50%"),
                    svg.prop("y", "45%"),
                    svg.prop("text-anchor", "middle"),
                    svg.prop("dominant-baseline", "middle"),
                    svg.prop("font-size", "150"),
                    svg.prop("font-weight", "bold"),
                    svg.prop("fill", "white")
                ),
                string.concat(svg.cdata("++"))
            ),
            svg.text(
                string.concat(
                    svg.prop("x", "50%"),
                    svg.prop("y", "70%"),
                    svg.prop("text-anchor", "middle"),
                    svg.prop("font-size", "20"),
                    svg.prop("fill", "white")
                ),
                string.concat(utils.uint2str(_tokenId), " / ", utils.uint2str(_supply))
            ),
            svg.text(
                string.concat(
                    svg.prop("x", "50%"),
                    svg.prop("y", "80%"),
                    svg.prop("text-anchor", "middle"),
                    svg.prop("font-size", "20"),
                    svg.prop("fill", "white")
                ),
                utils.uint2str(_count.net)
            ),
            svg.text(
                string.concat(
                    svg.prop("dominant-baseline", "middle"),
                    svg.prop("font-family", "Menlo, monospace"),
                    svg.prop("font-size", "9"),
                    svg.prop("fill", "white")
                ),
                string.concat(
                    svg.el(
                        "textPath",
                        string.concat(svg.prop("href", "#bottom")),
                        string.concat(
                            formatInc(_price),
                            svg.el(
                                "animate",
                                string.concat(
                                    svg.prop("attributeName", "startOffset"),
                                    svg.prop("from", "0%"),
                                    svg.prop("to", "100%"),
                                    svg.prop("dur", "120s"),
                                    svg.prop("begin", "0s"),
                                    svg.prop("repeatCount", "indefinite")
                                ),
                                ""
                            )
                        )
                    )
                )
            ),
            "</svg>"
        );
    }

    function formatInc(Inc memory inc) internal pure returns (string memory) {
        return svg.cdata(
            string.concat(
                "Inc ",
                Strings.toHexString(uint160(inc.guy), 20),
                " | net: ",
                utils.uint2str(inc.net),
                " | tab: ",
                utils.uint2str(inc.tab),
                " | tax: ",
                utils.uint2str(inc.tax),
                " | num: ",
                utils.uint2str(inc.num),
                " | hop: ",
                utils.uint2str(inc.hop)
            )
        );
    }
}

File 7 of 12 : proxy.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

/// proxy.sol -- Execute DSS actions through the proxy's identity

// Copyright (C) 2022 Horsefacts <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

pragma solidity ^0.8.15;

import {DSAuth} from "ds-auth/auth.sol";
import {DSNote} from "ds-note/note.sol";

contract DSSProxy is DSAuth, DSNote {
    // --- Data ---
    address public dss;

    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external auth note { wards[usr] = 1; }
    function deny(address usr) external auth note { wards[usr] = 0; }
    modifier ward {
        require(wards[msg.sender] == 1, "DSSProxy/not-authorized");
        require(msg.sender != owner, "DSSProxy/owner-not-ward");
        _;
    }

    // --- Init ---
    constructor(address dss_, address usr, address god) {
        dss = dss_;
        wards[usr] = 1;
        setOwner(god);
    }

    // --- Upgrade ---
    function upgrade(address dss_) external auth note {
        dss = dss_;
    }

    // --- Proxy ---
    fallback() external ward note {
        address _dss = dss;
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), _dss, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }
}

File 8 of 12 : SVG.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import './Utils.sol';

// Core SVG utilitiy library which helps us construct
// onchain SVG's with a simple, web-like API.
library svg {
    /* MAIN ELEMENTS */
    function g(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('g', _props, _children);
    }

    function path(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('path', _props, _children);
    }

    function text(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('text', _props, _children);
    }

    function line(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('line', _props, _children);
    }

    function circle(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('circle', _props, _children);
    }

    function circle(string memory _props)
        internal
        pure
        returns (string memory)
    {
        return el('circle', _props);
    }

    function rect(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('rect', _props, _children);
    }

    function rect(string memory _props)
        internal
        pure
        returns (string memory)
    {
        return el('rect', _props);
    }

    function filter(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('filter', _props, _children);
    }

    function cdata(string memory _content)
        internal
        pure
        returns (string memory)
    {
        return string.concat('<![CDATA[', _content, ']]>');
    }

    /* GRADIENTS */
    function radialGradient(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('radialGradient', _props, _children);
    }

    function linearGradient(string memory _props, string memory _children)
        internal
        pure
        returns (string memory)
    {
        return el('linearGradient', _props, _children);
    }

    function gradientStop(
        uint256 offset,
        string memory stopColor,
        string memory _props
    ) internal pure returns (string memory) {
        return
            el(
                'stop',
                string.concat(
                    prop('stop-color', stopColor),
                    ' ',
                    prop('offset', string.concat(utils.uint2str(offset), '%')),
                    ' ',
                    _props
                )
            );
    }

    function animateTransform(string memory _props)
        internal
        pure
        returns (string memory)
    {
        return el('animateTransform', _props);
    }

    function image(string memory _href, string memory _props)
        internal
        pure
        returns (string memory)
    {
        return
            el(
                'image',
                string.concat(prop('href', _href), ' ', _props)
            );
    }

    /* COMMON */
    // A generic element, can be used to construct any SVG (or HTML) element
    function el(
        string memory _tag,
        string memory _props,
        string memory _children
    ) internal pure returns (string memory) {
        return
            string.concat(
                '<',
                _tag,
                ' ',
                _props,
                '>',
                _children,
                '</',
                _tag,
                '>'
            );
    }

    // A generic element, can be used to construct any SVG (or HTML) element without children
    function el(
        string memory _tag,
        string memory _props
    ) internal pure returns (string memory) {
        return
            string.concat(
                '<',
                _tag,
                ' ',
                _props,
                '/>'
            );
    }

    // an SVG attribute
    function prop(string memory _key, string memory _val)
        internal
        pure
        returns (string memory)
    {
        return string.concat(_key, '=', '"', _val, '" ');
    }
}

File 9 of 12 : Utils.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

// Core utils used extensively to format CSS and numbers.
library utils {
    // used to simulate empty strings
    string internal constant NULL = '';

    // formats a CSS variable line. includes a semicolon for formatting.
    function setCssVar(string memory _key, string memory _val)
        internal
        pure
        returns (string memory)
    {
        return string.concat('--', _key, ':', _val, ';');
    }

    // formats getting a css variable
    function getCssVar(string memory _key)
        internal
        pure
        returns (string memory)
    {
        return string.concat('var(--', _key, ')');
    }

    // formats getting a def URL
    function getDefURL(string memory _id)
        internal
        pure
        returns (string memory)
    {
        return string.concat('url(#', _id, ')');
    }

    // formats rgba white with a specified opacity / alpha
    function white_a(uint256 _a) internal pure returns (string memory) {
        return rgba(255, 255, 255, _a);
    }

    // formats rgba black with a specified opacity / alpha
    function black_a(uint256 _a) internal pure returns (string memory) {
        return rgba(0, 0, 0, _a);
    }

    // formats generic rgba color in css
    function rgba(
        uint256 _r,
        uint256 _g,
        uint256 _b,
        uint256 _a
    ) internal pure returns (string memory) {
        string memory formattedA = _a < 100
            ? string.concat('0.', utils.uint2str(_a))
            : '1';
        return
            string.concat(
                'rgba(',
                utils.uint2str(_r),
                ',',
                utils.uint2str(_g),
                ',',
                utils.uint2str(_b),
                ',',
                formattedA,
                ')'
            );
    }

    // checks if two strings are equal
    function stringsEqual(string memory _a, string memory _b)
        internal
        pure
        returns (bool)
    {
        return
            keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b));
    }

    // returns the length of a string in characters
    function utfStringLength(string memory _str)
        internal
        pure
        returns (uint256 length)
    {
        uint256 i = 0;
        bytes memory string_rep = bytes(_str);

        while (i < string_rep.length) {
            if (string_rep[i] >> 7 == 0) i += 1;
            else if (string_rep[i] >> 5 == bytes1(uint8(0x6))) i += 2;
            else if (string_rep[i] >> 4 == bytes1(uint8(0xE))) i += 3;
            else if (string_rep[i] >> 3 == bytes1(uint8(0x1E)))
                i += 4;
                //For safety
            else i += 1;

            length++;
        }
    }

    // converts an unsigned integer to a string
    function uint2str(uint256 _i)
        internal
        pure
        returns (string memory _uintAsString)
    {
        if (_i == 0) {
            return '0';
        }
        uint256 j = _i;
        uint256 len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint256 k = len;
        while (_i != 0) {
            k = k - 1;
            uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }
}

File 10 of 12 : Base64.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

File 11 of 12 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 12 of 12 : auth.sol
// SPDX-License-Identifier: GNU-3
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.4.23;

interface DSAuthority {
    function canCall(
        address src, address dst, bytes4 sig
    ) external 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), "ds-auth-unauthorized");
        _;
    }

    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(address(0))) {
            return false;
        } else {
            return authority.canCall(src, address(this), sig);
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/=lib/hot-chain-svg/node_modules/@openzeppelin/contracts/",
    "ds-auth/=lib/dss/lib/ds-auth/src/",
    "ds-chief/=lib/dss/lib/ds-chief/src/",
    "ds-math/=lib/dss/lib/ds-token/lib/ds-math/src/",
    "ds-note/=lib/ds-note/src/",
    "ds-pause/=lib/dss/lib/ds-pause/src/",
    "ds-roles/=lib/dss/lib/ds-chief/lib/ds-roles/src/",
    "ds-test/=lib/dss/lib/ds-test/src/",
    "ds-thing/=lib/dss/lib/ds-chief/lib/ds-thing/src/",
    "ds-token/=lib/dss/lib/ds-token/src/",
    "dss/=lib/dss/src/",
    "forge-std/=lib/forge-std/src/",
    "hot-chain-svg/=lib/hot-chain-svg/contracts/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "script/=script/",
    "solmate/=lib/solmate/src/",
    "src/=src/",
    "test/=test/",
    "src/=src/",
    "test/=test/",
    "script/=script/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_dss","type":"address"},{"internalType":"address","name":"_ctr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[],"name":"PullFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"sent","type":"uint256"},{"internalType":"uint256","name":"cost","type":"uint256"}],"name":"WrongPayment","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":true,"internalType":"bytes32","name":"foo","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"bar","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coins","outputs":[{"internalType":"contract DSSLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"net","type":"uint256"}],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"count","outputs":[{"internalType":"contract DSSLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ctr","outputs":[{"internalType":"contract CTRLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"dip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dss","outputs":[{"internalType":"contract DSSLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hike","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"hit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"inc","outputs":[{"components":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"net","type":"uint256"},{"internalType":"uint256","name":"tab","type":"uint256"},{"internalType":"uint256","name":"tax","type":"uint256"},{"internalType":"uint256","name":"num","type":"uint256"},{"internalType":"uint256","name":"hop","type":"uint256"}],"internalType":"struct Inc","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"contract DSSLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"}],"name":"pull","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"see","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenJSON","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenSVG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101006040523480156200001257600080fd5b506040516200460e3803806200460e83398101604081905262000035916200034e565b6040518060400160405280600a815260200169436f756e74657244414f60b01b815250604051806040016040528060028152602001612b2b60f01b81525081600090816200008491906200042b565b5060016200009382826200042b565b5050600680546001600160a01b03191633179055506001600160a01b03828116608081905290821660e052604051635bf030a760e01b815264636f696e7360d81b600482015260006024820152635bf030a7906044016020604051808303816000875af115801562000109573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012f9190620004f7565b6001600160a01b0390811660a052608051604051635bf030a760e01b815264707269636560d81b600482015260006024820152911690635bf030a7906044016020604051808303816000875af11580156200018e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b49190620004f7565b6001600160a01b031660c0816001600160a01b03168152505060a0516001600160a01b031663401c8a536040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200020b57600080fd5b505af115801562000220573d6000803e3d6000fd5b5050505060c0516001600160a01b031663401c8a536040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200026257600080fd5b505af115801562000277573d6000803e3d6000fd5b5050505060a0516001600160a01b0316634c97d71a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620002b957600080fd5b505af1158015620002ce573d6000803e3d6000fd5b5050505060c0516001600160a01b0316634c97d71a6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200031057600080fd5b505af115801562000325573d6000803e3d6000fd5b5050505050506200051c565b80516001600160a01b03811681146200034957600080fd5b919050565b600080604083850312156200036257600080fd5b6200036d8362000331565b91506200037d6020840162000331565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620003b157607f821691505b602082108103620003d257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200042657600081815260208120601f850160051c81016020861015620004015750805b601f850160051c820191505b8181101562000422578281556001016200040d565b5050505b505050565b81516001600160401b0381111562000447576200044762000386565b6200045f816200045884546200039c565b84620003d8565b602080601f8311600181146200049757600084156200047e5750858301515b600019600386901b1c1916600185901b17855562000422565b600085815260208120601f198616915b82811015620004c857888601518255948401946001909101908401620004a7565b5085821015620004e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200050a57600080fd5b620005158262000331565b9392505050565b60805160a05160c05160e051614056620005b860003960008181610415015281816119f20152611a900152600081816104de01528181610be501528181610c8001528181610d080152818161135c015281816118fa01526119820152600081816103210152818161093c015281816109b1015261138801526000818161069201528181610a5301528181610fb501526115d801526140566000f3fe6080604052600436106101e35760003560e01c80638da5cb5b11610102578063c87b56dd11610095578063ea7a7aba11610064578063ea7a7aba1461062b578063ebf6e91d1461064b578063f751cd8f1461066b578063fa290fad1461068057600080fd5b8063c87b56dd14610540578063d7bb055914610560578063e31006ab146105d0578063e985e9c5146105f057600080fd5b80639bac5f7a116100d15780639bac5f7a146104ac578063a035b1fe146104cc578063a22cb46514610500578063b88d4fde1461052057600080fd5b80638da5cb5b146104375780638f7bb179146104575780639097548d1461047757806395d89b411461049757600080fd5b806322fcefbe1161017a57806352d112381161014957806352d11238146103a35780636352211e146103c357806370a08231146103e357806387e9e77f1461040357600080fd5b806322fcefbe1461030f57806323b872dd146103435780633b3546c81461036357806342842e0e1461038357600080fd5b8063095ea7b3116101b6578063095ea7b3146102af5780631249c58b146102cf57806313faede6146102d75780632027962f146102fa57600080fd5b806301ffc9a7146101e857806303438dd01461021d57806306fdde031461023f578063081812fc14610261575b600080fd5b3480156101f457600080fd5b506102086102033660046131a8565b6106b4565b60405190151581526020015b60405180910390f35b34801561022957600080fd5b5061023d6102383660046131da565b610706565b005b34801561024b57600080fd5b50610254610789565b6040516102149190613227565b34801561026d57600080fd5b5061029761027c36600461325a565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610214565b3480156102bb57600080fd5b5061023d6102ca366004613273565b610817565b61023d6108fe565b3480156102e357600080fd5b506102ec610bde565b604051908152602001610214565b34801561030657600080fd5b5061023d610c6a565b34801561031b57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b34801561034f57600080fd5b5061023d61035e36600461329f565b610dc8565b34801561036f57600080fd5b5061029761037e36600461325a565b610f8f565b34801561038f57600080fd5b5061023d61039e36600461329f565b611028565b3480156103af57600080fd5b5061023d6103be3660046131da565b6110fd565b3480156103cf57600080fd5b506102976103de36600461325a565b6111da565b3480156103ef57600080fd5b506102ec6103fe3660046131da565b611231565b34801561040f57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b34801561044357600080fd5b50600654610297906001600160a01b031681565b34801561046357600080fd5b5061025461047236600461325a565b611294565b34801561048357600080fd5b506102ec61049236600461325a565b6112fd565b3480156104a357600080fd5b5061025461132b565b3480156104b857600080fd5b506102546104c736600461325a565b611338565b3480156104d857600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b34801561050c57600080fd5b5061023d61051b3660046132e0565b611418565b34801561052c57600080fd5b5061023d61053b36600461331e565b611484565b34801561054c57600080fd5b5061025461055b36600461325a565b611549565b34801561056c57600080fd5b5061058061057b3660046131da565b611592565b604051610214919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201519181019190915260c00190565b3480156105dc57600080fd5b5061023d6105eb36600461325a565b611711565b3480156105fc57600080fd5b5061020861060b3660046133bd565b600560209081526000928352604080842090915290825290205460ff1681565b34801561063757600080fd5b506102ec61064636600461325a565b6117f3565b34801561065757600080fd5b5061023d61066636600461325a565b61185f565b34801561067757600080fd5b5061023d6118e4565b34801561068c57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b60006301ffc9a760e01b6001600160e01b0319831614806106e557506380ac58cd60e01b6001600160e01b03198316145b806107005750635b5e139f60e01b6001600160e01b03198316145b92915050565b6006546001600160a01b0316331461073157604051631dd2188d60e31b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b03831617905560405160043590602435903490829084903390600080356001600160e01b0319169161077b9187913690613414565b60405180910390a450505050565b600080546107969061342e565b80601f01602080910402602001604051908101604052809291908181526020018280546107c29061342e565b801561080f5780601f106107e45761010080835404028352916020019161080f565b820191906000526020600020905b8154815290600101906020018083116107f257829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b03163381148061086057506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6108a25760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60043560243534600061090f610bde565b905080341461093a57604051630374cb4760e21b815234600482015260248101829052604401610899565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632ae3594a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561099557600080fd5b505af11580156109a9573d6000803e3d6000fd5b5050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a319190613462565b604051635bf030a760e01b8152600481018290526000602482018190529192507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635bf030a7906044016020604051808303816000875af1158015610aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac8919061347b565b9050806001600160a01b031663401c8a536040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b0557600080fd5b505af1158015610b19573d6000803e3d6000fd5b50505050806001600160a01b0316634c97d71a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b5857600080fd5b505af1158015610b6c573d6000803e3d6000fd5b50505050610b8e33670de0b6b3a76400006064610b8991906134ae565b6119db565b610b983383611af1565b5050508183336001600160a01b03166000356001600160e01b0319166001600160e01b03191684600036604051610bd193929190613414565b60405180910390a4505050565b6000610c657f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c41573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104929190613462565b905090565b60008060006004359250602435915034905060647f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d009190613462565b1015610d92577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632ae3594a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d6157600080fd5b505af1158015610d75573d6000803e3d6000fd5b50505050610d9233670de0b6b3a7640000600a610b8991906134ae565b8183336001600160a01b03166000356001600160e01b0319166001600160e01b03191684600036604051610bd193929190613414565b6000818152600260205260409020546001600160a01b03848116911614610e1e5760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610899565b6001600160a01b038216610e685760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610899565b336001600160a01b0384161480610ea257506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b80610ec357506000818152600460205260409020546001600160a01b031633145b610f005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610899565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516332ce302f60e01b815230600482015260248101829052600060448201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906332ce302f90606401602060405180830381865afa158015611004573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610700919061347b565b611033838383610dc8565b6001600160a01b0382163b15806110dc5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156110ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d091906134cd565b6001600160e01b031916145b6110f85760405162461bcd60e51b8152600401610899906134ea565b505050565b6006546001600160a01b0316331461112857604051631dd2188d60e31b815260040160405180910390fd5b604051600435906024359034906000906001600160a01b0386169047908381818185875af1925050503d806000811461117d576040519150601f19603f3d011682016040523d82523d6000602084013e611182565b606091505b50509050806111a357604051627e40ef60e21b815260040160405180910390fd5b508183336001600160a01b03166000356001600160e01b0319166001600160e01b0319168460003660405161077b93929190613414565b6000818152600260205260409020546001600160a01b03168061122c5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606401610899565b919050565b60006001600160a01b0382166112785760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610899565b506001600160a01b031660009081526003602052604090205490565b6060816112a0816111da565b5060006112af61057b85610f8f565b90506112f3846112ed6040518060400160405280600d81526020016c1a5b5859d94bdcdd99cade1b5b609a1b8152506112e788611338565b90611bbd565b83611c10565b9250505b50919050565b600061070061131d670f43fc2c04ee000084670de0b6b3a7640000611c4f565b662386f26fc1000090611d0d565b600180546107969061342e565b606081611344816111da565b50600061135361057b85610f8f565b905060006113807f0000000000000000000000000000000000000000000000000000000000000000611592565b905061140f857f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114089190613462565b8484611d22565b95945050505050565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61148f858585610dc8565b6001600160a01b0384163b15806115265750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906114d79033908a90899089908990600401613514565b6020604051808303816000875af11580156114f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151a91906134cd565b6001600160e01b031916145b6115425760405162461bcd60e51b8152600401610899906134ea565b5050505050565b606081611555816111da565b5061158b6040518060400160405280601081526020016f30b8383634b1b0ba34b7b717b539b7b760811b8152506112e785611294565b9392505050565b6115d46040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663853255cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611634573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611658919061347b565b604051637bc1152d60e01b81526001600160a01b0385811660048301529192506000918291829182918291871690637bc1152d9060240160a060405180830381865afa1580156116ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d09190613553565b6040805160c0810182526001600160a01b03909e168e5260208e0195909552938c019290925260608b015260808a015260a089015250959695505050505050565b8061171b816111da565b6001600160a01b0316336001600160a01b03161461174c57604051631dd2188d60e31b815260040160405180910390fd5b6004356024353461175c85610f8f565b6001600160a01b03166328d36a836040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561179657600080fd5b505af11580156117aa573d6000803e3d6000fd5b505050508183336001600160a01b03166000356001600160e01b0319166001600160e01b031916846000366040516117e493929190613414565b60405180910390a45050505050565b60006117fe82610f8f565b6001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561183b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107009190613462565b80611869816111da565b6001600160a01b0316336001600160a01b03161461189a57604051631dd2188d60e31b815260040160405180910390fd5b600435602435346118aa85610f8f565b6001600160a01b0316632ae3594a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561179657600080fd5b60008060006004359250602435915034905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197a9190613462565b1115610d92577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166328d36a836040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d6157600080fd5b6040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a659190613462565b10611aed57604051632dd4ea6360e21b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063b753a98c90604401600060405180830381600087803b158015611ad457600080fd5b505af1158015611ae8573d6000803e3d6000fd5b505050505b5050565b611afb8282612a34565b6001600160a01b0382163b1580611ba15750604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015611b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9591906134cd565b6001600160e01b031916145b611aed5760405162461bcd60e51b8152600401610899906134ea565b606081611be884604051602001611bd491906135af565b604051602081830303815290604052612b3f565b604051602001611bf99291906135cb565b604051602081830303815290604052905092915050565b6060611c1b84612c92565b83611c2584612dbe565b604051602001611c379392919061361f565b60405160208183030381529060405290509392505050565b6000838015611cef57600184168015611c6a57859250611c6e565b8392505b508260011c8460011c94505b8415611ce9578560801c15611c8e57600080fd5b85860281810181811015611ca157600080fd5b8590049650506001851615611cde578583028387820414611cc7578615611cc757600080fd5b81810181811015611cd757600080fd5b8590049350505b8460011c9450611c7a565b50611d05565b838015611cff5760009250611d03565b8392505b505b509392505050565b600061158b8383670de0b6b3a7640000612eb7565b6060611e33604051806040016040528060048152602001630e0c2e8d60e31b815250611d83604051806040016040528060028152602001611a5960f21b815250604051806040016040528060038152602001620746f760ec1b815250612ee5565b611dbe604051806040016040528060018152602001601960fa1b8152506040518060800160405280605b8152602001613f29605b9139612ee5565b611e0360405180604001604052806004815260200163199a5b1b60e21b815250604051806040016040528060078152602001662337434333423360c81b815250612ee5565b604051602001611e1593929190613730565b60408051601f19818403018152602083019091526000825290612efa565b611ed0604051806040016040528060048152602001630e0c2e8d60e31b815250611e95604051806040016040528060028152602001611a5960f21b81525060405180604001604052806006815260200165626f74746f6d60d01b815250612ee5565b611dbe604051806040016040528060018152602001601960fa1b8152506040518060800160405280605d8152602001613fc4605d9139612ee5565b6122d4611f2460405180604001604052806011815260200170646f6d696e616e742d626173656c696e6560781b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b611f796040518060400160405280600b81526020016a666f6e742d66616d696c7960a81b8152506040518060400160405280601081526020016f4d656e6c6f2c206d6f6e6f737061636560801b815250612ee5565b611fbd60405180604001604052806009815260200168666f6e742d73697a6560b81b815250604051806040016040528060018152602001603960f81b815250612ee5565b61200060405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b6040516020016120139493929190613773565b6040516020818303038152906040526122b0604051806040016040528060088152602001670e8caf0e8a0c2e8d60c31b81525061208860405180604001604052806004815260200163343932b360e11b81525060405180604001604052806004815260200163023746f760e41b815250612ee5565b60405160200161209891906135af565b6040516020818303038152906040526120b08a612f13565b61228b60405180604001604052806007815260200166616e696d61746560c81b8152506121256040518060400160405280600d81526020016c6174747269627574654e616d6560981b8152506040518060400160405280600b81526020016a1cdd185c9d13d9999cd95d60aa1b815250612ee5565b6121656040518060400160405280600481526020016366726f6d60e01b81525060405180604001604052806002815260200161302560f01b815250612ee5565b6121a560405180604001604052806002815260200161746f60f01b815250604051806040016040528060048152602001633130302560e01b815250612ee5565b6121e660405180604001604052806003815260200162323ab960e91b815250604051806040016040528060048152602001633132307360e01b815250612ee5565b612227604051806040016040528060058152602001643132b3b4b760d91b81525060405180604001604052806002815260200161307360f01b815250612ee5565b6122766040518060400160405280600b81526020016a1c995c19585d10dbdd5b9d60aa1b8152506040518060400160405280600a815260200169696e646566696e69746560b01b815250612ee5565b604051602001611e15969594939291906137ca565b60405160200161229c929190613849565b604051602081830303815290604052612efa565b6040516020016122c091906135af565b604051602081830303815290604052612f9a565b612503612315604051806040016040528060018152602001600f60fb1b8152506040518060400160405280600381526020016235302560e81b815250612ee5565b612353604051806040016040528060018152602001607960f81b8152506040518060400160405280600381526020016234352560e81b815250612ee5565b61239e6040518060400160405280600b81526020016a3a32bc3a16b0b731b437b960a91b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b6123ef60405180604001604052806011815260200170646f6d696e616e742d626173656c696e6560781b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b61243560405180604001604052806009815260200168666f6e742d73697a6560b81b8152506040518060400160405280600381526020016203135360ec1b815250612ee5565b61247e6040518060400160405280600b81526020016a199bdb9d0b5dd95a59da1d60aa1b81525060405180604001604052806004815260200163189bdb1960e21b815250612ee5565b6124c160405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b6040516020016124d79796959493929190613878565b60408051601f1981840301815282820190915260028252612b2b60f01b6020830152906122b090612fc3565b61269b612544604051806040016040528060018152602001600f60fb1b8152506040518060400160405280600381526020016235302560e81b815250612ee5565b612582604051806040016040528060018152602001607960f81b8152506040518060400160405280600381526020016237302560e81b815250612ee5565b6125cd6040518060400160405280600b81526020016a3a32bc3a16b0b731b437b960a91b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b61261260405180604001604052806009815260200168666f6e742d73697a6560b81b81525060405180604001604052806002815260200161032360f41b815250612ee5565b61265560405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b60405160200161266995949392919061390a565b6040516020818303038152906040526126818b612c92565b61268a8b612c92565b6040516020016122c0929190613975565b6128226126dc604051806040016040528060018152602001600f60fb1b8152506040518060400160405280600381526020016235302560e81b815250612ee5565b61271a604051806040016040528060018152602001607960f81b8152506040518060400160405280600381526020016238302560e81b815250612ee5565b6127656040518060400160405280600b81526020016a3a32bc3a16b0b731b437b960a91b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b6127aa60405180604001604052806009815260200168666f6e742d73697a6560b81b81525060405180604001604052806002815260200161032360f41b815250612ee5565b6127ed60405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b60405160200161280195949392919061390a565b60405160208183030381529060405261281d8a60200151612c92565b612f9a565b612a0561287660405180604001604052806011815260200170646f6d696e616e742d626173656c696e6560781b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b6128cb6040518060400160405280600b81526020016a666f6e742d66616d696c7960a81b8152506040518060400160405280601081526020016f4d656e6c6f2c206d6f6e6f737061636560801b815250612ee5565b61290f60405180604001604052806009815260200168666f6e742d73697a6560b81b815250604051806040016040528060018152602001603960f81b815250612ee5565b61295260405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b6040516020016129659493929190613773565b6040516020818303038152906040526122b0604051806040016040528060088152602001670e8caf0e8a0c2e8d60c31b8152506129dd60405180604001604052806004815260200163343932b360e11b8152506040518060400160405280600781526020016623626f74746f6d60c81b815250612ee5565b6040516020016129ed91906135af565b6040516020818303038152906040526120b08d612f13565b604051602001612a1b97969594939291906139b3565b6040516020818303038152906040529050949350505050565b6001600160a01b038216612a7e5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610899565b6000818152600260205260409020546001600160a01b031615612ad45760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610899565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608151600003612b5e57505060408051602081019091526000815290565b6000604051806060016040528060408152602001613f846040913990506000600384516002612b8d9190613b02565b612b979190613b1a565b612ba29060046134ae565b67ffffffffffffffff811115612bba57612bba613b3c565b6040519080825280601f01601f191660200182016040528015612be4576020820181803683370190505b509050600182016020820185865187015b80821015612c50576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250612bf5565b5050600386510660018114612c6c5760028114612c7f57612c87565b603d6001830353603d6002830353612c87565b603d60018303535b509195945050505050565b606081600003612cb95750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612ce35780612ccd81613b52565b9150612cdc9050600a83613b1a565b9150612cbd565b60008167ffffffffffffffff811115612cfe57612cfe613b3c565b6040519080825280601f01601f191660200182016040528015612d28576020820181803683370190505b509050815b8515612db557612d3e600182613b6b565b90506000612d4d600a88613b1a565b612d5890600a6134ae565b612d629088613b6b565b612d6d906030613b82565b905060008160f81b905080848481518110612d8a57612d8a613ba7565b60200101906001600160f81b031916908160001a905350612dac600a89613b1a565b97505050612d2d565b50949350505050565b6060612de9604051806040016040528060038152602001621b995d60ea1b8152508360200151612fd6565b612e12604051806040016040528060038152602001623a30b160e91b8152508460400151612fd6565b612e3b604051806040016040528060038152602001620e8c2f60eb1b8152508560600151612fd6565b612e64604051806040016040528060038152602001626e756d60e81b8152508660800151612fd6565b612e8d604051806040016040528060038152602001620686f760ec1b8152508760a00151612fd6565b604051602001612ea1959493929190613bbd565b6040516020818303038152906040529050919050565b828202811515841585830485141716612ecf57600080fd5b6001826001830304018115150290509392505050565b60608282604051602001611bf9929190613c70565b606083838386604051602001611c379493929190613cc5565b6060610700612f3083600001516001600160a01b03166014612ff3565b612f3d8460200151612c92565b612f4a8560400151612c92565b612f578660600151612c92565b612f648760800151612c92565b612f718860a00151612c92565b604051602001612f8696959493929190613d5e565b604051602081830303815290604052612fc3565b606061158b604051806040016040528060048152602001631d195e1d60e21b8152508484612efa565b606081604051602001612ea19190613e44565b606082612fe283612c92565b604051602001611bf9929190613e82565b606060006130028360026134ae565b61300d906002613b02565b67ffffffffffffffff81111561302557613025613b3c565b6040519080825280601f01601f19166020018201604052801561304f576020820181803683370190505b509050600360fc1b8160008151811061306a5761306a613ba7565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061309957613099613ba7565b60200101906001600160f81b031916908160001a90535060006130bd8460026134ae565b6130c8906001613b02565b90505b6001811115613140576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106130fc576130fc613ba7565b1a60f81b82828151811061311257613112613ba7565b60200101906001600160f81b031916908160001a90535060049490941c9361313981613f11565b90506130cb565b50831561158b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610899565b6001600160e01b0319811681146131a557600080fd5b50565b6000602082840312156131ba57600080fd5b813561158b8161318f565b6001600160a01b03811681146131a557600080fd5b6000602082840312156131ec57600080fd5b813561158b816131c5565b60005b838110156132125781810151838201526020016131fa565b83811115613221576000848401525b50505050565b60208152600082518060208401526132468160408501602087016131f7565b601f01601f19169190910160400192915050565b60006020828403121561326c57600080fd5b5035919050565b6000806040838503121561328657600080fd5b8235613291816131c5565b946020939093013593505050565b6000806000606084860312156132b457600080fd5b83356132bf816131c5565b925060208401356132cf816131c5565b929592945050506040919091013590565b600080604083850312156132f357600080fd5b82356132fe816131c5565b91506020830135801515811461331357600080fd5b809150509250929050565b60008060008060006080868803121561333657600080fd5b8535613341816131c5565b94506020860135613351816131c5565b935060408601359250606086013567ffffffffffffffff8082111561337557600080fd5b818801915088601f83011261338957600080fd5b81358181111561339857600080fd5b8960208285010111156133aa57600080fd5b9699959850939650602001949392505050565b600080604083850312156133d057600080fd5b82356133db816131c5565b91506020830135613313816131c5565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061140f6040830184866133eb565b600181811c9082168061344257607f821691505b6020821081036112f757634e487b7160e01b600052602260045260246000fd5b60006020828403121561347457600080fd5b5051919050565b60006020828403121561348d57600080fd5b815161158b816131c5565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156134c8576134c8613498565b500290565b6000602082840312156134df57600080fd5b815161158b8161318f565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061354890830184866133eb565b979650505050505050565b600080600080600060a0868803121561356b57600080fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b600081516135a58185602086016131f7565b9290920192915050565b600082516135c18184602087016131f7565b9190910192915050565b643230ba309d60d91b8152600083516135eb8160058501602088016131f7565b670ed8985cd94d8d0b60c21b600591840191820152835161361381600d8401602088016131f7565b01600d01949350505050565b737b226e616d65223a2022436f756e74657244414f60601b815261202360f01b6014820152835160009061365a8160168501602089016131f7565b7f222c20226465736372697074696f6e223a2022492066726f6262656420616e206016918401918201527f696e6320616e6420616c6c204920676f74207761732074686973206c6f75737960368201527f206473732d746f6b656e222c2022696d616765223a2022000000000000000000605682015284516136e381606d8401602089016131f7565b7001116101130ba3a3934b13aba32b9911d1607d1b606d9290910191820152835161371581607e8401602088016131f7565b607d60f81b607e9290910191820152607f0195945050505050565b600084516137428184602089016131f7565b8451908301906137568183602089016131f7565b84519101906137698183602088016131f7565b0195945050505050565b60008551613785818460208a016131f7565b855190830190613799818360208a016131f7565b85519101906137ac8183602089016131f7565b84519101906137bf8183602088016131f7565b019695505050505050565b6000875160206137dd8285838d016131f7565b8851918401916137f08184848d016131f7565b88519201916138028184848c016131f7565b87519201916138148184848b016131f7565b86519201916138268184848a016131f7565b855192019161383881848489016131f7565b919091019998505050505050505050565b6000835161385b8184602088016131f7565b83519083019061386f8183602088016131f7565b01949350505050565b60008851602061388b8285838e016131f7565b89519184019161389e8184848e016131f7565b89519201916138b08184848d016131f7565b88519201916138c28184848c016131f7565b87519201916138d48184848b016131f7565b86519201916138e68184848a016131f7565b85519201916138f881848489016131f7565b919091019a9950505050505050505050565b6000865161391c818460208b016131f7565b865190830190613930818360208b016131f7565b8651910190613943818360208a016131f7565b85519101906139568183602089016131f7565b84519101906139698183602088016131f7565b01979650505050505050565b600083516139878184602088016131f7565b6201017960ed1b90830190815283516139a78160038401602088016131f7565b01600301949350505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222076696577426f783d2230203020333030203330302220737460208201527f796c653d226261636b67726f756e643a233743433342333b666f6e742d66616d60408201527f696c793a48656c766574696361204e6575652c2048656c7665746963612c20416060820152723934b0b6161039b0b73996b9b2b934b31d911f60691b608082015260008851613a79816093850160208d016131f7565b885190830190613a90816093840160208d016131f7565b8851910190613aa6816093840160208c016131f7565b8751910190613abc816093840160208b016131f7565b613add613ad7613ad16093848601018a613593565b88613593565b86613593565b915050613af281651e17b9bb339f60d11b9052565b6006019998505050505050505050565b60008219821115613b1557613b15613498565b500190565b600082613b3757634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b600060018201613b6457613b64613498565b5060010190565b600082821015613b7d57613b7d613498565b500390565b600060ff821660ff84168060ff03821115613b9f57613b9f613498565b019392505050565b634e487b7160e01b600052603260045260246000fd5b605b60f81b815260008651613bd9816001850160208b016131f7565b8083019050600b60fa1b8060018301528751613bfc816002850160208c016131f7565b600292019182018190528651613c19816003850160208b016131f7565b600392019182018190528551613c36816004850160208a016131f7565b60049201918201528351613c518160058401602088016131f7565b01613c6260058201605d60f81b9052565b600601979650505050505050565b60008351613c828184602088016131f7565b603d60f81b908301908152601160f91b60018201528351613caa8160028401602088016131f7565b61011160f51b60029290910191820152600401949350505050565b600f60fa1b815260008551613ce1816001850160208a016131f7565b600160fd1b6001918401918201528551613d02816002840160208a016131f7565b808201915050601f60f91b8060028301528551613d26816003850160208a016131f7565b613c2f60f01b600393909101928301528451613d498160058501602089016131f7565b60059201918201526006019695505050505050565b63024b731960e51b815260008751613d7d816004850160208c016131f7565b670103e103732ba1d160c51b6004918401918201528751613da581600c840160208c016131f7565b670103e103a30b11d160c51b600c92909101918201528651613dce816014840160208b016131f7565b670103e103a30bc1d160c51b601492909101918201528551613df781601c840160208a016131f7565b670103e10373ab69d160c51b601c9290910191820152613e1a6024820186613593565b670103e103437b81d160c51b81529050613e376008820185613593565b9998505050505050505050565b683c215b43444154415b60b81b815260008251613e688160098501602087016131f7565b622eae9f60e91b6009939091019283015250600c01919050565b6f3d913a3930b4ba2fba3cb832911d101160811b81528251600090613eae8160108501602088016131f7565b6c111610113b30b63ab2911d101160991b6010918401918201528351613edb81601d8401602088016131f7565b7f222c2022646973706c61795f74797065223a20226e756d626572227d00000000601d9290910191820152603901949350505050565b600081613f2057613f20613498565b50600019019056fe4d203130203130204820323830206131302c31302030203020312031302c3130205620323830206131302c3130203020302031202d31302c31302048203230206131302c3130203020302031202d31302c2d31302056203130207a4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f4d20323930203239302048203230206131302c3130203020302031202d31302c2d31302056203230206131302c31302030203020312031302c2d3130204820323830206131302c31302030203020312031302c3130205620323930207aa26469706673582212206e981fc57f7d7df941420b16ffb35566f018377075f03d279b18923b51bfd88764736f6c634300080f0033000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b000000000000000000000000a86c903cabab19f193a6252dd99bdfd747cd40ee

Deployed Bytecode

0x6080604052600436106101e35760003560e01c80638da5cb5b11610102578063c87b56dd11610095578063ea7a7aba11610064578063ea7a7aba1461062b578063ebf6e91d1461064b578063f751cd8f1461066b578063fa290fad1461068057600080fd5b8063c87b56dd14610540578063d7bb055914610560578063e31006ab146105d0578063e985e9c5146105f057600080fd5b80639bac5f7a116100d15780639bac5f7a146104ac578063a035b1fe146104cc578063a22cb46514610500578063b88d4fde1461052057600080fd5b80638da5cb5b146104375780638f7bb179146104575780639097548d1461047757806395d89b411461049757600080fd5b806322fcefbe1161017a57806352d112381161014957806352d11238146103a35780636352211e146103c357806370a08231146103e357806387e9e77f1461040357600080fd5b806322fcefbe1461030f57806323b872dd146103435780633b3546c81461036357806342842e0e1461038357600080fd5b8063095ea7b3116101b6578063095ea7b3146102af5780631249c58b146102cf57806313faede6146102d75780632027962f146102fa57600080fd5b806301ffc9a7146101e857806303438dd01461021d57806306fdde031461023f578063081812fc14610261575b600080fd5b3480156101f457600080fd5b506102086102033660046131a8565b6106b4565b60405190151581526020015b60405180910390f35b34801561022957600080fd5b5061023d6102383660046131da565b610706565b005b34801561024b57600080fd5b50610254610789565b6040516102149190613227565b34801561026d57600080fd5b5061029761027c36600461325a565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610214565b3480156102bb57600080fd5b5061023d6102ca366004613273565b610817565b61023d6108fe565b3480156102e357600080fd5b506102ec610bde565b604051908152602001610214565b34801561030657600080fd5b5061023d610c6a565b34801561031b57600080fd5b506102977f000000000000000000000000742532cc54ffc4ce854198e793d6121191799f5681565b34801561034f57600080fd5b5061023d61035e36600461329f565b610dc8565b34801561036f57600080fd5b5061029761037e36600461325a565b610f8f565b34801561038f57600080fd5b5061023d61039e36600461329f565b611028565b3480156103af57600080fd5b5061023d6103be3660046131da565b6110fd565b3480156103cf57600080fd5b506102976103de36600461325a565b6111da565b3480156103ef57600080fd5b506102ec6103fe3660046131da565b611231565b34801561040f57600080fd5b506102977f000000000000000000000000a86c903cabab19f193a6252dd99bdfd747cd40ee81565b34801561044357600080fd5b50600654610297906001600160a01b031681565b34801561046357600080fd5b5061025461047236600461325a565b611294565b34801561048357600080fd5b506102ec61049236600461325a565b6112fd565b3480156104a357600080fd5b5061025461132b565b3480156104b857600080fd5b506102546104c736600461325a565b611338565b3480156104d857600080fd5b506102977f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec86381565b34801561050c57600080fd5b5061023d61051b3660046132e0565b611418565b34801561052c57600080fd5b5061023d61053b36600461331e565b611484565b34801561054c57600080fd5b5061025461055b36600461325a565b611549565b34801561056c57600080fd5b5061058061057b3660046131da565b611592565b604051610214919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201519181019190915260c00190565b3480156105dc57600080fd5b5061023d6105eb36600461325a565b611711565b3480156105fc57600080fd5b5061020861060b3660046133bd565b600560209081526000928352604080842090915290825290205460ff1681565b34801561063757600080fd5b506102ec61064636600461325a565b6117f3565b34801561065757600080fd5b5061023d61066636600461325a565b61185f565b34801561067757600080fd5b5061023d6118e4565b34801561068c57600080fd5b506102977f000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b81565b60006301ffc9a760e01b6001600160e01b0319831614806106e557506380ac58cd60e01b6001600160e01b03198316145b806107005750635b5e139f60e01b6001600160e01b03198316145b92915050565b6006546001600160a01b0316331461073157604051631dd2188d60e31b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b03831617905560405160043590602435903490829084903390600080356001600160e01b0319169161077b9187913690613414565b60405180910390a450505050565b600080546107969061342e565b80601f01602080910402602001604051908101604052809291908181526020018280546107c29061342e565b801561080f5780601f106107e45761010080835404028352916020019161080f565b820191906000526020600020905b8154815290600101906020018083116107f257829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b03163381148061086057506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6108a25760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60043560243534600061090f610bde565b905080341461093a57604051630374cb4760e21b815234600482015260248101829052604401610899565b7f000000000000000000000000742532cc54ffc4ce854198e793d6121191799f566001600160a01b0316632ae3594a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561099557600080fd5b505af11580156109a9573d6000803e3d6000fd5b5050505060007f000000000000000000000000742532cc54ffc4ce854198e793d6121191799f566001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a319190613462565b604051635bf030a760e01b8152600481018290526000602482018190529192507f000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b6001600160a01b031690635bf030a7906044016020604051808303816000875af1158015610aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac8919061347b565b9050806001600160a01b031663401c8a536040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b0557600080fd5b505af1158015610b19573d6000803e3d6000fd5b50505050806001600160a01b0316634c97d71a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b5857600080fd5b505af1158015610b6c573d6000803e3d6000fd5b50505050610b8e33670de0b6b3a76400006064610b8991906134ae565b6119db565b610b983383611af1565b5050508183336001600160a01b03166000356001600160e01b0319166001600160e01b03191684600036604051610bd193929190613414565b60405180910390a4505050565b6000610c657f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec8636001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c41573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104929190613462565b905090565b60008060006004359250602435915034905060647f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec8636001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d009190613462565b1015610d92577f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec8636001600160a01b0316632ae3594a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d6157600080fd5b505af1158015610d75573d6000803e3d6000fd5b50505050610d9233670de0b6b3a7640000600a610b8991906134ae565b8183336001600160a01b03166000356001600160e01b0319166001600160e01b03191684600036604051610bd193929190613414565b6000818152600260205260409020546001600160a01b03848116911614610e1e5760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610899565b6001600160a01b038216610e685760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610899565b336001600160a01b0384161480610ea257506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b80610ec357506000818152600460205260409020546001600160a01b031633145b610f005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610899565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516332ce302f60e01b815230600482015260248101829052600060448201819052907f000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b6001600160a01b0316906332ce302f90606401602060405180830381865afa158015611004573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610700919061347b565b611033838383610dc8565b6001600160a01b0382163b15806110dc5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156110ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d091906134cd565b6001600160e01b031916145b6110f85760405162461bcd60e51b8152600401610899906134ea565b505050565b6006546001600160a01b0316331461112857604051631dd2188d60e31b815260040160405180910390fd5b604051600435906024359034906000906001600160a01b0386169047908381818185875af1925050503d806000811461117d576040519150601f19603f3d011682016040523d82523d6000602084013e611182565b606091505b50509050806111a357604051627e40ef60e21b815260040160405180910390fd5b508183336001600160a01b03166000356001600160e01b0319166001600160e01b0319168460003660405161077b93929190613414565b6000818152600260205260409020546001600160a01b03168061122c5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606401610899565b919050565b60006001600160a01b0382166112785760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610899565b506001600160a01b031660009081526003602052604090205490565b6060816112a0816111da565b5060006112af61057b85610f8f565b90506112f3846112ed6040518060400160405280600d81526020016c1a5b5859d94bdcdd99cade1b5b609a1b8152506112e788611338565b90611bbd565b83611c10565b9250505b50919050565b600061070061131d670f43fc2c04ee000084670de0b6b3a7640000611c4f565b662386f26fc1000090611d0d565b600180546107969061342e565b606081611344816111da565b50600061135361057b85610f8f565b905060006113807f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec863611592565b905061140f857f000000000000000000000000742532cc54ffc4ce854198e793d6121191799f566001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114089190613462565b8484611d22565b95945050505050565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61148f858585610dc8565b6001600160a01b0384163b15806115265750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906114d79033908a90899089908990600401613514565b6020604051808303816000875af11580156114f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151a91906134cd565b6001600160e01b031916145b6115425760405162461bcd60e51b8152600401610899906134ea565b5050505050565b606081611555816111da565b5061158b6040518060400160405280601081526020016f30b8383634b1b0ba34b7b717b539b7b760811b8152506112e785611294565b9392505050565b6115d46040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b60007f000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b6001600160a01b031663853255cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611634573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611658919061347b565b604051637bc1152d60e01b81526001600160a01b0385811660048301529192506000918291829182918291871690637bc1152d9060240160a060405180830381865afa1580156116ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d09190613553565b6040805160c0810182526001600160a01b03909e168e5260208e0195909552938c019290925260608b015260808a015260a089015250959695505050505050565b8061171b816111da565b6001600160a01b0316336001600160a01b03161461174c57604051631dd2188d60e31b815260040160405180910390fd5b6004356024353461175c85610f8f565b6001600160a01b03166328d36a836040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561179657600080fd5b505af11580156117aa573d6000803e3d6000fd5b505050508183336001600160a01b03166000356001600160e01b0319166001600160e01b031916846000366040516117e493929190613414565b60405180910390a45050505050565b60006117fe82610f8f565b6001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561183b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107009190613462565b80611869816111da565b6001600160a01b0316336001600160a01b03161461189a57604051631dd2188d60e31b815260040160405180910390fd5b600435602435346118aa85610f8f565b6001600160a01b0316632ae3594a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561179657600080fd5b60008060006004359250602435915034905060007f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec8636001600160a01b0316639ae5a2be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197a9190613462565b1115610d92577f0000000000000000000000002de1a9c088aa3b266265d59b7ee89a31125ec8636001600160a01b03166328d36a836040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d6157600080fd5b6040516370a0823160e01b815230600482015281907f000000000000000000000000a86c903cabab19f193a6252dd99bdfd747cd40ee6001600160a01b0316906370a0823190602401602060405180830381865afa158015611a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a659190613462565b10611aed57604051632dd4ea6360e21b81526001600160a01b038381166004830152602482018390527f000000000000000000000000a86c903cabab19f193a6252dd99bdfd747cd40ee169063b753a98c90604401600060405180830381600087803b158015611ad457600080fd5b505af1158015611ae8573d6000803e3d6000fd5b505050505b5050565b611afb8282612a34565b6001600160a01b0382163b1580611ba15750604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015611b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9591906134cd565b6001600160e01b031916145b611aed5760405162461bcd60e51b8152600401610899906134ea565b606081611be884604051602001611bd491906135af565b604051602081830303815290604052612b3f565b604051602001611bf99291906135cb565b604051602081830303815290604052905092915050565b6060611c1b84612c92565b83611c2584612dbe565b604051602001611c379392919061361f565b60405160208183030381529060405290509392505050565b6000838015611cef57600184168015611c6a57859250611c6e565b8392505b508260011c8460011c94505b8415611ce9578560801c15611c8e57600080fd5b85860281810181811015611ca157600080fd5b8590049650506001851615611cde578583028387820414611cc7578615611cc757600080fd5b81810181811015611cd757600080fd5b8590049350505b8460011c9450611c7a565b50611d05565b838015611cff5760009250611d03565b8392505b505b509392505050565b600061158b8383670de0b6b3a7640000612eb7565b6060611e33604051806040016040528060048152602001630e0c2e8d60e31b815250611d83604051806040016040528060028152602001611a5960f21b815250604051806040016040528060038152602001620746f760ec1b815250612ee5565b611dbe604051806040016040528060018152602001601960fa1b8152506040518060800160405280605b8152602001613f29605b9139612ee5565b611e0360405180604001604052806004815260200163199a5b1b60e21b815250604051806040016040528060078152602001662337434333423360c81b815250612ee5565b604051602001611e1593929190613730565b60408051601f19818403018152602083019091526000825290612efa565b611ed0604051806040016040528060048152602001630e0c2e8d60e31b815250611e95604051806040016040528060028152602001611a5960f21b81525060405180604001604052806006815260200165626f74746f6d60d01b815250612ee5565b611dbe604051806040016040528060018152602001601960fa1b8152506040518060800160405280605d8152602001613fc4605d9139612ee5565b6122d4611f2460405180604001604052806011815260200170646f6d696e616e742d626173656c696e6560781b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b611f796040518060400160405280600b81526020016a666f6e742d66616d696c7960a81b8152506040518060400160405280601081526020016f4d656e6c6f2c206d6f6e6f737061636560801b815250612ee5565b611fbd60405180604001604052806009815260200168666f6e742d73697a6560b81b815250604051806040016040528060018152602001603960f81b815250612ee5565b61200060405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b6040516020016120139493929190613773565b6040516020818303038152906040526122b0604051806040016040528060088152602001670e8caf0e8a0c2e8d60c31b81525061208860405180604001604052806004815260200163343932b360e11b81525060405180604001604052806004815260200163023746f760e41b815250612ee5565b60405160200161209891906135af565b6040516020818303038152906040526120b08a612f13565b61228b60405180604001604052806007815260200166616e696d61746560c81b8152506121256040518060400160405280600d81526020016c6174747269627574654e616d6560981b8152506040518060400160405280600b81526020016a1cdd185c9d13d9999cd95d60aa1b815250612ee5565b6121656040518060400160405280600481526020016366726f6d60e01b81525060405180604001604052806002815260200161302560f01b815250612ee5565b6121a560405180604001604052806002815260200161746f60f01b815250604051806040016040528060048152602001633130302560e01b815250612ee5565b6121e660405180604001604052806003815260200162323ab960e91b815250604051806040016040528060048152602001633132307360e01b815250612ee5565b612227604051806040016040528060058152602001643132b3b4b760d91b81525060405180604001604052806002815260200161307360f01b815250612ee5565b6122766040518060400160405280600b81526020016a1c995c19585d10dbdd5b9d60aa1b8152506040518060400160405280600a815260200169696e646566696e69746560b01b815250612ee5565b604051602001611e15969594939291906137ca565b60405160200161229c929190613849565b604051602081830303815290604052612efa565b6040516020016122c091906135af565b604051602081830303815290604052612f9a565b612503612315604051806040016040528060018152602001600f60fb1b8152506040518060400160405280600381526020016235302560e81b815250612ee5565b612353604051806040016040528060018152602001607960f81b8152506040518060400160405280600381526020016234352560e81b815250612ee5565b61239e6040518060400160405280600b81526020016a3a32bc3a16b0b731b437b960a91b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b6123ef60405180604001604052806011815260200170646f6d696e616e742d626173656c696e6560781b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b61243560405180604001604052806009815260200168666f6e742d73697a6560b81b8152506040518060400160405280600381526020016203135360ec1b815250612ee5565b61247e6040518060400160405280600b81526020016a199bdb9d0b5dd95a59da1d60aa1b81525060405180604001604052806004815260200163189bdb1960e21b815250612ee5565b6124c160405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b6040516020016124d79796959493929190613878565b60408051601f1981840301815282820190915260028252612b2b60f01b6020830152906122b090612fc3565b61269b612544604051806040016040528060018152602001600f60fb1b8152506040518060400160405280600381526020016235302560e81b815250612ee5565b612582604051806040016040528060018152602001607960f81b8152506040518060400160405280600381526020016237302560e81b815250612ee5565b6125cd6040518060400160405280600b81526020016a3a32bc3a16b0b731b437b960a91b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b61261260405180604001604052806009815260200168666f6e742d73697a6560b81b81525060405180604001604052806002815260200161032360f41b815250612ee5565b61265560405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b60405160200161266995949392919061390a565b6040516020818303038152906040526126818b612c92565b61268a8b612c92565b6040516020016122c0929190613975565b6128226126dc604051806040016040528060018152602001600f60fb1b8152506040518060400160405280600381526020016235302560e81b815250612ee5565b61271a604051806040016040528060018152602001607960f81b8152506040518060400160405280600381526020016238302560e81b815250612ee5565b6127656040518060400160405280600b81526020016a3a32bc3a16b0b731b437b960a91b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b6127aa60405180604001604052806009815260200168666f6e742d73697a6560b81b81525060405180604001604052806002815260200161032360f41b815250612ee5565b6127ed60405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b60405160200161280195949392919061390a565b60405160208183030381529060405261281d8a60200151612c92565b612f9a565b612a0561287660405180604001604052806011815260200170646f6d696e616e742d626173656c696e6560781b815250604051806040016040528060068152602001656d6964646c6560d01b815250612ee5565b6128cb6040518060400160405280600b81526020016a666f6e742d66616d696c7960a81b8152506040518060400160405280601081526020016f4d656e6c6f2c206d6f6e6f737061636560801b815250612ee5565b61290f60405180604001604052806009815260200168666f6e742d73697a6560b81b815250604051806040016040528060018152602001603960f81b815250612ee5565b61295260405180604001604052806004815260200163199a5b1b60e21b81525060405180604001604052806005815260200164776869746560d81b815250612ee5565b6040516020016129659493929190613773565b6040516020818303038152906040526122b0604051806040016040528060088152602001670e8caf0e8a0c2e8d60c31b8152506129dd60405180604001604052806004815260200163343932b360e11b8152506040518060400160405280600781526020016623626f74746f6d60c81b815250612ee5565b6040516020016129ed91906135af565b6040516020818303038152906040526120b08d612f13565b604051602001612a1b97969594939291906139b3565b6040516020818303038152906040529050949350505050565b6001600160a01b038216612a7e5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610899565b6000818152600260205260409020546001600160a01b031615612ad45760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610899565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60608151600003612b5e57505060408051602081019091526000815290565b6000604051806060016040528060408152602001613f846040913990506000600384516002612b8d9190613b02565b612b979190613b1a565b612ba29060046134ae565b67ffffffffffffffff811115612bba57612bba613b3c565b6040519080825280601f01601f191660200182016040528015612be4576020820181803683370190505b509050600182016020820185865187015b80821015612c50576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250612bf5565b5050600386510660018114612c6c5760028114612c7f57612c87565b603d6001830353603d6002830353612c87565b603d60018303535b509195945050505050565b606081600003612cb95750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612ce35780612ccd81613b52565b9150612cdc9050600a83613b1a565b9150612cbd565b60008167ffffffffffffffff811115612cfe57612cfe613b3c565b6040519080825280601f01601f191660200182016040528015612d28576020820181803683370190505b509050815b8515612db557612d3e600182613b6b565b90506000612d4d600a88613b1a565b612d5890600a6134ae565b612d629088613b6b565b612d6d906030613b82565b905060008160f81b905080848481518110612d8a57612d8a613ba7565b60200101906001600160f81b031916908160001a905350612dac600a89613b1a565b97505050612d2d565b50949350505050565b6060612de9604051806040016040528060038152602001621b995d60ea1b8152508360200151612fd6565b612e12604051806040016040528060038152602001623a30b160e91b8152508460400151612fd6565b612e3b604051806040016040528060038152602001620e8c2f60eb1b8152508560600151612fd6565b612e64604051806040016040528060038152602001626e756d60e81b8152508660800151612fd6565b612e8d604051806040016040528060038152602001620686f760ec1b8152508760a00151612fd6565b604051602001612ea1959493929190613bbd565b6040516020818303038152906040529050919050565b828202811515841585830485141716612ecf57600080fd5b6001826001830304018115150290509392505050565b60608282604051602001611bf9929190613c70565b606083838386604051602001611c379493929190613cc5565b6060610700612f3083600001516001600160a01b03166014612ff3565b612f3d8460200151612c92565b612f4a8560400151612c92565b612f578660600151612c92565b612f648760800151612c92565b612f718860a00151612c92565b604051602001612f8696959493929190613d5e565b604051602081830303815290604052612fc3565b606061158b604051806040016040528060048152602001631d195e1d60e21b8152508484612efa565b606081604051602001612ea19190613e44565b606082612fe283612c92565b604051602001611bf9929190613e82565b606060006130028360026134ae565b61300d906002613b02565b67ffffffffffffffff81111561302557613025613b3c565b6040519080825280601f01601f19166020018201604052801561304f576020820181803683370190505b509050600360fc1b8160008151811061306a5761306a613ba7565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061309957613099613ba7565b60200101906001600160f81b031916908160001a90535060006130bd8460026134ae565b6130c8906001613b02565b90505b6001811115613140576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106130fc576130fc613ba7565b1a60f81b82828151811061311257613112613ba7565b60200101906001600160f81b031916908160001a90535060049490941c9361313981613f11565b90506130cb565b50831561158b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610899565b6001600160e01b0319811681146131a557600080fd5b50565b6000602082840312156131ba57600080fd5b813561158b8161318f565b6001600160a01b03811681146131a557600080fd5b6000602082840312156131ec57600080fd5b813561158b816131c5565b60005b838110156132125781810151838201526020016131fa565b83811115613221576000848401525b50505050565b60208152600082518060208401526132468160408501602087016131f7565b601f01601f19169190910160400192915050565b60006020828403121561326c57600080fd5b5035919050565b6000806040838503121561328657600080fd5b8235613291816131c5565b946020939093013593505050565b6000806000606084860312156132b457600080fd5b83356132bf816131c5565b925060208401356132cf816131c5565b929592945050506040919091013590565b600080604083850312156132f357600080fd5b82356132fe816131c5565b91506020830135801515811461331357600080fd5b809150509250929050565b60008060008060006080868803121561333657600080fd5b8535613341816131c5565b94506020860135613351816131c5565b935060408601359250606086013567ffffffffffffffff8082111561337557600080fd5b818801915088601f83011261338957600080fd5b81358181111561339857600080fd5b8960208285010111156133aa57600080fd5b9699959850939650602001949392505050565b600080604083850312156133d057600080fd5b82356133db816131c5565b91506020830135613313816131c5565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061140f6040830184866133eb565b600181811c9082168061344257607f821691505b6020821081036112f757634e487b7160e01b600052602260045260246000fd5b60006020828403121561347457600080fd5b5051919050565b60006020828403121561348d57600080fd5b815161158b816131c5565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156134c8576134c8613498565b500290565b6000602082840312156134df57600080fd5b815161158b8161318f565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061354890830184866133eb565b979650505050505050565b600080600080600060a0868803121561356b57600080fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b600081516135a58185602086016131f7565b9290920192915050565b600082516135c18184602087016131f7565b9190910192915050565b643230ba309d60d91b8152600083516135eb8160058501602088016131f7565b670ed8985cd94d8d0b60c21b600591840191820152835161361381600d8401602088016131f7565b01600d01949350505050565b737b226e616d65223a2022436f756e74657244414f60601b815261202360f01b6014820152835160009061365a8160168501602089016131f7565b7f222c20226465736372697074696f6e223a2022492066726f6262656420616e206016918401918201527f696e6320616e6420616c6c204920676f74207761732074686973206c6f75737960368201527f206473732d746f6b656e222c2022696d616765223a2022000000000000000000605682015284516136e381606d8401602089016131f7565b7001116101130ba3a3934b13aba32b9911d1607d1b606d9290910191820152835161371581607e8401602088016131f7565b607d60f81b607e9290910191820152607f0195945050505050565b600084516137428184602089016131f7565b8451908301906137568183602089016131f7565b84519101906137698183602088016131f7565b0195945050505050565b60008551613785818460208a016131f7565b855190830190613799818360208a016131f7565b85519101906137ac8183602089016131f7565b84519101906137bf8183602088016131f7565b019695505050505050565b6000875160206137dd8285838d016131f7565b8851918401916137f08184848d016131f7565b88519201916138028184848c016131f7565b87519201916138148184848b016131f7565b86519201916138268184848a016131f7565b855192019161383881848489016131f7565b919091019998505050505050505050565b6000835161385b8184602088016131f7565b83519083019061386f8183602088016131f7565b01949350505050565b60008851602061388b8285838e016131f7565b89519184019161389e8184848e016131f7565b89519201916138b08184848d016131f7565b88519201916138c28184848c016131f7565b87519201916138d48184848b016131f7565b86519201916138e68184848a016131f7565b85519201916138f881848489016131f7565b919091019a9950505050505050505050565b6000865161391c818460208b016131f7565b865190830190613930818360208b016131f7565b8651910190613943818360208a016131f7565b85519101906139568183602089016131f7565b84519101906139698183602088016131f7565b01979650505050505050565b600083516139878184602088016131f7565b6201017960ed1b90830190815283516139a78160038401602088016131f7565b01600301949350505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222076696577426f783d2230203020333030203330302220737460208201527f796c653d226261636b67726f756e643a233743433342333b666f6e742d66616d60408201527f696c793a48656c766574696361204e6575652c2048656c7665746963612c20416060820152723934b0b6161039b0b73996b9b2b934b31d911f60691b608082015260008851613a79816093850160208d016131f7565b885190830190613a90816093840160208d016131f7565b8851910190613aa6816093840160208c016131f7565b8751910190613abc816093840160208b016131f7565b613add613ad7613ad16093848601018a613593565b88613593565b86613593565b915050613af281651e17b9bb339f60d11b9052565b6006019998505050505050505050565b60008219821115613b1557613b15613498565b500190565b600082613b3757634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b600060018201613b6457613b64613498565b5060010190565b600082821015613b7d57613b7d613498565b500390565b600060ff821660ff84168060ff03821115613b9f57613b9f613498565b019392505050565b634e487b7160e01b600052603260045260246000fd5b605b60f81b815260008651613bd9816001850160208b016131f7565b8083019050600b60fa1b8060018301528751613bfc816002850160208c016131f7565b600292019182018190528651613c19816003850160208b016131f7565b600392019182018190528551613c36816004850160208a016131f7565b60049201918201528351613c518160058401602088016131f7565b01613c6260058201605d60f81b9052565b600601979650505050505050565b60008351613c828184602088016131f7565b603d60f81b908301908152601160f91b60018201528351613caa8160028401602088016131f7565b61011160f51b60029290910191820152600401949350505050565b600f60fa1b815260008551613ce1816001850160208a016131f7565b600160fd1b6001918401918201528551613d02816002840160208a016131f7565b808201915050601f60f91b8060028301528551613d26816003850160208a016131f7565b613c2f60f01b600393909101928301528451613d498160058501602089016131f7565b60059201918201526006019695505050505050565b63024b731960e51b815260008751613d7d816004850160208c016131f7565b670103e103732ba1d160c51b6004918401918201528751613da581600c840160208c016131f7565b670103e103a30b11d160c51b600c92909101918201528651613dce816014840160208b016131f7565b670103e103a30bc1d160c51b601492909101918201528551613df781601c840160208a016131f7565b670103e10373ab69d160c51b601c9290910191820152613e1a6024820186613593565b670103e103437b81d160c51b81529050613e376008820185613593565b9998505050505050505050565b683c215b43444154415b60b81b815260008251613e688160098501602087016131f7565b622eae9f60e91b6009939091019283015250600c01919050565b6f3d913a3930b4ba2fba3cb832911d101160811b81528251600090613eae8160108501602088016131f7565b6c111610113b30b63ab2911d101160991b6010918401918201528351613edb81601d8401602088016131f7565b7f222c2022646973706c61795f74797065223a20226e756d626572227d00000000601d9290910191820152603901949350505050565b600081613f2057613f20613498565b50600019019056fe4d203130203130204820323830206131302c31302030203020312031302c3130205620323830206131302c3130203020302031202d31302c31302048203230206131302c3130203020302031202d31302c2d31302056203130207a4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f4d20323930203239302048203230206131302c3130203020302031202d31302c2d31302056203230206131302c31302030203020312031302c2d3130204820323830206131302c31302030203020312031302c3130205620323930207aa26469706673582212206e981fc57f7d7df941420b16ffb35566f018377075f03d279b18923b51bfd88764736f6c634300080f0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b000000000000000000000000a86c903cabab19f193a6252dd99bdfd747cd40ee

-----Decoded View---------------
Arg [0] : _dss (address): 0xcE78254bCD05040953d28FcB640c465f086BEC9b
Arg [1] : _ctr (address): 0xA86c903CabAb19f193A6252DD99bdFD747cD40Ee

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ce78254bcd05040953d28fcb640c465f086bec9b
Arg [1] : 000000000000000000000000a86c903cabab19f193a6252dd99bdfd747cd40ee


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.