ETH Price: $3,314.69 (+0.19%)
 

Overview

ETH Balance

0.007 ETH

Eth Value

$23.20 (@ $3,314.69/ETH)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Make Offer175843192023-06-29 10:19:47559 days ago1688033987IN
0x4E0bCedD...6C9E8f62f
0.007 ETH0.0025655717.46549265
Buy Artwork175707692023-06-27 12:44:35561 days ago1687869875IN
0x4E0bCedD...6C9E8f62f
0.0000001 ETH0.0058481814.65656219
Approve Token To...174779202023-06-14 11:35:47574 days ago1686742547IN
0x4E0bCedD...6C9E8f62f
0 ETH0.004321215.71290773
Buy Artwork174773772023-06-14 9:45:11574 days ago1686735911IN
0x4E0bCedD...6C9E8f62f
0.0000001 ETH0.0058270415.48119025
Propose Token To...174768232023-06-14 7:53:11574 days ago1686729191IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0040498416.33048526
Cancel Listed To...174768052023-06-14 7:49:35574 days ago1686728975IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0036340414.63429756
Approve Token To...174713532023-06-13 13:24:35575 days ago1686662675IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0041500716.32120183
Approve Token To...174713502023-06-13 13:23:59575 days ago1686662639IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0041608916.36377097
Approve Token To...174709692023-06-13 12:07:11575 days ago1686658031IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0040663614.7285803
Approve Token To...174708692023-06-13 11:47:11575 days ago1686656831IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0051331518.61672551
Approve Token To...174708232023-06-13 11:37:47575 days ago1686656267IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0043818515.91268227
Approve Token To...174708232023-06-13 11:37:47575 days ago1686656267IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0037310313.5668992
Approve Token To...174708002023-06-13 11:33:11575 days ago1686655991IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0037727813.73665836
Approve Token To...174707912023-06-13 11:31:23575 days ago1686655883IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0042426615.46767715
Approve Token To...174707902023-06-13 11:31:11575 days ago1686655871IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0041921215.30346572
Approve Token To...174707832023-06-13 11:29:47575 days ago1686655787IN
0x4E0bCedD...6C9E8f62f
0 ETH0.004265115.59033156
Approve Token To...174707752023-06-13 11:28:11575 days ago1686655691IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0042889915.69824673
Approve Token To...174707672023-06-13 11:26:35575 days ago1686655595IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0043235214.08285959
Propose Token To...174707652023-06-13 11:26:11575 days ago1686655571IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0039136214.60759952
Propose Token To...174707572023-06-13 11:24:35575 days ago1686655475IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0038312514.30016383
Propose Token To...174703992023-06-13 10:11:59575 days ago1686651119IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0051709319.30052214
Propose Token To...174701122023-06-13 9:13:59575 days ago1686647639IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0042266815.77608717
Propose Token To...174700882023-06-13 9:09:11575 days ago1686647351IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0038695414.443068
Propose Token To...174700522023-06-13 9:01:59575 days ago1686646919IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0037637914.04837013
Propose Token To...174700252023-06-13 8:56:35575 days ago1686646595IN
0x4E0bCedD...6C9E8f62f
0 ETH0.0039431414.71778665
View all transactions

Latest 24 internal transactions

Advanced mode:
Parent Transaction Hash Block
From
To
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0.00000005 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0.00000004 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
175707692023-06-27 12:44:35561 days ago1687869875
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0.00000005 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0.00000004 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
174773772023-06-14 9:45:11574 days ago1686735911
0x4E0bCedD...6C9E8f62f
0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NFTManager

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 9 : NFTManager.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./interface/INFTManager.sol";
import "../tokens/ERC20/IRoomerToken.sol";
import "../tokens/ERC721/IRoomNFT.sol";
import "../tokens/ERC721/IERC721Min.sol";
import "../tokens/ERC1155/IERC1155Min.sol";
import "../tokens/IRoyaltyNFT.sol";
import "../storage/IStorage.sol";

contract NFTManager is INFTManager, ReentrancyGuard {
    IStorage public storageContract;
    IRoomerToken public roomerToken;
    address public accessTokenAddress;
    address public singleTokenAddress;
    address public multipleTokenAddress;

    uint256 public platformFee;
    FeeRecipient[] public platformFeeRecipients;

    constructor(
        address _storageContract,
        address _roomerToken,
        address _accessTokenAddress,
        address _singleTokenAddress,
        address _multipleTokenAddress
    ) {
        storageContract = IStorage(_storageContract);
        roomerToken = IRoomerToken(_roomerToken);
        accessTokenAddress = _accessTokenAddress;
        singleTokenAddress = _singleTokenAddress;
        multipleTokenAddress = _multipleTokenAddress;
    }

    modifier onlyOwner {
        require(storageContract.owners(msg.sender), "021");
        _;
    }

    modifier tokenOwnerOrFactory(
        address _token_address,
        uint256 _token_id,
        uint256 _amount
    ) {
        if (
            msg.sender != singleTokenAddress &&
            msg.sender != multipleTokenAddress
        ) {
            require(
                _amount == 0
                    ? IERC721Min(_token_address).ownerOf(_token_id) == msg.sender
                    : IERC1155Min(_token_address).balanceOf(
                        msg.sender,
                        _token_id
                    ) >= _amount,
                "005"
            );
        }
        _;
    }

    modifier validateDate(uint128 _start_date, uint128 _end_date) {
        if (_start_date != 0) {
            require(
                block.timestamp > _start_date && block.timestamp < _end_date,
                "004"
            );
        }
        _;
    }

    modifier approvedToken(bool _approved) {
        require(_approved, "006");
        _;
    }

    modifier onlyTokenOwner(address _owner_of) {
        require(_owner_of == msg.sender, "002");
        _;
    }

    modifier notTokenOwner(address _owner_of) {
        require(_owner_of != msg.sender, "007");
        _;
    }

    modifier onlyCurator(uint256 _room_id) {
        require(
            msg.sender == storageContract.rooms(_room_id).curator_address,
            "003"
        );
        _;
    }

    function _checkAccess(address _user, uint256 _room_id) internal view {
        address _curator = storageContract.rooms(_room_id).curator_address;
        address _owner = storageContract.rooms(_room_id).owner_of;
        if (
            storageContract.privateRooms(_room_id) > 0 &&
            _user != _curator &&
            _user != _owner
        ) {
            require(
                IERC1155Min(accessTokenAddress).balanceOf(_user, _room_id) >= 1,
                "018"
            );
        }
    }

    function _transferRoomer(
        address _from,
        address _to,
        uint256 _amount
    ) internal {
        require(roomerToken.transferFrom(_from, _to, _amount), "039");
    }

    function _transferTokens(
        address token_address,
        uint256 token_id,
        address from,
        address to,
        uint256 amount
    ) internal {
        if (amount == 0) {
            IERC721Min(token_address).safeTransferFrom(from, to, token_id);
        } else {
            IERC1155Min(token_address).safeTransferFrom(
                from,
                to,
                token_id,
                amount,
                ""
            );
        }
    }

    function _getRoyaltyInfo(address _token_address, uint256 _token_id)
        internal
        view
        returns (
            address _creator,
            uint256 _royalty,
            bool _first_sale
        )
    {
        try IRoyaltyNFT(_token_address).getRoyaltyInfo(_token_id) returns (
            address creator,
            uint256 royalty,
            bool first_sale
        ) {
            require(royalty <= 100, "009");
            return (creator, royalty, first_sale);
        } catch {
            return (address(0), 0, false);
        }
    }

    function _updateFirstSale(address _token_address, uint256 _token_id)
        internal
        returns (bool success)
    {
        try IRoyaltyNFT(_token_address).updateFirstSale(_token_id) {
            return true;
        } catch {
            return false;
        }
    }

    function _distributeFees(
        uint256 _room_id,
        uint256 _total_value,
        address _token_owner
    ) internal returns (uint256) {
        IStorage.Room memory _room = storageContract.rooms(_room_id);
        uint256 _artistPercentage = _room.artist_percentage;
        uint256 _totalFees = (_total_value * _artistPercentage) / 1000;
        uint8 _totalArtists;
        address[] memory artists = storageContract.getArtists(_room_id);
        for (uint8 i; i < 38; i++) {
            if (artists[i] == address(0)) {
                break;
            }
            _totalArtists += 1;
        }
        uint256 _singleArtistRoyalty = _totalFees / _totalArtists;
        for (uint8 i; i < _totalArtists; i++) {
            payable(artists[i]).send(_singleArtistRoyalty);
        }

        uint256 _curatorFee = (_total_value * _room.curator_percentage) / 1000;
        payable(_room.curator_address).send(_curatorFee);
        _totalFees += _curatorFee;

        uint256 _ownerFee = (_total_value * _room.room_owner_percentage) / 1000;
        payable(_room.owner_of).send(_ownerFee);
        _totalFees += _ownerFee;

        // transfer leftover tokens to NFT seller
        payable(_token_owner).send(_total_value - _totalFees);

        emit roomerRoyaltiesPayed(_room_id, _total_value);
        return _totalFees;
    }

    function _distributePlatformFees(uint256 value) internal {
        uint256 _value_left = value;
        for (uint256 i; i < platformFeeRecipients.length; i++) {
            FeeRecipient memory _feeRecipient = platformFeeRecipients[i];
            uint256 send_value = (value * _feeRecipient.percentage) / 1000;
            if (_value_left < send_value) break;
            payable(_feeRecipient.recipient).transfer(send_value);
            _value_left -= send_value;
        }
        platformFee += _value_left;
    }

    function proposeTokenToRoom(TokenObject memory tokenInfo)
        external
        tokenOwnerOrFactory(
            tokenInfo.token_address,
            tokenInfo.token_id,
            tokenInfo.amount
        )
        validateDate(
            storageContract.rooms(tokenInfo.room_id).start_time,
            storageContract.rooms(tokenInfo.room_id).end_time
        )
    {
        // Make sure token is sold or not listed
        if (tokenInfo.is_auction) {
            // Only single item auctions are allowed
            require(tokenInfo.amount == 1 || tokenInfo.amount == 0, "017");
            require(
                storageContract.rooms(tokenInfo.room_id).auction_approved,
                "024"
            );
        }
        address _caller = msg.sender == singleTokenAddress || msg.sender == multipleTokenAddress
            ? tokenInfo.owner : msg.sender;
        require(
            roomerToken.balanceOf(_caller) >=
                storageContract.rooms(tokenInfo.room_id).roomer_fee,
            "044"
        );
        _getRoyaltyInfo(tokenInfo.token_address, tokenInfo.token_id);
        uint256 _uid = storageContract.tokensLength();
        if (tokenInfo.amount != 0) {
            storageContract.setTokensOnSale(_uid, tokenInfo.amount);
        }
        storageContract.setTokenSubmitTime(_uid, block.timestamp);
        storageContract.newToken(
            IStorage.Token(
                _uid,
                tokenInfo.token_address,
                _caller,
                tokenInfo.token_id,
                tokenInfo.room_id,
                tokenInfo.price,
                tokenInfo.amount,
                0,
                address(0),
                tokenInfo.start_time,
                tokenInfo.end_time,
                false,
                false,
                tokenInfo.is_auction
            )
        );
        emit tokenProposed(tokenInfo, _uid);
    }

    function cancelProposal(uint256 _uid)
        external
        onlyTokenOwner(storageContract.tokens(_uid).owner_of)
    {
        IStorage.Token memory _token = storageContract.tokens(_uid);
        require(!_token.resolved, "013");
        _token.resolved = true;
        storageContract.updateToken(_uid, _token);
        emit proposalCancelled(_uid);
    }

    function cancelListedToken(uint256 _uid)
        external
        onlyTokenOwner(storageContract.tokens(_uid).owner_of)
        nonReentrant
    {
        require(storageContract.tokens(_uid).approved, "008");
        uint256 _room_id = storageContract.tokens(_uid).room_id;
        IStorage.Token memory _token = storageContract.tokens(_uid);
        _token.approved = false;
        storageContract.updateToken(_uid, _token);
        IStorage.Room memory _room = storageContract.rooms(_room_id);
        address[] memory artists = storageContract.getArtists(_room_id);
        uint16[] memory artworks_owner_amt = storageContract.getArtworksOwnerAmount(_room_id);
        uint8 _removed_roomer_index;
        bool _roomer_removed_flag;
        uint8 _last_index = 37;
        for (uint8 i; i < 38; i++) {
            if (artists[i] == address(0)) {
                _last_index = i;
                break;
            }
            if (msg.sender == artists[i]) {
                artworks_owner_amt[i] -= 1;
                storageContract.setArtworksOwnerAmountById(
                    _room_id,
                    i,
                    artworks_owner_amt[i]
                );
                if (artworks_owner_amt[i] == 0) {
                    storageContract.setArtistsById(_room_id, i, address(0));
                    _removed_roomer_index = i;
                    _roomer_removed_flag = true;
                }
                break;
            }
        }
        // if roomers array is not empty, move last artists to removed user position,
        // e.g. [1, 2, 1, 1 <- removed user, 3, 1, 6, 0 ... 0] ->
        //      [1, 2, 1, 6 (swapped with last item), 3, 1, 0 ... 0]
        if (_roomer_removed_flag) {
            storageContract.setArtistsById(_room_id, _removed_roomer_index, artists[_last_index]);
            storageContract.setArtworksOwnerAmountById(
                _room_id,
                _removed_roomer_index,
                artworks_owner_amt[_last_index]
            );
            storageContract.setArtistsById(_room_id, _last_index, address(0));
            storageContract.setArtworksOwnerAmountById(_room_id, _last_index, 0);
        }
        _room.tokens_approved--;
        storageContract.updateArtroom(_room_id, _room);
        emit saleCancelled(_uid, msg.sender);
    }

    function approveTokenToRoom(uint256 _uid, bool approve)
        external
        nonReentrant
    {
        IStorage.Token memory _token = storageContract.tokens(_uid);
        require(
            msg.sender == storageContract.rooms(_token.room_id).curator_address,
            "003"
        );
        require(!_token.resolved, "010");
        require(storageContract.tokenSubmitTime(_uid) + 30 days >= block.timestamp, "037");
        _token.approved = approve;
        _token.resolved = true;
        storageContract.updateToken(_uid, _token);
        if (approve) {
            IStorage.Room memory _room = storageContract.rooms(_token.room_id);
            require(_room.tokens_approved < 38, "011");
            address token_owner = _token.owner_of;
            uint256 _roomerFeeSingle = _room.roomer_fee / 2;
            if (_roomerFeeSingle > 0) {
                _transferRoomer(
                    token_owner,
                    _room.curator_address,
                    _roomerFeeSingle
                );
                _transferRoomer(token_owner, _room.owner_of, _roomerFeeSingle);
            }
            address[] memory _artists = storageContract.getArtists(_token.room_id);
            uint16[] memory artworks_owner_amt = storageContract.getArtworksOwnerAmount(_token.room_id);
            for (uint8 i; i < 38; i++) {
                if (_artists[i] == address(0)) {
                    storageContract.setArtistsById(_token.room_id, i, token_owner);
                    _artists[i] = token_owner;
                }
                if (_artists[i] == token_owner) {
                    storageContract.setArtworksOwnerAmountById(
                        _token.room_id,
                        i,
                        artworks_owner_amt[i] + 1
                    );
                    break;
                }
            }
            _room.tokens_approved++;
            storageContract.updateArtroom(_token.room_id, _room);
            emit tokenApproved(_token.is_auction, _uid);
        } else {
            emit tokenRejected(_token.is_auction, _uid);
        }
    }

    function buyArtwork(uint256 _uid, uint256 _amount)
        external
        payable
        nonReentrant
        validateDate(
            storageContract
                .rooms(storageContract.tokens(_uid).room_id)
                .start_time,
            storageContract.rooms(storageContract.tokens(_uid).room_id).end_time
        )
        approvedToken(storageContract.tokens(_uid).approved)
        notTokenOwner(storageContract.tokens(_uid).owner_of)
    {
        IStorage.Token memory _token = storageContract.tokens(_uid);
        address _old_owner = _token.owner_of;
        {
            // prevent stack to deep
            _checkAccess(msg.sender, _token.room_id);
            require(msg.value >= _token.price, "012");
            require(_amount <= storageContract.tokensOnSale(_uid), "019");
            if (_amount == 0) {
                require(
                    IERC721Min(_token.token_address).ownerOf(_token.token_id) ==
                        _token.owner_of,
                    "047"
                );
            }
            _transferTokens(
                _token.token_address,
                _token.token_id,
                _token.owner_of,
                msg.sender,
                _amount
            );
            storageContract.setTokensOnSale(
                _uid,
                storageContract.tokensOnSale(_uid) - _amount
            );
            storageContract.updateToken(_uid, _token);
            emit tokenSold(_uid, _old_owner, msg.sender, _amount, msg.value);
        }
        (
            address _creator,
            uint256 _royalty,
            bool _first_sale
        ) = _getRoyaltyInfo(_token.token_address, _token.token_id);
        uint256 _platformFee = msg.value / 40;
        uint256 _value = msg.value - _platformFee;
        _distributePlatformFees(_platformFee);
        if (!_first_sale && _creator != address(0)) {
            uint256 _creator_royalty = (_value * _royalty) / 1000;
            payable(_creator).send(_creator_royalty);
            _value -= _creator_royalty;
        }
        _distributeFees(_token.room_id, _value, _token.owner_of);
        if (_first_sale && _creator != address(0))
            _updateFirstSale(_token.token_address, _token.token_id);
    }

    function bid(uint256 _uid)
        external
        payable
        nonReentrant
        approvedToken(storageContract.tokens(_uid).approved)
        validateDate(
            storageContract.tokens(_uid).start_time,
            storageContract.tokens(_uid).end_time
        )
        notTokenOwner(storageContract.tokens(_uid).owner_of)
    {
        IStorage.Token memory _token = storageContract.tokens(_uid);
        uint256 _highest_bid = _token.highest_bid;
        require(
            msg.value >= _highest_bid + (_highest_bid / 10) &&
                msg.value >= _token.price,
            "014"
        );
        require(_token.is_auction, "042");
        _checkAccess(msg.sender, _token.room_id);
        address _highest_bidder = _token.highest_bidder;
        // do not allow contracts to bid on auctions
        require(
            msg.sender == tx.origin && msg.sender != _highest_bidder,
            "046"
        );
        _token.highest_bid = msg.value;
        _token.highest_bidder = msg.sender;
        storageContract.setFeesAvailable(_uid, storageContract.feesAvailable(_uid) + msg.value);
        storageContract.updateToken(_uid, _token);
        if (_highest_bidder != address(0)) {
            payable(_highest_bidder).send(_highest_bid);
        }
        emit bidAdded(_uid, msg.value, msg.sender);
    }

    function finalizeAuction(uint256 _uid, bool _approve)
        external
        onlyCurator(storageContract.tokens(_uid).room_id)
        nonReentrant
    {
        IStorage.Token memory _token = storageContract.tokens(_uid);
        require(_token.is_auction, "001");
        if (_approve) {
            require(storageContract.feesAvailable(_uid) > 0, "020");
            if (_token.end_time != 0)
                require(block.timestamp >= _token.end_time, "015");
            _transferTokens(
                _token.token_address,
                _token.token_id,
                _token.owner_of,
                _token.highest_bidder,
                _token.amount
            );
            (
                address _creator,
                uint256 _royalty,
                bool _first_sale
            ) = _getRoyaltyInfo(_token.token_address, _token.token_id);
            uint256 _platformFee = _token.highest_bid / 40; //  2.5% platform fee
            _distributePlatformFees(_platformFee);
            uint256 _value = _token.highest_bid - _platformFee;
            if (!_first_sale && _creator != address(0)) {
                uint256 _creator_royalty = (_value * _royalty) / 1000;
                payable(_creator).send(_creator_royalty);
                _value -= _creator_royalty;
            }
            _distributeFees(
                storageContract.tokens(_uid).room_id,
                _value,
                _token.owner_of
            );
            if (_first_sale && _creator != address(0)) {
                _updateFirstSale(_token.token_address, _token.token_id);
            }
            storageContract.setFeesAvailable(
                _uid,
                storageContract.feesAvailable(_uid) - _token.highest_bid
            );
            storageContract.updateToken(_uid, _token);
        } else {
            // return bid to highest bidder
            payable(_token.highest_bidder).send(_token.highest_bid);
        }
        emit auctionFinalized(_uid, _approve);
    }

    function makeOffer(
        address _token_address,
        uint256 _token_id,
        uint256 _amount
    ) external payable {
        uint256 _value = msg.value;
        require(_value > 0, "041");
        uint256 _offer_id = storageContract.offersLength();
        storageContract.newOffer(
            IStorage.Offer(
                _token_address,
                _token_id,
                _value,
                _amount,
                msg.sender,
                false,
                false
            )
        );
        emit offerMade(
            _token_address,
            _token_id,
            _offer_id,
            _value,
            _amount,
            msg.sender
        );
    }

    function cancelOffer(uint256 _offer_id) public nonReentrant {
        IStorage.Offer memory _offer = storageContract.offers(_offer_id);
        require(msg.sender == _offer.bidder, "043");
        require(!_offer.resolved, "030");
        _offer.resolved = true;
        storageContract.updateOffer(_offer_id, _offer);
        payable(msg.sender).transfer(_offer.price);
        emit offerCancelled(_offer_id);
    }

    function resolveOffer(uint256 _offer_id, bool _approve)
        external
        nonReentrant
        tokenOwnerOrFactory(
            storageContract.offers(_offer_id).token_address,
            storageContract.offers(_offer_id).token_id,
            storageContract.offers(_offer_id).amount
        )
    {
        IStorage.Offer memory _offer = storageContract.offers(_offer_id);
        require(!_offer.resolved, "045");
        _offer.approved = _approve;
        _offer.resolved = true;
        if (_approve) {
            _transferTokens(
                _offer.token_address,
                _offer.token_id,
                msg.sender,
                _offer.bidder,
                _offer.amount
            );
            (
                address _creator,
                uint256 _royalty,
                bool _first_sale
            ) = _getRoyaltyInfo(_offer.token_address, _offer.token_id);
            uint256 _platformFee = _offer.price / 40;
            _distributePlatformFees(_platformFee);
            uint256 _value = _offer.price - _platformFee;
            if (!_first_sale && _creator != address(0)) {
                uint256 _creator_royalty = (_value * _royalty) / 1000;
                payable(_creator).send(_creator_royalty);
                _value -= _creator_royalty;
            }
            payable(msg.sender).transfer(_value);
            if (_first_sale && _creator != address(0))
                _updateFirstSale(_offer.token_address, _offer.token_id);
        } else {
            if (_offer.amount == 0) {
                payable(_offer.bidder).transfer(_offer.price);
            } else {
                _offer.resolved = false;
            }
        }
        storageContract.updateOffer(_offer_id, _offer);
        emit offerResolved(_offer_id, _approve, msg.sender);
    }

    function setFeeRecipients(FeeRecipient[] memory _recipients)
        external
        onlyOwner
    {
        if (platformFeeRecipients.length != 0) delete platformFeeRecipients;
        for (uint8 i; i < _recipients.length; i++) {
            platformFeeRecipients.push(_recipients[i]);
        }
    }

    function setTokens(
        address _roomerToken,
        address _accessTokenAddress,
        address _singleTokenAddress,
        address _multipleTokenAddress
    ) external onlyOwner {
        roomerToken = IRoomerToken(_roomerToken);
        accessTokenAddress = _accessTokenAddress;
        singleTokenAddress = _singleTokenAddress;
        multipleTokenAddress = _multipleTokenAddress;
    }
}

