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