ETH Price: $3,273.02 (+0.73%)
Gas: 1 Gwei

Contract

0x8f093895cD4C54eaB897C6377e1Bf85Fe5B4E948
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
New Umswap166445732023-02-16 23:27:59528 days ago1676590079IN
0x8f093895...Fe5B4E948
0 ETH0.0090715730.84267653
New Umswap156697932022-10-03 19:45:11664 days ago1664826311IN
0x8f093895...Fe5B4E948
0 ETH0.0051180617.32418418
New Umswap156573422022-10-02 2:02:35665 days ago1664676155IN
0x8f093895...Fe5B4E948
0 ETH0.003534536.40341722
New Umswap156549352022-10-01 17:56:59666 days ago1664647019IN
0x8f093895...Fe5B4E948
0 ETH0.04316846.66666666
New Umswap156497652022-10-01 0:34:11666 days ago1664584451IN
0x8f093895...Fe5B4E948
0 ETH0.002924339.85308763
Send Message156479862022-09-30 18:37:11667 days ago1664563031IN
0x8f093895...Fe5B4E948
0 ETH0.0004569216.30171512
New Umswap156454862022-09-30 10:14:47667 days ago1664532887IN
0x8f093895...Fe5B4E948
0 ETH0.002878979.71711812
New Umswap156442962022-09-30 6:14:59667 days ago1664518499IN
0x8f093895...Fe5B4E948
0 ETH0.0308230810.84414243
New Umswap156441152022-09-30 5:38:23667 days ago1664516303IN
0x8f093895...Fe5B4E948
0 ETH0.0030639610.41508493
New Umswap156378722022-09-29 8:40:59668 days ago1664440859IN
0x8f093895...Fe5B4E948
0 ETH0.0093293911.83052582
New Umswap156351512022-09-28 23:34:35669 days ago1664408075IN
0x8f093895...Fe5B4E948
0 ETH0.00495338.89153516
New Umswap156351322022-09-28 23:30:47669 days ago1664407847IN
0x8f093895...Fe5B4E948
0 ETH0.010346568.88888888
New Umswap156321692022-09-28 13:35:35669 days ago1664372135IN
0x8f093895...Fe5B4E948
0 ETH0.0052597417.5031206
New Umswap156319432022-09-28 12:49:47669 days ago1664369387IN
0x8f093895...Fe5B4E948
0 ETH0.0034822411.11111111
0x60806040156315852022-09-28 11:37:47669 days ago1664365067IN
 Create: UmswapFactory
0 ETH0.037804589.99999999

Latest 14 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
166445732023-02-16 23:27:59528 days ago1676590079
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156697932022-10-03 19:45:11664 days ago1664826311
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156573422022-10-02 2:02:35665 days ago1664676155
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156549352022-10-01 17:56:59666 days ago1664647019
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156497652022-10-01 0:34:11666 days ago1664584451
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156454862022-09-30 10:14:47667 days ago1664532887
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156442962022-09-30 6:14:59667 days ago1664518499
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156441152022-09-30 5:38:23667 days ago1664516303
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156378722022-09-29 8:40:59668 days ago1664440859
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156351512022-09-28 23:34:35669 days ago1664408075
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156351322022-09-28 23:30:47669 days ago1664407847
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156321692022-09-28 13:35:35669 days ago1664372135
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156319432022-09-28 12:49:47669 days ago1664369387
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
156315852022-09-28 11:37:47669 days ago1664365067
0x8f093895...Fe5B4E948
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
UmswapFactory

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-09-28
*/

/**
 *Submitted for verification at Etherscan.io on 2022-08-15
*/

pragma solidity ^0.8.0;

// ----------------------------------------------------------------------------
// Umswap v0.9.0 testing
//
// https://github.com/bokkypoobah/Umswap
//
// Deployments:
// - UmswapFactory 0x8f093895cD4C54eaB897C6377e1Bf85Fe5B4E948
// - Template Umswap 0xB595e208833164D43A08ce529ACc2b803d33C30E
//
// SPDX-License-Identifier: MIT
//
// Enjoy. And hello, from the past.
//
// (c) BokkyPooBah / Bok Consulting Pty Ltd 2022
// ----------------------------------------------------------------------------