File 2 of 9 : IStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IStorage {
    struct Room {
        uint256 uid;
        uint128 start_time;
        uint128 end_time;
        address owner_of;
        uint16 room_owner_percentage;
        uint16 artist_percentage;
        uint16 artwork_owner_percentage;
        address curator_address;
        uint16 curator_percentage;
        uint256 roomer_fee;
        uint256 price;
        uint128 tokens_approved;
        bool on_sale;
        bool auction_approved;
    }

    struct Token {
        uint256 uid;
        address token_address;
        address owner_of;
        uint256 token_id;
        uint256 room_id;
        uint256 price;
        uint256 amount;
        uint256 highest_bid;
        address highest_bidder;
        uint128 start_time;
        uint128 end_time;
        bool approved;
        bool resolved;
        bool is_auction;
    }
    
    struct Offer {
        address token_address;
        uint256 token_id;
        uint256 price;
        uint256 amount;
        address bidder;
        bool approved;
        bool resolved;
    }

    function owners(address _user) external view returns (bool);
    function getArtists(uint256 _uid) external view returns (address[] memory);
    function getArtworksOwnerAmount(uint256 _uid) external view returns (uint16[] memory);

    function rooms(uint256 _uid) external view returns (Room memory);
    function tokens(uint256 _uid) external view returns (Token memory);
    function offers(uint256 _uid) external view returns (Offer memory);
    function artists(uint256 _uid) external view returns (address[] memory);
    function artworksOwnerAmt(uint256 _uid) external view returns (uint16[] memory);

    function privateRooms(uint256 _uid) external view returns (uint256);
    function haveRoomsCreated(address _creator) external view returns (bool);
    function tokensOnSale(uint256 _uid) external view returns (uint256);
    function feesAvailable(uint256 _uid) external view returns (uint256);
    function tokenSubmitTime(uint256 _uid) external view returns (uint256);
    
    function updateArtroom(uint256 _uid, Room memory _updatedRoom) external;
    function updateToken(uint256 _uid, Token memory _updatedToken) external;
    function updateOffer(uint256 _uid, Offer memory _updatedOffer) external;
    
    function newArtroom(Room memory _newRoom) external;
    function newToken(Token memory _newToken) external;
    function newOffer(Offer memory _newOffer) external;
    function newArtworkCountRegistry(uint256 _uid, uint256 _size) external;

    function setRoomCreated(address _creator) external;
    function setPrivateRoom(uint256 _uid, uint256 _entranceFee) external;
    function setTokensOnSale(uint256 _uid, uint256 _amount) external;
    function setFeesAvailable(uint256 _uid, uint256 _amount) external;
    function setArtistsById(uint256 _uid, uint16 _index, address _artist) external;
    function setArtworksOwnerAmountById(uint256 _uid, uint16 _index, uint16 _amount) external;
    function setTokenSubmitTime(uint256 _uid, uint256 _timestamp) external;

    function roomsLength() external view returns (uint256);
    function tokensLength() external view returns (uint256);
    function offersLength() external view returns (uint256);
}

File 3 of 9 : IRoyaltyNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IRoyaltyNFT {
    function getCreator(uint256 token_id) external returns (address);
    function getRoyaltyInfo(uint256 token_id) external view returns (address, uint256, bool);
    function updateFirstSale(uint256 token_id) external;
}

File 4 of 9 : IERC1155Min.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IERC1155Min {
    function balanceOf(address account, uint256 id) external view returns (uint256);

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;
}

File 5 of 9 : IERC721Min.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IERC721Min {
    function ownerOf(uint256 tokenId) external view returns (address owner);

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;
}

File 6 of 9 : IRoomNFT.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IRoomNFT {
    function mint(
        address _to, 
        uint256 _uid, 
        string memory _uri
    ) external;

    function safeTransferFrom(address from, address to, uint256 tokenId) external;
}

File 7 of 9 : IRoomerToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IRoomerToken {
    function burnFrom(address account, uint256 amount) external;
    function approve(address operator, uint256 amount) external;
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function balanceOf(address account) external returns (uint256);
}

