Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Lottery
- Optimization enabled
- true
- Compiler version
- v0.8.0+commit.c7dfd78e
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:32:29.573150Z
Contract source code
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; // import "hardhat/console.sol"; abstract contract Entropy_interface { function get_entropy() public virtual view returns (uint256); function new_round() virtual external; } contract Lottery { address public owner = msg.sender; address payable public entropy_contract; address payable public reward_pool_contract; // Token rewards go to the special "staking contract" uint256 public deposits_phase_duration = 3 days; // The length of a phase when deposits are accepted; uint256 public entropy_phase_duration = 1 days; // The length of a phase when entropy providers reveal their entropy inputs; uint256 public entropy_fee = 30; // (will be divided by 1000 during calculations i.e. 1 means 0.1%) | this reward goes to the entropy providers reward pool uint256 public token_reward_fee = 100; // This reward goes to staked tokens reward pool uint256 public min_allowed_bet = 0.1 ether; // 1K CLO for now uint8 public max_allowed_deposits = 20; // A user can make 20 bets during a single round uint256 public current_round; uint256 public round_start_timestamp; uint256 public round_reward; uint256 private nonce = 0; bool public round_reward_paid = false; mapping (uint256 => bool) public round_successful; // Allows "refunds" of not succesful rounds. uint256 public current_interval_end; // Used for winner calculations struct interval { uint256 interval_start; uint256 interval_end; } struct player { mapping (uint256 => uint8) num_deposits; uint256 last_round; mapping (uint256 => mapping (uint8 => interval)) win_conditions; // This player is considered to be a winner when RNG provides a number that matches this intervals mapping (uint256 => bool) round_refunded; } mapping (address => player) public players; receive() external payable { } function get_round() public view returns (uint256) { return current_round; } function get_phase() public view returns (uint8) { // 0 - the lottery is not active / pending reward claim or new round start // 1 - a lottery round is in progress/ acquiring deposits // 2 - deposits are acquired / entropy revealing phase uint8 _status = 0; if(round_start_timestamp <= block.timestamp && block.timestamp < round_start_timestamp + deposits_phase_duration) { _status = 1; } else if (round_start_timestamp <= block.timestamp && block.timestamp < round_start_timestamp + deposits_phase_duration + entropy_phase_duration) { _status = 2; } return _status; } function deposit() public payable { require (msg.value > min_allowed_bet, "Minimum bet condition is not met"); require (players[msg.sender].num_deposits[current_round] < max_allowed_deposits || players[msg.sender].last_round < current_round, "Too much deposits during this round"); require (get_phase() == 1, "Deposits are only allowed during the depositing phase"); if(players[msg.sender].last_round < current_round) { players[msg.sender].last_round = current_round; players[msg.sender].num_deposits[current_round] = 0; } else { players[msg.sender].num_deposits[current_round]++; } // Assign the "winning interval" for the player players[msg.sender].win_conditions[current_round][players[msg.sender].num_deposits[current_round]].interval_start = current_interval_end; players[msg.sender].win_conditions[current_round][players[msg.sender].num_deposits[current_round]].interval_end = current_interval_end + msg.value; current_interval_end += msg.value; uint256 _reward_with_fees = msg.value; // TODO: replace it with SafeMath // TODO: update the contract to only send rewards upon completion of the round //send_token_reward(msg.value * token_reward_fee / 1000); _reward_with_fees -= msg.value * token_reward_fee / 1000; //send_entropy_reward(msg.value * entropy_fee / 1000); _reward_with_fees -= msg.value * entropy_fee / 1000; round_reward += _reward_with_fees; } function refund(uint256 _round) external { require(current_round > _round, "Only refunds of finished rounds are allowed"); require(!round_successful[_round], "Only refunds of FAILED rounds are allowed"); // Calculating the refund amount uint256 _reward = 0; for (uint8 i = 0; i < players[msg.sender].num_deposits[_round]; i++) { _reward += players[msg.sender].win_conditions[_round][i].interval_end - players[msg.sender].win_conditions[_round][i].interval_start; } // Subtract the entropy fee _reward -= _reward * entropy_fee / 1000; players[msg.sender].round_refunded[_round] = true; payable(msg.sender).transfer(_reward); } function send_entropy_reward(uint256 _reward) internal { //entropy_contract.transfer(msg.value * entropy_fee / 1000); entropy_contract.transfer(_reward); } function send_token_reward(uint256 _reward) internal { //reward_pool_contract.transfer(msg.value * token_reward_fee / 1000); reward_pool_contract.transfer(_reward); } function start_new_round() public payable { require(current_round == 0 || round_reward_paid, "Cannot start a new round while reward for the previous one is not paid. Call finish_round function"); current_round++; round_start_timestamp = block.timestamp; current_interval_end = 0; round_reward_paid = false; //require_entropy_provider(msg.sender); // Request the starter of a new round to also provide initial entropy // Initiate the first deposit of the round deposit(); } function finish_round(address payable _winner) public { // Important: finishing an active round does not automatically start a new one require(block.timestamp + 4 days > round_start_timestamp + deposits_phase_duration + entropy_phase_duration, "Round can be finished after the entropy reveal phase only"); //require(check_entropy_criteria(), "There is not enough entropy to ensure a fair winner calculation"); if(check_entropy_criteria()) { // Round is succsefully completed and there was enough entropy provided round_successful[current_round] = true; // Paying the winner // Safe loop, cannot be more than 20 iterations for (uint8 i = 0; i<players[_winner].num_deposits[current_round]; i++) { if(players[_winner].win_conditions[current_round][i].interval_start <= RNG() && RNG() < players[_winner].win_conditions[current_round][i].interval_end) { // console.log("\n%s\n%s\n%s", players[_winner].win_conditions[current_round][i].interval_start, RNG(), players[_winner].win_conditions[current_round][i].interval_end); _winner.transfer(round_reward); round_reward_paid = true; } } } else { // Round is completed without sufficient entropy => allow refunds and increase the round counter // round_successful[current_round] = false; // This values are `false` by default in solidity round_reward_paid = true; } require(round_reward_paid, "The provided address is not a winner of the current round"); } function pay_fees() internal { } function RNG() public returns (uint256) { // Primitive random number generator dependant on both `entropy` and `interval` for testing reasons uint256 _entropy = Entropy_interface(entropy_contract).get_entropy(); uint256 _result; // `entropy` is a random value; can be greater or less than `current_interval_end` if(_entropy > current_interval_end) { _result = _entropy % current_interval_end; } else { _result = current_interval_end % _entropy; } return _result; } function check_entropy_criteria() public returns (bool) { // Needs to check the sufficiency of entropy for the round reward prizepool size return true; } modifier only_owner { require(msg.sender == owner); _; } modifier only_entropy_contract { require(msg.sender == entropy_contract); _; } function set_entropy_contract(address payable _new_contract) public only_owner { entropy_contract = _new_contract; } function set_reward_contract(address payable _new_contract) public only_owner { reward_pool_contract = _new_contract; } function new_round_entropy() external { Entropy_interface(entropy_contract).new_round(); } }
Contract ABI
[{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"RNG","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"check_entropy_criteria","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"current_interval_end","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"current_round","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"deposits_phase_duration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"entropy_contract","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"entropy_fee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"entropy_phase_duration","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"finish_round","inputs":[{"type":"address","name":"_winner","internalType":"address payable"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"get_phase","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"get_round","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"max_allowed_deposits","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"min_allowed_bet","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"new_round_entropy","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"last_round","internalType":"uint256"}],"name":"players","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"refund","inputs":[{"type":"uint256","name":"_round","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"reward_pool_contract","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"round_reward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"round_reward_paid","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"round_start_timestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"round_successful","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_entropy_contract","inputs":[{"type":"address","name":"_new_contract","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_reward_contract","inputs":[{"type":"address","name":"_new_contract","internalType":"address payable"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"start_new_round","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"token_reward_fee","inputs":[]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x6080604052600080546001600160a01b031916331781556203f48060035562015180600455601e600555606460065567016345785d8a00006007556008805460ff19908116601417909155600c91909155600d8054909116905534801561006557600080fd5b50611113806100756000396000f3fe6080604052600436106101a05760003560e01c80638efdee23116100ec578063ce253f0d1161008a578063e037147211610064578063e0371472146103eb578063e2eb41ff14610400578063ef0c67e114610420578063f714922014610435576101a7565b8063ce253f0d146103b9578063d0e30db0146103ce578063d1205e26146103d6576101a7565b8063a2022a16116100c6578063a2022a161461035a578063a5b860041461037a578063b9802e3e1461038f578063c15d80c3146103a4576101a7565b80638efdee23146103105780639a74e1ed146103305780639f24eb6714610345576101a7565b80636021caab116101595780637cab348f116101335780637cab348f146102bc5780637e1eeb0a146102c45780638d9510d4146102d95780638da5cb5b146102fb576101a7565b80636021caab146102635780636893b41914610285578063709c4e911461029a576101a7565b8063214ab7d6146101ac578063278ecde1146101d75780632d02c681146101f95780633152fd0d1461020e578063319c068c1461022e5780633debbed514610243576101a7565b366101a757005b600080fd5b3480156101b857600080fd5b506101c161044a565b6040516101ce9190610fd4565b60405180910390f35b3480156101e357600080fd5b506101f76101f2366004610cdc565b610450565b005b34801561020557600080fd5b506101c16105af565b34801561021a57600080fd5b506101f7610229366004610cb9565b6105b5565b34801561023a57600080fd5b506101c16105ee565b34801561024f57600080fd5b506101f761025e366004610cb9565b6105f4565b34801561026f57600080fd5b5061027861062d565b6040516101ce9190610fdd565b34801561029157600080fd5b506101c1610636565b3480156102a657600080fd5b506102af61063c565b6040516101ce9190610d20565b6101f7610641565b3480156102d057600080fd5b506101f76106a0565b3480156102e557600080fd5b506102ee61070a565b6040516101ce9190610d0c565b34801561030757600080fd5b506102ee610719565b34801561031c57600080fd5b506102af61032b366004610cdc565b610728565b34801561033c57600080fd5b506102ee61073d565b34801561035157600080fd5b506101c161074c565b34801561036657600080fd5b506101f7610375366004610cb9565b610752565b34801561038657600080fd5b50610278610913565b34801561039b57600080fd5b506101c1610982565b3480156103b057600080fd5b506101c1610988565b3480156103c557600080fd5b506102af61098e565b6101f7610997565b3480156103e257600080fd5b506101c1610bd0565b3480156103f757600080fd5b506101c1610bd6565b34801561040c57600080fd5b506101c161041b366004610cb9565b610bdc565b34801561042c57600080fd5b506101c1610bf1565b34801561044157600080fd5b506101c1610bf7565b600b5481565b806009541161047a5760405162461bcd60e51b815260040161047190610e16565b60405180910390fd5b6000818152600e602052604090205460ff16156104a95760405162461bcd60e51b815260040161047190610e61565b6000805b33600090815260106020908152604080832086845290915290205460ff908116908216101561052e57336000908152601060209081526040808320868452600201825280832060ff85168452909152902080546001909101546105109190611036565b61051a9083610feb565b91508061052681611068565b9150506104ad565b506103e8600554826105409190611017565b61054a9190611003565b6105549082611036565b336000818152601060209081526040808320878452600301909152808220805460ff1916600117905551929350909183156108fc0291849190818181858888f193505050501580156105aa573d6000803e3d6000fd5b505050565b600a5481565b6000546001600160a01b031633146105cc57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60095481565b6000546001600160a01b0316331461060b57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b60065481565b600190565b60095415806106525750600d5460ff165b61066e5760405162461bcd60e51b815260040161047190610d88565b6009805490600061067e8361104d565b909155505042600a556000600f55600d805460ff1916905561069e610997565b565b600160009054906101000a90046001600160a01b03166001600160a01b03166322028a846040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156106f057600080fd5b505af1158015610704573d6000803e3d6000fd5b50505050565b6002546001600160a01b031681565b6000546001600160a01b031681565b600e6020526000908152604090205460ff1681565b6001546001600160a01b031681565b60055481565b600454600354600a546107659190610feb565b61076f9190610feb565b61077c4262054600610feb565b116107995760405162461bcd60e51b815260040161047190610f77565b6107a161063c565b156108e0576009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff90811690821610156108da576107ff610bf7565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff861684529091529020541180159061087d57506001600160a01b03821660009081526010602090815260408083206009548452600201825280832060ff8516845290915290206001015461087b610bf7565b105b156108c857600b546040516001600160a01b0384169180156108fc02916000818181858888f193505050501580156108b9573d6000803e3d6000fd5b50600d805460ff191660011790555b806108d281611068565b9150506107c3565b506108ee565b600d805460ff191660011790555b600d5460ff166109105760405162461bcd60e51b815260040161047190610d2b565b50565b6000806000905042600a541115801561093a5750600354600a546109379190610feb565b42105b156109475750600161097d565b42600a54111580156109745750600454600354600a546109679190610feb565b6109719190610feb565b42105b1561097d575060025b905090565b60095490565b60035481565b600d5460ff1681565b60075434116109b85760405162461bcd60e51b815260040161047190610eed565b600854336000908152601060209081526040808320600954845290915290205460ff918216911610806109fe575060095433600090815260106020526040902060010154105b610a1a5760405162461bcd60e51b815260040161047190610eaa565b610a22610913565b60ff16600114610a445760405162461bcd60e51b815260040161047190610f22565b600954336000908152601060205260409020600101541015610a90576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610ad5565b33600090815260106020908152604080832060095484529091528120805460ff1691610abb83611068565b91906101000a81548160ff021916908360ff160217905550505b600f5433600090815260106020908152604080832060095484526002810183528184209083528184205460ff1684529091529020819055610b17903490610feb565b33600090815260106020908152604080832060095484526002810183528184209083528184205460ff168452909152812060010191909155600f8054349290610b61908490610feb565b909155505060065434906103e890610b799083611017565b610b839190611003565b610b8d9082611036565b90506103e860055434610ba09190611017565b610baa9190611003565b610bb49082611036565b905080600b6000828254610bc89190610feb565b909155505050565b600f5481565b60075481565b60106020526000908152604090206001015481565b60045481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b815260040160206040518083038186803b158015610c4857600080fd5b505afa158015610c5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c809190610cf4565b90506000600f54821115610ca257600f54610c9b9083611088565b9050610cb3565b81600f54610cb09190611088565b90505b91505090565b600060208284031215610cca578081fd5b8135610cd5816110c8565b9392505050565b600060208284031215610ced578081fd5b5035919050565b600060208284031215610d05578081fd5b5051919050565b6001600160a01b0391909116815260200190565b901515815260200190565b60208082526039908201527f5468652070726f76696465642061646472657373206973206e6f74206120776960408201527f6e6e6572206f66207468652063757272656e7420726f756e6400000000000000606082015260800190565b60208082526062908201527f43616e6e6f742073746172742061206e657720726f756e64207768696c65207260408201527f657761726420666f72207468652070726576696f7573206f6e65206973206e6f60608201527f7420706169642e2043616c6c2066696e6973685f726f756e642066756e63746960808201526137b760f11b60a082015260c00190565b6020808252602b908201527f4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732060408201526a185c9948185b1b1bddd95960aa1b606082015260800190565b60208082526029908201527f4f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726040820152681948185b1b1bddd95960ba1b606082015260800190565b60208082526023908201527f546f6f206d756368206465706f7369747320647572696e67207468697320726f6040820152621d5b9960ea1b606082015260800190565b6020808252818101527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d6574604082015260600190565b60208082526035908201527f4465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6760408201527420746865206465706f736974696e6720706861736560581b606082015260800190565b60208082526039908201527f526f756e642063616e2062652066696e6973686564206166746572207468652060408201527f656e74726f70792072657665616c207068617365206f6e6c7900000000000000606082015260800190565b90815260200190565b60ff91909116815260200190565b60008219821115610ffe57610ffe61109c565b500190565b600082611012576110126110b2565b500490565b60008160001904831182151516156110315761103161109c565b500290565b6000828210156110485761104861109c565b500390565b60006000198214156110615761106161109c565b5060010190565b600060ff821660ff81141561107f5761107f61109c565b60010192915050565b600082611097576110976110b2565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b038116811461091057600080fdfea264697066735822122026f61a4f4851eae30e4ea6af36e05cd2da1ea1ac65030ad8e05299f43761bea364736f6c63430008000033
Deployed ByteCode
0x6080604052600436106101a05760003560e01c80638efdee23116100ec578063ce253f0d1161008a578063e037147211610064578063e0371472146103eb578063e2eb41ff14610400578063ef0c67e114610420578063f714922014610435576101a7565b8063ce253f0d146103b9578063d0e30db0146103ce578063d1205e26146103d6576101a7565b8063a2022a16116100c6578063a2022a161461035a578063a5b860041461037a578063b9802e3e1461038f578063c15d80c3146103a4576101a7565b80638efdee23146103105780639a74e1ed146103305780639f24eb6714610345576101a7565b80636021caab116101595780637cab348f116101335780637cab348f146102bc5780637e1eeb0a146102c45780638d9510d4146102d95780638da5cb5b146102fb576101a7565b80636021caab146102635780636893b41914610285578063709c4e911461029a576101a7565b8063214ab7d6146101ac578063278ecde1146101d75780632d02c681146101f95780633152fd0d1461020e578063319c068c1461022e5780633debbed514610243576101a7565b366101a757005b600080fd5b3480156101b857600080fd5b506101c161044a565b6040516101ce9190610fd4565b60405180910390f35b3480156101e357600080fd5b506101f76101f2366004610cdc565b610450565b005b34801561020557600080fd5b506101c16105af565b34801561021a57600080fd5b506101f7610229366004610cb9565b6105b5565b34801561023a57600080fd5b506101c16105ee565b34801561024f57600080fd5b506101f761025e366004610cb9565b6105f4565b34801561026f57600080fd5b5061027861062d565b6040516101ce9190610fdd565b34801561029157600080fd5b506101c1610636565b3480156102a657600080fd5b506102af61063c565b6040516101ce9190610d20565b6101f7610641565b3480156102d057600080fd5b506101f76106a0565b3480156102e557600080fd5b506102ee61070a565b6040516101ce9190610d0c565b34801561030757600080fd5b506102ee610719565b34801561031c57600080fd5b506102af61032b366004610cdc565b610728565b34801561033c57600080fd5b506102ee61073d565b34801561035157600080fd5b506101c161074c565b34801561036657600080fd5b506101f7610375366004610cb9565b610752565b34801561038657600080fd5b50610278610913565b34801561039b57600080fd5b506101c1610982565b3480156103b057600080fd5b506101c1610988565b3480156103c557600080fd5b506102af61098e565b6101f7610997565b3480156103e257600080fd5b506101c1610bd0565b3480156103f757600080fd5b506101c1610bd6565b34801561040c57600080fd5b506101c161041b366004610cb9565b610bdc565b34801561042c57600080fd5b506101c1610bf1565b34801561044157600080fd5b506101c1610bf7565b600b5481565b806009541161047a5760405162461bcd60e51b815260040161047190610e16565b60405180910390fd5b6000818152600e602052604090205460ff16156104a95760405162461bcd60e51b815260040161047190610e61565b6000805b33600090815260106020908152604080832086845290915290205460ff908116908216101561052e57336000908152601060209081526040808320868452600201825280832060ff85168452909152902080546001909101546105109190611036565b61051a9083610feb565b91508061052681611068565b9150506104ad565b506103e8600554826105409190611017565b61054a9190611003565b6105549082611036565b336000818152601060209081526040808320878452600301909152808220805460ff1916600117905551929350909183156108fc0291849190818181858888f193505050501580156105aa573d6000803e3d6000fd5b505050565b600a5481565b6000546001600160a01b031633146105cc57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60095481565b6000546001600160a01b0316331461060b57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b60065481565b600190565b60095415806106525750600d5460ff165b61066e5760405162461bcd60e51b815260040161047190610d88565b6009805490600061067e8361104d565b909155505042600a556000600f55600d805460ff1916905561069e610997565b565b600160009054906101000a90046001600160a01b03166001600160a01b03166322028a846040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156106f057600080fd5b505af1158015610704573d6000803e3d6000fd5b50505050565b6002546001600160a01b031681565b6000546001600160a01b031681565b600e6020526000908152604090205460ff1681565b6001546001600160a01b031681565b60055481565b600454600354600a546107659190610feb565b61076f9190610feb565b61077c4262054600610feb565b116107995760405162461bcd60e51b815260040161047190610f77565b6107a161063c565b156108e0576009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff90811690821610156108da576107ff610bf7565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff861684529091529020541180159061087d57506001600160a01b03821660009081526010602090815260408083206009548452600201825280832060ff8516845290915290206001015461087b610bf7565b105b156108c857600b546040516001600160a01b0384169180156108fc02916000818181858888f193505050501580156108b9573d6000803e3d6000fd5b50600d805460ff191660011790555b806108d281611068565b9150506107c3565b506108ee565b600d805460ff191660011790555b600d5460ff166109105760405162461bcd60e51b815260040161047190610d2b565b50565b6000806000905042600a541115801561093a5750600354600a546109379190610feb565b42105b156109475750600161097d565b42600a54111580156109745750600454600354600a546109679190610feb565b6109719190610feb565b42105b1561097d575060025b905090565b60095490565b60035481565b600d5460ff1681565b60075434116109b85760405162461bcd60e51b815260040161047190610eed565b600854336000908152601060209081526040808320600954845290915290205460ff918216911610806109fe575060095433600090815260106020526040902060010154105b610a1a5760405162461bcd60e51b815260040161047190610eaa565b610a22610913565b60ff16600114610a445760405162461bcd60e51b815260040161047190610f22565b600954336000908152601060205260409020600101541015610a90576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610ad5565b33600090815260106020908152604080832060095484529091528120805460ff1691610abb83611068565b91906101000a81548160ff021916908360ff160217905550505b600f5433600090815260106020908152604080832060095484526002810183528184209083528184205460ff1684529091529020819055610b17903490610feb565b33600090815260106020908152604080832060095484526002810183528184209083528184205460ff168452909152812060010191909155600f8054349290610b61908490610feb565b909155505060065434906103e890610b799083611017565b610b839190611003565b610b8d9082611036565b90506103e860055434610ba09190611017565b610baa9190611003565b610bb49082611036565b905080600b6000828254610bc89190610feb565b909155505050565b600f5481565b60075481565b60106020526000908152604090206001015481565b60045481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b815260040160206040518083038186803b158015610c4857600080fd5b505afa158015610c5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c809190610cf4565b90506000600f54821115610ca257600f54610c9b9083611088565b9050610cb3565b81600f54610cb09190611088565b90505b91505090565b600060208284031215610cca578081fd5b8135610cd5816110c8565b9392505050565b600060208284031215610ced578081fd5b5035919050565b600060208284031215610d05578081fd5b5051919050565b6001600160a01b0391909116815260200190565b901515815260200190565b60208082526039908201527f5468652070726f76696465642061646472657373206973206e6f74206120776960408201527f6e6e6572206f66207468652063757272656e7420726f756e6400000000000000606082015260800190565b60208082526062908201527f43616e6e6f742073746172742061206e657720726f756e64207768696c65207260408201527f657761726420666f72207468652070726576696f7573206f6e65206973206e6f60608201527f7420706169642e2043616c6c2066696e6973685f726f756e642066756e63746960808201526137b760f11b60a082015260c00190565b6020808252602b908201527f4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732060408201526a185c9948185b1b1bddd95960aa1b606082015260800190565b60208082526029908201527f4f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726040820152681948185b1b1bddd95960ba1b606082015260800190565b60208082526023908201527f546f6f206d756368206465706f7369747320647572696e67207468697320726f6040820152621d5b9960ea1b606082015260800190565b6020808252818101527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d6574604082015260600190565b60208082526035908201527f4465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6760408201527420746865206465706f736974696e6720706861736560581b606082015260800190565b60208082526039908201527f526f756e642063616e2062652066696e6973686564206166746572207468652060408201527f656e74726f70792072657665616c207068617365206f6e6c7900000000000000606082015260800190565b90815260200190565b60ff91909116815260200190565b60008219821115610ffe57610ffe61109c565b500190565b600082611012576110126110b2565b500490565b60008160001904831182151516156110315761103161109c565b500290565b6000828210156110485761104861109c565b500390565b60006000198214156110615761106161109c565b5060010190565b600060ff821660ff81141561107f5761107f61109c565b60010192915050565b600082611097576110976110b2565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b038116811461091057600080fdfea264697066735822122026f61a4f4851eae30e4ea6af36e05cd2da1ea1ac65030ad8e05299f43761bea364736f6c63430008000033