false
false
0

Contract Address Details

0xc6355B64cd7C7552BF555599645B91858f3c37fE

Contract Name
Lottery
Creator
0x7f0901–391c41 at 0x14cef3–cce507
Balance
0 CLO
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
16229178
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

Verify & Publish
0x6080604052600080546001600160a01b031916331781556203f48060035562015180600455601e6005556064600655683635c9adc5dea000006007556008805460ff19908116601417909155600c91909155600d8054909116905534801561006657600080fd5b50610edc806100766000396000f3fe60806040526004361061019c5760003560e01c80639a74e1ed116100ec578063ce253f0d1161008a578063e037147211610064578063e037147214610458578063e2eb41ff1461046d578063ef0c67e1146104a0578063f7149220146104b55761019c565b8063ce253f0d1461042e578063d0e30db01461019c578063d1205e26146104435761019c565b8063a5b86004116100c6578063a5b86004146103c5578063b863bd37146103da578063b9802e3e14610404578063c15d80c3146104195761019c565b80639a74e1ed146103685780639f24eb671461037d578063a2022a16146103925761019c565b80636021caab116101595780637cab348f116101335780637cab348f146102f05780638d9510d4146102f85780638da5cb5b146103295780638efdee231461033e5761019c565b80636021caab146102875780636893b419146102b2578063709c4e91146102c75761019c565b8063214ab7d6146101a6578063278ecde1146101cd5780632d02c681146101f75780633152fd0d1461020c578063319c068c1461023f5780633debbed514610254575b6101a46104ca565b005b3480156101b257600080fd5b506101bb6106f0565b60408051918252519081900360200190f35b3480156101d957600080fd5b506101a4600480360360208110156101f057600080fd5b50356106f6565b34801561020357600080fd5b506101bb61085c565b34801561021857600080fd5b506101a46004803603602081101561022f57600080fd5b50356001600160a01b0316610862565b34801561024b57600080fd5b506101bb61089b565b34801561026057600080fd5b506101a46004803603602081101561027757600080fd5b50356001600160a01b03166108a1565b34801561029357600080fd5b5061029c6108da565b6040805160ff9092168252519081900360200190f35b3480156102be57600080fd5b506101bb6108e3565b3480156102d357600080fd5b506102dc6108e9565b604080519115158252519081900360200190f35b6101a46108ee565b34801561030457600080fd5b5061030d610960565b604080516001600160a01b039092168252519081900360200190f35b34801561033557600080fd5b5061030d61096f565b34801561034a57600080fd5b506102dc6004803603602081101561036157600080fd5b503561097e565b34801561037457600080fd5b5061030d610993565b34801561038957600080fd5b506101bb6109a2565b34801561039e57600080fd5b506101a4600480360360208110156103b557600080fd5b50356001600160a01b03166109a8565b3480156103d157600080fd5b5061029c610b7e565b3480156103e657600080fd5b506101bb600480360360208110156103fd57600080fd5b5035610bd0565b34801561041057600080fd5b506101bb610c28565b34801561042557600080fd5b506101bb610c2e565b34801561043a57600080fd5b506102dc610c34565b34801561044f57600080fd5b506101bb610c3d565b34801561046457600080fd5b506101bb610c43565b34801561047957600080fd5b506101bb6004803603602081101561049057600080fd5b50356001600160a01b0316610c49565b3480156104ac57600080fd5b506101bb610c5e565b3480156104c157600080fd5b506101bb610c64565b6007543411610520576040805162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d6574604482015290519081900360640190fd5b600854336000908152601060209081526040808320600954845290915290205460ff91821691161080610566575060095433600090815260106020526040902060010154105b6105a15760405162461bcd60e51b8152600401808060200182810382526023815260200180610e176023913960400191505060405180910390fd5b6105a9610b7e565b60ff166001146105ea5760405162461bcd60e51b8152600401808060200182810382526035815260200180610e3a6035913960400191505060405180910390fd5b600954336000908152601060205260409020600101541015610636576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610667565b33600090815260106020908152604080832060095484529091529020805460ff8082166001011660ff199091161790555b600f8054336000908152601060209081526040808320600980548552600282018085528386208386528487205460ff908116885290865284872088905591548652845282852091845282852054168452909152902034918201600190910155815481019091556006546005546103e891830282900483039202600b805492909104909203019055565b600b5481565b80600954116107365760405162461bcd60e51b815260040180806020018281038252602b815260200180610dc3602b913960400191505060405180910390fd5b6000818152600e602052604090205460ff16156107845760405162461bcd60e51b8152600401808060200182810382526029815260200180610dee6029913960400191505060405180910390fd5b6000805b33600090815260106020908152604080832086845290915290205460ff90811690821610156107ed57336000908152601060209081526040808320868452600201825280832060ff851684529091529020805460019182015403929092019101610788565b506103e86005548202816107fd57fe5b336000818152601060209081526040808320888452600301909152808220805460ff191660011790555193909204909303929183156108fc0291849190818181858888f19350505050158015610857573d6000803e3d6000fd5b505050565b600a5481565b6000546001600160a01b0316331461087957600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60095481565b6000546001600160a01b031633146108b857600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b60065481565b600190565b60095415806108ff5750600d5460ff165b61093a5760405162461bcd60e51b8152600401808060200182810382526062815260200180610d616062913960800191505060405180910390fd5b60098054600101905542600a556000600f55600d805460ff1916905561095e6104ca565b565b6002546001600160a01b031681565b6000546001600160a01b031681565b600e6020526000908152604090205460ff1681565b6001546001600160a01b031681565b60055481565b600454600354600a54010142116109f05760405162461bcd60e51b8152600401808060200182810382526039815260200180610e6f6039913960400191505060405180910390fd5b6109f86108e9565b15610b2c576009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff9081169082161015610b2657610a56610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902054108015610ad35750610a9a610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902060010154115b15610b1e57600b546040516001600160a01b0384169180156108fc02916000818181858888f19350505050158015610b0f573d6000803e3d6000fd5b50600d805460ff191660011790555b600101610a1a565b50610b3a565b600d805460ff191660011790555b600d5460ff16610b7b5760405162461bcd60e51b8152600401808060200182810382526039815260200180610d286039913960400191505060405180910390fd5b50565b6000806000905042600a54108015610b9b5750600354600a540142105b15610ba857506001610bcb565b42600a54108015610bc25750600454600354600a54010142105b15610bcb575060025b905090565b600c5460408051426020808301919091523360601b8284015260548083019490945282518083039094018452607490910190915281519101206000908190839081610c1757fe5b600c80546001019055069392505050565b60095490565b60035481565b600d5460ff1681565b600f5481565b60075481565b60106020526000908152604090206001015481565b60045481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051600f549091506000908190610cf890600101610bd0565b905080831115610d1357808381610d0b57fe5b069150610d20565b828181610d1c57fe5b0691505b509150509056fe5468652070726f76696465642061646472657373206973206e6f7420612077696e6e6572206f66207468652063757272656e7420726f756e6443616e6e6f742073746172742061206e657720726f756e64207768696c652072657761726420666f72207468652070726576696f7573206f6e65206973206e6f7420706169642e2043616c6c2066696e6973685f726f756e642066756e6374696f6e4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732061726520616c6c6f7765644f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726520616c6c6f776564546f6f206d756368206465706f7369747320647572696e67207468697320726f756e644465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6720746865206465706f736974696e67207068617365526f756e642063616e2062652066696e69736865642061667465722074686520656e74726f70792072657665616c207068617365206f6e6c79a265627a7a7231582085d724d70be369343f9deff4035b35af65fad871c1831796f6a079c2f6a061f164736f6c63430005110032