File 8 of 9 : INFTManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface INFTManager {
    struct Room {
        uint256 uid;
        uint128 startTime;
        uint128 endTime;
        address owner_of;
        uint16 room_owner_percentage;
        uint16 artist_percentage;
        uint16 artwork_owner_percentage;
        address[38] artists;
        uint8[38] artworks_owner_amt;
        address curatorAddress;
        uint16 curatorPercentage;
        uint256 roomerFee;
        uint256 price;
        uint128 tokensApproved;
        bool on_sale;
        bool auction_approved;
    }
    
    struct TokenObject {
        address token_address;
        uint256 token_id;
        uint256 room_id;
        uint256 price;
        uint256 amount;
        uint128 start_time;
        uint128 end_time;
        bool is_auction;
        bool is_physical;
        address owner;
    }

    struct FeeRecipient {
        address recipient;
        uint16 percentage;
    }

    event tokenProposed(TokenObject tokenInfo, uint256 uid);
    event proposalCancelled(uint256 uid);

    event tokenApproved(bool isAuction, uint256 uid);
    event tokenRejected(bool isAuction, uint256 uid);
    event saleCancelled(uint256 uid, address curator);
    event tokenSold(
        uint256 uid,
        address old_owner,
        address new_owner,
        uint256 amount,
        uint256 total_price
    );
    event roomerRoyaltiesPayed(uint256 room_id, uint256 total_value);
    
    event bidAdded(uint256 auctId, uint256 highest_bid, address highest_bidder);
    event auctionFinalized(uint256 auctId, bool approve);
    
    event offerMade(address token_address, uint256 token_id, uint256 offer_id, uint256 price, uint256 amount, address bidder);
    event offerCancelled(uint256 offer_id);
    event offerResolved(uint256 offer_id, bool approved, address from);
}

