false
false
100

Contract Address Details

0x9FE39C5837943987c290CA28F19130E44450FA38

Contract Name
KavalandCitizenship
Creator
0x8de3c3–c0f852 at 0xe9c48e–b5acf0
Balance
0 KAVA ( )
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
11603237
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
KavalandCitizenship




Optimization enabled
true
Compiler version
v0.8.18+commit.87f61d96




Optimization runs
2000
EVM Version
default




Verified at
2023-06-22T20:33:17.786873Z

Contract source code

/**
 *Submitted for verification at FtmScan.com on 2023-01-14
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
interface ICitizen {
    function ownerOf(uint256 tokenId) external view returns (address);
    function getProperties(uint256 tokenId) external view returns (uint256[3] memory);
}
interface IMap {
    function getLocation (
        uint256 region, 
        uint256 location) external view returns (string memory);
    function getMaxPop (
        uint256 region, 
        uint256 location) external view returns (uint256);
    
}

interface IERC20 {
    function mint(address to, uint256 amount) external;
}

interface IUbi {
    function getUBI (
        uint256 region, 
        uint256 location) external view returns (uint256);
}

contract KavalandCitizenship is Ownable {

    error LocationDoesNotExist(uint256 region, uint256 location);
    error NotTheOwner(uint256 tokenId, address sender);
    error LocationIsFull(uint256 region, uint256 location);
    error AlreadyRegistered(uint256 tokenId);
    error NotRegistered(uint256 tokenId);

    ICitizen citizen = ICitizen(0x0000000000000000000000000000000000000000);
    function changeCitizenContract(address newCitizen) public onlyOwner {
        citizen = ICitizen(newCitizen);
    }

    IMap kavamap = IMap(0x87ef79ac3011721f134C4DE1dd0E9d45221564F4);
    function changeMap(address newMap) public onlyOwner {
        kavamap = IMap(newMap);
    }

    
    IERC20 ubi_token = IERC20(0xeff6a8B943564626e2A52Ef2da86882b1846c0ab);
    function changeUbiToken(address newUbiToken) public onlyOwner {
        ubi_token = IERC20(newUbiToken);
    }

    
    IUbi ubi = IUbi(0x6fd7e86eB1D5d76D50051502cAc3681E9Bbed65f);
    function changeUbi(address newUbi) public onlyOwner {
        ubi = IUbi(newUbi);
    }

    uint256 public fee = 10 ether;
    function changeFee(uint256 newFee) public onlyOwner {
        fee = newFee;
    }

    uint256 public minCitizenshipLength = 13 weeks;
    function changeMinCitizenshipLength(uint256 newMin) public onlyOwner {
        minCitizenshipLength = newMin;
    }

    mapping (uint256 => uint256[]) public pops;


    // ---------------------------------------------------------------------------
    // ---------------------------------------------------------------------------
    // citizenship ---------------------------------------------------------------
    mapping (uint256 => uint256[2]) locationIndicesByTokenId;
    mapping (uint256 => bool) hasRegisteredByTokenId;
    mapping (uint256 => uint256) citizenSinceById;

    function _ownsCitizen(uint256 _tokenId, address _sender) internal view {
        if (citizen.ownerOf(_tokenId) != _sender) revert NotTheOwner({tokenId: _tokenId, sender: _sender});
    }

    function _isValidLocation(uint256 _region, uint256 _location) internal view {
        if (_region >= 4 || bytes(kavamap.getLocation(_region,_location)).length == 0) revert LocationDoesNotExist({region: _region, location: _location});
    }

    function isValidLocation(uint256 _region, uint256 _location) public view {
        _isValidLocation(_region, _location);
    } 
    
    function _hasSpace(uint256 _region, uint256 _location) internal view {
        if (pops[_region][_location] + 1 > kavamap.getMaxPop(_region,_location)) revert LocationIsFull({region: _region, location: _location});
    }
    function hasSpace(uint256 _region, uint256 _location) public view {
        _hasSpace(_region, _location);
    }

    function _notRegistered(uint256 _tokenId) internal view {
        if (hasRegisteredByTokenId[_tokenId] == true) revert AlreadyRegistered({tokenId: _tokenId});
    }
    function _isRegistered(uint256 _tokenId) internal view {
        if (hasRegisteredByTokenId[_tokenId] == false) revert NotRegistered({tokenId: _tokenId});
    }

    function _updateCitizenship(uint256 tokenId, uint256 region, uint256 location) internal {
        locationIndicesByTokenId[tokenId] = [region, location];
        pops[region][location] += 1;
        citizenSinceById[tokenId] = block.timestamp;
    }

    function _timeAsCitizen(uint256 tokenId) internal view returns (uint256) {
        return block.timestamp - citizenSinceById[tokenId];
    }

    function _correctFee(uint256 value) internal view {
        if (value != fee) revert MustPayCitizenshipFee();
    }

    function _hasBeenCitizenLongEnough(uint256 tokenId) internal view {
        if (_timeAsCitizen(tokenId) < 13 weeks) revert ChangedTooRecently();
    }

    function commonChecks( 
        uint256 region, uint256 location ) public view {
            
            _isValidLocation(region, location);
            _hasSpace(region, location);
        }

    function registerCitizenship(uint256 tokenId, 
        uint256 region, uint256 location) public {
            _ownsCitizen(tokenId, msg.sender);
        commonChecks( region, location);
        _notRegistered(tokenId);
        hasRegisteredByTokenId[tokenId] = true;
        _updateCitizenship(tokenId, region, location);
        _registerForUBI(tokenId);
    }

    error ChangedTooRecently();
    error MustPayCitizenshipFee();
    function changeCitizenship(uint256 tokenId, 
        uint256 region, uint256 location) public payable {
            _ownsCitizen(tokenId, msg.sender);
        commonChecks( region, location);
        _isRegistered(tokenId);
        _hasBeenCitizenLongEnough(tokenId);
        _correctFee(msg.value);
        _claimUBI(msg.sender, tokenId);
        uint256 a = locationIndicesByTokenId[tokenId][0];
        uint256 b = locationIndicesByTokenId[tokenId][1];
        pops[a][b] -= 1;
        _updateCitizenship(tokenId, region, location);

    }

    function _getLocIndex(uint256 tokenId) internal view returns (uint256[2] memory) {
        uint256 a = locationIndicesByTokenId[tokenId][0];
        uint256 b = locationIndicesByTokenId[tokenId][1];
        return [a,b];
    }
    function getLocIndex(uint256 tokenId) public view returns (uint256[2] memory) {
        return _getLocIndex(tokenId);
    }

    function _getLocation(uint256 tokenId) internal view returns (string memory) {
        uint256 a = locationIndicesByTokenId[tokenId][0];
        uint256 b = locationIndicesByTokenId[tokenId][1];
        return kavamap.getLocation(a,b);
    }
    function getLocation(uint256 tokenId) public view returns (string memory) {
        return _getLocation(tokenId);
    }


    // ---------------------------------------------------------------------------
    // ---------------------------------------------------------------------------
    // universal basic income ----------------------------------------------------
    mapping (uint256 => uint256) public lastUBIclaimByID;
    error AlreadyUBI();
    function _registerForUBI (uint256 tokenId) internal {
        if (lastUBIclaimByID[tokenId] > 0) revert AlreadyUBI();
        lastUBIclaimByID[tokenId] = block.timestamp;
    }

    function getLastClaim (uint256 tokenId) public view returns (uint256) {
        return lastUBIclaimByID[tokenId];
    }

    function _getBaseRate(uint256 tokenId) internal view returns (uint256) {
        uint256[2] memory index = _getLocIndex(tokenId);
        return ubi.getUBI(index[0],index[1]);
    }
    function getBaseRate(uint256 tokenId) public view returns (uint256) {
        return _getBaseRate(tokenId);
    }

    function _getExtraRate(uint256 tokenId) internal view returns (uint256) {
        return citizen.getProperties(tokenId)[2];
    }
    function getExtraRate(uint256 tokenId) public view returns (uint256) {
        return _getExtraRate(tokenId);
    }

    function _getUBIrate (uint256 tokenId) internal view returns (uint256) {
        
        return (_getExtraRate(tokenId) + _getBaseRate(tokenId)) * 10 ** 18;
    }

    function getUBIrate (uint256 tokenId) public view returns (uint256) {
        return _getUBIrate(tokenId);
    }
    
    function _accumulatedUBI (uint256 tokenId) internal view returns (uint256) {
        uint256 ubirate = _getUBIrate(tokenId);
        uint256 ubiPerSecond = ubirate/365 days;
        return (block.timestamp - lastUBIclaimByID[tokenId])*ubiPerSecond;
    }

    function accumulatedUBI (uint256 tokenId) public view returns (uint256) {
        return _accumulatedUBI(tokenId);
    }

    function _claimUBI (address to, uint256 _tokenId) internal {
        if (citizen.ownerOf(_tokenId) != to) revert NotTheOwner({tokenId: _tokenId, sender: to});
        ubi_token.mint(to, _accumulatedUBI(_tokenId));
        lastUBIclaimByID[_tokenId] = block.timestamp;
    }

    function claimUBI (uint256 _tokenId) public {
        _claimUBI(msg.sender, _tokenId);
    }
    
    constructor() Ownable() {        
        pops[0] = [0,0];
        pops[1] = [0,0];
        pops[2] = [0,0];
        pops[3] = [0,0];    
       
    }  
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"error","name":"AlreadyRegistered","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"error","name":"AlreadyUBI","inputs":[]},{"type":"error","name":"ChangedTooRecently","inputs":[]},{"type":"error","name":"LocationDoesNotExist","inputs":[{"type":"uint256","name":"region","internalType":"uint256"},{"type":"uint256","name":"location","internalType":"uint256"}]},{"type":"error","name":"LocationIsFull","inputs":[{"type":"uint256","name":"region","internalType":"uint256"},{"type":"uint256","name":"location","internalType":"uint256"}]},{"type":"error","name":"MustPayCitizenshipFee","inputs":[]},{"type":"error","name":"NotRegistered","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"error","name":"NotTheOwner","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"address","name":"sender","internalType":"address"}]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"accumulatedUBI","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeCitizenContract","inputs":[{"type":"address","name":"newCitizen","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"changeCitizenship","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"uint256","name":"region","internalType":"uint256"},{"type":"uint256","name":"location","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeMap","inputs":[{"type":"address","name":"newMap","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeMinCitizenshipLength","inputs":[{"type":"uint256","name":"newMin","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeUbi","inputs":[{"type":"address","name":"newUbi","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeUbiToken","inputs":[{"type":"address","name":"newUbiToken","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimUBI","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[],"name":"commonChecks","inputs":[{"type":"uint256","name":"region","internalType":"uint256"},{"type":"uint256","name":"location","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"fee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getBaseRate","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getExtraRate","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLastClaim","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[2]","name":"","internalType":"uint256[2]"}],"name":"getLocIndex","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getLocation","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getUBIrate","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[],"name":"hasSpace","inputs":[{"type":"uint256","name":"_region","internalType":"uint256"},{"type":"uint256","name":"_location","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[],"name":"isValidLocation","inputs":[{"type":"uint256","name":"_region","internalType":"uint256"},{"type":"uint256","name":"_location","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastUBIclaimByID","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minCitizenshipLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pops","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerCitizenship","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"uint256","name":"region","internalType":"uint256"},{"type":"uint256","name":"location","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
              

Contract Creation Code

0x6080604052600180546001600160a01b03199081169091556002805482167387ef79ac3011721f134c4de1dd0e9d45221564f417905560038054821673eff6a8b943564626e2a52ef2da86882b1846c0ab17905560048054909116736fd7e86eb1d5d76d50051502cac3681e9bbed65f179055678ac7230489e800006005556277f8806006553480156200009257600080fd5b506200009e33620001e1565b604080518082019091526000808252602080830182905290805260079052620000eb907f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df90600262000231565b5060408051808201909152600080825260208083018290526001909152600790526200013b907fb39221ace053465ec3453ce2b36430bd138b997ecea25c1043da0c366812b82890600262000231565b506040805180820190915260008082526020808301829052600291829052600790526200018a917fb7c774451310d1be4108bc180d1b52823cb0ee0274a6c0081bcaf94f115fb96d9162000231565b506040805180820190915260008082526020808301829052600390915260079052620001da907f3be6fd20d5acfde5b873b48692cd31f4d3c7e8ee8a813af4696af8859e5ca6c690600262000231565b506200029d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000274579160200282015b8281111562000274578251829060ff1690559160200191906001019062000252565b506200028292915062000286565b5090565b5b8082111562000282576000815560010162000287565b61180c80620002ad6000396000f3fe6080604052600436106101a15760003560e01c8063b2ead1a2116100e1578063df2b88a01161008a578063e6be10c111610064578063e6be10c114610499578063ed031a31146104af578063ed9800bc146104cf578063f2fde38b146104ef57600080fd5b8063df2b88a014610446578063e210c44c14610459578063e60c19d61461047957600080fd5b8063d8104779116100bb578063d8104779146103f0578063dd339a2614610410578063ddca3f431461043057600080fd5b8063b2ead1a214610383578063bf2d6d99146103b0578063d1404178146103d057600080fd5b8063715018a61161014e5780638da5cb5b116101285780638da5cb5b146102d357806391716d05146102fb578063a05ee88a14610336578063b0c541651461035657600080fd5b8063715018a61461026857806371aba4761461027d5780637f7b13931461029d57600080fd5b806367f45d571161017f57806367f45d57146102085780636a1db1bf146102285780636d87c66c1461024857600080fd5b806303cc9642146101a65780632ff6ee06146101c85780633c7e7492146101e8575b600080fd5b3480156101b257600080fd5b506101c66101c13660046114c8565b61050f565b005b3480156101d457600080fd5b506101c66101e33660046114e5565b61059d565b3480156101f457600080fd5b506101c6610203366004611507565b6105b5565b34801561021457600080fd5b506101c66102233660046114c8565b610614565b34801561023457600080fd5b506101c6610243366004611507565b61069d565b34801561025457600080fd5b506101c66102633660046114c8565b6106fc565b34801561027457600080fd5b506101c6610785565b34801561028957600080fd5b506101c6610298366004611507565b6107eb565b3480156102a957600080fd5b506102bd6102b8366004611507565b6107f8565b6040516102ca9190611544565b60405180910390f35b3480156102df57600080fd5b506000546040516001600160a01b0390911681526020016102ca565b34801561030757600080fd5b50610328610316366004611507565b6000908152600b602052604090205490565b6040519081526020016102ca565b34801561034257600080fd5b506101c66103513660046114e5565b6105a7565b34801561036257600080fd5b50610376610371366004611507565b610809565b6040516102ca9190611577565b34801561038f57600080fd5b5061032861039e366004611507565b600b6020526000908152604090205481565b3480156103bc57600080fd5b506103286103cb366004611507565b61081a565b3480156103dc57600080fd5b506103286103eb366004611507565b610825565b3480156103fc57600080fd5b5061032861040b366004611507565b610830565b34801561041c57600080fd5b5061032861042b3660046114e5565b61083b565b34801561043c57600080fd5b5061032860055481565b6101c66104543660046115a8565b61086c565b34801561046557600080fd5b506101c66104743660046114c8565b610910565b34801561048557600080fd5b50610328610494366004611507565b610999565b3480156104a557600080fd5b5061032860065481565b3480156104bb57600080fd5b506101c66104ca3660046114e5565b6109a4565b3480156104db57600080fd5b506101c66104ea3660046115a8565b6109ae565b3480156104fb57600080fd5b506101c661050a3660046114c8565b610a1b565b6000546001600160a01b0316331461056e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6105a78282610afa565b6105b18282610bda565b5050565b6000546001600160a01b0316331461060f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b600655565b6000546001600160a01b0316331461066e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b031633146106f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b600555565b6000546001600160a01b031633146107565760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b031633146107df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6107e96000610ce0565b565b6107f53382610d3d565b50565b606061080382610ebc565b92915050565b610811611442565b61080382610f6d565b600061080382610fa2565b600061080382611033565b600061080382611079565b6007602052816000526040600020818154811061085757600080fd5b90600052602060002001600091509150505481565b6108768333611122565b610880828261059d565b610889836111fc565b6108928361124b565b61089b34611290565b6108a53384610d3d565b600083815260086020908152604080832080546001918201548186526007909452919093208054919391839081106108df576108df6115d4565b9060005260206000200160008282546108f89190611600565b9091555061090990508585856112cb565b5050505050565b6000546001600160a01b0316331461096a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600061080382611350565b6105b18282610afa565b6109b88333611122565b6109c2828261059d565b6109cb83611380565b600083815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610a0d8383836112cb565b610a16836113d0565b505050565b6000546001600160a01b03163314610a755760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6001600160a01b038116610af15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610565565b6107f581610ce0565b600482101580610b9957506002546040517f3684aa6600000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b0390911690633684aa6690604401600060405180830381865afa158015610b6e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b969190810190611629565b51155b156105b1576040517f37f434790000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610565565b6002546040517f9d07471100000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b0390911690639d07471190604401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6791906116d6565b6000838152600760205260409020805483908110610c8757610c876115d4565b90600052602060002001546001610c9e91906116ef565b11156105b1576040517f5f5e953a0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610565565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b03848116921690636352211e90602401602060405180830381865afa158015610da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc59190611702565b6001600160a01b031614610e17576040517f1bec84ca000000000000000000000000000000000000000000000000000000008152600481018290526001600160a01b0383166024820152604401610565565b6003546001600160a01b03166340c10f1983610e3284611033565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610e9057600080fd5b505af1158015610ea4573d6000803e3d6000fd5b505050600091825250600b6020526040902042905550565b60008181526008602052604090819020805460019091015460025492517f3684aa6600000000000000000000000000000000000000000000000000000000815260048101839052602481018290526060936001600160a01b031690633684aa6690604401600060405180830381865afa158015610f3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f659190810190611629565b949350505050565b610f75611442565b50600090815260086020908152604091829020805460019091015483518085019094529083529082015290565b6001546040517f1b8ca217000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b031690631b8ca21790602401606060405180830381865afa158015611005573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611029919061171f565b6040015192915050565b60008061103f83611350565b905060006110516301e133808361179d565b6000858152600b6020526040902054909150819061106f9042611600565b610f6591906117bf565b60008061108583610f6d565b60048054825160208401516040517fbe57f1b40000000000000000000000000000000000000000000000000000000081529384019190915260248301529192506001600160a01b039091169063be57f1b490604401602060405180830381865afa1580156110f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111b91906116d6565b9392505050565b6001546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b03838116921690636352211e90602401602060405180830381865afa158015611186573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111aa9190611702565b6001600160a01b0316146105b1576040517f1bec84ca000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382166024820152604401610565565b60008181526009602052604081205460ff16151590036107f5576040517f05ce119700000000000000000000000000000000000000000000000000000000815260048101829052602401610565565b6277f88061125882611429565b10156107f5576040517fd184ed4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055481146107f5576040517fde87eb9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082018252838152602080820184905260008681526008909152919091206112f8916002611460565b5060008281526007602052604090208054600191908390811061131d5761131d6115d4565b90600052602060002001600082825461133691906116ef565b909155505050600091825250600a60205260409020429055565b600061135b82611079565b61136483610fa2565b61136e91906116ef565b61080390670de0b6b3a76400006117bf565b60008181526009602052604090205460ff1615156001036107f5576040517fe4b6767400000000000000000000000000000000000000000000000000000000815260048101829052602401610565565b6000818152600b602052604090205415611416576040517fa51129df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000908152600b60205260409020429055565b6000818152600a60205260408120546108039042611600565b60405180604001604052806002906020820280368337509192915050565b826002810192821561148e579160200282015b8281111561148e578251825591602001919060010190611473565b5061149a92915061149e565b5090565b5b8082111561149a576000815560010161149f565b6001600160a01b03811681146107f557600080fd5b6000602082840312156114da57600080fd5b813561111b816114b3565b600080604083850312156114f857600080fd5b50508035926020909101359150565b60006020828403121561151957600080fd5b5035919050565b60005b8381101561153b578181015183820152602001611523565b50506000910152565b6020815260008251806020840152611563816040850160208701611520565b601f01601f19169190910160400192915050565b60408101818360005b600281101561159f578151835260209283019290910190600101611580565b50505092915050565b6000806000606084860312156115bd57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610803576108036115ea565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561163b57600080fd5b815167ffffffffffffffff8082111561165357600080fd5b818401915084601f83011261166757600080fd5b81518181111561167957611679611613565b604051601f8201601f19908116603f011681019083821181831017156116a1576116a1611613565b816040528281528760208487010111156116ba57600080fd5b6116cb836020830160208801611520565b979650505050505050565b6000602082840312156116e857600080fd5b5051919050565b80820180821115610803576108036115ea565b60006020828403121561171457600080fd5b815161111b816114b3565b60006060828403121561173157600080fd5b82601f83011261174057600080fd5b6040516060810181811067ffffffffffffffff8211171561176357611763611613565b60405280606084018581111561177857600080fd5b845b8181101561179257805183526020928301920161177a565b509195945050505050565b6000826117ba57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610803576108036115ea56fea26469706673582212203b26a0569f6ddca51af127d19863a74d25eddae0751dd6fb4bf0520fd746763d64736f6c63430008120033

Deployed ByteCode

0x6080604052600436106101a15760003560e01c8063b2ead1a2116100e1578063df2b88a01161008a578063e6be10c111610064578063e6be10c114610499578063ed031a31146104af578063ed9800bc146104cf578063f2fde38b146104ef57600080fd5b8063df2b88a014610446578063e210c44c14610459578063e60c19d61461047957600080fd5b8063d8104779116100bb578063d8104779146103f0578063dd339a2614610410578063ddca3f431461043057600080fd5b8063b2ead1a214610383578063bf2d6d99146103b0578063d1404178146103d057600080fd5b8063715018a61161014e5780638da5cb5b116101285780638da5cb5b146102d357806391716d05146102fb578063a05ee88a14610336578063b0c541651461035657600080fd5b8063715018a61461026857806371aba4761461027d5780637f7b13931461029d57600080fd5b806367f45d571161017f57806367f45d57146102085780636a1db1bf146102285780636d87c66c1461024857600080fd5b806303cc9642146101a65780632ff6ee06146101c85780633c7e7492146101e8575b600080fd5b3480156101b257600080fd5b506101c66101c13660046114c8565b61050f565b005b3480156101d457600080fd5b506101c66101e33660046114e5565b61059d565b3480156101f457600080fd5b506101c6610203366004611507565b6105b5565b34801561021457600080fd5b506101c66102233660046114c8565b610614565b34801561023457600080fd5b506101c6610243366004611507565b61069d565b34801561025457600080fd5b506101c66102633660046114c8565b6106fc565b34801561027457600080fd5b506101c6610785565b34801561028957600080fd5b506101c6610298366004611507565b6107eb565b3480156102a957600080fd5b506102bd6102b8366004611507565b6107f8565b6040516102ca9190611544565b60405180910390f35b3480156102df57600080fd5b506000546040516001600160a01b0390911681526020016102ca565b34801561030757600080fd5b50610328610316366004611507565b6000908152600b602052604090205490565b6040519081526020016102ca565b34801561034257600080fd5b506101c66103513660046114e5565b6105a7565b34801561036257600080fd5b50610376610371366004611507565b610809565b6040516102ca9190611577565b34801561038f57600080fd5b5061032861039e366004611507565b600b6020526000908152604090205481565b3480156103bc57600080fd5b506103286103cb366004611507565b61081a565b3480156103dc57600080fd5b506103286103eb366004611507565b610825565b3480156103fc57600080fd5b5061032861040b366004611507565b610830565b34801561041c57600080fd5b5061032861042b3660046114e5565b61083b565b34801561043c57600080fd5b5061032860055481565b6101c66104543660046115a8565b61086c565b34801561046557600080fd5b506101c66104743660046114c8565b610910565b34801561048557600080fd5b50610328610494366004611507565b610999565b3480156104a557600080fd5b5061032860065481565b3480156104bb57600080fd5b506101c66104ca3660046114e5565b6109a4565b3480156104db57600080fd5b506101c66104ea3660046115a8565b6109ae565b3480156104fb57600080fd5b506101c661050a3660046114c8565b610a1b565b6000546001600160a01b0316331461056e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6105a78282610afa565b6105b18282610bda565b5050565b6000546001600160a01b0316331461060f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b600655565b6000546001600160a01b0316331461066e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b031633146106f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b600555565b6000546001600160a01b031633146107565760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b031633146107df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6107e96000610ce0565b565b6107f53382610d3d565b50565b606061080382610ebc565b92915050565b610811611442565b61080382610f6d565b600061080382610fa2565b600061080382611033565b600061080382611079565b6007602052816000526040600020818154811061085757600080fd5b90600052602060002001600091509150505481565b6108768333611122565b610880828261059d565b610889836111fc565b6108928361124b565b61089b34611290565b6108a53384610d3d565b600083815260086020908152604080832080546001918201548186526007909452919093208054919391839081106108df576108df6115d4565b9060005260206000200160008282546108f89190611600565b9091555061090990508585856112cb565b5050505050565b6000546001600160a01b0316331461096a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600061080382611350565b6105b18282610afa565b6109b88333611122565b6109c2828261059d565b6109cb83611380565b600083815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610a0d8383836112cb565b610a16836113d0565b505050565b6000546001600160a01b03163314610a755760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610565565b6001600160a01b038116610af15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610565565b6107f581610ce0565b600482101580610b9957506002546040517f3684aa6600000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b0390911690633684aa6690604401600060405180830381865afa158015610b6e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b969190810190611629565b51155b156105b1576040517f37f434790000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610565565b6002546040517f9d07471100000000000000000000000000000000000000000000000000000000815260048101849052602481018390526001600160a01b0390911690639d07471190604401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6791906116d6565b6000838152600760205260409020805483908110610c8757610c876115d4565b90600052602060002001546001610c9e91906116ef565b11156105b1576040517f5f5e953a0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610565565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b03848116921690636352211e90602401602060405180830381865afa158015610da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc59190611702565b6001600160a01b031614610e17576040517f1bec84ca000000000000000000000000000000000000000000000000000000008152600481018290526001600160a01b0383166024820152604401610565565b6003546001600160a01b03166340c10f1983610e3284611033565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610e9057600080fd5b505af1158015610ea4573d6000803e3d6000fd5b505050600091825250600b6020526040902042905550565b60008181526008602052604090819020805460019091015460025492517f3684aa6600000000000000000000000000000000000000000000000000000000815260048101839052602481018290526060936001600160a01b031690633684aa6690604401600060405180830381865afa158015610f3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f659190810190611629565b949350505050565b610f75611442565b50600090815260086020908152604091829020805460019091015483518085019094529083529082015290565b6001546040517f1b8ca217000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b031690631b8ca21790602401606060405180830381865afa158015611005573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611029919061171f565b6040015192915050565b60008061103f83611350565b905060006110516301e133808361179d565b6000858152600b6020526040902054909150819061106f9042611600565b610f6591906117bf565b60008061108583610f6d565b60048054825160208401516040517fbe57f1b40000000000000000000000000000000000000000000000000000000081529384019190915260248301529192506001600160a01b039091169063be57f1b490604401602060405180830381865afa1580156110f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111b91906116d6565b9392505050565b6001546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b03838116921690636352211e90602401602060405180830381865afa158015611186573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111aa9190611702565b6001600160a01b0316146105b1576040517f1bec84ca000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382166024820152604401610565565b60008181526009602052604081205460ff16151590036107f5576040517f05ce119700000000000000000000000000000000000000000000000000000000815260048101829052602401610565565b6277f88061125882611429565b10156107f5576040517fd184ed4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055481146107f5576040517fde87eb9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082018252838152602080820184905260008681526008909152919091206112f8916002611460565b5060008281526007602052604090208054600191908390811061131d5761131d6115d4565b90600052602060002001600082825461133691906116ef565b909155505050600091825250600a60205260409020429055565b600061135b82611079565b61136483610fa2565b61136e91906116ef565b61080390670de0b6b3a76400006117bf565b60008181526009602052604090205460ff1615156001036107f5576040517fe4b6767400000000000000000000000000000000000000000000000000000000815260048101829052602401610565565b6000818152600b602052604090205415611416576040517fa51129df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000908152600b60205260409020429055565b6000818152600a60205260408120546108039042611600565b60405180604001604052806002906020820280368337509192915050565b826002810192821561148e579160200282015b8281111561148e578251825591602001919060010190611473565b5061149a92915061149e565b5090565b5b8082111561149a576000815560010161149f565b6001600160a01b03811681146107f557600080fd5b6000602082840312156114da57600080fd5b813561111b816114b3565b600080604083850312156114f857600080fd5b50508035926020909101359150565b60006020828403121561151957600080fd5b5035919050565b60005b8381101561153b578181015183820152602001611523565b50506000910152565b6020815260008251806020840152611563816040850160208701611520565b601f01601f19169190910160400192915050565b60408101818360005b600281101561159f578151835260209283019290910190600101611580565b50505092915050565b6000806000606084860312156115bd57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610803576108036115ea565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561163b57600080fd5b815167ffffffffffffffff8082111561165357600080fd5b818401915084601f83011261166757600080fd5b81518181111561167957611679611613565b604051601f8201601f19908116603f011681019083821181831017156116a1576116a1611613565b816040528281528760208487010111156116ba57600080fd5b6116cb836020830160208801611520565b979650505050505050565b6000602082840312156116e857600080fd5b5051919050565b80820180821115610803576108036115ea565b60006020828403121561171457600080fd5b815161111b816114b3565b60006060828403121561173157600080fd5b82601f83011261174057600080fd5b6040516060810181811067ffffffffffffffff8211171561176357611763611613565b60405280606084018581111561177857600080fd5b845b8181101561179257805183526020928301920161177a565b509195945050505050565b6000826117ba57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610803576108036115ea56fea26469706673582212203b26a0569f6ddca51af127d19863a74d25eddae0751dd6fb4bf0520fd746763d64736f6c63430008120033