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