File 9 of 9 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_storageContract","type":"address"},{"internalType":"address","name":"_roomerToken","type":"address"},{"internalType":"address","name":"_accessTokenAddress","type":"address"},{"internalType":"address","name":"_singleTokenAddress","type":"address"},{"internalType":"address","name":"_multipleTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"auctId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"approve","type":"bool"}],"name":"auctionFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"auctId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"highest_bid","type":"uint256"},{"indexed":false,"internalType":"address","name":"highest_bidder","type":"address"}],"name":"bidAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"offer_id","type":"uint256"}],"name":"offerCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"offer_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"}],"name":"offerMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"offer_id","type":"uint256"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"},{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"offerResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"uid","type":"uint256"}],"name":"proposalCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"room_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total_value","type":"uint256"}],"name":"roomerRoyaltiesPayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"uid","type":"uint256"},{"indexed":false,"internalType":"address","name":"curator","type":"address"}],"name":"saleCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isAuction","type":"bool"},{"indexed":false,"internalType":"uint256","name":"uid","type":"uint256"}],"name":"tokenApproved","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"token_address","type":"address"},{"internalType":"uint256","name":"token_id","type":"uint256"},{"internalType":"uint256","name":"room_id","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint128","name":"start_time","type":"uint128"},{"internalType":"uint128","name":"end_time","type":"uint128"},{"internalType":"bool","name":"is_auction","type":"bool"},{"internalType":"bool","name":"is_physical","type":"bool"},{"internalType":"address","name":"owner","type":"address"}],"indexed":false,"internalType":"struct INFTManager.TokenObject","name":"tokenInfo","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"uid","type":"uint256"}],"name":"tokenProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isAuction","type":"bool"},{"indexed":false,"internalType":"uint256","name":"uid","type":"uint256"}],"name":"tokenRejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"uid","type":"uint256"},{"indexed":false,"internalType":"address","name":"old_owner","type":"address"},{"indexed":false,"internalType":"address","name":"new_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total_price","type":"uint256"}],"name":"tokenSold","type":"event"},{"inputs":[],"name":"accessTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uid","type":"uint256"},{"internalType":"bool","name":"approve","type":"bool"}],"name":"approveTokenToRoom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uid","type":"uint256"}],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"buyArtwork","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uid","type":"uint256"}],"name":"cancelListedToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offer_id","type":"uint256"}],"name":"cancelOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uid","type":"uint256"}],"name":"cancelProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uid","type":"uint256"},{"internalType":"bool","name":"_approve","type":"bool"}],"name":"finalizeAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token_address","type":"address"},{"internalType":"uint256","name":"_token_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"makeOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"multipleTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"platformFeeRecipients","outputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint16","name":"percentage","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token_address","type":"address"},{"internalType":"uint256","name":"token_id","type":"uint256"},{"internalType":"uint256","name":"room_id","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint128","name":"start_time","type":"uint128"},{"internalType":"uint128","name":"end_time","type":"uint128"},{"internalType":"bool","name":"is_auction","type":"bool"},{"internalType":"bool","name":"is_physical","type":"bool"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct INFTManager.TokenObject","name":"tokenInfo","type":"tuple"}],"name":"proposeTokenToRoom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offer_id","type":"uint256"},{"internalType":"bool","name":"_approve","type":"bool"}],"name":"resolveOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"roomerToken","outputs":[{"internalType":"contract IRoomerToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint16","name":"percentage","type":"uint16"}],"internalType":"struct INFTManager.FeeRecipient[]","name":"_recipients","type":"tuple[]"}],"name":"setFeeRecipients","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_roomerToken","type":"address"},{"internalType":"address","name":"_accessTokenAddress","type":"address"},{"internalType":"address","name":"_singleTokenAddress","type":"address"},{"internalType":"address","name":"_multipleTokenAddress","type":"address"}],"name":"setTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"singleTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"storageContract","outputs":[{"internalType":"contract IStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b506040516200568a3803806200568a8339810160408190526200003491620000b9565b6001600081905580546001600160a01b03199081166001600160a01b0397881617909155600280548216958716959095179094556003805485169386169390931790925560048054841691851691909117905560058054909216921691909117905562000129565b80516001600160a01b0381168114620000b457600080fd5b919050565b600080600080600060a08688031215620000d257600080fd5b620000dd866200009c565b9450620000ed602087016200009c565b9350620000fd604087016200009c565b92506200010d606087016200009c565b91506200011d608087016200009c565b90509295509295909350565b61555180620001396000396000f3fe6080604052600436106101145760003560e01c80636da464dc116100a05780638cdaab53116100645780638cdaab53146102f7578063ba89dfab14610317578063d0b755cc14610337578063e0a8f6f514610357578063ef706adf1461037757600080fd5b80636da464dc1461024f578063720123331461026f5780637de3bd0714610282578063852da752146102955780638b28ebfd146102b557600080fd5b8063537820bf116100e7578063537820bf146101af578063597690c0146101cf5780635e25041d146101ef57806366c3049e1461020f5780636d5a5fa61461022f57600080fd5b80630e733d9e1461011957806311ce02671461015657806326232a2e14610176578063454a2ab31461019a575b600080fd5b34801561012557600080fd5b50600454610139906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561016257600080fd5b50600154610139906001600160a01b031681565b34801561018257600080fd5b5061018c60065481565b60405190815260200161014d565b6101ad6101a8366004614813565b610397565b005b3480156101bb57600080fd5b506101ad6101ca366004614851565b610982565b3480156101db57600080fd5b50600554610139906001600160a01b031681565b3480156101fb57600080fd5b506101ad61020a36600461499e565b610a70565b34801561021b57600080fd5b506101ad61022a366004614813565b61123c565b34801561023b57600080fd5b50600354610139906001600160a01b031681565b34801561025b57600080fd5b506101ad61026a366004614a4a565b611b43565b6101ad61027d366004614a7a565b6122eb565b6101ad610290366004614a9c565b612b4e565b3480156102a157600080fd5b506101ad6102b0366004614a4a565b612cee565b3480156102c157600080fd5b506102d56102d0366004614813565b6132bc565b604080516001600160a01b03909316835261ffff90911660208301520161014d565b34801561030357600080fd5b506101ad610312366004614a4a565b6132f2565b34801561032357600080fd5b506101ad610332366004614b05565b613939565b34801561034357600080fd5b50600254610139906001600160a01b031681565b34801561036357600080fd5b506101ad610372366004614813565b613a7a565b34801561038357600080fd5b506101ad610392366004614813565b613c7e565b6002600054036103c25760405162461bcd60e51b81526004016103b990614bd3565b60405180910390fd5b60026000556001546040516327b2595f60e11b8152600481018390526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015610411573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104359190614c2b565b61016001518061046d5760405162461bcd60e51b815260206004820152600360248201526218181b60e91b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa1580156104b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104db9190614c2b565b61012001516001546040516327b2595f60e11b8152600481018590526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561052a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054e9190614c2b565b61014001516001600160801b0382161561059e57816001600160801b0316421180156105825750806001600160801b031642105b61059e5760405162461bcd60e51b81526004016103b990614d06565b6001546040516327b2595f60e11b8152600481018690526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa1580156105e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190614c2b565b60400151336001600160a01b0382160361064e5760405162461bcd60e51b815260206004820152600360248201526230303760e81b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018790526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015610699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bd9190614c2b565b60e08101519091506106d0600a82614d39565b6106da9082614d5b565b34101580156106ed57508160a001513410155b61071f5760405162461bcd60e51b81526020600482015260036024820152620c0c4d60ea1b60448201526064016103b9565b816101a001516107575760405162461bcd60e51b8152602060048201526003602482015262181a1960e91b60448201526064016103b9565b610765338360800151613e71565b61010082015133321480156107835750336001600160a01b03821614155b6107b55760405162461bcd60e51b8152602060048201526003602482015262181a1b60e91b60448201526064016103b9565b3460e0840181905233610100850152600154604051630131556d60e31b8152600481018b90526001600160a01b039091169163e54e3f9f918b9190849063098aab6890602401602060405180830381865afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083c9190614d6e565b6108469190614d5b565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561088457600080fd5b505af1158015610898573d6000803e3d6000fd5b5050600154604051630c58367160e21b81526001600160a01b039091169250633160d9c491506108ce908b908790600401614e64565b600060405180830381600087803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b505050506001600160a01b03811615610935576040516001600160a01b0382169083156108fc029084906000818181858888f150505050505b60408051898152346020820152338183015290517f9e331edbebe8146ffa663dc1af424de11f33ef98bac5fa54df39ed595939dce29181900360600190a150506001600055505050505050565b60015460405163022914a760e01b81523360048201526001600160a01b039091169063022914a790602401602060405180830381865afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee9190614e79565b610a205760405162461bcd60e51b815260206004820152600360248201526230323160e81b60448201526064016103b9565b600280546001600160a01b039586166001600160a01b0319918216179091556003805494861694821694909417909355600480549285169284169290921790915560058054919093169116179055565b8051602082015160808301516004546001600160a01b03163314801590610aa257506005546001600160a01b03163314155b15610bcb578015610b2357604051627eeac760e11b81523360048201526024810183905281906001600160a01b0385169062fdd58e90604401602060405180830381865afa158015610af8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1c9190614d6e565b1015610b99565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e90602401602060405180830381865afa158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e9190614e96565b6001600160a01b0316145b610bcb5760405162461bcd60e51b815260206004820152600360248201526230303560e81b60448201526064016103b9565b6001546040808601519051630375c15960e31b81526001600160a01b0390921691631bae0ac891610c029160040190815260200190565b6101c060405180830381865afa158015610c20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c449190614ebe565b602001516001546040808701519051630375c15960e31b81526001600160a01b0390921691631bae0ac891610c7f9160040190815260200190565b6101c060405180830381865afa158015610c9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc19190614ebe565b604001516001600160801b03821615610d1057816001600160801b031642118015610cf45750806001600160801b031642105b610d105760405162461bcd60e51b81526004016103b990614d06565b8560e0015115610e1157856080015160011480610d2f57506080860151155b610d615760405162461bcd60e51b815260206004820152600360248201526230313760e81b60448201526064016103b9565b6001546040808801519051630375c15960e31b81526001600160a01b0390921691631bae0ac891610d989160040190815260200190565b6101c060405180830381865afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dda9190614ebe565b6101a00151610e115760405162461bcd60e51b81526020600482015260036024820152620c0c8d60ea1b60448201526064016103b9565b6004546000906001600160a01b0316331480610e3757506005546001600160a01b031633145b610e415733610e48565b8661012001515b6001546040898101519051630375c15960e31b815260048101919091529192506001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015610e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebd9190614ebe565b61012001516002546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024016020604051808303816000875af1158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f329190614d6e565b1015610f665760405162461bcd60e51b81526020600482015260036024820152620c0d0d60ea1b60448201526064016103b9565b610f78876000015188602001516140bf565b5050506000600160009054906101000a90046001600160a01b03166001600160a01b031663d92fc67b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff49190614d6e565b9050876080015160001461106e5760015460808901516040516305a241cf60e01b81526004810184905260248101919091526001600160a01b03909116906305a241cf90604401600060405180830381600087803b15801561105557600080fd5b505af1158015611069573d6000803e3d6000fd5b505050505b600154604051631f16fb5960e11b8152600481018390524260248201526001600160a01b0390911690633e2df6b290604401600060405180830381600087803b1580156110ba57600080fd5b505af11580156110ce573d6000803e3d6000fd5b50505050600160009054906101000a90046001600160a01b03166001600160a01b031663b976a72b604051806101c001604052808481526020018b600001516001600160a01b03168152602001856001600160a01b031681526020018b6020015181526020018b6040015181526020018b6060015181526020018b6080015181526020016000815260200160006001600160a01b031681526020018b60a001516001600160801b031681526020018b60c001516001600160801b031681526020016000151581526020016000151581526020018b60e0015115158152506040518263ffffffff1660e01b81526004016111c79190614f8a565b600060405180830381600087803b1580156111e157600080fd5b505af11580156111f5573d6000803e3d6000fd5b505050507f8ec1218093f086777e347d6747d77a1c6ea62770cbd1c22234fbb34fa93f8575888260405161122a929190614f99565b60405180910390a15050505050505050565b6001546040516327b2595f60e11b8152600481018390526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015611286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112aa9190614c2b565b604001516001600160a01b03811633146112ec5760405162461bcd60e51b815260206004820152600360248201526218181960e91b60448201526064016103b9565b60026000540361130e5760405162461bcd60e51b81526004016103b990614bd3565b60026000556001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190614c2b565b61016001516113b85760405162461bcd60e51b815260206004820152600360248201526206060760eb1b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018490526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114279190614c2b565b608001516001546040516327b2595f60e11b8152600481018690529192506000916001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561147b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149f9190614c2b565b6000610160820152600154604051630c58367160e21b81529192506001600160a01b031690633160d9c4906114da9087908590600401614e64565b600060405180830381600087803b1580156114f457600080fd5b505af1158015611508573d6000803e3d6000fd5b5050600154604051630375c15960e31b815260048101869052600093506001600160a01b039091169150631bae0ac8906024016101c060405180830381865afa158015611559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157d9190614ebe565b60015460405163e9ca25c160e01b8152600481018690529192506000916001600160a01b039091169063e9ca25c190602401600060405180830381865afa1580156115cc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115f49190810190615049565b600154604051630149cf8d60e31b8152600481018790529192506000916001600160a01b0390911690630a4e7c6890602401600060405180830381865afa158015611643573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261166b91908101906150d8565b90506000806025815b60268160ff1610156118735760006001600160a01b0316868260ff16815181106116a0576116a0615167565b60200260200101516001600160a01b0316036116be57809150611873565b858160ff16815181106116d3576116d3615167565b60200260200101516001600160a01b0316336001600160a01b031603611861576001858260ff168151811061170a5761170a615167565b6020026020010181815161171e919061517d565b61ffff1690525060015485516001600160a01b0390911690632b9e8f41908b908490899060ff831690811061175557611755615167565b60200260200101516040518463ffffffff1660e01b81526004016117939392919092835260ff91909116602083015261ffff16604082015260600190565b600060405180830381600087803b1580156117ad57600080fd5b505af11580156117c1573d6000803e3d6000fd5b50505050848160ff16815181106117da576117da615167565b602002602001015161ffff1660000361185c57600154604051631102d98960e31b81526001600160a01b0390911690638816cc4890611822908c90859060009060040161519f565b600060405180830381600087803b15801561183c57600080fd5b505af1158015611850573d6000803e3d6000fd5b50505050809350600192505b611873565b8061186b816151c1565b915050611674565b508115611a785760015485516001600160a01b0390911690638816cc48908a908690899060ff87169081106118aa576118aa615167565b60200260200101516040518463ffffffff1660e01b81526004016118d09392919061519f565b600060405180830381600087803b1580156118ea57600080fd5b505af11580156118fe573d6000803e3d6000fd5b505060015486516001600160a01b039091169250632b9e8f4191508a908690889060ff871690811061193257611932615167565b60200260200101516040518463ffffffff1660e01b81526004016119709392919092835260ff91909116602083015261ffff16604082015260600190565b600060405180830381600087803b15801561198a57600080fd5b505af115801561199e573d6000803e3d6000fd5b5050600154604051631102d98960e31b81526001600160a01b039091169250638816cc4891506119d7908b90859060009060040161519f565b600060405180830381600087803b1580156119f157600080fd5b505af1158015611a05573d6000803e3d6000fd5b5050600154604051632b9e8f4160e01b8152600481018c905260ff85166024820152600060448201526001600160a01b039091169250632b9e8f419150606401600060405180830381600087803b158015611a5f57600080fd5b505af1158015611a73573d6000803e3d6000fd5b505050505b6101608601805190611a89826151e0565b6001600160801b0316905250600154604051635d58d77760e11b81526001600160a01b039091169063bab1aeee90611ac7908b908a90600401615203565b600060405180830381600087803b158015611ae157600080fd5b505af1158015611af5573d6000803e3d6000fd5b5050604080518d81523360208201527f3ced7e7832110d6dc12e554a78c8ef8c5dadc0ea07f46174b22ec00120954e66935001905060405180910390a1505060016000555050505050505050565b600260005403611b655760405162461bcd60e51b81526004016103b990614bd3565b600260009081556001546040516327b2595f60e11b8152600481018590526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015611bb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bda9190614c2b565b6001546080820151604051630375c15960e31b815260048101919091529192506001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4f9190614ebe565b60e001516001600160a01b0316336001600160a01b031614611c995760405162461bcd60e51b815260206004820152600360248201526230303360e81b60448201526064016103b9565b80610180015115611cd25760405162461bcd60e51b815260206004820152600360248201526203031360ec1b60448201526064016103b9565b6001546040516389e6bf6d60e01b81526004810185905242916001600160a01b0316906389e6bf6d90602401602060405180830381865afa158015611d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3f9190614d6e565b611d4c9062278d00614d5b565b1015611d805760405162461bcd60e51b815260206004820152600360248201526230333760e81b60448201526064016103b9565b8115156101608201526001610180820181905254604051630c58367160e21b81526001600160a01b0390911690633160d9c490611dc39086908590600401614e64565b600060405180830381600087803b158015611ddd57600080fd5b505af1158015611df1573d6000803e3d6000fd5b50505050811561229f576001546080820151604051630375c15960e31b815260048101919091526000916001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190614ebe565b905060268161016001516001600160801b031610611eb65760405162461bcd60e51b815260206004820152600360248201526230313160e81b60448201526064016103b9565b6040820151610120820151600090611ed090600290614d39565b90508015611ef657611ee7828460e0015183614183565b611ef682846060015183614183565b600154608085015160405163e9ca25c160e01b815260048101919091526000916001600160a01b03169063e9ca25c190602401600060405180830381865afa158015611f46573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6e9190810190615049565b6001546080870151604051630149cf8d60e31b81529293506000926001600160a01b0390921691630a4e7c6891611fab9160040190815260200190565b600060405180830381865afa158015611fc8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ff091908101906150d8565b905060005b60268160ff1610156121cf5760006001600160a01b0316838260ff168151811061202157612021615167565b60200260200101516001600160a01b0316036120d7576001546080880151604051631102d98960e31b81526001600160a01b0390921691638816cc489161206e9185908a9060040161519f565b600060405180830381600087803b15801561208857600080fd5b505af115801561209c573d6000803e3d6000fd5b5050505084838260ff16815181106120b6576120b6615167565b60200260200101906001600160a01b031690816001600160a01b0316815250505b846001600160a01b0316838260ff16815181106120f6576120f6615167565b60200260200101516001600160a01b0316036121bd57600154608088015183516001600160a01b0390921691632b9e8f4191908490869060ff831690811061214057612140615167565b60200260200101516001612154919061531f565b6040516001600160e01b031960e086901b168152600481019390935260ff909116602483015261ffff166044820152606401600060405180830381600087803b1580156121a057600080fd5b505af11580156121b4573d6000803e3d6000fd5b505050506121cf565b806121c7816151c1565b915050611ff5565b5061016085018051906121e18261533a565b6001600160801b03169052506001546080870151604051635d58d77760e11b81526001600160a01b039092169163bab1aeee91612222918990600401615203565b600060405180830381600087803b15801561223c57600080fd5b505af1158015612250573d6000803e3d6000fd5b5050506101a0870151604080519115158252602082018b90527ff7f3bd1b56cd57e01f9f548bed2c4746361abc809faee25e5060e09b8d79471f92500160405180910390a150505050506122e1565b6101a0810151604080519115158252602082018590527f47236ddb9e343bdc8b6678a97a93ee473a835583135b599b18bbb33d4c8dba15910160405180910390a15b5050600160005550565b60026000540361230d5760405162461bcd60e51b81526004016103b990614bd3565b60026000556001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690631bae0ac8908290634f64b2be906024016101c060405180830381865afa158015612364573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123889190614c2b565b608001516040518263ffffffff1660e01b81526004016123aa91815260200190565b6101c060405180830381865afa1580156123c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ec9190614ebe565b602001516001546040516327b2595f60e11b8152600481018590526001600160a01b0390911690631bae0ac8908290634f64b2be906024016101c060405180830381865afa158015612442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124669190614c2b565b608001516040518263ffffffff1660e01b815260040161248891815260200190565b6101c060405180830381865afa1580156124a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ca9190614ebe565b604001516001600160801b0382161561251957816001600160801b0316421180156124fd5750806001600160801b031642105b6125195760405162461bcd60e51b81526004016103b990614d06565b6001546040516327b2595f60e11b8152600481018690526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015612563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125879190614c2b565b6101600151806125bf5760405162461bcd60e51b815260206004820152600360248201526218181b60e91b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018790526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015612609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262d9190614c2b565b60400151336001600160a01b0382160361266f5760405162461bcd60e51b815260206004820152600360248201526230303760e81b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018890526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa1580156126ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126de9190614c2b565b90506000816040015190506126f7338360800151613e71565b8160a001513410156127315760405162461bcd60e51b815260206004820152600360248201526218189960e91b60448201526064016103b9565b60015460405163308b4c9760e01b8152600481018a90526001600160a01b039091169063308b4c9790602401602060405180830381865afa15801561277a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279e9190614d6e565b8711156127d35760405162461bcd60e51b815260206004820152600360248201526230313960e81b60448201526064016103b9565b8660000361289c5781604001516001600160a01b031682602001516001600160a01b0316636352211e84606001516040518263ffffffff1660e01b815260040161281f91815260200190565b602060405180830381865afa15801561283c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128609190614e96565b6001600160a01b03161461289c5760405162461bcd60e51b815260206004820152600360248201526230343760e81b60448201526064016103b9565b6128b5826020015183606001518460400151338b614239565b60015460405163308b4c9760e01b8152600481018a90526001600160a01b03909116906305a241cf908a908a90849063308b4c9790602401602060405180830381865afa15801561290a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292e9190614d6e565b6129389190615360565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561297657600080fd5b505af115801561298a573d6000803e3d6000fd5b5050600154604051630c58367160e21b81526001600160a01b039091169250633160d9c491506129c0908b908690600401614e64565b600060405180830381600087803b1580156129da57600080fd5b505af11580156129ee573d6000803e3d6000fd5b5050604080518b81526001600160a01b03851660208201523381830152606081018b905234608082015290517fe6f3aea277454a2f5194b36793fbffd29ac6760ea9c0de28be6b01cb8f5d13e293509081900360a0019150a16000806000612a5e856020015186606001516140bf565b919450925090506000612a72602834614d39565b90506000612a808234615360565b9050612a8b82614337565b82158015612aa157506001600160a01b03851615155b15612af85760006103e8612ab58684615373565b612abf9190614d39565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f19350505050508082612af49190615360565b9150505b612b0b8760800151828960400151614431565b50828015612b2157506001600160a01b03851615155b15612b3a57612b3887602001518860600151614763565b505b505060016000555050505050505050505050565b3480612b825760405162461bcd60e51b815260206004820152600360248201526230343160e81b60448201526064016103b9565b6001546040805163013ccd2b60e01b815290516000926001600160a01b03169163013ccd2b9160048083019260209291908290030181865afa158015612bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf09190614d6e565b6001546040805160e0810182526001600160a01b0389811682526020820189905281830187905260608201889052336080830152600060a0830181905260c0830152915163010a64eb60e71b8152939450911691638532758091612c56916004016153de565b600060405180830381600087803b158015612c7057600080fd5b505af1158015612c84573d6000803e3d6000fd5b5050604080516001600160a01b03891681526020810188905290810184905260608101859052608081018690523360a08201527ffe4f5a8239b24cb201b3eb9f1d3f3c6b4d4b49564974f47e03dcf014502c4f71925060c001905060405180910390a15050505050565b600260005403612d105760405162461bcd60e51b81526004016103b990614bd3565b6002600055600154604051634539753560e11b8152600481018490526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015612d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8291906153ec565b51600154604051634539753560e11b8152600481018590526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015612dcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df091906153ec565b60200151600154604051634539753560e11b8152600481018690526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015612e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6191906153ec565b606001516004546001600160a01b03163314801590612e8b57506005546001600160a01b03163314155b15612fb4578015612f0c57604051627eeac760e11b81523360048201526024810183905281906001600160a01b0385169062fdd58e90604401602060405180830381865afa158015612ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f059190614d6e565b1015612f82565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e90602401602060405180830381865afa158015612f53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f779190614e96565b6001600160a01b0316145b612fb45760405162461bcd60e51b815260206004820152600360248201526230303560e81b60448201526064016103b9565b600154604051634539753560e11b8152600481018790526000916001600160a01b031690638a72ea6a9060240160e060405180830381865afa158015612ffe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302291906153ec565b90508060c001511561305c5760405162461bcd60e51b815260206004820152600360248201526230343560e81b60448201526064016103b9565b8415801560a0830152600160c08301526131af5761308d816000015182602001513384608001518560600151614239565b60008060006130a4846000015185602001516140bf565b9250925092506000602885604001516130bd9190614d39565b90506130c881614337565b60008186604001516130da9190615360565b9050821580156130f257506001600160a01b03851615155b156131495760006103e86131068684615373565b6131109190614d39565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f193505050505080826131459190615360565b9150505b604051339082156108fc029083906000818181858888f19350505050158015613176573d6000803e3d6000fd5b5082801561318c57506001600160a01b03851615155b156131a5576131a386600001518760200151614763565b505b505050505061320a565b80606001516000036132025780608001516001600160a01b03166108fc82604001519081150290604051600060405180830381858888f193505050501580156131fc573d6000803e3d6000fd5b5061320a565b600060c08201525b600154604051631d77e78f60e21b81526001600160a01b03909116906375df9e3c9061323c9089908590600401615491565b600060405180830381600087803b15801561325657600080fd5b505af115801561326a573d6000803e3d6000fd5b5050604080518981528815156020820152338183015290517fe9f6060889e0434a651f8001c16e9d158877519e53363996d74d659c605580fe9350908190036060019150a15050600160005550505050565b600781815481106132cc57600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b900461ffff1682565b6001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561333c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133609190614c2b565b60800151600154604051630375c15960e31b8152600481018390526001600160a01b0390911690631bae0ac8906024016101c060405180830381865afa1580156133ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d29190614ebe565b60e001516001600160a01b0316336001600160a01b03161461341c5760405162461bcd60e51b815260206004820152600360248201526230303360e81b60448201526064016103b9565b60026000540361343e5760405162461bcd60e51b81526004016103b990614bd3565b600260009081556001546040516327b2595f60e11b8152600481018690526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561348f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b39190614c2b565b9050806101a001516134ed5760405162461bcd60e51b815260206004820152600360248201526230303160e81b60448201526064016103b9565b82156138c257600154604051630131556d60e31b8152600481018690526000916001600160a01b03169063098aab6890602401602060405180830381865afa15801561353d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135619190614d6e565b116135945760405162461bcd60e51b815260206004820152600360248201526203032360ec1b60448201526064016103b9565b6101408101516001600160801b0316156135ec578061014001516001600160801b03164210156135ec5760405162461bcd60e51b815260206004820152600360248201526230313560e81b60448201526064016103b9565b61360e8160200151826060015183604001518461010001518560c00151614239565b6000806000613625846020015185606001516140bf565b925092509250600060288560e0015161363e9190614d39565b905061364981614337565b6000818660e0015161365b9190615360565b90508215801561367357506001600160a01b03851615155b156136ca5760006103e86136878684615373565b6136919190614d39565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f193505050505080826136c69190615360565b9150505b6001546040516327b2595f60e11b8152600481018b9052613749916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015613716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373a9190614c2b565b60800151828860400151614431565b5082801561375f57506001600160a01b03851615155b156137785761377686602001518760600151614763565b505b60015460e0870151604051630131556d60e31b8152600481018c90526001600160a01b039092169163e54e3f9f918c91849063098aab6890602401602060405180830381865afa1580156137d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137f49190614d6e565b6137fe9190615360565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561383c57600080fd5b505af1158015613850573d6000803e3d6000fd5b5050600154604051630c58367160e21b81526001600160a01b039091169250633160d9c49150613886908c908a90600401614e64565b600060405180830381600087803b1580156138a057600080fd5b505af11580156138b4573d6000803e3d6000fd5b5050505050505050506138f4565b8061010001516001600160a01b03166108fc8260e001519081150290604051600060405180830381858888f150505050505b6040805185815284151560208201527f9d909994f18f6424ad7e7bc4e667b553582bbb4798ec8b17c93c6866b32b48e4910160405180910390a1505060016000555050565b60015460405163022914a760e01b81523360048201526001600160a01b039091169063022914a790602401602060405180830381865afa158015613981573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a59190614e79565b6139d75760405162461bcd60e51b815260206004820152600360248201526230323160e81b60448201526064016103b9565b600754156139eb576139eb600760006147cf565b60005b81518160ff161015613a76576007828260ff1681518110613a1157613a11615167565b6020908102919091018101518254600181018455600093845292829020815193018054919092015161ffff16600160a01b026001600160b01b03199091166001600160a01b039093169290921791909117905580613a6e816151c1565b9150506139ee565b5050565b6001546040516327b2595f60e11b8152600481018390526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015613ac4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae89190614c2b565b604001516001600160a01b0381163314613b2a5760405162461bcd60e51b815260206004820152600360248201526218181960e91b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018490526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015613b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b999190614c2b565b905080610180015115613bd45760405162461bcd60e51b815260206004820152600360248201526230313360e81b60448201526064016103b9565b6001610180820181905254604051630c58367160e21b81526001600160a01b0390911690633160d9c490613c0e9086908590600401614e64565b600060405180830381600087803b158015613c2857600080fd5b505af1158015613c3c573d6000803e3d6000fd5b505050507f3cbe45d0a02a4b58f7f8b054ffa27ae85a80593af56e11e9c155c7e66fd7fd1783604051613c7191815260200190565b60405180910390a1505050565b600260005403613ca05760405162461bcd60e51b81526004016103b990614bd3565b60026000908155600154604051634539753560e11b8152600481018490526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015613cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d1491906153ec565b905080608001516001600160a01b0316336001600160a01b031614613d615760405162461bcd60e51b815260206004820152600360248201526230343360e81b60448201526064016103b9565b8060c0015115613d995760405162461bcd60e51b815260206004820152600360248201526203033360ec1b60448201526064016103b9565b600160c0820181905254604051631d77e78f60e21b81526001600160a01b03909116906375df9e3c90613dd29085908590600401615491565b600060405180830381600087803b158015613dec57600080fd5b505af1158015613e00573d6000803e3d6000fd5b50505050604081810151905133916108fc811502916000818181858888f19350505050158015613e34573d6000803e3d6000fd5b506040518281527fddb90d1e00f0b34a7794092f1433b8469d43eb9e540070e7423659c3f987f2869060200160405180910390a150506001600055565b600154604051630375c15960e31b8152600481018390526000916001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015613ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ee09190614ebe565b60e00151600154604051630375c15960e31b8152600481018590529192506000916001600160a01b0390911690631bae0ac8906024016101c060405180830381865afa158015613f34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f589190614ebe565b60600151600154604051637abfa49d60e11b8152600481018690529192506000916001600160a01b039091169063f57f493a90602401602060405180830381865afa158015613fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fcf9190614d6e565b118015613fee5750816001600160a01b0316846001600160a01b031614155b801561400c5750806001600160a01b0316846001600160a01b031614155b156140b957600354604051627eeac760e11b81526001600160a01b03868116600483015260248201869052600192169062fdd58e90604401602060405180830381865afa158015614061573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140859190614d6e565b10156140b95760405162461bcd60e51b815260206004820152600360248201526206062760eb1b60448201526064016103b9565b50505050565b6000806000846001600160a01b031663b76c632b856040518263ffffffff1660e01b81526004016140f291815260200190565b606060405180830381865afa92505050801561412b575060408051601f3d908101601f19168201909252614128918101906154a6565b60015b61413d5750600091508190508061417c565b60648211156141745760405162461bcd60e51b815260206004820152600360248201526230303960e81b60448201526064016103b9565b919450925090505b9250925092565b6002546040516323b872dd60e01b81526001600160a01b038581166004830152848116602483015260448201849052909116906323b872dd906064016020604051808303816000875af11580156141de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142029190614e79565b6142345760405162461bcd60e51b815260206004820152600360248201526230333960e81b60448201526064016103b9565b505050565b806000036142b057604051632142170760e11b81526001600160a01b0384811660048301528381166024830152604482018690528616906342842e0e90606401600060405180830381600087803b15801561429357600080fd5b505af11580156142a7573d6000803e3d6000fd5b50505050614330565b604051637921219560e11b81526001600160a01b0384811660048301528381166024830152604482018690526064820183905260a06084830152600060a483015286169063f242432a9060c401600060405180830381600087803b15801561431757600080fd5b505af115801561432b573d6000803e3d6000fd5b505050505b5050505050565b8060005b6007548110156144155760006007828154811061435a5761435a615167565b60009182526020808320604080518082019091529201546001600160a01b0381168352600160a01b900461ffff169082018190529092506103e89061439f9087615373565b6143a99190614d39565b9050808410156143ba575050614415565b81516040516001600160a01b039091169082156108fc029083906000818181858888f193505050501580156143f3573d6000803e3d6000fd5b506143fe8185615360565b93505050808061440d906154e9565b91505061433b565b5080600660008282546144289190614d5b565b90915550505050565b600154604051630375c15960e31b81526004810185905260009182916001600160a01b0390911690631bae0ac8906024016101c060405180830381865afa158015614480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144a49190614ebe565b60a081015190915061ffff1660006103e86144bf8388615373565b6144c99190614d39565b60015460405163e9ca25c160e01b8152600481018a905291925060009182916001600160a01b03169063e9ca25c190602401600060405180830381865afa158015614518573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526145409190810190615049565b905060005b60268160ff1610156145a75760006001600160a01b0316828260ff168151811061457157614571615167565b60200260200101516001600160a01b031603156145a757614593600184615502565b92508061459f816151c1565b915050614545565b5060006145b760ff841685614d39565b905060005b8360ff168160ff16101561462257828160ff16815181106145df576145df615167565b60200260200101516001600160a01b03166108fc839081150290604051600060405180830381858888f1935050505050808061461a906151c1565b9150506145bc565b5060006103e887610100015161ffff168b61463d9190615373565b6146479190614d39565b60e08801516040519192506001600160a01b03169082156108fc029083906000818181858888f193505050505080856146809190614d5b565b945060006103e8886080015161ffff168c61469b9190615373565b6146a59190614d39565b60608901516040519192506001600160a01b03169082156108fc029083906000818181858888f193505050505080866146de9190614d5b565b95506001600160a01b038a166108fc6146f7888e615360565b6040518115909202916000818181858888f19350505050507f23cb16b09a61498f6e546e9c9020101ce3f462f7cda6e6fe87a82d04efdbb7278c8c604051614749929190918252602082015260400190565b60405180910390a1509396505050505050505b9392505050565b60405163415d0aa360e11b8152600481018290526000906001600160a01b038416906382ba154690602401600060405180830381600087803b1580156147a857600080fd5b505af19250505080156147b9575060015b6147c5575060006147c9565b5060015b92915050565b50805460008255906000526020600020908101906147ed91906147f0565b50565b5b8082111561480f5780546001600160b01b03191681556001016147f1565b5090565b60006020828403121561482557600080fd5b5035919050565b6001600160a01b03811681146147ed57600080fd5b803561484c8161482c565b919050565b6000806000806080858703121561486757600080fd5b84356148728161482c565b935060208501356148828161482c565b925060408501356148928161482c565b915060608501356148a28161482c565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156148e7576148e76148ad565b60405290565b6040805190810167ffffffffffffffff811182821017156148e7576148e76148ad565b6040516101c0810167ffffffffffffffff811182821017156148e7576148e76148ad565b604051601f8201601f1916810167ffffffffffffffff8111828210171561495d5761495d6148ad565b604052919050565b6001600160801b03811681146147ed57600080fd5b803561484c81614965565b80151581146147ed57600080fd5b803561484c81614985565b600061014082840312156149b157600080fd5b6149b96148c3565b6149c283614841565b8152602083013560208201526040830135604082015260608301356060820152608083013560808201526149f860a0840161497a565b60a0820152614a0960c0840161497a565b60c0820152614a1a60e08401614993565b60e0820152610100614a2d818501614993565b90820152610120614a3f848201614841565b908201529392505050565b60008060408385031215614a5d57600080fd5b823591506020830135614a6f81614985565b809150509250929050565b60008060408385031215614a8d57600080fd5b50508035926020909101359150565b600080600060608486031215614ab157600080fd5b8335614abc8161482c565b95602085013595506040909401359392505050565b600067ffffffffffffffff821115614aeb57614aeb6148ad565b5060051b60200190565b61ffff811681146147ed57600080fd5b60006020808385031215614b1857600080fd5b823567ffffffffffffffff811115614b2f57600080fd5b8301601f81018513614b4057600080fd5b8035614b53614b4e82614ad1565b614934565b81815260069190911b82018301908381019087831115614b7257600080fd5b928401925b82841015614bc85760408489031215614b905760008081fd5b614b986148ed565b8435614ba38161482c565b815284860135614bb281614af5565b8187015282526040939093019290840190614b77565b979650505050505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b805161484c8161482c565b805161484c81614965565b805161484c81614985565b60006101c08284031215614c3e57600080fd5b614c46614910565b82518152614c5660208401614c0a565b6020820152614c6760408401614c0a565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e0820152610100614cac818501614c0a565b90820152610120614cbe848201614c15565b90820152610140614cd0848201614c15565b90820152610160614ce2848201614c20565b90820152610180614cf4848201614c20565b908201526101a0614a3f848201614c20565b6020808252600390820152620c0c0d60ea1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082614d5657634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156147c9576147c9614d23565b600060208284031215614d8057600080fd5b5051919050565b805182526020810151614da560208401826001600160a01b03169052565b506040810151614dc060408401826001600160a01b03169052565b50606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e083015261010080820151614e0e828501826001600160a01b03169052565b5050610120818101516001600160801b0390811691840191909152610140808301519091169083015261016080820151151590830152610180808201511515908301526101a080820151801515828501526140b9565b8281526101e0810161475c6020830184614d87565b600060208284031215614e8b57600080fd5b815161475c81614985565b600060208284031215614ea857600080fd5b815161475c8161482c565b805161484c81614af5565b60006101c08284031215614ed157600080fd5b614ed9614910565b82518152614ee960208401614c15565b6020820152614efa60408401614c15565b6040820152614f0b60608401614c0a565b6060820152614f1c60808401614eb3565b6080820152614f2d60a08401614eb3565b60a0820152614f3e60c08401614eb3565b60c0820152614f4f60e08401614c0a565b60e0820152610100614f62818501614eb3565b9082015261012083810151908201526101408084015190820152610160614ce2818501614c15565b6101c081016147c98284614d87565b82516001600160a01b0316815261016081016020840151602083015260408401516040830152606084015160608301526080840151608083015260a0840151614fed60a08401826001600160801b03169052565b5060c084015161500860c08401826001600160801b03169052565b5060e084015161501c60e084018215159052565b5061010084810151151590830152610120938401516001600160a01b031693820193909352610140015290565b6000602080838503121561505c57600080fd5b825167ffffffffffffffff81111561507357600080fd5b8301601f8101851361508457600080fd5b8051615092614b4e82614ad1565b81815260059190911b820183019083810190878311156150b157600080fd5b928401925b82841015614bc85783516150c98161482c565b825292840192908401906150b6565b600060208083850312156150eb57600080fd5b825167ffffffffffffffff81111561510257600080fd5b8301601f8101851361511357600080fd5b8051615121614b4e82614ad1565b81815260059190911b8201830190838101908783111561514057600080fd5b928401925b82841015614bc857835161515881614af5565b82529284019290840190615145565b634e487b7160e01b600052603260045260246000fd5b61ffff82811682821603908082111561519857615198614d23565b5092915050565b92835260ff9190911660208301526001600160a01b0316604082015260600190565b600060ff821660ff81036151d7576151d7614d23565b60010192915050565b60006001600160801b038216806151f9576151f9614d23565b6000190192915050565b60006101e08201905083825282516020830152602083015161523060408401826001600160801b03169052565b5060408301516001600160801b03811660608401525060608301516001600160a01b038116608084015250608083015161ffff811660a08401525060a083015161ffff811660c08401525060c083015161ffff811660e08401525060e08301516101006152a7818501836001600160a01b03169052565b84015190506101206152be8482018361ffff169052565b840151610140848101919091528401516101608085019190915284015190506101806152f4818501836001600160801b03169052565b84015190506101a06153098482018315159052565b8401518015156101c08501529050509392505050565b61ffff81811683821601908082111561519857615198614d23565b60006001600160801b0380831681810361535657615356614d23565b6001019392505050565b818103818111156147c9576147c9614d23565b80820281158282048414176147c9576147c9614d23565b60018060a01b038082511683526020820151602084015260408201516040840152606082015160608401528060808301511660808401525060a0810151151560a083015260c0810151151560c08301525050565b60e081016147c9828461538a565b600060e082840312156153fe57600080fd5b60405160e0810181811067ffffffffffffffff82111715615421576154216148ad565b604052825161542f8161482c565b80825250602083015160208201526040830151604082015260608301516060820152608083015161545f8161482c565b608082015260a083015161547281614985565b60a082015260c083015161548581614985565b60c08201529392505050565b828152610100810161475c602083018461538a565b6000806000606084860312156154bb57600080fd5b83516154c68161482c565b6020850151604086015191945092506154de81614985565b809150509250925092565b6000600182016154fb576154fb614d23565b5060010190565b60ff81811683821601908111156147c9576147c9614d2356fea264697066735822122035f6fe14bd0080c9c3c8957079aa2f5a336eff07c90d15e2e953fe0041bc873e64736f6c63430008110033000000000000000000000000e4f092172ca07038c1f87b5fe4d0fc4805201580000000000000000000000000f18623645b0c04c4938494e076c11bdbbfe8df6e000000000000000000000000fe1e5ef9cc718b47b41611f09a186be4f2ffdf11000000000000000000000000ad527b838de3a8719f335975ba7fadeb5f082c710000000000000000000000004ffefd252d8f9ecfde7ae4a3f6233dd43ad9b36f

Deployed Bytecode

0x6080604052600436106101145760003560e01c80636da464dc116100a05780638cdaab53116100645780638cdaab53146102f7578063ba89dfab14610317578063d0b755cc14610337578063e0a8f6f514610357578063ef706adf1461037757600080fd5b80636da464dc1461024f578063720123331461026f5780637de3bd0714610282578063852da752146102955780638b28ebfd146102b557600080fd5b8063537820bf116100e7578063537820bf146101af578063597690c0146101cf5780635e25041d146101ef57806366c3049e1461020f5780636d5a5fa61461022f57600080fd5b80630e733d9e1461011957806311ce02671461015657806326232a2e14610176578063454a2ab31461019a575b600080fd5b34801561012557600080fd5b50600454610139906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561016257600080fd5b50600154610139906001600160a01b031681565b34801561018257600080fd5b5061018c60065481565b60405190815260200161014d565b6101ad6101a8366004614813565b610397565b005b3480156101bb57600080fd5b506101ad6101ca366004614851565b610982565b3480156101db57600080fd5b50600554610139906001600160a01b031681565b3480156101fb57600080fd5b506101ad61020a36600461499e565b610a70565b34801561021b57600080fd5b506101ad61022a366004614813565b61123c565b34801561023b57600080fd5b50600354610139906001600160a01b031681565b34801561025b57600080fd5b506101ad61026a366004614a4a565b611b43565b6101ad61027d366004614a7a565b6122eb565b6101ad610290366004614a9c565b612b4e565b3480156102a157600080fd5b506101ad6102b0366004614a4a565b612cee565b3480156102c157600080fd5b506102d56102d0366004614813565b6132bc565b604080516001600160a01b03909316835261ffff90911660208301520161014d565b34801561030357600080fd5b506101ad610312366004614a4a565b6132f2565b34801561032357600080fd5b506101ad610332366004614b05565b613939565b34801561034357600080fd5b50600254610139906001600160a01b031681565b34801561036357600080fd5b506101ad610372366004614813565b613a7a565b34801561038357600080fd5b506101ad610392366004614813565b613c7e565b6002600054036103c25760405162461bcd60e51b81526004016103b990614bd3565b60405180910390fd5b60026000556001546040516327b2595f60e11b8152600481018390526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015610411573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104359190614c2b565b61016001518061046d5760405162461bcd60e51b815260206004820152600360248201526218181b60e91b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa1580156104b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104db9190614c2b565b61012001516001546040516327b2595f60e11b8152600481018590526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561052a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054e9190614c2b565b61014001516001600160801b0382161561059e57816001600160801b0316421180156105825750806001600160801b031642105b61059e5760405162461bcd60e51b81526004016103b990614d06565b6001546040516327b2595f60e11b8152600481018690526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa1580156105e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060c9190614c2b565b60400151336001600160a01b0382160361064e5760405162461bcd60e51b815260206004820152600360248201526230303760e81b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018790526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015610699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bd9190614c2b565b60e08101519091506106d0600a82614d39565b6106da9082614d5b565b34101580156106ed57508160a001513410155b61071f5760405162461bcd60e51b81526020600482015260036024820152620c0c4d60ea1b60448201526064016103b9565b816101a001516107575760405162461bcd60e51b8152602060048201526003602482015262181a1960e91b60448201526064016103b9565b610765338360800151613e71565b61010082015133321480156107835750336001600160a01b03821614155b6107b55760405162461bcd60e51b8152602060048201526003602482015262181a1b60e91b60448201526064016103b9565b3460e0840181905233610100850152600154604051630131556d60e31b8152600481018b90526001600160a01b039091169163e54e3f9f918b9190849063098aab6890602401602060405180830381865afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083c9190614d6e565b6108469190614d5b565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561088457600080fd5b505af1158015610898573d6000803e3d6000fd5b5050600154604051630c58367160e21b81526001600160a01b039091169250633160d9c491506108ce908b908790600401614e64565b600060405180830381600087803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b505050506001600160a01b03811615610935576040516001600160a01b0382169083156108fc029084906000818181858888f150505050505b60408051898152346020820152338183015290517f9e331edbebe8146ffa663dc1af424de11f33ef98bac5fa54df39ed595939dce29181900360600190a150506001600055505050505050565b60015460405163022914a760e01b81523360048201526001600160a01b039091169063022914a790602401602060405180830381865afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee9190614e79565b610a205760405162461bcd60e51b815260206004820152600360248201526230323160e81b60448201526064016103b9565b600280546001600160a01b039586166001600160a01b0319918216179091556003805494861694821694909417909355600480549285169284169290921790915560058054919093169116179055565b8051602082015160808301516004546001600160a01b03163314801590610aa257506005546001600160a01b03163314155b15610bcb578015610b2357604051627eeac760e11b81523360048201526024810183905281906001600160a01b0385169062fdd58e90604401602060405180830381865afa158015610af8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1c9190614d6e565b1015610b99565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e90602401602060405180830381865afa158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e9190614e96565b6001600160a01b0316145b610bcb5760405162461bcd60e51b815260206004820152600360248201526230303560e81b60448201526064016103b9565b6001546040808601519051630375c15960e31b81526001600160a01b0390921691631bae0ac891610c029160040190815260200190565b6101c060405180830381865afa158015610c20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c449190614ebe565b602001516001546040808701519051630375c15960e31b81526001600160a01b0390921691631bae0ac891610c7f9160040190815260200190565b6101c060405180830381865afa158015610c9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc19190614ebe565b604001516001600160801b03821615610d1057816001600160801b031642118015610cf45750806001600160801b031642105b610d105760405162461bcd60e51b81526004016103b990614d06565b8560e0015115610e1157856080015160011480610d2f57506080860151155b610d615760405162461bcd60e51b815260206004820152600360248201526230313760e81b60448201526064016103b9565b6001546040808801519051630375c15960e31b81526001600160a01b0390921691631bae0ac891610d989160040190815260200190565b6101c060405180830381865afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dda9190614ebe565b6101a00151610e115760405162461bcd60e51b81526020600482015260036024820152620c0c8d60ea1b60448201526064016103b9565b6004546000906001600160a01b0316331480610e3757506005546001600160a01b031633145b610e415733610e48565b8661012001515b6001546040898101519051630375c15960e31b815260048101919091529192506001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015610e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebd9190614ebe565b61012001516002546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024016020604051808303816000875af1158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f329190614d6e565b1015610f665760405162461bcd60e51b81526020600482015260036024820152620c0d0d60ea1b60448201526064016103b9565b610f78876000015188602001516140bf565b5050506000600160009054906101000a90046001600160a01b03166001600160a01b031663d92fc67b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff49190614d6e565b9050876080015160001461106e5760015460808901516040516305a241cf60e01b81526004810184905260248101919091526001600160a01b03909116906305a241cf90604401600060405180830381600087803b15801561105557600080fd5b505af1158015611069573d6000803e3d6000fd5b505050505b600154604051631f16fb5960e11b8152600481018390524260248201526001600160a01b0390911690633e2df6b290604401600060405180830381600087803b1580156110ba57600080fd5b505af11580156110ce573d6000803e3d6000fd5b50505050600160009054906101000a90046001600160a01b03166001600160a01b031663b976a72b604051806101c001604052808481526020018b600001516001600160a01b03168152602001856001600160a01b031681526020018b6020015181526020018b6040015181526020018b6060015181526020018b6080015181526020016000815260200160006001600160a01b031681526020018b60a001516001600160801b031681526020018b60c001516001600160801b031681526020016000151581526020016000151581526020018b60e0015115158152506040518263ffffffff1660e01b81526004016111c79190614f8a565b600060405180830381600087803b1580156111e157600080fd5b505af11580156111f5573d6000803e3d6000fd5b505050507f8ec1218093f086777e347d6747d77a1c6ea62770cbd1c22234fbb34fa93f8575888260405161122a929190614f99565b60405180910390a15050505050505050565b6001546040516327b2595f60e11b8152600481018390526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015611286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112aa9190614c2b565b604001516001600160a01b03811633146112ec5760405162461bcd60e51b815260206004820152600360248201526218181960e91b60448201526064016103b9565b60026000540361130e5760405162461bcd60e51b81526004016103b990614bd3565b60026000556001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190614c2b565b61016001516113b85760405162461bcd60e51b815260206004820152600360248201526206060760eb1b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018490526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114279190614c2b565b608001516001546040516327b2595f60e11b8152600481018690529192506000916001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561147b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149f9190614c2b565b6000610160820152600154604051630c58367160e21b81529192506001600160a01b031690633160d9c4906114da9087908590600401614e64565b600060405180830381600087803b1580156114f457600080fd5b505af1158015611508573d6000803e3d6000fd5b5050600154604051630375c15960e31b815260048101869052600093506001600160a01b039091169150631bae0ac8906024016101c060405180830381865afa158015611559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157d9190614ebe565b60015460405163e9ca25c160e01b8152600481018690529192506000916001600160a01b039091169063e9ca25c190602401600060405180830381865afa1580156115cc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115f49190810190615049565b600154604051630149cf8d60e31b8152600481018790529192506000916001600160a01b0390911690630a4e7c6890602401600060405180830381865afa158015611643573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261166b91908101906150d8565b90506000806025815b60268160ff1610156118735760006001600160a01b0316868260ff16815181106116a0576116a0615167565b60200260200101516001600160a01b0316036116be57809150611873565b858160ff16815181106116d3576116d3615167565b60200260200101516001600160a01b0316336001600160a01b031603611861576001858260ff168151811061170a5761170a615167565b6020026020010181815161171e919061517d565b61ffff1690525060015485516001600160a01b0390911690632b9e8f41908b908490899060ff831690811061175557611755615167565b60200260200101516040518463ffffffff1660e01b81526004016117939392919092835260ff91909116602083015261ffff16604082015260600190565b600060405180830381600087803b1580156117ad57600080fd5b505af11580156117c1573d6000803e3d6000fd5b50505050848160ff16815181106117da576117da615167565b602002602001015161ffff1660000361185c57600154604051631102d98960e31b81526001600160a01b0390911690638816cc4890611822908c90859060009060040161519f565b600060405180830381600087803b15801561183c57600080fd5b505af1158015611850573d6000803e3d6000fd5b50505050809350600192505b611873565b8061186b816151c1565b915050611674565b508115611a785760015485516001600160a01b0390911690638816cc48908a908690899060ff87169081106118aa576118aa615167565b60200260200101516040518463ffffffff1660e01b81526004016118d09392919061519f565b600060405180830381600087803b1580156118ea57600080fd5b505af11580156118fe573d6000803e3d6000fd5b505060015486516001600160a01b039091169250632b9e8f4191508a908690889060ff871690811061193257611932615167565b60200260200101516040518463ffffffff1660e01b81526004016119709392919092835260ff91909116602083015261ffff16604082015260600190565b600060405180830381600087803b15801561198a57600080fd5b505af115801561199e573d6000803e3d6000fd5b5050600154604051631102d98960e31b81526001600160a01b039091169250638816cc4891506119d7908b90859060009060040161519f565b600060405180830381600087803b1580156119f157600080fd5b505af1158015611a05573d6000803e3d6000fd5b5050600154604051632b9e8f4160e01b8152600481018c905260ff85166024820152600060448201526001600160a01b039091169250632b9e8f419150606401600060405180830381600087803b158015611a5f57600080fd5b505af1158015611a73573d6000803e3d6000fd5b505050505b6101608601805190611a89826151e0565b6001600160801b0316905250600154604051635d58d77760e11b81526001600160a01b039091169063bab1aeee90611ac7908b908a90600401615203565b600060405180830381600087803b158015611ae157600080fd5b505af1158015611af5573d6000803e3d6000fd5b5050604080518d81523360208201527f3ced7e7832110d6dc12e554a78c8ef8c5dadc0ea07f46174b22ec00120954e66935001905060405180910390a1505060016000555050505050505050565b600260005403611b655760405162461bcd60e51b81526004016103b990614bd3565b600260009081556001546040516327b2595f60e11b8152600481018590526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015611bb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bda9190614c2b565b6001546080820151604051630375c15960e31b815260048101919091529192506001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4f9190614ebe565b60e001516001600160a01b0316336001600160a01b031614611c995760405162461bcd60e51b815260206004820152600360248201526230303360e81b60448201526064016103b9565b80610180015115611cd25760405162461bcd60e51b815260206004820152600360248201526203031360ec1b60448201526064016103b9565b6001546040516389e6bf6d60e01b81526004810185905242916001600160a01b0316906389e6bf6d90602401602060405180830381865afa158015611d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3f9190614d6e565b611d4c9062278d00614d5b565b1015611d805760405162461bcd60e51b815260206004820152600360248201526230333760e81b60448201526064016103b9565b8115156101608201526001610180820181905254604051630c58367160e21b81526001600160a01b0390911690633160d9c490611dc39086908590600401614e64565b600060405180830381600087803b158015611ddd57600080fd5b505af1158015611df1573d6000803e3d6000fd5b50505050811561229f576001546080820151604051630375c15960e31b815260048101919091526000916001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190614ebe565b905060268161016001516001600160801b031610611eb65760405162461bcd60e51b815260206004820152600360248201526230313160e81b60448201526064016103b9565b6040820151610120820151600090611ed090600290614d39565b90508015611ef657611ee7828460e0015183614183565b611ef682846060015183614183565b600154608085015160405163e9ca25c160e01b815260048101919091526000916001600160a01b03169063e9ca25c190602401600060405180830381865afa158015611f46573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6e9190810190615049565b6001546080870151604051630149cf8d60e31b81529293506000926001600160a01b0390921691630a4e7c6891611fab9160040190815260200190565b600060405180830381865afa158015611fc8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ff091908101906150d8565b905060005b60268160ff1610156121cf5760006001600160a01b0316838260ff168151811061202157612021615167565b60200260200101516001600160a01b0316036120d7576001546080880151604051631102d98960e31b81526001600160a01b0390921691638816cc489161206e9185908a9060040161519f565b600060405180830381600087803b15801561208857600080fd5b505af115801561209c573d6000803e3d6000fd5b5050505084838260ff16815181106120b6576120b6615167565b60200260200101906001600160a01b031690816001600160a01b0316815250505b846001600160a01b0316838260ff16815181106120f6576120f6615167565b60200260200101516001600160a01b0316036121bd57600154608088015183516001600160a01b0390921691632b9e8f4191908490869060ff831690811061214057612140615167565b60200260200101516001612154919061531f565b6040516001600160e01b031960e086901b168152600481019390935260ff909116602483015261ffff166044820152606401600060405180830381600087803b1580156121a057600080fd5b505af11580156121b4573d6000803e3d6000fd5b505050506121cf565b806121c7816151c1565b915050611ff5565b5061016085018051906121e18261533a565b6001600160801b03169052506001546080870151604051635d58d77760e11b81526001600160a01b039092169163bab1aeee91612222918990600401615203565b600060405180830381600087803b15801561223c57600080fd5b505af1158015612250573d6000803e3d6000fd5b5050506101a0870151604080519115158252602082018b90527ff7f3bd1b56cd57e01f9f548bed2c4746361abc809faee25e5060e09b8d79471f92500160405180910390a150505050506122e1565b6101a0810151604080519115158252602082018590527f47236ddb9e343bdc8b6678a97a93ee473a835583135b599b18bbb33d4c8dba15910160405180910390a15b5050600160005550565b60026000540361230d5760405162461bcd60e51b81526004016103b990614bd3565b60026000556001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690631bae0ac8908290634f64b2be906024016101c060405180830381865afa158015612364573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123889190614c2b565b608001516040518263ffffffff1660e01b81526004016123aa91815260200190565b6101c060405180830381865afa1580156123c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ec9190614ebe565b602001516001546040516327b2595f60e11b8152600481018590526001600160a01b0390911690631bae0ac8908290634f64b2be906024016101c060405180830381865afa158015612442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124669190614c2b565b608001516040518263ffffffff1660e01b815260040161248891815260200190565b6101c060405180830381865afa1580156124a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ca9190614ebe565b604001516001600160801b0382161561251957816001600160801b0316421180156124fd5750806001600160801b031642105b6125195760405162461bcd60e51b81526004016103b990614d06565b6001546040516327b2595f60e11b8152600481018690526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015612563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125879190614c2b565b6101600151806125bf5760405162461bcd60e51b815260206004820152600360248201526218181b60e91b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018790526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015612609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262d9190614c2b565b60400151336001600160a01b0382160361266f5760405162461bcd60e51b815260206004820152600360248201526230303760e81b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018890526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa1580156126ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126de9190614c2b565b90506000816040015190506126f7338360800151613e71565b8160a001513410156127315760405162461bcd60e51b815260206004820152600360248201526218189960e91b60448201526064016103b9565b60015460405163308b4c9760e01b8152600481018a90526001600160a01b039091169063308b4c9790602401602060405180830381865afa15801561277a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279e9190614d6e565b8711156127d35760405162461bcd60e51b815260206004820152600360248201526230313960e81b60448201526064016103b9565b8660000361289c5781604001516001600160a01b031682602001516001600160a01b0316636352211e84606001516040518263ffffffff1660e01b815260040161281f91815260200190565b602060405180830381865afa15801561283c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128609190614e96565b6001600160a01b03161461289c5760405162461bcd60e51b815260206004820152600360248201526230343760e81b60448201526064016103b9565b6128b5826020015183606001518460400151338b614239565b60015460405163308b4c9760e01b8152600481018a90526001600160a01b03909116906305a241cf908a908a90849063308b4c9790602401602060405180830381865afa15801561290a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061292e9190614d6e565b6129389190615360565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561297657600080fd5b505af115801561298a573d6000803e3d6000fd5b5050600154604051630c58367160e21b81526001600160a01b039091169250633160d9c491506129c0908b908690600401614e64565b600060405180830381600087803b1580156129da57600080fd5b505af11580156129ee573d6000803e3d6000fd5b5050604080518b81526001600160a01b03851660208201523381830152606081018b905234608082015290517fe6f3aea277454a2f5194b36793fbffd29ac6760ea9c0de28be6b01cb8f5d13e293509081900360a0019150a16000806000612a5e856020015186606001516140bf565b919450925090506000612a72602834614d39565b90506000612a808234615360565b9050612a8b82614337565b82158015612aa157506001600160a01b03851615155b15612af85760006103e8612ab58684615373565b612abf9190614d39565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f19350505050508082612af49190615360565b9150505b612b0b8760800151828960400151614431565b50828015612b2157506001600160a01b03851615155b15612b3a57612b3887602001518860600151614763565b505b505060016000555050505050505050505050565b3480612b825760405162461bcd60e51b815260206004820152600360248201526230343160e81b60448201526064016103b9565b6001546040805163013ccd2b60e01b815290516000926001600160a01b03169163013ccd2b9160048083019260209291908290030181865afa158015612bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf09190614d6e565b6001546040805160e0810182526001600160a01b0389811682526020820189905281830187905260608201889052336080830152600060a0830181905260c0830152915163010a64eb60e71b8152939450911691638532758091612c56916004016153de565b600060405180830381600087803b158015612c7057600080fd5b505af1158015612c84573d6000803e3d6000fd5b5050604080516001600160a01b03891681526020810188905290810184905260608101859052608081018690523360a08201527ffe4f5a8239b24cb201b3eb9f1d3f3c6b4d4b49564974f47e03dcf014502c4f71925060c001905060405180910390a15050505050565b600260005403612d105760405162461bcd60e51b81526004016103b990614bd3565b6002600055600154604051634539753560e11b8152600481018490526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015612d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8291906153ec565b51600154604051634539753560e11b8152600481018590526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015612dcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df091906153ec565b60200151600154604051634539753560e11b8152600481018690526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015612e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6191906153ec565b606001516004546001600160a01b03163314801590612e8b57506005546001600160a01b03163314155b15612fb4578015612f0c57604051627eeac760e11b81523360048201526024810183905281906001600160a01b0385169062fdd58e90604401602060405180830381865afa158015612ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f059190614d6e565b1015612f82565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e90602401602060405180830381865afa158015612f53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f779190614e96565b6001600160a01b0316145b612fb45760405162461bcd60e51b815260206004820152600360248201526230303560e81b60448201526064016103b9565b600154604051634539753560e11b8152600481018790526000916001600160a01b031690638a72ea6a9060240160e060405180830381865afa158015612ffe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302291906153ec565b90508060c001511561305c5760405162461bcd60e51b815260206004820152600360248201526230343560e81b60448201526064016103b9565b8415801560a0830152600160c08301526131af5761308d816000015182602001513384608001518560600151614239565b60008060006130a4846000015185602001516140bf565b9250925092506000602885604001516130bd9190614d39565b90506130c881614337565b60008186604001516130da9190615360565b9050821580156130f257506001600160a01b03851615155b156131495760006103e86131068684615373565b6131109190614d39565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f193505050505080826131459190615360565b9150505b604051339082156108fc029083906000818181858888f19350505050158015613176573d6000803e3d6000fd5b5082801561318c57506001600160a01b03851615155b156131a5576131a386600001518760200151614763565b505b505050505061320a565b80606001516000036132025780608001516001600160a01b03166108fc82604001519081150290604051600060405180830381858888f193505050501580156131fc573d6000803e3d6000fd5b5061320a565b600060c08201525b600154604051631d77e78f60e21b81526001600160a01b03909116906375df9e3c9061323c9089908590600401615491565b600060405180830381600087803b15801561325657600080fd5b505af115801561326a573d6000803e3d6000fd5b5050604080518981528815156020820152338183015290517fe9f6060889e0434a651f8001c16e9d158877519e53363996d74d659c605580fe9350908190036060019150a15050600160005550505050565b600781815481106132cc57600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b900461ffff1682565b6001546040516327b2595f60e11b8152600481018490526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561333c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133609190614c2b565b60800151600154604051630375c15960e31b8152600481018390526001600160a01b0390911690631bae0ac8906024016101c060405180830381865afa1580156133ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d29190614ebe565b60e001516001600160a01b0316336001600160a01b03161461341c5760405162461bcd60e51b815260206004820152600360248201526230303360e81b60448201526064016103b9565b60026000540361343e5760405162461bcd60e51b81526004016103b990614bd3565b600260009081556001546040516327b2595f60e11b8152600481018690526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa15801561348f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b39190614c2b565b9050806101a001516134ed5760405162461bcd60e51b815260206004820152600360248201526230303160e81b60448201526064016103b9565b82156138c257600154604051630131556d60e31b8152600481018690526000916001600160a01b03169063098aab6890602401602060405180830381865afa15801561353d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135619190614d6e565b116135945760405162461bcd60e51b815260206004820152600360248201526203032360ec1b60448201526064016103b9565b6101408101516001600160801b0316156135ec578061014001516001600160801b03164210156135ec5760405162461bcd60e51b815260206004820152600360248201526230313560e81b60448201526064016103b9565b61360e8160200151826060015183604001518461010001518560c00151614239565b6000806000613625846020015185606001516140bf565b925092509250600060288560e0015161363e9190614d39565b905061364981614337565b6000818660e0015161365b9190615360565b90508215801561367357506001600160a01b03851615155b156136ca5760006103e86136878684615373565b6136919190614d39565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f193505050505080826136c69190615360565b9150505b6001546040516327b2595f60e11b8152600481018b9052613749916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015613716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373a9190614c2b565b60800151828860400151614431565b5082801561375f57506001600160a01b03851615155b156137785761377686602001518760600151614763565b505b60015460e0870151604051630131556d60e31b8152600481018c90526001600160a01b039092169163e54e3f9f918c91849063098aab6890602401602060405180830381865afa1580156137d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137f49190614d6e565b6137fe9190615360565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561383c57600080fd5b505af1158015613850573d6000803e3d6000fd5b5050600154604051630c58367160e21b81526001600160a01b039091169250633160d9c49150613886908c908a90600401614e64565b600060405180830381600087803b1580156138a057600080fd5b505af11580156138b4573d6000803e3d6000fd5b5050505050505050506138f4565b8061010001516001600160a01b03166108fc8260e001519081150290604051600060405180830381858888f150505050505b6040805185815284151560208201527f9d909994f18f6424ad7e7bc4e667b553582bbb4798ec8b17c93c6866b32b48e4910160405180910390a1505060016000555050565b60015460405163022914a760e01b81523360048201526001600160a01b039091169063022914a790602401602060405180830381865afa158015613981573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a59190614e79565b6139d75760405162461bcd60e51b815260206004820152600360248201526230323160e81b60448201526064016103b9565b600754156139eb576139eb600760006147cf565b60005b81518160ff161015613a76576007828260ff1681518110613a1157613a11615167565b6020908102919091018101518254600181018455600093845292829020815193018054919092015161ffff16600160a01b026001600160b01b03199091166001600160a01b039093169290921791909117905580613a6e816151c1565b9150506139ee565b5050565b6001546040516327b2595f60e11b8152600481018390526001600160a01b0390911690634f64b2be906024016101c060405180830381865afa158015613ac4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae89190614c2b565b604001516001600160a01b0381163314613b2a5760405162461bcd60e51b815260206004820152600360248201526218181960e91b60448201526064016103b9565b6001546040516327b2595f60e11b8152600481018490526000916001600160a01b031690634f64b2be906024016101c060405180830381865afa158015613b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b999190614c2b565b905080610180015115613bd45760405162461bcd60e51b815260206004820152600360248201526230313360e81b60448201526064016103b9565b6001610180820181905254604051630c58367160e21b81526001600160a01b0390911690633160d9c490613c0e9086908590600401614e64565b600060405180830381600087803b158015613c2857600080fd5b505af1158015613c3c573d6000803e3d6000fd5b505050507f3cbe45d0a02a4b58f7f8b054ffa27ae85a80593af56e11e9c155c7e66fd7fd1783604051613c7191815260200190565b60405180910390a1505050565b600260005403613ca05760405162461bcd60e51b81526004016103b990614bd3565b60026000908155600154604051634539753560e11b8152600481018490526001600160a01b0390911690638a72ea6a9060240160e060405180830381865afa158015613cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d1491906153ec565b905080608001516001600160a01b0316336001600160a01b031614613d615760405162461bcd60e51b815260206004820152600360248201526230343360e81b60448201526064016103b9565b8060c0015115613d995760405162461bcd60e51b815260206004820152600360248201526203033360ec1b60448201526064016103b9565b600160c0820181905254604051631d77e78f60e21b81526001600160a01b03909116906375df9e3c90613dd29085908590600401615491565b600060405180830381600087803b158015613dec57600080fd5b505af1158015613e00573d6000803e3d6000fd5b50505050604081810151905133916108fc811502916000818181858888f19350505050158015613e34573d6000803e3d6000fd5b506040518281527fddb90d1e00f0b34a7794092f1433b8469d43eb9e540070e7423659c3f987f2869060200160405180910390a150506001600055565b600154604051630375c15960e31b8152600481018390526000916001600160a01b031690631bae0ac8906024016101c060405180830381865afa158015613ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ee09190614ebe565b60e00151600154604051630375c15960e31b8152600481018590529192506000916001600160a01b0390911690631bae0ac8906024016101c060405180830381865afa158015613f34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f589190614ebe565b60600151600154604051637abfa49d60e11b8152600481018690529192506000916001600160a01b039091169063f57f493a90602401602060405180830381865afa158015613fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fcf9190614d6e565b118015613fee5750816001600160a01b0316846001600160a01b031614155b801561400c5750806001600160a01b0316846001600160a01b031614155b156140b957600354604051627eeac760e11b81526001600160a01b03868116600483015260248201869052600192169062fdd58e90604401602060405180830381865afa158015614061573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140859190614d6e565b10156140b95760405162461bcd60e51b815260206004820152600360248201526206062760eb1b60448201526064016103b9565b50505050565b6000806000846001600160a01b031663b76c632b856040518263ffffffff1660e01b81526004016140f291815260200190565b606060405180830381865afa92505050801561412b575060408051601f3d908101601f19168201909252614128918101906154a6565b60015b61413d5750600091508190508061417c565b60648211156141745760405162461bcd60e51b815260206004820152600360248201526230303960e81b60448201526064016103b9565b919450925090505b9250925092565b6002546040516323b872dd60e01b81526001600160a01b038581166004830152848116602483015260448201849052909116906323b872dd906064016020604051808303816000875af11580156141de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142029190614e79565b6142345760405162461bcd60e51b815260206004820152600360248201526230333960e81b60448201526064016103b9565b505050565b806000036142b057604051632142170760e11b81526001600160a01b0384811660048301528381166024830152604482018690528616906342842e0e90606401600060405180830381600087803b15801561429357600080fd5b505af11580156142a7573d6000803e3d6000fd5b50505050614330565b604051637921219560e11b81526001600160a01b0384811660048301528381166024830152604482018690526064820183905260a06084830152600060a483015286169063f242432a9060c401600060405180830381600087803b15801561431757600080fd5b505af115801561432b573d6000803e3d6000fd5b505050505b5050505050565b8060005b6007548110156144155760006007828154811061435a5761435a615167565b60009182526020808320604080518082019091529201546001600160a01b0381168352600160a01b900461ffff169082018190529092506103e89061439f9087615373565b6143a99190614d39565b9050808410156143ba575050614415565b81516040516001600160a01b039091169082156108fc029083906000818181858888f193505050501580156143f3573d6000803e3d6000fd5b506143fe8185615360565b93505050808061440d906154e9565b91505061433b565b5080600660008282546144289190614d5b565b90915550505050565b600154604051630375c15960e31b81526004810185905260009182916001600160a01b0390911690631bae0ac8906024016101c060405180830381865afa158015614480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144a49190614ebe565b60a081015190915061ffff1660006103e86144bf8388615373565b6144c99190614d39565b60015460405163e9ca25c160e01b8152600481018a905291925060009182916001600160a01b03169063e9ca25c190602401600060405180830381865afa158015614518573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526145409190810190615049565b905060005b60268160ff1610156145a75760006001600160a01b0316828260ff168151811061457157614571615167565b60200260200101516001600160a01b031603156145a757614593600184615502565b92508061459f816151c1565b915050614545565b5060006145b760ff841685614d39565b905060005b8360ff168160ff16101561462257828160ff16815181106145df576145df615167565b60200260200101516001600160a01b03166108fc839081150290604051600060405180830381858888f1935050505050808061461a906151c1565b9150506145bc565b5060006103e887610100015161ffff168b61463d9190615373565b6146479190614d39565b60e08801516040519192506001600160a01b03169082156108fc029083906000818181858888f193505050505080856146809190614d5b565b945060006103e8886080015161ffff168c61469b9190615373565b6146a59190614d39565b60608901516040519192506001600160a01b03169082156108fc029083906000818181858888f193505050505080866146de9190614d5b565b95506001600160a01b038a166108fc6146f7888e615360565b6040518115909202916000818181858888f19350505050507f23cb16b09a61498f6e546e9c9020101ce3f462f7cda6e6fe87a82d04efdbb7278c8c604051614749929190918252602082015260400190565b60405180910390a1509396505050505050505b9392505050565b60405163415d0aa360e11b8152600481018290526000906001600160a01b038416906382ba154690602401600060405180830381600087803b1580156147a857600080fd5b505af19250505080156147b9575060015b6147c5575060006147c9565b5060015b92915050565b50805460008255906000526020600020908101906147ed91906147f0565b50565b5b8082111561480f5780546001600160b01b03191681556001016147f1565b5090565b60006020828403121561482557600080fd5b5035919050565b6001600160a01b03811681146147ed57600080fd5b803561484c8161482c565b919050565b6000806000806080858703121561486757600080fd5b84356148728161482c565b935060208501356148828161482c565b925060408501356148928161482c565b915060608501356148a28161482c565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156148e7576148e76148ad565b60405290565b6040805190810167ffffffffffffffff811182821017156148e7576148e76148ad565b6040516101c0810167ffffffffffffffff811182821017156148e7576148e76148ad565b604051601f8201601f1916810167ffffffffffffffff8111828210171561495d5761495d6148ad565b604052919050565b6001600160801b03811681146147ed57600080fd5b803561484c81614965565b80151581146147ed57600080fd5b803561484c81614985565b600061014082840312156149b157600080fd5b6149b96148c3565b6149c283614841565b8152602083013560208201526040830135604082015260608301356060820152608083013560808201526149f860a0840161497a565b60a0820152614a0960c0840161497a565b60c0820152614a1a60e08401614993565b60e0820152610100614a2d818501614993565b90820152610120614a3f848201614841565b908201529392505050565b60008060408385031215614a5d57600080fd5b823591506020830135614a6f81614985565b809150509250929050565b60008060408385031215614a8d57600080fd5b50508035926020909101359150565b600080600060608486031215614ab157600080fd5b8335614abc8161482c565b95602085013595506040909401359392505050565b600067ffffffffffffffff821115614aeb57614aeb6148ad565b5060051b60200190565b61ffff811681146147ed57600080fd5b60006020808385031215614b1857600080fd5b823567ffffffffffffffff811115614b2f57600080fd5b8301601f81018513614b4057600080fd5b8035614b53614b4e82614ad1565b614934565b81815260069190911b82018301908381019087831115614b7257600080fd5b928401925b82841015614bc85760408489031215614b905760008081fd5b614b986148ed565b8435614ba38161482c565b815284860135614bb281614af5565b8187015282526040939093019290840190614b77565b979650505050505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b805161484c8161482c565b805161484c81614965565b805161484c81614985565b60006101c08284031215614c3e57600080fd5b614c46614910565b82518152614c5660208401614c0a565b6020820152614c6760408401614c0a565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e0820152610100614cac818501614c0a565b90820152610120614cbe848201614c15565b90820152610140614cd0848201614c15565b90820152610160614ce2848201614c20565b90820152610180614cf4848201614c20565b908201526101a0614a3f848201614c20565b6020808252600390820152620c0c0d60ea1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082614d5657634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156147c9576147c9614d23565b600060208284031215614d8057600080fd5b5051919050565b805182526020810151614da560208401826001600160a01b03169052565b506040810151614dc060408401826001600160a01b03169052565b50606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e083015261010080820151614e0e828501826001600160a01b03169052565b5050610120818101516001600160801b0390811691840191909152610140808301519091169083015261016080820151151590830152610180808201511515908301526101a080820151801515828501526140b9565b8281526101e0810161475c6020830184614d87565b600060208284031215614e8b57600080fd5b815161475c81614985565b600060208284031215614ea857600080fd5b815161475c8161482c565b805161484c81614af5565b60006101c08284031215614ed157600080fd5b614ed9614910565b82518152614ee960208401614c15565b6020820152614efa60408401614c15565b6040820152614f0b60608401614c0a565b6060820152614f1c60808401614eb3565b6080820152614f2d60a08401614eb3565b60a0820152614f3e60c08401614eb3565b60c0820152614f4f60e08401614c0a565b60e0820152610100614f62818501614eb3565b9082015261012083810151908201526101408084015190820152610160614ce2818501614c15565b6101c081016147c98284614d87565b82516001600160a01b0316815261016081016020840151602083015260408401516040830152606084015160608301526080840151608083015260a0840151614fed60a08401826001600160801b03169052565b5060c084015161500860c08401826001600160801b03169052565b5060e084015161501c60e084018215159052565b5061010084810151151590830152610120938401516001600160a01b031693820193909352610140015290565b6000602080838503121561505c57600080fd5b825167ffffffffffffffff81111561507357600080fd5b8301601f8101851361508457600080fd5b8051615092614b4e82614ad1565b81815260059190911b820183019083810190878311156150b157600080fd5b928401925b82841015614bc85783516150c98161482c565b825292840192908401906150b6565b600060208083850312156150eb57600080fd5b825167ffffffffffffffff81111561510257600080fd5b8301601f8101851361511357600080fd5b8051615121614b4e82614ad1565b81815260059190911b8201830190838101908783111561514057600080fd5b928401925b82841015614bc857835161515881614af5565b82529284019290840190615145565b634e487b7160e01b600052603260045260246000fd5b61ffff82811682821603908082111561519857615198614d23565b5092915050565b92835260ff9190911660208301526001600160a01b0316604082015260600190565b600060ff821660ff81036151d7576151d7614d23565b60010192915050565b60006001600160801b038216806151f9576151f9614d23565b6000190192915050565b60006101e08201905083825282516020830152602083015161523060408401826001600160801b03169052565b5060408301516001600160801b03811660608401525060608301516001600160a01b038116608084015250608083015161ffff811660a08401525060a083015161ffff811660c08401525060c083015161ffff811660e08401525060e08301516101006152a7818501836001600160a01b03169052565b84015190506101206152be8482018361ffff169052565b840151610140848101919091528401516101608085019190915284015190506101806152f4818501836001600160801b03169052565b84015190506101a06153098482018315159052565b8401518015156101c08501529050509392505050565b61ffff81811683821601908082111561519857615198614d23565b60006001600160801b0380831681810361535657615356614d23565b6001019392505050565b818103818111156147c9576147c9614d23565b80820281158282048414176147c9576147c9614d23565b60018060a01b038082511683526020820151602084015260408201516040840152606082015160608401528060808301511660808401525060a0810151151560a083015260c0810151151560c08301525050565b60e081016147c9828461538a565b600060e082840312156153fe57600080fd5b60405160e0810181811067ffffffffffffffff82111715615421576154216148ad565b604052825161542f8161482c565b80825250602083015160208201526040830151604082015260608301516060820152608083015161545f8161482c565b608082015260a083015161547281614985565b60a082015260c083015161548581614985565b60c08201529392505050565b828152610100810161475c602083018461538a565b6000806000606084860312156154bb57600080fd5b83516154c68161482c565b6020850151604086015191945092506154de81614985565b809150509250925092565b6000600182016154fb576154fb614d23565b5060010190565b60ff81811683821601908111156147c9576147c9614d2356fea264697066735822122035f6fe14bd0080c9c3c8957079aa2f5a336eff07c90d15e2e953fe0041bc873e64736f6c63430008110033

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

000000000000000000000000e4f092172ca07038c1f87b5fe4d0fc4805201580000000000000000000000000f18623645b0c04c4938494e076c11bdbbfe8df6e000000000000000000000000fe1e5ef9cc718b47b41611f09a186be4f2ffdf11000000000000000000000000ad527b838de3a8719f335975ba7fadeb5f082c710000000000000000000000004ffefd252d8f9ecfde7ae4a3f6233dd43ad9b36f

-----Decoded View---------------
Arg [0] : _storageContract (address): 0xe4F092172CA07038c1f87B5fe4d0fc4805201580
Arg [1] : _roomerToken (address): 0xF18623645B0C04c4938494E076C11BDbbFE8dF6e
Arg [2] : _accessTokenAddress (address): 0xfE1E5eF9cc718B47b41611F09a186Be4f2FfdF11
Arg [3] : _singleTokenAddress (address): 0xad527B838DE3A8719F335975BA7FADEb5F082C71
Arg [4] : _multipleTokenAddress (address): 0x4FFEFd252D8f9eCFDe7AE4a3F6233DD43Ad9b36F

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000e4f092172ca07038c1f87b5fe4d0fc4805201580
Arg [1] : 000000000000000000000000f18623645b0c04c4938494e076c11bdbbfe8df6e
Arg [2] : 000000000000000000000000fe1e5ef9cc718b47b41611f09a186be4f2ffdf11
Arg [3] : 000000000000000000000000ad527b838de3a8719f335975ba7fadeb5f082c71
Arg [4] : 0000000000000000000000004ffefd252d8f9ecfde7ae4a3f6233dd43ad9b36f


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.