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.5.17+commit.d19bba13
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:32:32.010250Z
Contract source code
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.5.1; contract Entropy_interface { function get_entropy() public view returns (uint256); } 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 = 1000 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; function() external payable { deposit(); } 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 < now && now < round_start_timestamp + deposits_phase_duration) { _status = 1; } else if (round_start_timestamp < now && now < 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; 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 = now; 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(now > 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() && players[_winner].win_conditions[current_round][i].interval_end > RNG()) { _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 random(uint256 to) public returns (uint) { uint randomnumber = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, nonce))) % to; nonce++; return randomnumber; } 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` uint256 _current_interval_end = random(current_interval_end + 1); 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; } }
Contract ABI
[{"type":"fallback","stateMutability":"payable","payable":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"RNG","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"check_entropy_criteria","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"current_interval_end","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"current_round","inputs":[],"constant":true},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"deposit","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"deposits_phase_duration","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"entropy_contract","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"entropy_fee","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"entropy_phase_duration","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"finish_round","inputs":[{"type":"address","name":"_winner","internalType":"address payable"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"get_phase","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"get_round","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"max_allowed_deposits","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"min_allowed_bet","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"last_round","internalType":"uint256"}],"name":"players","inputs":[{"type":"address","name":"","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"random","inputs":[{"type":"uint256","name":"to","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"refund","inputs":[{"type":"uint256","name":"_round","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"reward_pool_contract","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"round_reward","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"round_reward_paid","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"round_start_timestamp","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"round_successful","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"set_entropy_contract","inputs":[{"type":"address","name":"_new_contract","internalType":"address payable"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"set_reward_contract","inputs":[{"type":"address","name":"_new_contract","internalType":"address payable"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"start_new_round","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"token_reward_fee","inputs":[],"constant":true}]
Contract Creation Code
0x6080604052600080546001600160a01b031916331781556203f48060035562015180600455601e6005556064600655683635c9adc5dea000006007556008805460ff19908116601417909155600c91909155600d8054909116905534801561006657600080fd5b50610edc806100766000396000f3fe60806040526004361061019c5760003560e01c80639a74e1ed116100ec578063ce253f0d1161008a578063e037147211610064578063e037147214610458578063e2eb41ff1461046d578063ef0c67e1146104a0578063f7149220146104b55761019c565b8063ce253f0d1461042e578063d0e30db01461019c578063d1205e26146104435761019c565b8063a5b86004116100c6578063a5b86004146103c5578063b863bd37146103da578063b9802e3e14610404578063c15d80c3146104195761019c565b80639a74e1ed146103685780639f24eb671461037d578063a2022a16146103925761019c565b80636021caab116101595780637cab348f116101335780637cab348f146102f05780638d9510d4146102f85780638da5cb5b146103295780638efdee231461033e5761019c565b80636021caab146102875780636893b419146102b2578063709c4e91146102c75761019c565b8063214ab7d6146101a6578063278ecde1146101cd5780632d02c681146101f75780633152fd0d1461020c578063319c068c1461023f5780633debbed514610254575b6101a46104ca565b005b3480156101b257600080fd5b506101bb6106f0565b60408051918252519081900360200190f35b3480156101d957600080fd5b506101a4600480360360208110156101f057600080fd5b50356106f6565b34801561020357600080fd5b506101bb61085c565b34801561021857600080fd5b506101a46004803603602081101561022f57600080fd5b50356001600160a01b0316610862565b34801561024b57600080fd5b506101bb61089b565b34801561026057600080fd5b506101a46004803603602081101561027757600080fd5b50356001600160a01b03166108a1565b34801561029357600080fd5b5061029c6108da565b6040805160ff9092168252519081900360200190f35b3480156102be57600080fd5b506101bb6108e3565b3480156102d357600080fd5b506102dc6108e9565b604080519115158252519081900360200190f35b6101a46108ee565b34801561030457600080fd5b5061030d610960565b604080516001600160a01b039092168252519081900360200190f35b34801561033557600080fd5b5061030d61096f565b34801561034a57600080fd5b506102dc6004803603602081101561036157600080fd5b503561097e565b34801561037457600080fd5b5061030d610993565b34801561038957600080fd5b506101bb6109a2565b34801561039e57600080fd5b506101a4600480360360208110156103b557600080fd5b50356001600160a01b03166109a8565b3480156103d157600080fd5b5061029c610b7e565b3480156103e657600080fd5b506101bb600480360360208110156103fd57600080fd5b5035610bd0565b34801561041057600080fd5b506101bb610c28565b34801561042557600080fd5b506101bb610c2e565b34801561043a57600080fd5b506102dc610c34565b34801561044f57600080fd5b506101bb610c3d565b34801561046457600080fd5b506101bb610c43565b34801561047957600080fd5b506101bb6004803603602081101561049057600080fd5b50356001600160a01b0316610c49565b3480156104ac57600080fd5b506101bb610c5e565b3480156104c157600080fd5b506101bb610c64565b6007543411610520576040805162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d6574604482015290519081900360640190fd5b600854336000908152601060209081526040808320600954845290915290205460ff91821691161080610566575060095433600090815260106020526040902060010154105b6105a15760405162461bcd60e51b8152600401808060200182810382526023815260200180610e176023913960400191505060405180910390fd5b6105a9610b7e565b60ff166001146105ea5760405162461bcd60e51b8152600401808060200182810382526035815260200180610e3a6035913960400191505060405180910390fd5b600954336000908152601060205260409020600101541015610636576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610667565b33600090815260106020908152604080832060095484529091529020805460ff8082166001011660ff199091161790555b600f8054336000908152601060209081526040808320600980548552600282018085528386208386528487205460ff908116885290865284872088905591548652845282852091845282852054168452909152902034918201600190910155815481019091556006546005546103e891830282900483039202600b805492909104909203019055565b600b5481565b80600954116107365760405162461bcd60e51b815260040180806020018281038252602b815260200180610dc3602b913960400191505060405180910390fd5b6000818152600e602052604090205460ff16156107845760405162461bcd60e51b8152600401808060200182810382526029815260200180610dee6029913960400191505060405180910390fd5b6000805b33600090815260106020908152604080832086845290915290205460ff90811690821610156107ed57336000908152601060209081526040808320868452600201825280832060ff851684529091529020805460019182015403929092019101610788565b506103e86005548202816107fd57fe5b336000818152601060209081526040808320888452600301909152808220805460ff191660011790555193909204909303929183156108fc0291849190818181858888f19350505050158015610857573d6000803e3d6000fd5b505050565b600a5481565b6000546001600160a01b0316331461087957600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60095481565b6000546001600160a01b031633146108b857600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b60065481565b600190565b60095415806108ff5750600d5460ff165b61093a5760405162461bcd60e51b8152600401808060200182810382526062815260200180610d616062913960800191505060405180910390fd5b60098054600101905542600a556000600f55600d805460ff1916905561095e6104ca565b565b6002546001600160a01b031681565b6000546001600160a01b031681565b600e6020526000908152604090205460ff1681565b6001546001600160a01b031681565b60055481565b600454600354600a54010142116109f05760405162461bcd60e51b8152600401808060200182810382526039815260200180610e6f6039913960400191505060405180910390fd5b6109f86108e9565b15610b2c576009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff9081169082161015610b2657610a56610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902054108015610ad35750610a9a610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902060010154115b15610b1e57600b546040516001600160a01b0384169180156108fc02916000818181858888f19350505050158015610b0f573d6000803e3d6000fd5b50600d805460ff191660011790555b600101610a1a565b50610b3a565b600d805460ff191660011790555b600d5460ff16610b7b5760405162461bcd60e51b8152600401808060200182810382526039815260200180610d286039913960400191505060405180910390fd5b50565b6000806000905042600a54108015610b9b5750600354600a540142105b15610ba857506001610bcb565b42600a54108015610bc25750600454600354600a54010142105b15610bcb575060025b905090565b600c5460408051426020808301919091523360601b8284015260548083019490945282518083039094018452607490910190915281519101206000908190839081610c1757fe5b600c80546001019055069392505050565b60095490565b60035481565b600d5460ff1681565b600f5481565b60075481565b60106020526000908152604090206001015481565b60045481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051600f549091506000908190610cf890600101610bd0565b905080831115610d1357808381610d0b57fe5b069150610d20565b828181610d1c57fe5b0691505b509150509056fe5468652070726f76696465642061646472657373206973206e6f7420612077696e6e6572206f66207468652063757272656e7420726f756e6443616e6e6f742073746172742061206e657720726f756e64207768696c652072657761726420666f72207468652070726576696f7573206f6e65206973206e6f7420706169642e2043616c6c2066696e6973685f726f756e642066756e6374696f6e4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732061726520616c6c6f7765644f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726520616c6c6f776564546f6f206d756368206465706f7369747320647572696e67207468697320726f756e644465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6720746865206465706f736974696e67207068617365526f756e642063616e2062652066696e69736865642061667465722074686520656e74726f70792072657665616c207068617365206f6e6c79a265627a7a7231582085d724d70be369343f9deff4035b35af65fad871c1831796f6a079c2f6a061f164736f6c63430005110032
Deployed ByteCode
0x60806040526004361061019c5760003560e01c80639a74e1ed116100ec578063ce253f0d1161008a578063e037147211610064578063e037147214610458578063e2eb41ff1461046d578063ef0c67e1146104a0578063f7149220146104b55761019c565b8063ce253f0d1461042e578063d0e30db01461019c578063d1205e26146104435761019c565b8063a5b86004116100c6578063a5b86004146103c5578063b863bd37146103da578063b9802e3e14610404578063c15d80c3146104195761019c565b80639a74e1ed146103685780639f24eb671461037d578063a2022a16146103925761019c565b80636021caab116101595780637cab348f116101335780637cab348f146102f05780638d9510d4146102f85780638da5cb5b146103295780638efdee231461033e5761019c565b80636021caab146102875780636893b419146102b2578063709c4e91146102c75761019c565b8063214ab7d6146101a6578063278ecde1146101cd5780632d02c681146101f75780633152fd0d1461020c578063319c068c1461023f5780633debbed514610254575b6101a46104ca565b005b3480156101b257600080fd5b506101bb6106f0565b60408051918252519081900360200190f35b3480156101d957600080fd5b506101a4600480360360208110156101f057600080fd5b50356106f6565b34801561020357600080fd5b506101bb61085c565b34801561021857600080fd5b506101a46004803603602081101561022f57600080fd5b50356001600160a01b0316610862565b34801561024b57600080fd5b506101bb61089b565b34801561026057600080fd5b506101a46004803603602081101561027757600080fd5b50356001600160a01b03166108a1565b34801561029357600080fd5b5061029c6108da565b6040805160ff9092168252519081900360200190f35b3480156102be57600080fd5b506101bb6108e3565b3480156102d357600080fd5b506102dc6108e9565b604080519115158252519081900360200190f35b6101a46108ee565b34801561030457600080fd5b5061030d610960565b604080516001600160a01b039092168252519081900360200190f35b34801561033557600080fd5b5061030d61096f565b34801561034a57600080fd5b506102dc6004803603602081101561036157600080fd5b503561097e565b34801561037457600080fd5b5061030d610993565b34801561038957600080fd5b506101bb6109a2565b34801561039e57600080fd5b506101a4600480360360208110156103b557600080fd5b50356001600160a01b03166109a8565b3480156103d157600080fd5b5061029c610b7e565b3480156103e657600080fd5b506101bb600480360360208110156103fd57600080fd5b5035610bd0565b34801561041057600080fd5b506101bb610c28565b34801561042557600080fd5b506101bb610c2e565b34801561043a57600080fd5b506102dc610c34565b34801561044f57600080fd5b506101bb610c3d565b34801561046457600080fd5b506101bb610c43565b34801561047957600080fd5b506101bb6004803603602081101561049057600080fd5b50356001600160a01b0316610c49565b3480156104ac57600080fd5b506101bb610c5e565b3480156104c157600080fd5b506101bb610c64565b6007543411610520576040805162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d6574604482015290519081900360640190fd5b600854336000908152601060209081526040808320600954845290915290205460ff91821691161080610566575060095433600090815260106020526040902060010154105b6105a15760405162461bcd60e51b8152600401808060200182810382526023815260200180610e176023913960400191505060405180910390fd5b6105a9610b7e565b60ff166001146105ea5760405162461bcd60e51b8152600401808060200182810382526035815260200180610e3a6035913960400191505060405180910390fd5b600954336000908152601060205260409020600101541015610636576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610667565b33600090815260106020908152604080832060095484529091529020805460ff8082166001011660ff199091161790555b600f8054336000908152601060209081526040808320600980548552600282018085528386208386528487205460ff908116885290865284872088905591548652845282852091845282852054168452909152902034918201600190910155815481019091556006546005546103e891830282900483039202600b805492909104909203019055565b600b5481565b80600954116107365760405162461bcd60e51b815260040180806020018281038252602b815260200180610dc3602b913960400191505060405180910390fd5b6000818152600e602052604090205460ff16156107845760405162461bcd60e51b8152600401808060200182810382526029815260200180610dee6029913960400191505060405180910390fd5b6000805b33600090815260106020908152604080832086845290915290205460ff90811690821610156107ed57336000908152601060209081526040808320868452600201825280832060ff851684529091529020805460019182015403929092019101610788565b506103e86005548202816107fd57fe5b336000818152601060209081526040808320888452600301909152808220805460ff191660011790555193909204909303929183156108fc0291849190818181858888f19350505050158015610857573d6000803e3d6000fd5b505050565b600a5481565b6000546001600160a01b0316331461087957600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60095481565b6000546001600160a01b031633146108b857600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b60065481565b600190565b60095415806108ff5750600d5460ff165b61093a5760405162461bcd60e51b8152600401808060200182810382526062815260200180610d616062913960800191505060405180910390fd5b60098054600101905542600a556000600f55600d805460ff1916905561095e6104ca565b565b6002546001600160a01b031681565b6000546001600160a01b031681565b600e6020526000908152604090205460ff1681565b6001546001600160a01b031681565b60055481565b600454600354600a54010142116109f05760405162461bcd60e51b8152600401808060200182810382526039815260200180610e6f6039913960400191505060405180910390fd5b6109f86108e9565b15610b2c576009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff9081169082161015610b2657610a56610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902054108015610ad35750610a9a610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902060010154115b15610b1e57600b546040516001600160a01b0384169180156108fc02916000818181858888f19350505050158015610b0f573d6000803e3d6000fd5b50600d805460ff191660011790555b600101610a1a565b50610b3a565b600d805460ff191660011790555b600d5460ff16610b7b5760405162461bcd60e51b8152600401808060200182810382526039815260200180610d286039913960400191505060405180910390fd5b50565b6000806000905042600a54108015610b9b5750600354600a540142105b15610ba857506001610bcb565b42600a54108015610bc25750600454600354600a54010142105b15610bcb575060025b905090565b600c5460408051426020808301919091523360601b8284015260548083019490945282518083039094018452607490910190915281519101206000908190839081610c1757fe5b600c80546001019055069392505050565b60095490565b60035481565b600d5460ff1681565b600f5481565b60075481565b60106020526000908152604090206001015481565b60045481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051600f549091506000908190610cf890600101610bd0565b905080831115610d1357808381610d0b57fe5b069150610d20565b828181610d1c57fe5b0691505b509150509056fe5468652070726f76696465642061646472657373206973206e6f7420612077696e6e6572206f66207468652063757272656e7420726f756e6443616e6e6f742073746172742061206e657720726f756e64207768696c652072657761726420666f72207468652070726576696f7573206f6e65206973206e6f7420706169642e2043616c6c2066696e6973685f726f756e642066756e6374696f6e4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732061726520616c6c6f7765644f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726520616c6c6f776564546f6f206d756368206465706f7369747320647572696e67207468697320726f756e644465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6720746865206465706f736974696e67207068617365526f756e642063616e2062652066696e69736865642061667465722074686520656e74726f70792072657665616c207068617365206f6e6c79a265627a7a7231582085d724d70be369343f9deff4035b35af65fad871c1831796f6a079c2f6a061f164736f6c63430005110032