/// @notice https://github.com/optionality/clone-factory/blob/32782f82dfc5a00d103a7e61a17a5dedbd1e8e9d/contracts/CloneFactory.sol
/*
The MIT License (MIT)

Copyright (c) 2018 Murray Software, LLC.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//solhint-disable max-line-length
//solhint-disable no-inline-assembly

contract CloneFactory {
  function createClone(address target) internal returns (address result) {
    bytes20 targetBytes = bytes20(target);
    assembly {
      let clone := mload(0x40)
      mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
      mstore(add(clone, 0x14), targetBytes)
      mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
      result := create(0, clone, 0x37)
    }
  }
}
// End CloneFactory.sol


/// @author Alex W.(github.com/nonstopcoderaxw)
/// @title Array utility functions optimized for Nix
library ArrayUtils {
    /// @notice divide-and-conquer check if an targeted item exists in a sorted array
    /// @param self the given sorted array
    /// @param target the targeted item to the array
    /// @return true - if exists, false - not found
    function includes16(uint16[] memory self, uint target) internal pure returns (bool) {
        if (self.length > 0) {
            uint left;
            uint right = self.length - 1;
            uint mid;
            while (left <= right) {
                mid = (left + right) / 2;
                if (uint(self[mid]) < target) {
                    left = mid + 1;
                } else if (uint(self[mid]) > target) {
                    if (mid < 1) {
                        break;
                    }
                    right = mid - 1;
                } else {
                    return true;
                }
            }
        }
        return false;
    }
    function includes32(uint32[] memory self, uint target) internal pure returns (bool) {
        if (self.length > 0) {
            uint left;
            uint right = self.length - 1;
            uint mid;
            while (left <= right) {
                mid = (left + right) / 2;
                if (uint(self[mid]) < target) {
                    left = mid + 1;
                } else if (uint(self[mid]) > target) {
                    if (mid < 1) {
                        break;
                    }
                    right = mid - 1;
                } else {
                    return true;
                }
            }
        }
        return false;
    }
    function includes64(uint64[] memory self, uint target) internal pure returns (bool) {
        if (self.length > 0) {
            uint left;
            uint right = self.length - 1;
            uint mid;
            while (left <= right) {
                mid = (left + right) / 2;
                if (uint(self[mid]) < target) {
                    left = mid + 1;
                } else if (uint(self[mid]) > target) {
                    if (mid < 1) {
                        break;
                    }
                    right = mid - 1;
                } else {
                    return true;
                }
            }
        }
        return false;
    }
    function includes256(uint[] memory self, uint target) internal pure returns (bool) {
        if (self.length > 0) {
            uint left;
            uint right = self.length - 1;
            uint mid;
            while (left <= right) {
                mid = (left + right) / 2;
                if (self[mid] < target) {
                    left = mid + 1;
                } else if (self[mid] > target) {
                    if (mid < 1) {
                        break;
                    }
                    right = mid - 1;
                } else {
                    return true;
                }
            }
        }
        return false;
    }
}


library TokenIdList {
    struct TokenId {
        uint64 timestamp;
        uint192 index;
        uint tokenId;
    }
    struct Data {
        mapping(uint => TokenId) entries;
        uint[] index;
    }

    error CannotAddDuplicate();
    error NotFound();

    function add(Data storage self, uint tokenId) internal {
        if (self.entries[tokenId].timestamp > 0) {
            revert CannotAddDuplicate();
        }
        self.index.push(tokenId);
        self.entries[tokenId] = TokenId(uint64(block.timestamp), uint192(self.index.length - 1), tokenId);
    }
    function remove(Data storage self, uint tokenId) internal {
        if (self.entries[tokenId].timestamp == 0) {
            revert NotFound();
        }
        uint removeIndex = self.entries[tokenId].index;
        uint lastIndex = self.index.length - 1;
        uint lastIndexKey = self.index[lastIndex];
        self.index[removeIndex] = lastIndexKey;
        self.entries[lastIndexKey].index = uint192(removeIndex);
        delete self.entries[tokenId];
        if (self.index.length > 0) {
            self.index.pop();
        }
    }
    function length(Data storage self) internal view returns (uint) {
        return self.index.length;
    }
}


/// @notice ERC20 https://eips.ethereum.org/EIPS/eip-20 with optional symbol, name and decimals
interface IERC20 {
    function totalSupply() external view returns (uint);
    function balanceOf(address tokenOwner) external view returns (uint balance);
    function allowance(address tokenOwner, address spender) external view returns (uint remaining);
    function transfer(address to, uint tokens) external returns (bool success);
    function approve(address spender, uint tokens) external returns (bool success);
    function transferFrom(address from, address to, uint tokens) external returns (bool success);

    function symbol() external view returns (string memory);
    function name() external view returns (string memory);
    function decimals() external view returns (uint8);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

interface IERC721Partial is IERC165 {
    function ownerOf(uint tokenId) external view returns (address);
    function balanceOf(address owner) external view returns (uint balance);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function transferFrom(address from, address to, uint tokenId) external payable;
    function safeTransferFrom(address from, address to, uint tokenId) external payable;
}


function onePlus(uint x) pure returns (uint) {
    unchecked { return 1 + x; }
}


contract ReentrancyGuard {
    uint private _executing;

    error ReentrancyAttempted();

    modifier reentrancyGuard() {
        if (_executing == 1) {
            revert ReentrancyAttempted();
        }
        _executing = 1;
        _;
        _executing = 2;
    }
}


/// @notice Basic token = ERC20 + symbol + name + decimals + mint + ownership
contract BasicToken is IERC20 {

    bool initialised;
    string _symbol;
    string _name;
    uint8 _decimals;
    uint _totalSupply;

    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;

    error AlreadyInitialised();

    function initBasicToken(string memory __symbol, string memory __name, uint8 __decimals) internal {
        if (initialised) {
            revert AlreadyInitialised();
        }
        initialised = true;
        _symbol = __symbol;
        _name = __name;
        _decimals = __decimals;
    }
    function symbol() override external view returns (string memory) {
        return _symbol;
    }
    function name() override external view returns (string memory) {
        return _name;
    }
    function decimals() override external view returns (uint8) {
        return _decimals;
    }
    function totalSupply() override external view returns (uint) {
        return _totalSupply - balances[address(0)];
    }
    function balanceOf(address tokenOwner) override external view returns (uint balance) {
        return balances[tokenOwner];
    }
    function transfer(address to, uint tokens) override external returns (bool success) {
        balances[msg.sender] -= tokens;
        balances[to] += tokens;
        emit Transfer(msg.sender, to, tokens);
        return true;
    }
    function approve(address spender, uint tokens) override external returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }
    function transferFrom(address from, address to, uint tokens) override external returns (bool success) {
        balances[from] -= tokens;
        allowed[from][msg.sender] -= tokens;
        balances[to] += tokens;
        emit Transfer(from, to, tokens);
        return true;
    }
    function allowance(address tokenOwner, address spender) override external view returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }
    function _mint(address tokenOwner, uint tokens) internal returns (bool success) {
        balances[tokenOwner] += tokens;
        _totalSupply += tokens;
        emit Transfer(address(0), tokenOwner, tokens);
        return true;
    }
    function _burn(address tokenOwner, uint tokens) internal returns (bool success) {
        balances[tokenOwner] -= tokens;
        _totalSupply -= tokens;
        emit Transfer(tokenOwner, address(0), tokens);
        return true;
    }
}


/// @title ERC-721 pool
/// @author BokkyPooBah, Bok Consulting Pty Ltd
contract Umswap is BasicToken, ReentrancyGuard {
    using TokenIdList for TokenIdList.Data;
    using TokenIdList for TokenIdList.TokenId;

    enum Stats { SwappedIn, SwappedOut, TotalScores }

    struct Rating {
        address account;
        uint64 score;
    }

    uint8 constant DECIMALS = 18;
    uint constant MAXRATINGSCORE = 10;
    uint constant MAXRATINGTEXTLENGTH = 48;

    address private creator;
    IERC721Partial private collection;
    uint16[] private validTokenIds16;
    uint32[] private validTokenIds32;
    uint64[] private validTokenIds64;
    uint[] private validTokenIds256;
    uint64[3] private stats;

    mapping(address => Rating) public ratings;
    address[] public raters;
    TokenIdList.Data private tokenIds;

    event Swapped(address indexed account, uint indexed timestamp, uint[] inTokenIds, uint[] outTokenIds, uint64[3] stats);
    event Rated(address indexed account, uint indexed timestamp, uint score, string text, uint64[3] stats);

    error InsufficientTokensToBurn();
    error InvalidTokenId(uint tokenId);
    error MaxRatingExceeded(uint max);
    error InvalidRatingMessage();

    function initUmswap(address _creator, IERC721Partial _collection, string calldata _symbol, string calldata _name, uint[] calldata _tokenIds) public {
        creator = _creator;
        collection = _collection;
        super.initBasicToken(_symbol, _name, DECIMALS);
        uint maxTokenId;
        for (uint i = 0; i < _tokenIds.length; i = onePlus(i)) {
            if (_tokenIds[i] > maxTokenId) {
                maxTokenId = _tokenIds[i];
            }
        }
        if (maxTokenId < 2 ** 16) {
            for (uint i = 0; i < _tokenIds.length; i = onePlus(i)) {
                validTokenIds16.push(uint16(_tokenIds[i]));
            }
        } else if (maxTokenId < 2 ** 32) {
            for (uint i = 0; i < _tokenIds.length; i = onePlus(i)) {
                validTokenIds32.push(uint32(_tokenIds[i]));
            }
        } else if (maxTokenId < 2 ** 64) {
            for (uint i = 0; i < _tokenIds.length; i = onePlus(i)) {
                validTokenIds64.push(uint64(_tokenIds[i]));
            }
        } else {
            validTokenIds256 = _tokenIds;
        }
    }

    /// @dev Is tokenId valid?
    /// @param tokenId TokenId to check
    /// @return True if valid
    function isValidTokenId(uint tokenId) public view returns (bool) {
        if (validTokenIds16.length > 0) {
            return ArrayUtils.includes16(validTokenIds16, tokenId);
        } else if (validTokenIds32.length > 0) {
            return ArrayUtils.includes32(validTokenIds32, tokenId);
        } else if (validTokenIds64.length > 0) {
            return ArrayUtils.includes64(validTokenIds64, tokenId);
        } else if (validTokenIds256.length > 0) {
            return ArrayUtils.includes256(validTokenIds256, tokenId);
        } else {
            return true;
        }
    }

    /// @dev Swap tokens into and out of the Umswap
    /// @param inTokenIds TokenIds to be transferred in
    /// @param outTokenIds TokenIds to be transferred out
    function swap(uint[] calldata inTokenIds, uint[] calldata outTokenIds) public reentrancyGuard {
        if (outTokenIds.length > inTokenIds.length) {
            uint tokensToBurn = (outTokenIds.length - inTokenIds.length) * 10 ** DECIMALS;
            if (tokensToBurn > this.balanceOf(msg.sender)) {
                revert InsufficientTokensToBurn();
            }
            _burn(msg.sender, tokensToBurn);
        }
        for (uint i = 0; i < inTokenIds.length; i = onePlus(i)) {
            if (!isValidTokenId(inTokenIds[i])) {
                revert InvalidTokenId(inTokenIds[i]);
            }
            collection.transferFrom(msg.sender, address(this), inTokenIds[i]);
            tokenIds.add(inTokenIds[i]);
        }
        for (uint i = 0; i < outTokenIds.length; i = onePlus(i)) {
            if (!isValidTokenId(outTokenIds[i])) {
                revert InvalidTokenId(outTokenIds[i]);
            }
            tokenIds.remove(outTokenIds[i]);
            collection.transferFrom(address(this), msg.sender, outTokenIds[i]);
        }
        if (outTokenIds.length < inTokenIds.length) {
            _mint(msg.sender, (inTokenIds.length - outTokenIds.length) * 10 ** DECIMALS);
        }
        stats[uint(Stats.SwappedIn)] += uint64(inTokenIds.length);
        stats[uint(Stats.SwappedOut)] += uint64(outTokenIds.length);
        emit Swapped(msg.sender, block.timestamp, inTokenIds, outTokenIds, stats);
    }

    /// @dev Rate a Umswap. Ratings scores can be updated forever
    /// @param score Score between 0 and `MAXRATINGSCORE` inclusive
    /// @param text Length between 1 and `MAXRATINGTEXTLENGTH`
    function rate(uint score, string calldata text) public {
        if (score > MAXRATINGSCORE) {
            revert MaxRatingExceeded(MAXRATINGSCORE);
        }
        bytes memory textBytes = bytes(text);
        if (textBytes.length > MAXRATINGTEXTLENGTH) {
            revert InvalidRatingMessage();
        }
        Rating storage rating = ratings[msg.sender];
        if (rating.account == address(0)) {
            ratings[msg.sender] = Rating(msg.sender, uint64(score));
            raters.push(msg.sender);
        } else {
            stats[uint(Stats.TotalScores)] -= rating.score;
            rating.score = uint64(score);
        }
        stats[uint(Stats.TotalScores)] += uint64(score);
        emit Rated(msg.sender, block.timestamp, score, text, stats);
    }

    function isApprovedForAll(address tokenOwner) internal view returns (bool b) {
        try IERC721Partial(collection).isApprovedForAll(tokenOwner, address(this)) returns (bool _b) {
            b = _b;
        } catch {
        }
    }

    /// @dev Get info
    /// @param tokenOwner To check collection.isApprovedForAll(tokenOwner, this)
    /// @return symbol_ Symbol
    /// @return name_ Name
    /// @return collection_ Collection
    /// @return validTokenIds_ Valid tokenIds
    /// @return tokenIds_ TokenIds
    /// @return creator_ Creator
    /// @return stats_ Stats
    function getInfo(address tokenOwner) public view returns (string memory symbol_, string memory name_, IERC721Partial collection_, uint[] memory validTokenIds_, uint[] memory tokenIds_, address creator_, uint[] memory stats_) {
        symbol_ = _symbol;
        name_ = _name;
        collection_ = collection;
        if (validTokenIds16.length > 0) {
            validTokenIds_ = new uint[](validTokenIds16.length);
            for (uint i = 0; i < validTokenIds16.length; i = onePlus(i)) {
                validTokenIds_[i] = validTokenIds16[i];
            }
        } else if (validTokenIds32.length > 0) {
            validTokenIds_ = new uint[](validTokenIds32.length);
            for (uint i = 0; i < validTokenIds32.length; i = onePlus(i)) {
                validTokenIds_[i] = validTokenIds32[i];
            }
        } else if (validTokenIds64.length > 0) {
            validTokenIds_ = new uint[](validTokenIds64.length);
            for (uint i = 0; i < validTokenIds64.length; i = onePlus(i)) {
                validTokenIds_[i] = validTokenIds64[i];
            }
        } else if (validTokenIds256.length > 0) {
            validTokenIds_ = new uint[](validTokenIds256.length);
            for (uint i = 0; i < validTokenIds256.length; i = onePlus(i)) {
                validTokenIds_[i] = validTokenIds256[i];
            }
        } else {
            validTokenIds_ = new uint[](0);
        }
        tokenIds_ = new uint[](tokenIds.length());
        for (uint i = 0; i < tokenIds.length(); i = onePlus(i)) {
            tokenIds_[i] = tokenIds.index[i];
        }
        creator_ = creator;
        stats_ = new uint[](7);
        stats_[0] = stats[uint(Stats.SwappedIn)];
        stats_[1] = stats[uint(Stats.SwappedOut)];
        stats_[2] = stats[uint(Stats.TotalScores)];
        stats_[3] = this.balanceOf(tokenOwner);
        stats_[4] = _totalSupply;
        stats_[5] = raters.length;
        stats_[6] = isApprovedForAll(tokenOwner) ? 1 : 0;
    }

    function getRatings(uint[] memory indices) public view returns (Rating[] memory ratings_) {
        uint length = indices.length;
        ratings_ = new Rating[](length);
        for (uint i = 0; i < length; i = onePlus(i)) {
            ratings_[i] = ratings[raters[i]];
        }
    }
}


/// @title Factory to deploy cloned Umswaps instances
/// @author BokkyPooBah, Bok Consulting Pty Ltd
contract UmswapFactory is CloneFactory {

    bytes1 constant SPACE = 0x20;
    bytes1 constant ZERO = 0x30;
    bytes1 constant TILDE = 0x7e;
    bytes constant UMSYMBOLPREFIX = "UMS";
    bytes4 constant ERC721_INTERFACE = 0x80ac58cd;
    uint constant MAXNAMELENGTH = 48;
    uint constant MAXTOPICLENGTH = 48;
    uint constant MAXTEXTLENGTH = 280;

    Umswap public template;
    Umswap[] public umswaps;
    mapping(Umswap => bool) umswapExists;
    mapping(bytes32 => bool) setExists;

    error NotERC721();
    error InvalidName();
    error InvalidTopic();
    error InvalidMessage();
    error InvalidUmswapOrCollection();
    error DuplicateSet();
    error TokenIdsMustBeSortedWithNoDuplicates();

    event NewUmswap(address indexed creator, uint timestamp, Umswap indexed umswap, IERC721Partial indexed collection, string name, uint[] tokenIds);
    event Message(address indexed from, uint timestamp, address indexed to, address indexed umswapOrCollection, string topic, string message);
    event Withdrawn(address owner, uint timestamp, address indexed token, uint tokens, uint tokenId);

    constructor() {
        template = new Umswap();
    }

    function isERC721(address token) internal view returns (bool b) {
        if (token.code.length > 0) {
            try IERC721Partial(token).supportsInterface(ERC721_INTERFACE) returns (bool _b) {
                b = _b;
            } catch {
            }
        }
    }

    function genSymbol(uint id) internal pure returns (string memory s) {
        bytes memory b = new bytes(8);
        uint i;
        uint j;
        uint num;
        for (i = 0; i < UMSYMBOLPREFIX.length; i = onePlus(i)) {
            b[j++] = UMSYMBOLPREFIX[i];
        }
        i = 5;
        do {
            unchecked {
                i--;
            }
            num = id / 10 ** i;
            b[j++] = bytes1(uint8(num % 10 + uint8(ZERO)));
        } while (i > 0);
        s = string(b);
    }

    /// @dev Is name valid? Length between 1 and `MAXNAMELENGTH`. Characters between SPACE and TILDE inclusive. No leading, trailing or repeating SPACEs
    /// @param str Name to check
    /// @return True if valid
    function isValidName(string memory str) public pure returns (bool) {
        bytes memory b = bytes(str);
        if (b.length < 1 || b.length > MAXNAMELENGTH) {
            return false;
        }
        if (b[0] == SPACE || b[b.length-1] == SPACE) {
            return false;
        }
        bytes1 lastChar = b[0];
        for (uint i; i < b.length; i = onePlus(i)) {
            bytes1 char = b[i];
            if (char == SPACE && lastChar == SPACE) {
                return false;
            }
            if (!(char >= SPACE && char <= TILDE)) {
                return false;
            }
            lastChar = char;
        }
        return true;
    }

    /// @dev Create new Umswap
    /// @param collection ERC-721 contract address
    /// @param name Name. See `isValidName` for valid names
    /// @param tokenIds List of valid tokenIds in this Umswap. Set to [] for any tokenIds in the collection
    function newUmswap(IERC721Partial collection, string calldata name, uint[] calldata tokenIds) public {
        if (!isERC721(address(collection))) {
            revert NotERC721();
        }
        if (!isValidName(name)) {
            revert InvalidName();
        }
        if (tokenIds.length > 0) {
            for (uint i = 1; i < tokenIds.length; i = onePlus(i)) {
                if (tokenIds[i - 1] >= tokenIds[i]) {
                    revert TokenIdsMustBeSortedWithNoDuplicates();
                }
            }
        }
        bytes32 key = keccak256(abi.encodePacked(collection, tokenIds));
        if (setExists[key]) {
            revert DuplicateSet();
        }
        setExists[key] = true;
        Umswap umswap = Umswap(createClone(address(template)));
        umswap.initUmswap(msg.sender, collection, genSymbol(umswaps.length), name, tokenIds);
        umswaps.push(umswap);
        umswapExists[umswap] = true;
        emit NewUmswap(msg.sender, block.timestamp, umswap, collection, name, tokenIds);
    }

    /// @dev Send message
    /// @param to Destination address, or address(0) for general messages
    /// @param umswapOrCollection Specific umswap or ERC-721 contract address, or address(0) for general messages
    /// @param topic Message topic. Length between 0 and `MAXTOPICLENGTH`
    /// @param text Message text. Length between 1 and `MAXTEXTLENGTH`
    function sendMessage(address to, address umswapOrCollection, string calldata topic, string calldata text) public {
        bytes memory topicBytes = bytes(topic);
        if (topicBytes.length > MAXTOPICLENGTH) {
            revert InvalidTopic();
        }
        bytes memory textBytes = bytes(text);
        if (textBytes.length < 1 || textBytes.length > MAXTEXTLENGTH) {
            revert InvalidMessage();
        }
        if (umswapOrCollection != address(0) && !umswapExists[Umswap(umswapOrCollection)] && !isERC721(umswapOrCollection)) {
            revert InvalidUmswapOrCollection();
        }
        emit Message(msg.sender, block.timestamp, to, umswapOrCollection, topic, text);
    }

    function getUmswapsLength() public view returns (uint _length) {
        return umswaps.length;
    }

    function getUmswaps(address tokenOwner, uint[] memory indices) public view returns (
        Umswap[] memory umswaps_,
        string[] memory symbols,
        string[] memory names,
        IERC721Partial[] memory collections,
        uint[][] memory validTokenIds,
        uint[][] memory tokenIds,
        address[] memory creators,
        uint[][] memory stats
    ) {
        uint length = indices.length;
        umswaps_ = new Umswap[](length);
        symbols = new string[](length);
        names = new string[](length);
        collections = new IERC721Partial[](length);
        validTokenIds = new uint[][](length);
        tokenIds = new uint[][](length);
        creators = new address[](length);
        stats = new uint[][](length);
        for (uint i = 0; i < length; i = onePlus(i)) {
            umswaps_[i] = umswaps[indices[i]];
            (symbols[i], names[i], collections[i], validTokenIds[i], tokenIds[i], creators[i], stats[i]) = umswaps[indices[i]].getInfo(tokenOwner);
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DuplicateSet","type":"error"},{"inputs":[],"name":"InvalidMessage","type":"error"},{"inputs":[],"name":"InvalidName","type":"error"},{"inputs":[],"name":"InvalidTopic","type":"error"},{"inputs":[],"name":"InvalidUmswapOrCollection","type":"error"},{"inputs":[],"name":"NotERC721","type":"error"},{"inputs":[],"name":"TokenIdsMustBeSortedWithNoDuplicates","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"umswapOrCollection","type":"address"},{"indexed":false,"internalType":"string","name":"topic","type":"string"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Message","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":true,"internalType":"contract Umswap","name":"umswap","type":"address"},{"indexed":true,"internalType":"contract IERC721Partial","name":"collection","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"NewUmswap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint256[]","name":"indices","type":"uint256[]"}],"name":"getUmswaps","outputs":[{"internalType":"contract Umswap[]","name":"umswaps_","type":"address[]"},{"internalType":"string[]","name":"symbols","type":"string[]"},{"internalType":"string[]","name":"names","type":"string[]"},{"internalType":"contract IERC721Partial[]","name":"collections","type":"address[]"},{"internalType":"uint256[][]","name":"validTokenIds","type":"uint256[][]"},{"internalType":"uint256[][]","name":"tokenIds","type":"uint256[][]"},{"internalType":"address[]","name":"creators","type":"address[]"},{"internalType":"uint256[][]","name":"stats","type":"uint256[][]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUmswapsLength","outputs":[{"internalType":"uint256","name":"_length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"isValidName","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"contract IERC721Partial","name":"collection","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"newUmswap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"umswapOrCollection","type":"address"},{"internalType":"string","name":"topic","type":"string"},{"internalType":"string","name":"text","type":"string"}],"name":"sendMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"template","outputs":[{"internalType":"contract Umswap","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"umswaps","outputs":[{"internalType":"contract Umswap","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5060405161001d9061005f565b604051809103906000f080158015610039573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b039290921691909117905561006c565b6129e68061191783390190565b61189c8061007b6000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80634d6bd2141161005b5780634d6bd214146100d05780636c625498146100f75780636f2ddd93146101225780638945f0541461013557600080fd5b80631e30397f146100825780632b07439f146100aa5780633218b75e146100bf575b600080fd5b610095610090366004610e3e565b610148565b60405190151581526020015b60405180910390f35b6100bd6100b8366004610f1d565b6102ba565b005b6001546040519081526020016100a1565b6100e36100de366004610fd4565b61044e565b6040516100a19897969594939291906111de565b61010a6101053660046112bd565b6108d0565b6040516001600160a01b0390911681526020016100a1565b60005461010a906001600160a01b031681565b6100bd6101433660046112d6565b6108fa565b60008082905060018151108061015f575060308151115b1561016d5750600092915050565b8051600160fd1b90829060009061018657610186611385565b01602001516001600160f81b03191614806101d357508051600160fd1b9082906101b2906001906113b1565b815181106101c2576101c2611385565b01602001516001600160f81b031916145b156101e15750600092915050565b6000816000815181106101f6576101f6611385565b01602001516001600160f81b031916905060005b82518110156102af57600083828151811061022757610227611385565b01602001516001600160f81b0319169050600160fd1b8114801561025857506001600160f81b03198316600160fd1b145b156102695750600095945050505050565b600160fd1b6001600160f81b03198216108015906102955750603f60f91b6001600160f81b0319821611155b6102a55750600095945050505050565b915060010161020a565b506001949350505050565b600084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250508251929350505060301015610318576040516369585f9960e01b815260040160405180910390fd5b600083838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050600190911090508061036857506101188151115b1561038657604051636eca2e4b60e01b815260040160405180910390fd5b6001600160a01b038716158015906103b757506001600160a01b03871660009081526002602052604090205460ff16155b80156103c957506103c787610bad565b155b156103e75760405163070845df60e31b815260040160405180910390fd5b866001600160a01b0316886001600160a01b0316336001600160a01b03167fecf7cba0a43f1cd8521a490776b3d7ce17c6521eb4e164acede254de0551ba7f428a8a8a8a60405161043c9594939291906113f3565b60405180910390a45050505050505050565b606080606080606080606080600089519050806001600160401b0381111561047857610478610dd1565b6040519080825280602002602001820160405280156104a1578160200160208202803683370190505b509850806001600160401b038111156104bc576104bc610dd1565b6040519080825280602002602001820160405280156104ef57816020015b60608152602001906001900390816104da5790505b509750806001600160401b0381111561050a5761050a610dd1565b60405190808252806020026020018201604052801561053d57816020015b60608152602001906001900390816105285790505b509650806001600160401b0381111561055857610558610dd1565b604051908082528060200260200182016040528015610581578160200160208202803683370190505b509550806001600160401b0381111561059c5761059c610dd1565b6040519080825280602002602001820160405280156105cf57816020015b60608152602001906001900390816105ba5790505b509450806001600160401b038111156105ea576105ea610dd1565b60405190808252806020026020018201604052801561061d57816020015b60608152602001906001900390816106085790505b509350806001600160401b0381111561063857610638610dd1565b604051908082528060200260200182016040528015610661578160200160208202803683370190505b509250806001600160401b0381111561067c5761067c610dd1565b6040519080825280602002602001820160405280156106af57816020015b606081526020019060019003908161069a5790505b50915060005b818110156108c15760018b82815181106106d1576106d1611385565b6020026020010151815481106106e9576106e9611385565b9060005260206000200160009054906101000a90046001600160a01b03168a828151811061071957610719611385565b60200260200101906001600160a01b031690816001600160a01b03168152505060018b828151811061074d5761074d611385565b60200260200101518154811061076557610765611385565b60009182526020909120015460405160016222a30f60e01b031981526001600160a01b038e811660048301529091169063ffdd5cf190602401600060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107e391908101906114ea565b8f88815181106107f5576107f5611385565b602002602001018f898151811061080e5761080e611385565b602002602001018f8a8151811061082757610827611385565b602002602001018f8b8151811061084057610840611385565b602002602001018f8c8151811061085957610859611385565b602002602001018f8d8151811061087257610872611385565b602002602001018f8e8151811061088b5761088b611385565b60209081029190910101969096526001600160a01b039687169095529590935294909352931690925291909152526001016106b5565b50509295985092959890939650565b600181815481106108e057600080fd5b6000918252602090912001546001600160a01b0316905081565b61090385610bad565b61092057604051635444e56f60e01b815260040160405180910390fd5b61095f84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014892505050565b61097c5760405163430f13b360e01b815260040160405180910390fd5b80156109f35760015b818110156109f15782828281811061099f5761099f611385565b9050602002013583836001846109b591906113b1565b8181106109c4576109c4611385565b90506020020135106109e957604051638578e98b60e01b815260040160405180910390fd5b600101610985565b505b6000858383604051602001610a0a939291906115dc565b60408051601f1981840301815291815281516020928301206000818152600390935291205490915060ff1615610a535760405163161b26bb60e31b815260040160405180910390fd5b6000818152600360205260408120805460ff191660011790558054610a80906001600160a01b0316610c33565b9050806001600160a01b031663df57849c3389610aa1600180549050610c85565b8a8a8a8a6040518863ffffffff1660e01b8152600401610ac79796959493929190611654565b600060405180830381600087803b158015610ae157600080fd5b505af1158015610af5573d6000803e3d6000fd5b50506001805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0386811691821790925560008181526002602052604090819020805460ff19169094179093559151908b16935090915033907f077e1cf6babf9ad326aba5f77f1dc9829deb8eb27be7e883108bb3837ad0214e90610b9c9042908c908c908c908c906116b6565b60405180910390a450505050505050565b60006001600160a01b0382163b15610c2e576040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610c26575060408051601f3d908101601f19168201909252610c23918101906116e3565b60015b15610c2e5790505b919050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b60408051600880825281830190925260609160009190602082018180368337019050509050600080805b60405180604001604052806003815260200162554d5360e81b81525051831015610d4e5760405180604001604052806003815260200162554d5360e81b8152508381518110610d0057610d00611385565b01602001516001600160f81b0319168483610d1a8161170c565b945081518110610d2c57610d2c611385565b60200101906001600160f81b031916908160001a905350600183019250610caf565b600592505b60001990920191610d6583600a611809565b610d6f908761182b565b90506030610d7e600a8361183f565b610d889190611853565b60f81b8483610d968161170c565b945081518110610da857610da8611385565b60200101906001600160f81b031916908160001a90535060008311610d53575091949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610e0f57610e0f610dd1565b604052919050565b60006001600160401b03821115610e3057610e30610dd1565b50601f01601f191660200190565b600060208284031215610e5057600080fd5b81356001600160401b03811115610e6657600080fd5b8201601f81018413610e7757600080fd5b8035610e8a610e8582610e17565b610de7565b818152856020838501011115610e9f57600080fd5b81602084016020830137600091810160200191909152949350505050565b6001600160a01b0381168114610ed257600080fd5b50565b60008083601f840112610ee757600080fd5b5081356001600160401b03811115610efe57600080fd5b602083019150836020828501011115610f1657600080fd5b9250929050565b60008060008060008060808789031215610f3657600080fd5b8635610f4181610ebd565b95506020870135610f5181610ebd565b945060408701356001600160401b0380821115610f6d57600080fd5b610f798a838b01610ed5565b90965094506060890135915080821115610f9257600080fd5b50610f9f89828a01610ed5565b979a9699509497509295939492505050565b60006001600160401b03821115610fca57610fca610dd1565b5060051b60200190565b60008060408385031215610fe757600080fd5b8235610ff281610ebd565b91506020838101356001600160401b0381111561100e57600080fd5b8401601f8101861361101f57600080fd5b803561102d610e8582610fb1565b81815260059190911b8201830190838101908883111561104c57600080fd5b928401925b8284101561106a57833582529284019290840190611051565b80955050505050509250929050565b60005b8381101561109457818101518382015260200161107c565b50506000910152565b600081518084526110b5816020860160208601611079565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b858110156111115782840389526110ff84835161109d565b988501989350908401906001016110e7565b5091979650505050505050565b600081518084526020808501945080840160005b838110156111575781516001600160a01b031687529582019590820190600101611132565b509495945050505050565b600081518084526020808501808196508360051b810191508286016000805b868110156111d0578385038a52825180518087529087019087870190845b818110156111bb5783518352928901929189019160010161119f565b50509a87019a95505091850191600101611181565b509298975050505050505050565b6101008082528951908201819052600090610120830190602090818d01845b828110156112225781516001600160a01b0316855293830193908301906001016111fd565b50505083820390840152611236818b6110c9565b9050828103604084015261124a818a6110c9565b9050828103606084015261125e818961111e565b905082810360808401526112728188611162565b905082810360a08401526112868187611162565b905082810360c084015261129a818661111e565b905082810360e08401526112ae8185611162565b9b9a5050505050505050505050565b6000602082840312156112cf57600080fd5b5035919050565b6000806000806000606086880312156112ee57600080fd5b85356112f981610ebd565b945060208601356001600160401b038082111561131557600080fd5b61132189838a01610ed5565b9096509450604088013591508082111561133a57600080fd5b818801915088601f83011261134e57600080fd5b81358181111561135d57600080fd5b8960208260051b850101111561137257600080fd5b9699959850939650602001949392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156113c4576113c461139b565b92915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b85815260606020820152600061140d6060830186886113ca565b82810360408401526114208185876113ca565b98975050505050505050565b600082601f83011261143d57600080fd5b815161144b610e8582610e17565b81815284602083860101111561146057600080fd5b611471826020830160208701611079565b949350505050565b8051610c2e81610ebd565b600082601f83011261149557600080fd5b815160206114a5610e8583610fb1565b82815260059290921b840181019181810190868411156114c457600080fd5b8286015b848110156114df57805183529183019183016114c8565b509695505050505050565b600080600080600080600060e0888a03121561150557600080fd5b87516001600160401b038082111561151c57600080fd5b6115288b838c0161142c565b985060208a015191508082111561153e57600080fd5b61154a8b838c0161142c565b975061155860408b01611479565b965060608a015191508082111561156e57600080fd5b61157a8b838c01611484565b955060808a015191508082111561159057600080fd5b61159c8b838c01611484565b94506115aa60a08b01611479565b935060c08a01519150808211156115c057600080fd5b506115cd8a828b01611484565b91505092959891949750929550565b606084901b6bffffffffffffffffffffffff1916815260006001600160fb1b0383111561160857600080fd5b8260051b8085601485013791909101601401949350505050565b81835260006001600160fb1b0383111561163b57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0388811682528716602082015260a0604082018190526000906116809083018861109d565b82810360608401526116938187896113ca565b905082810360808401526116a8818587611622565b9a9950505050505050505050565b8581526060602082015260006116d06060830186886113ca565b8281036040840152611420818587611622565b6000602082840312156116f557600080fd5b8151801515811461170557600080fd5b9392505050565b60006001820161171e5761171e61139b565b5060010190565b600181815b808511156117605781600019048211156117465761174661139b565b8085161561175357918102915b93841c939080029061172a565b509250929050565b600082611777575060016113c4565b81611784575060006113c4565b816001811461179a57600281146117a4576117c0565b60019150506113c4565b60ff8411156117b5576117b561139b565b50506001821b6113c4565b5060208310610133831016604e8410600b84101617156117e3575081810a6113c4565b6117ed8383611725565b80600019048211156118015761180161139b565b029392505050565b60006117058383611768565b634e487b7160e01b600052601260045260246000fd5b60008261183a5761183a611815565b500490565b60008261184e5761184e611815565b500690565b808201808211156113c4576113c461139b56fea2646970667358221220967314a9e33c71e3ec492a1d3a005496099490c1c4981592591bd61d128da8c964736f6c63430008110033608060405234801561001057600080fd5b506129c6806100206000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a9059cbb11610071578063a9059cbb14610295578063dd62ed3e146102a8578063df57849c146102e1578063e9d80bd1146102f4578063ffdd5cf11461030757600080fd5b806370a08231146101d75780638463b38b1461020057806395d89b411461022b5780639e01dfbb1461023357600080fd5b80632213ed62116100de5780632213ed621461017c57806323b872dd1461019c5780632c1b38ee146101af578063313ce567146101c257600080fd5b806306fdde0314610110578063095ea7b31461012e5780630a3cb72e1461015157806318160ddd14610166575b600080fd5b61011861032d565b6040516101259190612011565b60405180910390f35b61014161013c366004612043565b6103bf565b6040519015158152602001610125565b61016461015f3660046120ba565b61042c565b005b61016e610856565b604051908152602001610125565b61018f61018a36600461213b565b610894565b60405161012591906121f8565b6101416101aa366004612259565b6109a3565b6101416101bd36600461229a565b610a7e565b60035460405160ff9091168152602001610125565b61016e6101e53660046122b3565b6001600160a01b031660009081526005602052604090205490565b61021361020e36600461229a565b610c9c565b6040516001600160a01b039091168152602001610125565b610118610cc6565b61026e6102413660046122b3565b600f602052600090815260409020546001600160a01b03811690600160a01b90046001600160401b031682565b604080516001600160a01b0390931683526001600160401b03909116602083015201610125565b6101416102a3366004612043565b610cd5565b61016e6102b63660046122d0565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b6101646102ef36600461234a565b610d53565b610164610302366004612408565b610fdc565b61031a6103153660046122b3565b611228565b604051610125979695949392919061248e565b60606002805461033c90612516565b80601f016020809104026020016040519081016040528092919081815260200182805461036890612516565b80156103b55780601f1061038a576101008083540402835291602001916103b5565b820191906000526020600020905b81548152906001019060200180831161039857829003601f168201915b5050505050905090565b3360008181526006602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061041a9086815260200190565b60405180910390a35060015b92915050565b60075460010361044f57604051633fc62fc160e11b815260040160405180910390fd5b60016007558281111561050d57600061046a6012600a61264a565b6104748584612659565b61047e919061266c565b6040516370a0823160e01b815233600482015290915030906370a0823190602401602060405180830381865afa1580156104bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e09190612683565b81111561050057604051633394d6d360e01b815260040160405180910390fd5b61050a33826118c3565b50505b60005b838110156106435761053985858381811061052d5761052d61269c565b90506020020135610a7e565b61057b5784848281811061054f5761054f61269c565b9050602002013560405163ed15e6cf60e01b815260040161057291815260200190565b60405180910390fd5b6009546001600160a01b03166323b872dd33308888868181106105a0576105a061269c565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156105f757600080fd5b505af115801561060b573d6000803e3d6000fd5b5050505061063b8585838181106106245761062461269c565b90506020020135601161193790919063ffffffff16565b600101610510565b5060005b8181101561074b5761066483838381811061052d5761052d61269c565b61067a5782828281811061054f5761054f61269c565b6106a683838381811061068f5761068f61269c565b9050602002013560116119fd90919063ffffffff16565b6009546001600160a01b03166323b872dd30338686868181106106cb576106cb61269c565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561072257600080fd5b505af1158015610736573d6000803e3d6000fd5b505050506107448160010190565b9050610647565b508281101561077f5761077d336107646012600a61264a565b61076e8487612659565b610778919061266c565b611b28565b505b600e805484919060009061079d9084906001600160401b03166126b2565b82546101009290920a6001600160401b03818102199093169183160217909155600e805484935090916008916107dc918591600160401b9004166126b2565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555042336001600160a01b03167fd03d7fc2b11276326661de98a5f2efeeb83b095eb821f2f282e5f589c2d4a59f86868686600e60405161084395949392919061270b565b60405180910390a3505060026007555050565b600080805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460045461088f9190612659565b905090565b8051606090806001600160401b038111156108b1576108b1612125565b6040519080825280602002602001820160405280156108f657816020015b60408051808201909152600080825260208201528152602001906001900390816108cf5790505b50915060005b8181101561099c57600f60006010838154811061091b5761091b61269c565b6000918252602080832091909101546001600160a01b0390811684528382019490945260409283019091208251808401909352549283168252600160a01b9092046001600160401b03169181019190915283518490839081106109805761098061269c565b60200260200101819052506109958160010190565b90506108fc565b5050919050565b6001600160a01b0383166000908152600560205260408120805483919083906109cd908490612659565b90915550506001600160a01b038416600090815260066020908152604080832033845290915281208054849290610a05908490612659565b90915550506001600160a01b03831660009081526005602052604081208054849290610a3290849061276d565b92505081905550826001600160a01b0316846001600160a01b031660008051602061297183398151915284604051610a6c91815260200190565b60405180910390a35060019392505050565b600a5460009015610b0b57610426600a805480602002602001604051908101604052809291908181526020018280548015610b0057602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610ac75790505b505050505083611b9c565b600b5415610b9957610426600b805480602002602001604051908101604052809291908181526020018280548015610b8e57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610b515790505b505050505083611c6a565b600c5415610c2d57610426600c805480602002602001604051908101604052809291908181526020018280548015610c2257602002820191906000526020600020906000905b82829054906101000a90046001600160401b03166001600160401b031681526020019060080190602082600701049283019260010382029150808411610bdf5790505b505050505083611d23565b600d5415610c8f57610426600d805480602002602001604051908101604052809291908181526020018280548015610c8457602002820191906000526020600020905b815481526020019060010190808311610c70575b505050505083611de2565b506001919050565b919050565b60108181548110610cac57600080fd5b6000918252602090912001546001600160a01b0316905081565b60606001805461033c90612516565b33600090815260056020526040812080548391908390610cf6908490612659565b90915550506001600160a01b03831660009081526005602052604081208054849290610d2390849061276d565b90915550506040518281526001600160a01b0384169033906000805160206129718339815191529060200161041a565b600880546001600160a01b03808b166001600160a01b03199283161790925560098054928a1692909116919091179055604080516020601f8801819004810282018101909252868152610df791889088908190840183828082843760009201919091525050604080516020601f8a01819004810282018101909252888152925088915087908190840183828082843760009201919091525060129250611e8f915050565b6000805b82811015610e475781848483818110610e1657610e1661269c565b905060200201351115610e3f57838382818110610e3557610e3561269c565b9050602002013591505b600101610dfb565b5062010000811015610ec75760005b82811015610ec157600a848483818110610e7257610e7261269c565b835460018082018655600095865260209586902060108304018054600f9093166002026101000a61ffff8181021990941694909702959095013590911694909402179091555081019050610e56565b50610fd1565b640100000000811015610f445760005b82811015610ec157600b848483818110610ef357610ef361269c565b83546001808201865560009586526020958690206008830401805460079093166004026101000a63ffffffff8181021990941694909702959095013590911694909402179091555081019050610ed7565b600160401b811015610fc35760005b82811015610ec157600c848483818110610f6f57610f6f61269c565b83546001808201865560009586526020958690206004830401805460039093166008026101000a6001600160401b038181021990941694909702959095013590911694909402179091555081019050610f53565b610fcf600d8484611f6b565b505b505050505050505050565b600a831115611001576040516385de615f60e01b8152600a6004820152602401610572565b600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050506030101561105f57604051632d13d9f160e01b815260040160405180910390fd5b336000908152600f6020526040902080546001600160a01b031661111f57604080518082018252338082526001600160401b0380891660208085019182526000848152600f909152948520935184549151909216600160a01b026001600160e01b03199091166001600160a01b039290921691909117179091556010805460018101825592527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67290910180546001600160a01b031916909117905561118f565b8054600e80546001600160401b03600160a01b90930483169260109161114e918591600160801b900416612780565b82546101009290920a6001600160401b03818102199093169183160217909155825467ffffffffffffffff60a01b1916600160a01b91881691909102178255505b600e80548691906010906111b4908490600160801b90046001600160401b03166126b2565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555042336001600160a01b03167f645dc3ff76881bfb2bb80eaafe4f0e12fe5c517c3b5200ea9108bc6273ecaf05878787600e60405161121994939291906127a0565b60405180910390a35050505050565b6060806000606080600060606001805461124190612516565b80601f016020809104026020016040519081016040528092919081815260200182805461126d90612516565b80156112ba5780601f1061128f576101008083540402835291602001916112ba565b820191906000526020600020905b81548152906001019060200180831161129d57829003601f168201915b50505050509650600280546112ce90612516565b80601f01602080910402602001604051908101604052809291908181526020018280546112fa90612516565b80156113475780601f1061131c57610100808354040283529160200191611347565b820191906000526020600020905b81548152906001019060200180831161132a57829003601f168201915b5050600954600a54949a506001600160a01b031698505091159150611421905057600a546001600160401b0381111561138257611382612125565b6040519080825280602002602001820160405280156113ab578160200160208202803683370190505b50935060005b600a5481101561141b57600a81815481106113ce576113ce61269c565b90600052602060002090601091828204019190066002029054906101000a900461ffff1661ffff168582815181106114085761140861269c565b60209081029190910101526001016113b1565b50611655565b600b54156114e057600b546001600160401b0381111561144357611443612125565b60405190808252806020026020018201604052801561146c578160200160208202803683370190505b50935060005b600b5481101561141b57600b818154811061148f5761148f61269c565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff168582815181106114cd576114cd61269c565b6020908102919091010152600101611472565b600c54156115a557600c546001600160401b0381111561150257611502612125565b60405190808252806020026020018201604052801561152b578160200160208202803683370190505b50935060005b600c5481101561141b57600c818154811061154e5761154e61269c565b90600052602060002090600491828204019190066008029054906101000a90046001600160401b03166001600160401b03168582815181106115925761159261269c565b6020908102919091010152600101611531565b600d541561164357600d546001600160401b038111156115c7576115c7612125565b6040519080825280602002602001820160405280156115f0578160200160208202803683370190505b50935060005b600d5481101561141b57600d81815481106116135761161361269c565b90600052602060002001548582815181106116305761163061269c565b60209081029190910101526001016115f6565b60408051600081526020810190915293505b6012546001600160401b0381111561166f5761166f612125565b604051908082528060200260200182016040528015611698578160200160208202803683370190505b50925060005b6012548110156116ec5760128054829081106116bc576116bc61269c565b90600052602060002001548482815181106116d9576116d961269c565b602090810291909101015260010161169e565b5060085460408051600780825261010082019092526001600160a01b0390921693506020820160e0803683375050600e5482519293506001600160401b03169183915060009061173e5761173e61269c565b6020908102919091010152600e548151600160401b9091046001600160401b031690829060019081106117735761177361269c565b6020908102919091010152600e548151600160801b9091046001600160401b031690829060029081106117a8576117a861269c565b60209081029190910101526040516370a0823160e01b81526001600160a01b038916600482015230906370a0823190602401602060405180830381865afa1580156117f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181b9190612683565b8160038151811061182e5761182e61269c565b602002602001018181525050600454816004815181106118505761185061269c565b60209081029190910101526010548151829060059081106118735761187361269c565b60200260200101818152505061188888611ef3565b611893576000611896565b60015b60ff16816006815181106118ac576118ac61269c565b602002602001018181525050919395979092949650565b6001600160a01b0382166000908152600560205260408120805483919083906118ed908490612659565b9250508190555081600460008282546119069190612659565b90915550506040518281526000906001600160a01b038516906000805160206129718339815191529060200161041a565b6000818152602083905260409020546001600160401b03161561196d5760405163783c195960e11b815260040160405180910390fd5b600180830180548083018255600082815260209081902090910184905560408051606081019091526001600160401b034216815291549192908301916119b39190612659565b6001600160c01b03908116825260209182018490526000938452938152604092839020825191830151909416600160401b026001600160401b039091161783550151600190910155565b6000818152602083905260408120546001600160401b03169003611a345760405163c5723b5160e01b815260040160405180910390fd5b600081815260208390526040812054600180850154600160401b9092046001600160c01b03169291611a669190612659565b90506000846001018281548110611a7f57611a7f61269c565b9060005260206000200154905080856001018481548110611aa257611aa261269c565b60009182526020808320919091019290925582815290869052604080822080546001600160401b0316600160401b6001600160c01b03881602179055858252812081815560019081019190915585015415611b215784600101805480611b0a57611b0a612808565b600190038181906000526020600020016000905590555b5050505050565b6001600160a01b038216600090815260056020526040812080548391908390611b5290849061276d565b925050819055508160046000828254611b6b919061276d565b90915550506040518281526001600160a01b038416906000906000805160206129718339815191529060200161041a565b815160009015611c615760008060018551611bb79190612659565b905060005b818311611c5d576002611bcf838561276d565b611bd9919061281e565b905084868281518110611bee57611bee61269c565b602002602001015161ffff161015611c1257611c0b81600161276d565b9250611bbc565b84868281518110611c2557611c2561269c565b602002602001015161ffff161115611c515760018110611c5d57611c4a600182612659565b9150611bbc565b60019350505050610426565b5050505b50600092915050565b815160009015611c615760008060018551611c859190612659565b905060005b818311611c5d576002611c9d838561276d565b611ca7919061281e565b905084868281518110611cbc57611cbc61269c565b602002602001015163ffffffff161015611ce257611cdb81600161276d565b9250611c8a565b84868281518110611cf557611cf561269c565b602002602001015163ffffffff161115611c515760018110611c5d57611d1c600182612659565b9150611c8a565b815160009015611c615760008060018551611d3e9190612659565b905060005b818311611c5d576002611d56838561276d565b611d60919061281e565b905084868281518110611d7557611d7561269c565b60200260200101516001600160401b03161015611d9e57611d9781600161276d565b9250611d43565b84868281518110611db157611db161269c565b60200260200101516001600160401b03161115611c515760018110611c5d57611ddb600182612659565b9150611d43565b815160009015611c615760008060018551611dfd9190612659565b905060005b818311611c5d576002611e15838561276d565b611e1f919061281e565b905084868281518110611e3457611e3461269c565b60200260200101511015611e5457611e4d81600161276d565b9250611e02565b84868281518110611e6757611e6761269c565b60200260200101511115611c515760018110611c5d57611e88600182612659565b9150611e02565b60005460ff1615611eb357604051633c3282e760e01b815260040160405180910390fd5b6000805460ff19166001908117909155611ecd848261288f565b506002611eda838261288f565b506003805460ff191660ff929092169190911790555050565b60095460405163e985e9c560e01b81526001600160a01b038381166004830152306024830152600092169063e985e9c590604401602060405180830381865afa925050508015611f60575060408051601f3d908101601f19168201909252611f5d9181019061294e565b60015b15610c975792915050565b828054828255906000526020600020908101928215611fa6579160200282015b82811115611fa6578235825591602001919060010190611f8b565b50611fb2929150611fb6565b5090565b5b80821115611fb25760008155600101611fb7565b6000815180845260005b81811015611ff157602081850181015186830182015201611fd5565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006120246020830184611fcb565b9392505050565b6001600160a01b038116811461204057600080fd5b50565b6000806040838503121561205657600080fd5b82356120618161202b565b946020939093013593505050565b60008083601f84011261208157600080fd5b5081356001600160401b0381111561209857600080fd5b6020830191508360208260051b85010111156120b357600080fd5b9250929050565b600080600080604085870312156120d057600080fd5b84356001600160401b03808211156120e757600080fd5b6120f38883890161206f565b9096509450602087013591508082111561210c57600080fd5b506121198782880161206f565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561214e57600080fd5b82356001600160401b038082111561216557600080fd5b818501915085601f83011261217957600080fd5b81358181111561218b5761218b612125565b8060051b604051601f19603f830116810181811085821117156121b0576121b0612125565b6040529182528482019250838101850191888311156121ce57600080fd5b938501935b828510156121ec578435845293850193928501926121d3565b98975050505050505050565b602080825282518282018190526000919060409081850190868401855b8281101561224c57815180516001600160a01b031685528601516001600160401b0316868501529284019290850190600101612215565b5091979650505050505050565b60008060006060848603121561226e57600080fd5b83356122798161202b565b925060208401356122898161202b565b929592945050506040919091013590565b6000602082840312156122ac57600080fd5b5035919050565b6000602082840312156122c557600080fd5b81356120248161202b565b600080604083850312156122e357600080fd5b82356122ee8161202b565b915060208301356122fe8161202b565b809150509250929050565b60008083601f84011261231b57600080fd5b5081356001600160401b0381111561233257600080fd5b6020830191508360208285010111156120b357600080fd5b60008060008060008060008060a0898b03121561236657600080fd5b88356123718161202b565b975060208901356123818161202b565b965060408901356001600160401b038082111561239d57600080fd5b6123a98c838d01612309565b909850965060608b01359150808211156123c257600080fd5b6123ce8c838d01612309565b909650945060808b01359150808211156123e757600080fd5b506123f48b828c0161206f565b999c989b5096995094979396929594505050565b60008060006040848603121561241d57600080fd5b8335925060208401356001600160401b0381111561243a57600080fd5b61244686828701612309565b9497909650939450505050565b600081518084526020808501945080840160005b8381101561248357815187529582019590820190600101612467565b509495945050505050565b60e0815260006124a160e083018a611fcb565b82810360208401526124b3818a611fcb565b6001600160a01b03898116604086015284820360608601529091506124d88289612453565b915083820360808501526124ec8288612453565b90861660a085015283810360c085015290506125088185612453565b9a9950505050505050505050565b600181811c9082168061252a57607f821691505b60208210810361254a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156125a157816000190482111561258757612587612550565b8085161561259457918102915b93841c939080029061256b565b509250929050565b6000826125b857506001610426565b816125c557506000610426565b81600181146125db57600281146125e557612601565b6001915050610426565b60ff8411156125f6576125f6612550565b50506001821b610426565b5060208310610133831016604e8410600b8410161715612624575081810a610426565b61262e8383612566565b806000190482111561264257612642612550565b029392505050565b600061202460ff8416836125a9565b8181038181111561042657610426612550565b808202811582820484141761042657610426612550565b60006020828403121561269557600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6001600160401b038181168382160190808211156126d2576126d2612550565b5092915050565b81835260006001600160fb1b038311156126f257600080fd5b8260051b80836020870137939093016020019392505050565b60a08152600061271f60a0830187896126d9565b82810360208401526127328186886126d9565b9150506127636040830184546001600160401b038082168352604082811c8216602085015260809290921c16910152565b9695505050505050565b8082018082111561042657610426612550565b6001600160401b038281168282160390808211156126d2576126d2612550565b84815260a060208201528260a0820152828460c0830137600060c08483010152600060c0601f19601f86011683010190506127ff6040830184546001600160401b038082168352604082811c8216602085015260809290921c16910152565b95945050505050565b634e487b7160e01b600052603160045260246000fd5b60008261283b57634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561288a57600081815260208120601f850160051c810160208610156128675750805b601f850160051c820191505b8181101561288657828155600101612873565b5050505b505050565b81516001600160401b038111156128a8576128a8612125565b6128bc816128b68454612516565b84612840565b602080601f8311600181146128f157600084156128d95750858301515b600019600386901b1c1916600185901b178555612886565b600085815260208120601f198616915b8281101561292057888601518255948401946001909101908401612901565b508582101561293e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121561296057600080fd5b8151801515811461202457600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220d986ebd2e402b2027d02504ca9aa45b08b9e58fec2fce3f89e7259032e0ffab064736f6c63430008110033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80634d6bd2141161005b5780634d6bd214146100d05780636c625498146100f75780636f2ddd93146101225780638945f0541461013557600080fd5b80631e30397f146100825780632b07439f146100aa5780633218b75e146100bf575b600080fd5b610095610090366004610e3e565b610148565b60405190151581526020015b60405180910390f35b6100bd6100b8366004610f1d565b6102ba565b005b6001546040519081526020016100a1565b6100e36100de366004610fd4565b61044e565b6040516100a19897969594939291906111de565b61010a6101053660046112bd565b6108d0565b6040516001600160a01b0390911681526020016100a1565b60005461010a906001600160a01b031681565b6100bd6101433660046112d6565b6108fa565b60008082905060018151108061015f575060308151115b1561016d5750600092915050565b8051600160fd1b90829060009061018657610186611385565b01602001516001600160f81b03191614806101d357508051600160fd1b9082906101b2906001906113b1565b815181106101c2576101c2611385565b01602001516001600160f81b031916145b156101e15750600092915050565b6000816000815181106101f6576101f6611385565b01602001516001600160f81b031916905060005b82518110156102af57600083828151811061022757610227611385565b01602001516001600160f81b0319169050600160fd1b8114801561025857506001600160f81b03198316600160fd1b145b156102695750600095945050505050565b600160fd1b6001600160f81b03198216108015906102955750603f60f91b6001600160f81b0319821611155b6102a55750600095945050505050565b915060010161020a565b506001949350505050565b600084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250508251929350505060301015610318576040516369585f9960e01b815260040160405180910390fd5b600083838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050600190911090508061036857506101188151115b1561038657604051636eca2e4b60e01b815260040160405180910390fd5b6001600160a01b038716158015906103b757506001600160a01b03871660009081526002602052604090205460ff16155b80156103c957506103c787610bad565b155b156103e75760405163070845df60e31b815260040160405180910390fd5b866001600160a01b0316886001600160a01b0316336001600160a01b03167fecf7cba0a43f1cd8521a490776b3d7ce17c6521eb4e164acede254de0551ba7f428a8a8a8a60405161043c9594939291906113f3565b60405180910390a45050505050505050565b606080606080606080606080600089519050806001600160401b0381111561047857610478610dd1565b6040519080825280602002602001820160405280156104a1578160200160208202803683370190505b509850806001600160401b038111156104bc576104bc610dd1565b6040519080825280602002602001820160405280156104ef57816020015b60608152602001906001900390816104da5790505b509750806001600160401b0381111561050a5761050a610dd1565b60405190808252806020026020018201604052801561053d57816020015b60608152602001906001900390816105285790505b509650806001600160401b0381111561055857610558610dd1565b604051908082528060200260200182016040528015610581578160200160208202803683370190505b509550806001600160401b0381111561059c5761059c610dd1565b6040519080825280602002602001820160405280156105cf57816020015b60608152602001906001900390816105ba5790505b509450806001600160401b038111156105ea576105ea610dd1565b60405190808252806020026020018201604052801561061d57816020015b60608152602001906001900390816106085790505b509350806001600160401b0381111561063857610638610dd1565b604051908082528060200260200182016040528015610661578160200160208202803683370190505b509250806001600160401b0381111561067c5761067c610dd1565b6040519080825280602002602001820160405280156106af57816020015b606081526020019060019003908161069a5790505b50915060005b818110156108c15760018b82815181106106d1576106d1611385565b6020026020010151815481106106e9576106e9611385565b9060005260206000200160009054906101000a90046001600160a01b03168a828151811061071957610719611385565b60200260200101906001600160a01b031690816001600160a01b03168152505060018b828151811061074d5761074d611385565b60200260200101518154811061076557610765611385565b60009182526020909120015460405160016222a30f60e01b031981526001600160a01b038e811660048301529091169063ffdd5cf190602401600060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107e391908101906114ea565b8f88815181106107f5576107f5611385565b602002602001018f898151811061080e5761080e611385565b602002602001018f8a8151811061082757610827611385565b602002602001018f8b8151811061084057610840611385565b602002602001018f8c8151811061085957610859611385565b602002602001018f8d8151811061087257610872611385565b602002602001018f8e8151811061088b5761088b611385565b60209081029190910101969096526001600160a01b039687169095529590935294909352931690925291909152526001016106b5565b50509295985092959890939650565b600181815481106108e057600080fd5b6000918252602090912001546001600160a01b0316905081565b61090385610bad565b61092057604051635444e56f60e01b815260040160405180910390fd5b61095f84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014892505050565b61097c5760405163430f13b360e01b815260040160405180910390fd5b80156109f35760015b818110156109f15782828281811061099f5761099f611385565b9050602002013583836001846109b591906113b1565b8181106109c4576109c4611385565b90506020020135106109e957604051638578e98b60e01b815260040160405180910390fd5b600101610985565b505b6000858383604051602001610a0a939291906115dc565b60408051601f1981840301815291815281516020928301206000818152600390935291205490915060ff1615610a535760405163161b26bb60e31b815260040160405180910390fd5b6000818152600360205260408120805460ff191660011790558054610a80906001600160a01b0316610c33565b9050806001600160a01b031663df57849c3389610aa1600180549050610c85565b8a8a8a8a6040518863ffffffff1660e01b8152600401610ac79796959493929190611654565b600060405180830381600087803b158015610ae157600080fd5b505af1158015610af5573d6000803e3d6000fd5b50506001805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0386811691821790925560008181526002602052604090819020805460ff19169094179093559151908b16935090915033907f077e1cf6babf9ad326aba5f77f1dc9829deb8eb27be7e883108bb3837ad0214e90610b9c9042908c908c908c908c906116b6565b60405180910390a450505050505050565b60006001600160a01b0382163b15610c2e576040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015610c26575060408051601f3d908101601f19168201909252610c23918101906116e3565b60015b15610c2e5790505b919050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b60408051600880825281830190925260609160009190602082018180368337019050509050600080805b60405180604001604052806003815260200162554d5360e81b81525051831015610d4e5760405180604001604052806003815260200162554d5360e81b8152508381518110610d0057610d00611385565b01602001516001600160f81b0319168483610d1a8161170c565b945081518110610d2c57610d2c611385565b60200101906001600160f81b031916908160001a905350600183019250610caf565b600592505b60001990920191610d6583600a611809565b610d6f908761182b565b90506030610d7e600a8361183f565b610d889190611853565b60f81b8483610d968161170c565b945081518110610da857610da8611385565b60200101906001600160f81b031916908160001a90535060008311610d53575091949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610e0f57610e0f610dd1565b604052919050565b60006001600160401b03821115610e3057610e30610dd1565b50601f01601f191660200190565b600060208284031215610e5057600080fd5b81356001600160401b03811115610e6657600080fd5b8201601f81018413610e7757600080fd5b8035610e8a610e8582610e17565b610de7565b818152856020838501011115610e9f57600080fd5b81602084016020830137600091810160200191909152949350505050565b6001600160a01b0381168114610ed257600080fd5b50565b60008083601f840112610ee757600080fd5b5081356001600160401b03811115610efe57600080fd5b602083019150836020828501011115610f1657600080fd5b9250929050565b60008060008060008060808789031215610f3657600080fd5b8635610f4181610ebd565b95506020870135610f5181610ebd565b945060408701356001600160401b0380821115610f6d57600080fd5b610f798a838b01610ed5565b90965094506060890135915080821115610f9257600080fd5b50610f9f89828a01610ed5565b979a9699509497509295939492505050565b60006001600160401b03821115610fca57610fca610dd1565b5060051b60200190565b60008060408385031215610fe757600080fd5b8235610ff281610ebd565b91506020838101356001600160401b0381111561100e57600080fd5b8401601f8101861361101f57600080fd5b803561102d610e8582610fb1565b81815260059190911b8201830190838101908883111561104c57600080fd5b928401925b8284101561106a57833582529284019290840190611051565b80955050505050509250929050565b60005b8381101561109457818101518382015260200161107c565b50506000910152565b600081518084526110b5816020860160208601611079565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b858110156111115782840389526110ff84835161109d565b988501989350908401906001016110e7565b5091979650505050505050565b600081518084526020808501945080840160005b838110156111575781516001600160a01b031687529582019590820190600101611132565b509495945050505050565b600081518084526020808501808196508360051b810191508286016000805b868110156111d0578385038a52825180518087529087019087870190845b818110156111bb5783518352928901929189019160010161119f565b50509a87019a95505091850191600101611181565b509298975050505050505050565b6101008082528951908201819052600090610120830190602090818d01845b828110156112225781516001600160a01b0316855293830193908301906001016111fd565b50505083820390840152611236818b6110c9565b9050828103604084015261124a818a6110c9565b9050828103606084015261125e818961111e565b905082810360808401526112728188611162565b905082810360a08401526112868187611162565b905082810360c084015261129a818661111e565b905082810360e08401526112ae8185611162565b9b9a5050505050505050505050565b6000602082840312156112cf57600080fd5b5035919050565b6000806000806000606086880312156112ee57600080fd5b85356112f981610ebd565b945060208601356001600160401b038082111561131557600080fd5b61132189838a01610ed5565b9096509450604088013591508082111561133a57600080fd5b818801915088601f83011261134e57600080fd5b81358181111561135d57600080fd5b8960208260051b850101111561137257600080fd5b9699959850939650602001949392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156113c4576113c461139b565b92915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b85815260606020820152600061140d6060830186886113ca565b82810360408401526114208185876113ca565b98975050505050505050565b600082601f83011261143d57600080fd5b815161144b610e8582610e17565b81815284602083860101111561146057600080fd5b611471826020830160208701611079565b949350505050565b8051610c2e81610ebd565b600082601f83011261149557600080fd5b815160206114a5610e8583610fb1565b82815260059290921b840181019181810190868411156114c457600080fd5b8286015b848110156114df57805183529183019183016114c8565b509695505050505050565b600080600080600080600060e0888a03121561150557600080fd5b87516001600160401b038082111561151c57600080fd5b6115288b838c0161142c565b985060208a015191508082111561153e57600080fd5b61154a8b838c0161142c565b975061155860408b01611479565b965060608a015191508082111561156e57600080fd5b61157a8b838c01611484565b955060808a015191508082111561159057600080fd5b61159c8b838c01611484565b94506115aa60a08b01611479565b935060c08a01519150808211156115c057600080fd5b506115cd8a828b01611484565b91505092959891949750929550565b606084901b6bffffffffffffffffffffffff1916815260006001600160fb1b0383111561160857600080fd5b8260051b8085601485013791909101601401949350505050565b81835260006001600160fb1b0383111561163b57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0388811682528716602082015260a0604082018190526000906116809083018861109d565b82810360608401526116938187896113ca565b905082810360808401526116a8818587611622565b9a9950505050505050505050565b8581526060602082015260006116d06060830186886113ca565b8281036040840152611420818587611622565b6000602082840312156116f557600080fd5b8151801515811461170557600080fd5b9392505050565b60006001820161171e5761171e61139b565b5060010190565b600181815b808511156117605781600019048211156117465761174661139b565b8085161561175357918102915b93841c939080029061172a565b509250929050565b600082611777575060016113c4565b81611784575060006113c4565b816001811461179a57600281146117a4576117c0565b60019150506113c4565b60ff8411156117b5576117b561139b565b50506001821b6113c4565b5060208310610133831016604e8410600b84101617156117e3575081810a6113c4565b6117ed8383611725565b80600019048211156118015761180161139b565b029392505050565b60006117058383611768565b634e487b7160e01b600052601260045260246000fd5b60008261183a5761183a611815565b500490565b60008261184e5761184e611815565b500690565b808201808211156113c4576113c461139b56fea2646970667358221220967314a9e33c71e3ec492a1d3a005496099490c1c4981592591bd61d128da8c964736f6c63430008110033

Deployed Bytecode Sourcemap

20229:6491:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22470:686;;;;;;:::i;:::-;;:::i;:::-;;;1461:14:1;;1454:22;1436:41;;1424:2;1409:18;22470:686:0;;;;;;;;24847:713;;;;;;:::i;:::-;;:::i;:::-;;25568:103;25649:7;:14;25568:103;;3126:25:1;;;3114:2;3099:18;25568:103:0;2980:177:1;25679:1038:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;:::i;20627:23::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9841:32:1;;;9823:51;;9811:2;9796:18;20627:23:0;9662:218:1;20598:22:0;;;;;-1:-1:-1;;;;;20598:22:0;;;23418:1057;;;;;;:::i;:::-;;:::i;22470:686::-;22531:4;22548:14;22571:3;22548:27;;22601:1;22590;:8;:12;:40;;;;20507:2;22606:1;:8;:24;22590:40;22586:85;;;-1:-1:-1;22654:5:0;;22470:686;-1:-1:-1;;22470:686:0:o;22586:85::-;22685:4;;-1:-1:-1;;;22693:5:0;22685:1;;22687;;22685:4;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;22685:4:0;:13;;:39;;-1:-1:-1;22704:8:0;;-1:-1:-1;;;22719:5:0;22702:1;;22704:10;;22713:1;;22704:10;:::i;:::-;22702:13;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;22702:13:0;:22;22685:39;22681:84;;;-1:-1:-1;22748:5:0;;22470:686;-1:-1:-1;;22470:686:0:o;22681:84::-;22775:15;22793:1;22795;22793:4;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;22793:4:0;;-1:-1:-1;22813:6:0;22808:319;22825:1;:8;22821:1;:12;22808:319;;;22866:11;22880:1;22882;22880:4;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;22880:4:0;;-1:-1:-1;;;;22903:13:0;;:34;;;;-1:-1:-1;;;;;;;22920:17:0;;-1:-1:-1;;;22920:17:0;22903:34;22899:87;;;-1:-1:-1;22965:5:0;;22470:686;-1:-1:-1;;;;;22470:686:0:o;22899:87::-;-1:-1:-1;;;;;;;;;23006:13:0;;;;;;:30;;-1:-1:-1;;;;;;;;;;23023:13:0;;;;23006:30;23000:86;;-1:-1:-1;23065:5:0;;22470:686;-1:-1:-1;;;;;22470:686:0:o;23000:86::-;23111:4;-1:-1:-1;8490:1:0;:5;22808:319;;;-1:-1:-1;23144:4:0;;22470:686;-1:-1:-1;;;;22470:686:0:o;24847:713::-;24971:23;25003:5;;24971:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25024:17:0;;24971:38;;-1:-1:-1;;;20547:2:0;-1:-1:-1;25020:88:0;;;25082:14;;-1:-1:-1;;;25082:14:0;;;;;;;;;;;25020:88;25118:22;25149:4;;25118:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25169:16:0;;25118:36;;-1:-1:-1;;25188:1:0;25169:20;;;;-1:-1:-1;25169:20:0;:56;;;20586:3;25193:9;:16;:32;25169:56;25165:112;;;25249:16;;-1:-1:-1;;;25249:16:0;;;;;;;;;;;25165:112;-1:-1:-1;;;;;25291:32:0;;;;;;:77;;-1:-1:-1;;;;;;25328:40:0;;;;;;:12;:40;;;;;;;;25327:41;25291:77;:110;;;;;25373:28;25382:18;25373:8;:28::i;:::-;25372:29;25291:110;25287:177;;;25425:27;;-1:-1:-1;;;25425:27:0;;;;;;;;;;;25287:177;25520:18;-1:-1:-1;;;;;25479:73:0;25516:2;-1:-1:-1;;;;;25479:73:0;25487:10;-1:-1:-1;;;;;25479:73:0;;25499:15;25540:5;;25547:4;;25479:73;;;;;;;;;;:::i;:::-;;;;;;;;24960:600;;24847:713;;;;;;:::o;25679:1038::-;25773:24;25808:23;25842:21;25874:35;25920:29;25960:24;25995:25;26031:21;26071:11;26085:7;:14;26071:28;;26134:6;-1:-1:-1;;;;;26121:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26121:20:0;;26110:31;;26175:6;-1:-1:-1;;;;;26162:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26152:30;;26214:6;-1:-1:-1;;;;;26201:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26193:28;;26267:6;-1:-1:-1;;;;;26246:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26246:28:0;;26232:42;;26314:6;-1:-1:-1;;;;;26301:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26285:36;;26356:6;-1:-1:-1;;;;;26343:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26332:31;;26399:6;-1:-1:-1;;;;;26385:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26385:21:0;;26374:32;;26438:6;-1:-1:-1;;;;;26425:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26417:28;;26461:6;26456:254;26477:6;26473:1;:10;26456:254;;;26530:7;26538;26546:1;26538:10;;;;;;;;:::i;:::-;;;;;;;26530:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26530:19:0;26516:8;26525:1;26516:11;;;;;;;;:::i;:::-;;;;;;:33;-1:-1:-1;;;;;26516:33:0;;;-1:-1:-1;;;;;26516:33:0;;;;;26659:7;26667;26675:1;26667:10;;;;;;;;:::i;:::-;;;;;;;26659:19;;;;;;;;:::i;:::-;;;;;;;;;;;:39;;-1:-1:-1;;;;;;26659:39:0;;-1:-1:-1;;;;;9841:32:1;;;26659:39:0;;;9823:51:1;26659:19:0;;;;:27;;9796:18:1;;26659:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26659:39:0;;;;;;;;;;;;:::i;:::-;26565:7;26573:1;26565:10;;;;;;;;:::i;:::-;;;;;;26577:5;26583:1;26577:8;;;;;;;;:::i;:::-;;;;;;26587:11;26599:1;26587:14;;;;;;;;:::i;:::-;;;;;;26603:13;26617:1;26603:16;;;;;;;;:::i;:::-;;;;;;26621:8;26630:1;26621:11;;;;;;;;:::i;:::-;;;;;;26634:8;26643:1;26634:11;;;;;;;;:::i;:::-;;;;;;26647:5;26653:1;26647:8;;;;;;;;:::i;:::-;;;;;;;;;;26564:134;;;;-1:-1:-1;;;;;26564:134:0;;;;;;;;;;;;;;;;;;;;;;;;8490:1;:5;26456:254;;;;26060:657;25679:1038;;;;;;;;;;;:::o;20627:23::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20627:23:0;;-1:-1:-1;20627:23:0;:::o;23418:1057::-;23535:29;23552:10;23535:8;:29::i;:::-;23530:81;;23588:11;;-1:-1:-1;;;23588:11:0;;;;;;;;;;;23530:81;23626:17;23638:4;;23626:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23626:11:0;;-1:-1:-1;;;23626:17:0:i;:::-;23621:71;;23667:13;;-1:-1:-1;;;23667:13:0;;;;;;;;;;;23621:71;23706:19;;23702:263;;23756:1;23742:212;23759:19;;;23742:212;;;23838:8;;23847:1;23838:11;;;;;;;:::i;:::-;;;;;;;23819:8;;23832:1;23828;:5;;;;:::i;:::-;23819:15;;;;;;;:::i;:::-;;;;;;;:30;23815:124;;23881:38;;-1:-1:-1;;;23881:38:0;;;;;;;;;;;23815:124;8490:1;:5;23742:212;;;;23702:263;23975:11;24016:10;24028:8;;23999:38;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;23999:38:0;;;;;;;;;23989:49;;23999:38;23989:49;;;;24053:14;;;;:9;:14;;;;;;23989:49;;-1:-1:-1;24053:14:0;;24049:68;;;24091:14;;-1:-1:-1;;;24091:14:0;;;;;;;;;;;24049:68;24127:14;;;;:9;:14;;;;;:21;;-1:-1:-1;;24127:21:0;24144:4;24127:21;;;24202:8;;24182:30;;-1:-1:-1;;;;;24202:8:0;24182:11;:30::i;:::-;24159:54;;24224:6;-1:-1:-1;;;;;24224:17:0;;24242:10;24254;24266:25;24276:7;:14;;;;24266:9;:25::i;:::-;24293:4;;24299:8;;24224:84;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;24319:7:0;:20;;;;;;;;;;;-1:-1:-1;;;;;;24319:20:0;-1:-1:-1;;;;;24319:20:0;;;;;;;;;-1:-1:-1;24350:20:0;;;:12;24319:20;24350;;;;;;:27;;-1:-1:-1;;24350:27:0;;;;;;;24393:74;;;;;;-1:-1:-1;24319:20:0;;-1:-1:-1;24403:10:0;;24393:74;;;;24415:15;;24452:4;;;;24458:8;;;;24393:74;:::i;:::-;;;;;;;;23519:956;;23418:1057;;;;;:::o;21433:279::-;21489:6;-1:-1:-1;;;;;21512:17:0;;;:21;21508:197;;21554:57;;-1:-1:-1;;;21554:57:0;;-1:-1:-1;;;21554:57:0;;;17485:52:1;-1:-1:-1;;;;;21554:39:0;;;;;17458:18:1;;21554:57:0;;;;;;;;;;;;;;;;;;-1:-1:-1;21554:57:0;;;;;;;;-1:-1:-1;;21554:57:0;;;;;;;;;;;;:::i;:::-;;;21550:144;;;21653:2;-1:-1:-1;21550:144:0;21433:279;;;:::o;1966:450::-;2021:14;2044:19;2074:6;2066:15;;2044:37;;2125:4;2119:11;-1:-1:-1;;;2145:5:0;2138:81;2252:11;2245:4;2238:5;2234:16;2227:37;-1:-1:-1;;;2290:4:0;2283:5;2279:16;2272:92;2399:4;2392:5;2389:1;2382:22;2372:32;1966:450;-1:-1:-1;;;;1966:450:0:o;21720:523::-;21816:12;;;21826:1;21816:12;;;;;;;;;21771:15;;21799:14;;21816:12;;;;;;;;;;;-1:-1:-1;;21799:29:0;-1:-1:-1;21839:6:0;;;21892:108;21908:14;;;;;;;;;;;;;-1:-1:-1;;;21908:14:0;;;:21;21904:1;:25;21892:108;;;21971:14;;;;;;;;;;;;;-1:-1:-1;;;21971:14:0;;;21986:1;21971:17;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;21971:17:0;21962:1;21964:3;;;;:::i;:::-;;;21962:6;;;;;;;;:::i;:::-;;;;:26;-1:-1:-1;;;;;21962:26:0;;;;;;;;-1:-1:-1;8490:1:0;:5;;21931:14;;21892:108;;;22014:1;22010:5;;22026:186;-1:-1:-1;;22073:3:0;;;;22117:7;22073:3;22117:2;:7;:::i;:::-;22112:12;;:2;:12;:::i;:::-;22106:18;-1:-1:-1;20335:4:0;22161:8;22167:2;22106:18;22161:8;:::i;:::-;:22;;;;:::i;:::-;22148:37;;22139:1;22141:3;;;;:::i;:::-;;;22139:6;;;;;;;;:::i;:::-;;;;:46;-1:-1:-1;;;;;22139:46:0;;;;;;;;;22209:1;22205;:5;22026:186;;-1:-1:-1;22233:1:0;;21720:523;-1:-1:-1;;;;21720:523:0:o;14:127:1:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:275;217:2;211:9;282:2;263:13;;-1:-1:-1;;259:27:1;247:40;;-1:-1:-1;;;;;302:34:1;;338:22;;;299:62;296:88;;;364:18;;:::i;:::-;400:2;393:22;146:275;;-1:-1:-1;146:275:1:o;426:187::-;475:4;-1:-1:-1;;;;;500:6:1;497:30;494:56;;;530:18;;:::i;:::-;-1:-1:-1;596:2:1;575:15;-1:-1:-1;;571:29:1;602:4;567:40;;426:187::o;618:673::-;687:6;740:2;728:9;719:7;715:23;711:32;708:52;;;756:1;753;746:12;708:52;796:9;783:23;-1:-1:-1;;;;;821:6:1;818:30;815:50;;;861:1;858;851:12;815:50;884:22;;937:4;929:13;;925:27;-1:-1:-1;915:55:1;;966:1;963;956:12;915:55;1002:2;989:16;1027:49;1043:32;1072:2;1043:32;:::i;:::-;1027:49;:::i;:::-;1099:2;1092:5;1085:17;1139:7;1134:2;1129;1125;1121:11;1117:20;1114:33;1111:53;;;1160:1;1157;1150:12;1111:53;1215:2;1210;1206;1202:11;1197:2;1190:5;1186:14;1173:45;1259:1;1238:14;;;1254:2;1234:23;1227:34;;;;1242:5;618:673;-1:-1:-1;;;;618:673:1:o;1488:131::-;-1:-1:-1;;;;;1563:31:1;;1553:42;;1543:70;;1609:1;1606;1599:12;1543:70;1488:131;:::o;1624:348::-;1676:8;1686:6;1740:3;1733:4;1725:6;1721:17;1717:27;1707:55;;1758:1;1755;1748:12;1707:55;-1:-1:-1;1781:20:1;;-1:-1:-1;;;;;1813:30:1;;1810:50;;;1856:1;1853;1846:12;1810:50;1893:4;1885:6;1881:17;1869:29;;1945:3;1938:4;1929:6;1921;1917:19;1913:30;1910:39;1907:59;;;1962:1;1959;1952:12;1907:59;1624:348;;;;;:::o;1977:998::-;2087:6;2095;2103;2111;2119;2127;2180:3;2168:9;2159:7;2155:23;2151:33;2148:53;;;2197:1;2194;2187:12;2148:53;2236:9;2223:23;2255:31;2280:5;2255:31;:::i;:::-;2305:5;-1:-1:-1;2362:2:1;2347:18;;2334:32;2375:33;2334:32;2375:33;:::i;:::-;2427:7;-1:-1:-1;2485:2:1;2470:18;;2457:32;-1:-1:-1;;;;;2538:14:1;;;2535:34;;;2565:1;2562;2555:12;2535:34;2604:59;2655:7;2646:6;2635:9;2631:22;2604:59;:::i;:::-;2682:8;;-1:-1:-1;2578:85:1;-1:-1:-1;2770:2:1;2755:18;;2742:32;;-1:-1:-1;2786:16:1;;;2783:36;;;2815:1;2812;2805:12;2783:36;;2854:61;2907:7;2896:8;2885:9;2881:24;2854:61;:::i;:::-;1977:998;;;;-1:-1:-1;1977:998:1;;-1:-1:-1;1977:998:1;;2934:8;;1977:998;-1:-1:-1;;;1977:998:1:o;3162:183::-;3222:4;-1:-1:-1;;;;;3247:6:1;3244:30;3241:56;;;3277:18;;:::i;:::-;-1:-1:-1;3322:1:1;3318:14;3334:4;3314:25;;3162:183::o;3350:1026::-;3443:6;3451;3504:2;3492:9;3483:7;3479:23;3475:32;3472:52;;;3520:1;3517;3510:12;3472:52;3559:9;3546:23;3578:31;3603:5;3578:31;:::i;:::-;3628:5;-1:-1:-1;3652:2:1;3690:18;;;3677:32;-1:-1:-1;;;;;3721:30:1;;3718:50;;;3764:1;3761;3754:12;3718:50;3787:22;;3840:4;3832:13;;3828:27;-1:-1:-1;3818:55:1;;3869:1;3866;3859:12;3818:55;3905:2;3892:16;3928:60;3944:43;3984:2;3944:43;:::i;3928:60::-;4022:15;;;4104:1;4100:10;;;;4092:19;;4088:28;;;4053:12;;;;4128:19;;;4125:39;;;4160:1;4157;4150:12;4125:39;4184:11;;;;4204:142;4220:6;4215:3;4212:15;4204:142;;;4286:17;;4274:30;;4237:12;;;;4324;;;;4204:142;;;4365:5;4355:15;;;;;;;3350:1026;;;;;:::o;4381:250::-;4466:1;4476:113;4490:6;4487:1;4484:13;4476:113;;;4566:11;;;4560:18;4547:11;;;4540:39;4512:2;4505:10;4476:113;;;-1:-1:-1;;4623:1:1;4605:16;;4598:27;4381:250::o;4636:271::-;4678:3;4716:5;4710:12;4743:6;4738:3;4731:19;4759:76;4828:6;4821:4;4816:3;4812:14;4805:4;4798:5;4794:16;4759:76;:::i;:::-;4889:2;4868:15;-1:-1:-1;;4864:29:1;4855:39;;;;4896:4;4851:50;;4636:271;-1:-1:-1;;4636:271:1:o;4912:616::-;4964:3;5002:5;4996:12;5029:6;5024:3;5017:19;5055:4;5096:2;5091:3;5087:12;5121:11;5148;5141:18;;5198:6;5195:1;5191:14;5184:5;5180:26;5168:38;;5240:2;5233:5;5229:14;5261:1;5271:231;5285:6;5282:1;5279:13;5271:231;;;5356:5;5350:4;5346:16;5341:3;5334:29;5384:38;5417:4;5408:6;5402:13;5384:38;:::i;:::-;5480:12;;;;5376:46;-1:-1:-1;5445:15:1;;;;5307:1;5300:9;5271:231;;;-1:-1:-1;5518:4:1;;4912:616;-1:-1:-1;;;;;;;4912:616:1:o;5533:477::-;5602:3;5640:5;5634:12;5667:6;5662:3;5655:19;5693:4;5722:2;5717:3;5713:12;5706:19;;5759:2;5752:5;5748:14;5780:1;5790:195;5804:6;5801:1;5798:13;5790:195;;;5869:13;;-1:-1:-1;;;;;5865:39:1;5853:52;;5925:12;;;;5960:15;;;;5901:1;5819:9;5790:195;;;-1:-1:-1;6001:3:1;;5533:477;-1:-1:-1;;;;;5533:477:1:o;6015:1082::-;6078:3;6116:5;6110:12;6143:6;6138:3;6131:19;6169:4;6210:2;6205:3;6201:12;6235:11;6262;6255:18;;6312:6;6309:1;6305:14;6298:5;6294:26;6282:38;;6354:2;6347:5;6343:14;6375:1;6396;6406:665;6422:6;6417:3;6414:15;6406:665;;;6487:16;;;6475:29;;6527:13;;6599:9;;6621:22;;;6707:11;;;;6665:13;;;;6742:1;6756:209;6772:8;6767:3;6764:17;6756:209;;;6849:15;;6835:30;;6934:17;;;;6891:14;;;;6800:1;6791:11;6756:209;;;-1:-1:-1;;7049:12:1;;;;6986:5;-1:-1:-1;;7014:15:1;;;;6448:1;6439:11;6406:665;;;-1:-1:-1;7087:4:1;;6015:1082;-1:-1:-1;;;;;;;;6015:1082:1:o;7102:2370::-;8046:3;8099:21;;;8169:13;;8072:18;;;8191:22;;;8017:4;;8244:3;8229:19;;;8267:4;;8294:15;;;8017:4;8337:195;8351:6;8348:1;8345:13;8337:195;;;8416:13;;-1:-1:-1;;;;;8412:39:1;8400:52;;8472:12;;;;8507:15;;;;8448:1;8366:9;8337:195;;;-1:-1:-1;;;8568:19:1;;;8548:18;;;8541:47;8611:40;8572:3;8639:6;8611:40;:::i;:::-;8597:54;;8699:9;8691:6;8687:22;8682:2;8671:9;8667:18;8660:50;8733:43;8769:6;8761;8733:43;:::i;:::-;8719:57;;8824:9;8816:6;8812:22;8807:2;8796:9;8792:18;8785:50;8858:60;8911:6;8903;8858:60;:::i;:::-;8844:74;;8967:9;8959:6;8955:22;8949:3;8938:9;8934:19;8927:51;9001:54;9048:6;9040;9001:54;:::i;:::-;8987:68;;9104:9;9096:6;9092:22;9086:3;9075:9;9071:19;9064:51;9138:54;9185:6;9177;9138:54;:::i;:::-;9124:68;;9241:9;9233:6;9229:22;9223:3;9212:9;9208:19;9201:51;9275:60;9328:6;9320;9275:60;:::i;:::-;9261:74;;9384:9;9376:6;9372:22;9366:3;9355:9;9351:19;9344:51;9412:54;9459:6;9451;9412:54;:::i;:::-;9404:62;7102:2370;-1:-1:-1;;;;;;;;;;;7102:2370:1:o;9477:180::-;9536:6;9589:2;9577:9;9568:7;9564:23;9560:32;9557:52;;;9605:1;9602;9595:12;9557:52;-1:-1:-1;9628:23:1;;9477:180;-1:-1:-1;9477:180:1:o;9885:1061::-;10023:6;10031;10039;10047;10055;10108:2;10096:9;10087:7;10083:23;10079:32;10076:52;;;10124:1;10121;10114:12;10076:52;10163:9;10150:23;10182:31;10207:5;10182:31;:::i;:::-;10232:5;-1:-1:-1;10288:2:1;10273:18;;10260:32;-1:-1:-1;;;;;10341:14:1;;;10338:34;;;10368:1;10365;10358:12;10338:34;10407:59;10458:7;10449:6;10438:9;10434:22;10407:59;:::i;:::-;10485:8;;-1:-1:-1;10381:85:1;-1:-1:-1;10573:2:1;10558:18;;10545:32;;-1:-1:-1;10589:16:1;;;10586:36;;;10618:1;10615;10608:12;10586:36;10656:8;10645:9;10641:24;10631:34;;10703:7;10696:4;10692:2;10688:13;10684:27;10674:55;;10725:1;10722;10715:12;10674:55;10765:2;10752:16;10791:2;10783:6;10780:14;10777:34;;;10807:1;10804;10797:12;10777:34;10860:7;10855:2;10845:6;10842:1;10838:14;10834:2;10830:23;10826:32;10823:45;10820:65;;;10881:1;10878;10871:12;10820:65;9885:1061;;;;-1:-1:-1;9885:1061:1;;-1:-1:-1;10912:2:1;10904:11;;10934:6;9885:1061;-1:-1:-1;;;9885:1061:1:o;10951:127::-;11012:10;11007:3;11003:20;11000:1;10993:31;11043:4;11040:1;11033:15;11067:4;11064:1;11057:15;11083:127;11144:10;11139:3;11135:20;11132:1;11125:31;11175:4;11172:1;11165:15;11199:4;11196:1;11189:15;11215:128;11282:9;;;11303:11;;;11300:37;;;11317:18;;:::i;:::-;11215:128;;;;:::o;11348:267::-;11437:6;11432:3;11425:19;11489:6;11482:5;11475:4;11470:3;11466:14;11453:43;-1:-1:-1;11541:1:1;11516:16;;;11534:4;11512:27;;;11505:38;;;;11597:2;11576:15;;;-1:-1:-1;;11572:29:1;11563:39;;;11559:50;;11348:267::o;11620:508::-;11865:6;11854:9;11847:25;11908:2;11903;11892:9;11888:18;11881:30;11828:4;11934:62;11992:2;11981:9;11977:18;11969:6;11961;11934:62;:::i;:::-;12044:9;12036:6;12032:22;12027:2;12016:9;12012:18;12005:50;12072;12115:6;12107;12099;12072:50;:::i;:::-;12064:58;11620:508;-1:-1:-1;;;;;;;;11620:508:1:o;12341:443::-;12395:5;12448:3;12441:4;12433:6;12429:17;12425:27;12415:55;;12466:1;12463;12456:12;12415:55;12495:6;12489:13;12526:49;12542:32;12571:2;12542:32;:::i;12526:49::-;12600:2;12591:7;12584:19;12646:3;12639:4;12634:2;12626:6;12622:15;12618:26;12615:35;12612:55;;;12663:1;12660;12653:12;12612:55;12676:77;12750:2;12743:4;12734:7;12730:18;12723:4;12715:6;12711:17;12676:77;:::i;:::-;12771:7;12341:443;-1:-1:-1;;;;12341:443:1:o;12789:154::-;12884:13;;12906:31;12884:13;12906:31;:::i;12948:659::-;13013:5;13066:3;13059:4;13051:6;13047:17;13043:27;13033:55;;13084:1;13081;13074:12;13033:55;13113:6;13107:13;13139:4;13163:60;13179:43;13219:2;13179:43;:::i;13163:60::-;13257:15;;;13343:1;13339:10;;;;13327:23;;13323:32;;;13288:12;;;;13367:15;;;13364:35;;;13395:1;13392;13385:12;13364:35;13431:2;13423:6;13419:15;13443:135;13459:6;13454:3;13451:15;13443:135;;;13525:10;;13513:23;;13556:12;;;;13476;;13443:135;;;-1:-1:-1;13596:5:1;12948:659;-1:-1:-1;;;;;;12948:659:1:o;13612:1480::-;13853:6;13861;13869;13877;13885;13893;13901;13954:3;13942:9;13933:7;13929:23;13925:33;13922:53;;;13971:1;13968;13961:12;13922:53;14004:9;13998:16;-1:-1:-1;;;;;14074:2:1;14066:6;14063:14;14060:34;;;14090:1;14087;14080:12;14060:34;14113:61;14166:7;14157:6;14146:9;14142:22;14113:61;:::i;:::-;14103:71;;14220:2;14209:9;14205:18;14199:25;14183:41;;14249:2;14239:8;14236:16;14233:36;;;14265:1;14262;14255:12;14233:36;14288:63;14343:7;14332:8;14321:9;14317:24;14288:63;:::i;:::-;14278:73;;14370:65;14431:2;14420:9;14416:18;14370:65;:::i;:::-;14360:75;;14481:2;14470:9;14466:18;14460:25;14444:41;;14510:2;14500:8;14497:16;14494:36;;;14526:1;14523;14516:12;14494:36;14549:74;14615:7;14604:8;14593:9;14589:24;14549:74;:::i;:::-;14539:84;;14669:3;14658:9;14654:19;14648:26;14632:42;;14699:2;14689:8;14686:16;14683:36;;;14715:1;14712;14705:12;14683:36;14738:74;14804:7;14793:8;14782:9;14778:24;14738:74;:::i;:::-;14728:84;;14831:66;14892:3;14881:9;14877:19;14831:66;:::i;:::-;14821:76;;14943:3;14932:9;14928:19;14922:26;14906:42;;14973:2;14963:8;14960:16;14957:36;;;14989:1;14986;14979:12;14957:36;;15012:74;15078:7;15067:8;15056:9;15052:24;15012:74;:::i;:::-;15002:84;;;13612:1480;;;;;;;;;;:::o;15097:500::-;15356:2;15352:15;;;-1:-1:-1;;15348:53:1;15336:66;;15318:3;-1:-1:-1;;;;;15414:31:1;;15411:51;;;15458:1;15455;15448:12;15411:51;15492:6;15489:1;15485:14;15543:6;15535;15530:2;15525:3;15521:12;15508:42;15570:16;;;;15588:2;15566:25;;15097:500;-1:-1:-1;;;;15097:500:1:o;15602:311::-;15690:19;;;15672:3;-1:-1:-1;;;;;15721:31:1;;15718:51;;;15765:1;15762;15755:12;15718:51;15801:6;15798:1;15794:14;15853:8;15846:5;15839:4;15834:3;15830:14;15817:45;15882:18;;;;15902:4;15878:29;;15602:311;-1:-1:-1;;;15602:311:1:o;15918:864::-;-1:-1:-1;;;;;16329:15:1;;;16311:34;;16381:15;;16376:2;16361:18;;16354:43;16291:3;16428:2;16413:18;;16406:31;;;16254:4;;16460:46;;16486:19;;16478:6;16460:46;:::i;:::-;16554:9;16546:6;16542:22;16537:2;16526:9;16522:18;16515:50;16588;16631:6;16623;16615;16588:50;:::i;:::-;16574:64;;16687:9;16679:6;16675:22;16669:3;16658:9;16654:19;16647:51;16715:61;16769:6;16761;16753;16715:61;:::i;:::-;16707:69;15918:864;-1:-1:-1;;;;;;;;;;15918:864:1:o;16787:549::-;17062:6;17051:9;17044:25;17105:2;17100;17089:9;17085:18;17078:30;17025:4;17131:62;17189:2;17178:9;17174:18;17166:6;17158;17131:62;:::i;:::-;17241:9;17233:6;17229:22;17224:2;17213:9;17209:18;17202:50;17269:61;17323:6;17315;17307;17269:61;:::i;17548:277::-;17615:6;17668:2;17656:9;17647:7;17643:23;17639:32;17636:52;;;17684:1;17681;17674:12;17636:52;17716:9;17710:16;17769:5;17762:13;17755:21;17748:5;17745:32;17735:60;;17791:1;17788;17781:12;17735:60;17814:5;17548:277;-1:-1:-1;;;17548:277:1:o;17830:135::-;17869:3;17890:17;;;17887:43;;17910:18;;:::i;:::-;-1:-1:-1;17957:1:1;17946:13;;17830:135::o;17970:422::-;18059:1;18102:5;18059:1;18116:270;18137:7;18127:8;18124:21;18116:270;;;18196:4;18192:1;18188:6;18184:17;18178:4;18175:27;18172:53;;;18205:18;;:::i;:::-;18255:7;18245:8;18241:22;18238:55;;;18275:16;;;;18238:55;18354:22;;;;18314:15;;;;18116:270;;;18120:3;17970:422;;;;;:::o;18397:806::-;18446:5;18476:8;18466:80;;-1:-1:-1;18517:1:1;18531:5;;18466:80;18565:4;18555:76;;-1:-1:-1;18602:1:1;18616:5;;18555:76;18647:4;18665:1;18660:59;;;;18733:1;18728:130;;;;18640:218;;18660:59;18690:1;18681:10;;18704:5;;;18728:130;18765:3;18755:8;18752:17;18749:43;;;18772:18;;:::i;:::-;-1:-1:-1;;18828:1:1;18814:16;;18843:5;;18640:218;;18942:2;18932:8;18929:16;18923:3;18917:4;18914:13;18910:36;18904:2;18894:8;18891:16;18886:2;18880:4;18877:12;18873:35;18870:77;18867:159;;;-1:-1:-1;18979:19:1;;;19011:5;;18867:159;19058:34;19083:8;19077:4;19058:34;:::i;:::-;19128:6;19124:1;19120:6;19116:19;19107:7;19104:32;19101:58;;;19139:18;;:::i;:::-;19177:20;;18397:806;-1:-1:-1;;;18397:806:1:o;19208:131::-;19268:5;19297:36;19324:8;19318:4;19297:36;:::i;19344:127::-;19405:10;19400:3;19396:20;19393:1;19386:31;19436:4;19433:1;19426:15;19460:4;19457:1;19450:15;19476:120;19516:1;19542;19532:35;;19547:18;;:::i;:::-;-1:-1:-1;19581:9:1;;19476:120::o;19601:112::-;19633:1;19659;19649:35;;19664:18;;:::i;:::-;-1:-1:-1;19698:9:1;;19601:112::o;19718:125::-;19783:9;;;19804:10;;;19801:36;;;19817:18;;:::i

Swarm Source

ipfs://d986ebd2e402b2027d02504ca9aa45b08b9e58fec2fce3f89e7259032e0ffab0

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.