Deployed ByteCode

0x60806040526004361061019c5760003560e01c80639a74e1ed116100ec578063ce253f0d1161008a578063e037147211610064578063e037147214610458578063e2eb41ff1461046d578063ef0c67e1146104a0578063f7149220146104b55761019c565b8063ce253f0d1461042e578063d0e30db01461019c578063d1205e26146104435761019c565b8063a5b86004116100c6578063a5b86004146103c5578063b863bd37146103da578063b9802e3e14610404578063c15d80c3146104195761019c565b80639a74e1ed146103685780639f24eb671461037d578063a2022a16146103925761019c565b80636021caab116101595780637cab348f116101335780637cab348f146102f05780638d9510d4146102f85780638da5cb5b146103295780638efdee231461033e5761019c565b80636021caab146102875780636893b419146102b2578063709c4e91146102c75761019c565b8063214ab7d6146101a6578063278ecde1146101cd5780632d02c681146101f75780633152fd0d1461020c578063319c068c1461023f5780633debbed514610254575b6101a46104ca565b005b3480156101b257600080fd5b506101bb6106f0565b60408051918252519081900360200190f35b3480156101d957600080fd5b506101a4600480360360208110156101f057600080fd5b50356106f6565b34801561020357600080fd5b506101bb61085c565b34801561021857600080fd5b506101a46004803603602081101561022f57600080fd5b50356001600160a01b0316610862565b34801561024b57600080fd5b506101bb61089b565b34801561026057600080fd5b506101a46004803603602081101561027757600080fd5b50356001600160a01b03166108a1565b34801561029357600080fd5b5061029c6108da565b6040805160ff9092168252519081900360200190f35b3480156102be57600080fd5b506101bb6108e3565b3480156102d357600080fd5b506102dc6108e9565b604080519115158252519081900360200190f35b6101a46108ee565b34801561030457600080fd5b5061030d610960565b604080516001600160a01b039092168252519081900360200190f35b34801561033557600080fd5b5061030d61096f565b34801561034a57600080fd5b506102dc6004803603602081101561036157600080fd5b503561097e565b34801561037457600080fd5b5061030d610993565b34801561038957600080fd5b506101bb6109a2565b34801561039e57600080fd5b506101a4600480360360208110156103b557600080fd5b50356001600160a01b03166109a8565b3480156103d157600080fd5b5061029c610b7e565b3480156103e657600080fd5b506101bb600480360360208110156103fd57600080fd5b5035610bd0565b34801561041057600080fd5b506101bb610c28565b34801561042557600080fd5b506101bb610c2e565b34801561043a57600080fd5b506102dc610c34565b34801561044f57600080fd5b506101bb610c3d565b34801561046457600080fd5b506101bb610c43565b34801561047957600080fd5b506101bb6004803603602081101561049057600080fd5b50356001600160a01b0316610c49565b3480156104ac57600080fd5b506101bb610c5e565b3480156104c157600080fd5b506101bb610c64565b6007543411610520576040805162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2062657420636f6e646974696f6e206973206e6f74206d6574604482015290519081900360640190fd5b600854336000908152601060209081526040808320600954845290915290205460ff91821691161080610566575060095433600090815260106020526040902060010154105b6105a15760405162461bcd60e51b8152600401808060200182810382526023815260200180610e176023913960400191505060405180910390fd5b6105a9610b7e565b60ff166001146105ea5760405162461bcd60e51b8152600401808060200182810382526035815260200180610e3a6035913960400191505060405180910390fd5b600954336000908152601060205260409020600101541015610636576009543360009081526010602090815260408083206001810185905593835292905220805460ff19169055610667565b33600090815260106020908152604080832060095484529091529020805460ff8082166001011660ff199091161790555b600f8054336000908152601060209081526040808320600980548552600282018085528386208386528487205460ff908116885290865284872088905591548652845282852091845282852054168452909152902034918201600190910155815481019091556006546005546103e891830282900483039202600b805492909104909203019055565b600b5481565b80600954116107365760405162461bcd60e51b815260040180806020018281038252602b815260200180610dc3602b913960400191505060405180910390fd5b6000818152600e602052604090205460ff16156107845760405162461bcd60e51b8152600401808060200182810382526029815260200180610dee6029913960400191505060405180910390fd5b6000805b33600090815260106020908152604080832086845290915290205460ff90811690821610156107ed57336000908152601060209081526040808320868452600201825280832060ff851684529091529020805460019182015403929092019101610788565b506103e86005548202816107fd57fe5b336000818152601060209081526040808320888452600301909152808220805460ff191660011790555193909204909303929183156108fc0291849190818181858888f19350505050158015610857573d6000803e3d6000fd5b505050565b600a5481565b6000546001600160a01b0316331461087957600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60095481565b6000546001600160a01b031633146108b857600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b60065481565b600190565b60095415806108ff5750600d5460ff165b61093a5760405162461bcd60e51b8152600401808060200182810382526062815260200180610d616062913960800191505060405180910390fd5b60098054600101905542600a556000600f55600d805460ff1916905561095e6104ca565b565b6002546001600160a01b031681565b6000546001600160a01b031681565b600e6020526000908152604090205460ff1681565b6001546001600160a01b031681565b60055481565b600454600354600a54010142116109f05760405162461bcd60e51b8152600401808060200182810382526039815260200180610e6f6039913960400191505060405180910390fd5b6109f86108e9565b15610b2c576009546000908152600e60205260408120805460ff191660011790555b6001600160a01b0382166000908152601060209081526040808320600954845290915290205460ff9081169082161015610b2657610a56610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902054108015610ad35750610a9a610c64565b6001600160a01b03831660009081526010602090815260408083206009548452600201825280832060ff86168452909152902060010154115b15610b1e57600b546040516001600160a01b0384169180156108fc02916000818181858888f19350505050158015610b0f573d6000803e3d6000fd5b50600d805460ff191660011790555b600101610a1a565b50610b3a565b600d805460ff191660011790555b600d5460ff16610b7b5760405162461bcd60e51b8152600401808060200182810382526039815260200180610d286039913960400191505060405180910390fd5b50565b6000806000905042600a54108015610b9b5750600354600a540142105b15610ba857506001610bcb565b42600a54108015610bc25750600454600354600a54010142105b15610bcb575060025b905090565b600c5460408051426020808301919091523360601b8284015260548083019490945282518083039094018452607490910190915281519101206000908190839081610c1757fe5b600c80546001019055069392505050565b60095490565b60035481565b600d5460ff1681565b600f5481565b60075481565b60106020526000908152604090206001015481565b60045481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663658f17886040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051600f549091506000908190610cf890600101610bd0565b905080831115610d1357808381610d0b57fe5b069150610d20565b828181610d1c57fe5b0691505b509150509056fe5468652070726f76696465642061646472657373206973206e6f7420612077696e6e6572206f66207468652063757272656e7420726f756e6443616e6e6f742073746172742061206e657720726f756e64207768696c652072657761726420666f72207468652070726576696f7573206f6e65206973206e6f7420706169642e2043616c6c2066696e6973685f726f756e642066756e6374696f6e4f6e6c7920726566756e6473206f662066696e697368656420726f756e64732061726520616c6c6f7765644f6e6c7920726566756e6473206f66204641494c454420726f756e64732061726520616c6c6f776564546f6f206d756368206465706f7369747320647572696e67207468697320726f756e644465706f7369747320617265206f6e6c7920616c6c6f77656420647572696e6720746865206465706f736974696e67207068617365526f756e642063616e2062652066696e69736865642061667465722074686520656e74726f70792072657665616c207068617365206f6e6c79a265627a7a7231582085d724d70be369343f9deff4035b35af65fad871c1831796f6a079c2f6a061f164736f6c63430005110032