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.12+commit.f00d7308
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:32:30.420678Z
Contract source code
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;
interface Entropy_interface {
function get_entropy() external 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 block.timestamp
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 <= 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() && 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;
}
receive() external payable { }
}
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":"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":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"random","inputs":[{"type":"uint256","name":"to","internalType":"uint256"}]},{"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
0x6080604052600080546001600160a01b031916331781556203f48060035562015180600455601e6005556064600655683635c9adc5dea000006007556008805460ff19908116601417909155600c91909155600d8054909116905534801561006657600080fd5b50611058806100766000396000f3fe6080604052600436106101a05760003560e01c80639a74e1ed116100ec578063ce253f0d1161008a578063e037147211610064578063e037147214610443578063e2eb41ff14610459578063ef0c67e114610489578063f71492201461049f57600080fd5b8063ce253f0d1461040b578063d0e30db014610425578063d1205e261461042d57600080fd5b8063a5b86004116100c6578063a5b86004146103ab578063b863bd37146103c0578063b9802e3e146103e0578063c15d80c3146103f557600080fd5b80639a74e1ed146103555780639f24eb6714610375578063a2022a161461038b57600080fd5b80636021caab116101595780637cab348f116101335780637cab348f146102c55780638d9510d4146102cd5780638da5cb5b146103055780638efdee231461032557600080fd5b80636021caab146102635780636893b4191461028f578063709c4e91146102a557600080fd5b8063214ab7d6146101ac578063278ecde1146101d55780632d02c681146101f75780633152fd0d1461020d578063319c068c1461022d5780633debbed51461024357600080fd5b366101a757005b600080fd5b3480156101b857600080fd5b506101c2600b5481565b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004610eda565b6104b4565b005b34801561020357600080fd5b506101c2600a5481565b34801561021957600080fd5b506101f5610228366004610f08565b610695565b34801561023957600080fd5b506101c260095481565b34801561024f57600080fd5b506101f561025e366004610f08565b6106ce565b34801561026f57600080fd5b5060085461027d9060ff1681565b60405160ff90911681526020016101cc565b34801561029b57600080fd5b506101c260065481565b3480156102b157600080fd5b5060015b60405190151581526020016101cc565b6101f5610707565b3480156102d957600080fd5b506002546102ed906001600160a01b031681565b6040516001600160a01b0390911681526020016101cc565b34801561031157600080fd5b506000546102ed906001600160a01b031681565b34801561033157600080fd5b506102b5610340366004610eda565b600e6020526000908152604090205460ff1681565b34801561036157600080fd5b506001546102ed906001600160a01b031681565b34801561038157600080fd5b506101c260055481565b34801561039757600080fd5b506101f56103a6366004610f08565b6107ed565b3480156103b757600080fd5b5061027d610a39565b3480156103cc57600080fd5b506101c26103db366004610eda565b610aa8565b3480156103ec57600080fd5b506009546101c2565b34801561040157600080fd5b506101c260035481565b34801561041757600080fd5b50600d546102b59060ff1681565b6101f5610b27565b34801561043957600080fd5b506101c2600f5481565b34801561044f57600080fd5b506101c260075481565b34801561046557600080fd5b506101c2610474366004610f08565b60106020526000908152604090206001015481565b34801561049557600080fd5b506101c260045481565b3480156104ab57600080fd5b506101c2610e1a565b806009541161051e5760405162461bcd60e51b815260206004820152602b60248201527f4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732060448201526a185c9948185b1b1bddd95960aa1b60648201526084015b60405180910390fd5b6000818152600e602052604090205460ff161561058f5760405162461bcd60e51b815260206004820152602960248201527f4f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726044820152681948185b1b1bddd95960ba1b6064820152608401610515565b6000805b33600090815260106020908152604080832086845290915290205460ff908116908216101561061457336000908152601060209081526040808320868452600201825280832060ff85168452909152902080546001909101546105f69190610f42565b6106009083610f59565b91508061060c81610f71565b915050610593565b506103e8600554826106269190610f91565b6106309190610fc6565b61063a9082610f42565b336000818152601060209081526040808320878452600301909152808220805460ff1916600117905551929350909183156108fc0291849190818181858888f19350505050158015610690573d6000803e3d6000fd5b505050565b6000546001600160a01b031633146106ac57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146106e557600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60095415806107185750600d5460ff165b6107bb5760405162461bcd60e51b815260206004820152606260248201527f43616e6e6f742073746172742061206e657720726f756e64207768696c65207260448201527f657761726420666f72207468652070726576696f7573206f6e65206973206e6f60648201527f7420706169642e2043616c6c2066696e6973685f726f756e642066756e63746960848201526137b760f11b60a482015260c401610515565b600980549060006107cb83610fda565b909155505042600a556000600f55600d805460ff191690556107eb610b27565b565b600454600354600a546108009190610f59565b61080a9190610f59565b6108174262054600610f59565b1161088a5760405162461bcd60e51b815260206004820152603960248201527f526f756e642063616e2062652066696e6973686564206166746572207468652060448201527f656e74726f70792072657665616c207068617365206f6e6c79000000000000006064820152608401610515565b6009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff90811690821610156109bd576108e3610e1a565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff861684529091529020541080156109605750610927610e1a565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902060010154115b156109ab57600b546040516001600160a01b0384169180156108fc02916000818181858888f1935050505015801561099c573d6000803e3d6000fd5b50600d805460ff191660011790555b806109b581610f71565b9150506108a7565b50600d5460ff16610a365760405162461bcd60e51b815260206004820152603960248201527f5468652070726f76696465642061646472657373206973206e6f74206120776960448201527f6e6e6572206f66207468652063757272656e7420726f756e64000000000000006064820152608401610515565b50565b6000806000905042600a5411158015610a605750600354600a54610a5d9190610f59565b42105b15610a6d57506001919050565b42600a5411158015610a9a5750600454600354600a54610a8d9190610f59565b610a979190610f59565b42105b15610aa3575060025b919050565b600080824233600c54604051602001610ae69392919092835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b6040516020818303038152906040528051906020012060001c610b099190610ff5565b600c80549192506000610b1b83610fda565b90915550909392505050565b6007543411610b785760405162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d65746044820152606401610515565b600854336000908152601060209081526040808320600954845290915290205460ff91821691161080610bbe575060095433600090815260106020526040902060010154105b610c165760405162461bcd60e51b815260206004820152602360248201527f546f6f206d756368206465706f7369747320647572696e67207468697320726f6044820152621d5b9960ea1b6064820152608401610515565b610c1e610a39565b60ff16600114610c8e5760405162461bcd60e51b815260206004820152603560248201527f4465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6760448201527420746865206465706f736974696e6720706861736560581b6064820152608401610515565b600954336000908152601060205260409020600101541015610cda576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610d1f565b33600090815260106020908152604080832060095484529091528120805460ff1691610d0583610f71565b91906101000a81548160ff021916908360ff160217905550505b600f5433600090815260106020908152604080832060095484526002810183528184209083528184205460ff1684529091529020819055610d61903490610f59565b33600090815260106020908152604080832060095484526002810183528184209083528184205460ff168452909152812060010191909155600f8054349290610dab908490610f59565b909155505060065434906103e890610dc39083610f91565b610dcd9190610fc6565b610dd79082610f42565b90506103e860055434610dea9190610f91565b610df49190610fc6565b610dfe9082610f42565b905080600b6000828254610e129190610f59565b909155505050565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e949190611009565b9050600080610eab600f5460016103db9190610f59565b905080831115610ec657610ebf8184610ff5565b9150610ed3565b610ed08382610ff5565b91505b5092915050565b600060208284031215610eec57600080fd5b5035919050565b6001600160a01b0381168114610a3657600080fd5b600060208284031215610f1a57600080fd5b8135610f2581610ef3565b9392505050565b634e487b7160e01b600052601160045260246000fd5b600082821015610f5457610f54610f2c565b500390565b60008219821115610f6c57610f6c610f2c565b500190565b600060ff821660ff811415610f8857610f88610f2c565b60010192915050565b6000816000190483118215151615610fab57610fab610f2c565b500290565b634e487b7160e01b600052601260045260246000fd5b600082610fd557610fd5610fb0565b500490565b6000600019821415610fee57610fee610f2c565b5060010190565b60008261100457611004610fb0565b500690565b60006020828403121561101b57600080fd5b505191905056fea26469706673582212203267e462bba1ac5470a7e1dd7f11afb763e12bc76e7ab5ac3aa39b5e171292cf64736f6c634300080c0033
Deployed ByteCode
0x6080604052600436106101a05760003560e01c80639a74e1ed116100ec578063ce253f0d1161008a578063e037147211610064578063e037147214610443578063e2eb41ff14610459578063ef0c67e114610489578063f71492201461049f57600080fd5b8063ce253f0d1461040b578063d0e30db014610425578063d1205e261461042d57600080fd5b8063a5b86004116100c6578063a5b86004146103ab578063b863bd37146103c0578063b9802e3e146103e0578063c15d80c3146103f557600080fd5b80639a74e1ed146103555780639f24eb6714610375578063a2022a161461038b57600080fd5b80636021caab116101595780637cab348f116101335780637cab348f146102c55780638d9510d4146102cd5780638da5cb5b146103055780638efdee231461032557600080fd5b80636021caab146102635780636893b4191461028f578063709c4e91146102a557600080fd5b8063214ab7d6146101ac578063278ecde1146101d55780632d02c681146101f75780633152fd0d1461020d578063319c068c1461022d5780633debbed51461024357600080fd5b366101a757005b600080fd5b3480156101b857600080fd5b506101c2600b5481565b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004610eda565b6104b4565b005b34801561020357600080fd5b506101c2600a5481565b34801561021957600080fd5b506101f5610228366004610f08565b610695565b34801561023957600080fd5b506101c260095481565b34801561024f57600080fd5b506101f561025e366004610f08565b6106ce565b34801561026f57600080fd5b5060085461027d9060ff1681565b60405160ff90911681526020016101cc565b34801561029b57600080fd5b506101c260065481565b3480156102b157600080fd5b5060015b60405190151581526020016101cc565b6101f5610707565b3480156102d957600080fd5b506002546102ed906001600160a01b031681565b6040516001600160a01b0390911681526020016101cc565b34801561031157600080fd5b506000546102ed906001600160a01b031681565b34801561033157600080fd5b506102b5610340366004610eda565b600e6020526000908152604090205460ff1681565b34801561036157600080fd5b506001546102ed906001600160a01b031681565b34801561038157600080fd5b506101c260055481565b34801561039757600080fd5b506101f56103a6366004610f08565b6107ed565b3480156103b757600080fd5b5061027d610a39565b3480156103cc57600080fd5b506101c26103db366004610eda565b610aa8565b3480156103ec57600080fd5b506009546101c2565b34801561040157600080fd5b506101c260035481565b34801561041757600080fd5b50600d546102b59060ff1681565b6101f5610b27565b34801561043957600080fd5b506101c2600f5481565b34801561044f57600080fd5b506101c260075481565b34801561046557600080fd5b506101c2610474366004610f08565b60106020526000908152604090206001015481565b34801561049557600080fd5b506101c260045481565b3480156104ab57600080fd5b506101c2610e1a565b806009541161051e5760405162461bcd60e51b815260206004820152602b60248201527f4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732060448201526a185c9948185b1b1bddd95960aa1b60648201526084015b60405180910390fd5b6000818152600e602052604090205460ff161561058f5760405162461bcd60e51b815260206004820152602960248201527f4f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726044820152681948185b1b1bddd95960ba1b6064820152608401610515565b6000805b33600090815260106020908152604080832086845290915290205460ff908116908216101561061457336000908152601060209081526040808320868452600201825280832060ff85168452909152902080546001909101546105f69190610f42565b6106009083610f59565b91508061060c81610f71565b915050610593565b506103e8600554826106269190610f91565b6106309190610fc6565b61063a9082610f42565b336000818152601060209081526040808320878452600301909152808220805460ff1916600117905551929350909183156108fc0291849190818181858888f19350505050158015610690573d6000803e3d6000fd5b505050565b6000546001600160a01b031633146106ac57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146106e557600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60095415806107185750600d5460ff165b6107bb5760405162461bcd60e51b815260206004820152606260248201527f43616e6e6f742073746172742061206e657720726f756e64207768696c65207260448201527f657761726420666f72207468652070726576696f7573206f6e65206973206e6f60648201527f7420706169642e2043616c6c2066696e6973685f726f756e642066756e63746960848201526137b760f11b60a482015260c401610515565b600980549060006107cb83610fda565b909155505042600a556000600f55600d805460ff191690556107eb610b27565b565b600454600354600a546108009190610f59565b61080a9190610f59565b6108174262054600610f59565b1161088a5760405162461bcd60e51b815260206004820152603960248201527f526f756e642063616e2062652066696e6973686564206166746572207468652060448201527f656e74726f70792072657665616c207068617365206f6e6c79000000000000006064820152608401610515565b6009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff90811690821610156109bd576108e3610e1a565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff861684529091529020541080156109605750610927610e1a565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902060010154115b156109ab57600b546040516001600160a01b0384169180156108fc02916000818181858888f1935050505015801561099c573d6000803e3d6000fd5b50600d805460ff191660011790555b806109b581610f71565b9150506108a7565b50600d5460ff16610a365760405162461bcd60e51b815260206004820152603960248201527f5468652070726f76696465642061646472657373206973206e6f74206120776960448201527f6e6e6572206f66207468652063757272656e7420726f756e64000000000000006064820152608401610515565b50565b6000806000905042600a5411158015610a605750600354600a54610a5d9190610f59565b42105b15610a6d57506001919050565b42600a5411158015610a9a5750600454600354600a54610a8d9190610f59565b610a979190610f59565b42105b15610aa3575060025b919050565b600080824233600c54604051602001610ae69392919092835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b6040516020818303038152906040528051906020012060001c610b099190610ff5565b600c80549192506000610b1b83610fda565b90915550909392505050565b6007543411610b785760405162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d65746044820152606401610515565b600854336000908152601060209081526040808320600954845290915290205460ff91821691161080610bbe575060095433600090815260106020526040902060010154105b610c165760405162461bcd60e51b815260206004820152602360248201527f546f6f206d756368206465706f7369747320647572696e67207468697320726f6044820152621d5b9960ea1b6064820152608401610515565b610c1e610a39565b60ff16600114610c8e5760405162461bcd60e51b815260206004820152603560248201527f4465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6760448201527420746865206465706f736974696e6720706861736560581b6064820152608401610515565b600954336000908152601060205260409020600101541015610cda576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610d1f565b33600090815260106020908152604080832060095484529091528120805460ff1691610d0583610f71565b91906101000a81548160ff021916908360ff160217905550505b600f5433600090815260106020908152604080832060095484526002810183528184209083528184205460ff1684529091529020819055610d61903490610f59565b33600090815260106020908152604080832060095484526002810183528184209083528184205460ff168452909152812060010191909155600f8054349290610dab908490610f59565b909155505060065434906103e890610dc39083610f91565b610dcd9190610fc6565b610dd79082610f42565b90506103e860055434610dea9190610f91565b610df49190610fc6565b610dfe9082610f42565b905080600b6000828254610e129190610f59565b909155505050565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e949190611009565b9050600080610eab600f5460016103db9190610f59565b905080831115610ec657610ebf8184610ff5565b9150610ed3565b610ed08382610ff5565b91505b5092915050565b600060208284031215610eec57600080fd5b5035919050565b6001600160a01b0381168114610a3657600080fd5b600060208284031215610f1a57600080fd5b8135610f2581610ef3565b9392505050565b634e487b7160e01b600052601160045260246000fd5b600082821015610f5457610f54610f2c565b500390565b60008219821115610f6c57610f6c610f2c565b500190565b600060ff821660ff811415610f8857610f88610f2c565b60010192915050565b6000816000190483118215151615610fab57610fab610f2c565b500290565b634e487b7160e01b600052601260045260246000fd5b600082610fd557610fd5610fb0565b500490565b6000600019821415610fee57610fee610f2c565b5060010190565b60008261100457611004610fb0565b500690565b60006020828403121561101b57600080fd5b505191905056fea26469706673582212203267e462bba1ac5470a7e1dd7f11afb763e12bc76e7ab5ac3aa39b5e171292cf64736f6c634300080c0033