Contract Address Details

0x2300e0cd5d065d285236D7f55f6E2a19EB090C50

PoaMania Last Balance Update: Block #23488301
Created by 0x78bccb–fd6e91 at 0xb0b320–15d5ad

Balance

0 POA

(@ /POA)

Fetching tokens...

Contract name:
PoaMania




Optimization enabled
false
Compiler version
v0.5.16+commit.9c3226ce




EVM Version
petersburg




Verified at
2020-05-04 16:57:29.294156Z

Contract source code

// File: @openzeppelin/upgrades/contracts/Initializable.sol
pragma solidity >=0.4.24 <0.7.0;
/**
* @title Initializable
*
* @dev Helper contract to support initializer functions. To use it, replace
* the constructor with a function that has the `initializer` modifier.
* WARNING: Unlike constructors, initializer functions must be manually
* invoked. This applies both to deploying an Initializable contract, as well
* as extending an Initializable contract via inheritance.
* WARNING: When used with inheritance, manual care must be taken to not invoke
* a parent initializer twice, or ensure that all initializers are idempotent,
* because this is not dealt with automatically as with constructors.
*/
contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}
// File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol
pragma solidity ^0.5.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context is Initializable {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: @openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol
pragma solidity ^0.5.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be aplied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Initializable, Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function initialize(address sender) public initializer {
_owner = sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* > Note: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[50] private ______gap;
}
// File: @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol
pragma solidity ^0.5.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// File: contracts/IPOSDAORandom.sol
pragma solidity 0.5.16;
interface IPOSDAORandom {
function collectRoundLength() external view returns(uint256);
function currentSeed() external view returns(uint256);
function isCommitPhase() external view returns(bool);
}
// File: contracts/Random.sol
pragma solidity 0.5.16;
library Random {
struct State {
// POSDAORandom contract
IPOSDAORandom posdaoRandomContract;
// The current seed
uint256 seed;
// The last number of the block when the seed was updated
uint256 seedLastBlock;
// Update interval of the seed
uint256 randomUpdateInterval;
}
/**
* @dev Initializes the contract
* @param _randomContract The address of the POSDAORandom contract
*/
function init(State storage self, address _randomContract) public {
require(_randomContract != address(0), "Random/contract-zero");
self.posdaoRandomContract = IPOSDAORandom(_randomContract);
self.seed = self.posdaoRandomContract.currentSeed();
self.seedLastBlock = block.number;
self.randomUpdateInterval = self.posdaoRandomContract.collectRoundLength();
require(self.randomUpdateInterval != 0, "Random/interval-zero");
}
/**
* @dev Checks if the seed was updated and returns a new one
* @return Random seed
*/
function get(State storage self) public returns (uint256) {
require(_wasSeedUpdated(self), "Random/seed-not-updated");
require(self.posdaoRandomContract.isCommitPhase(), "Random/not-commit-phase");
return self.seed;
}
/**
* @dev Updates the seed
* @return True if the seed was updated
*/
function _wasSeedUpdated(State storage self) private returns (bool) {
if (block.number - self.seedLastBlock <= self.randomUpdateInterval) {
return false;
}
self.randomUpdateInterval = self.posdaoRandomContract.collectRoundLength();
uint256 remoteSeed = self.posdaoRandomContract.currentSeed();
if (remoteSeed != self.seed) {
self.seed = remoteSeed;
self.seedLastBlock = block.number;
return true;
}
return false;
}
/**
* @param _value The provided seed
* @return A new random seed generated from the provided seed
*/
function next(State storage, uint256 _value) public pure returns (uint256) {
return uint256(keccak256(abi.encodePacked(_value)));
}
/**
* @return The update interval of the seed
*/
function getUpdateInterval(State storage self) public view returns (uint256) {
return self.randomUpdateInterval;
}
}
// File: @kleros/kleros/contracts/data-structures/SortitionSumTreeFactory.sol
/**
* @reviewers: [@clesaege, @unknownunknown1, @ferittuncer]
* @auditors: []
* @bounties: [<14 days 10 ETH max payout>]
* @deployments: []
*/
pragma solidity ^0.5.0;
/**
* @title SortitionSumTreeFactory
* @author Enrique Piqueras - <[email protected]>
* @dev A factory of trees that keep track of staked values for sortition.
*/
library SortitionSumTreeFactory {
/* Structs */
struct SortitionSumTree {
uint K; // The maximum number of childs per node.
// We use this to keep track of vacant positions in the tree after removing a leaf. This is for keeping the tree as balanced as possible without spending gas on moving nodes around.
uint[] stack;
uint[] nodes;
// Two-way mapping of IDs to node indexes. Note that node index 0 is reserved for the root node, and means the ID does not have a node.
mapping(bytes32 => uint) IDsToNodeIndexes;
mapping(uint => bytes32) nodeIndexesToIDs;
}
/* Storage */
struct SortitionSumTrees {
mapping(bytes32 => SortitionSumTree) sortitionSumTrees;
}
/* Public */
/**
* @dev Create a sortition sum tree at the specified key.
* @param _key The key of the new tree.
* @param _K The number of children each node in the tree should have.
*/
function createTree(SortitionSumTrees storage self, bytes32 _key, uint _K) public {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
require(tree.K == 0, "Tree already exists.");
require(_K > 1, "K must be greater than one.");
tree.K = _K;
tree.stack.length = 0;
tree.nodes.length = 0;
tree.nodes.push(0);
}
/**
* @dev Set a value of a tree.
* @param _key The key of the tree.
* @param _value The new value.
* @param _ID The ID of the value.
* `O(log_k(n))` where
* `k` is the maximum number of childs per node in the tree,
* and `n` is the maximum number of nodes ever appended.
*/
function set(SortitionSumTrees storage self, bytes32 _key, uint _value, bytes32 _ID) public {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
uint treeIndex = tree.IDsToNodeIndexes[_ID];
if (treeIndex == 0) { // No existing node.
if (_value != 0) { // Non zero value.
// Append.
// Add node.
if (tree.stack.length == 0) { // No vacant spots.
// Get the index and append the value.
treeIndex = tree.nodes.length;
tree.nodes.push(_value);
// Potentially append a new node and make the parent a sum node.
if (treeIndex != 1 && (treeIndex - 1) % tree.K == 0) { // Is first child.
uint parentIndex = treeIndex / tree.K;
bytes32 parentID = tree.nodeIndexesToIDs[parentIndex];
uint newIndex = treeIndex + 1;
tree.nodes.push(tree.nodes[parentIndex]);
delete tree.nodeIndexesToIDs[parentIndex];
tree.IDsToNodeIndexes[parentID] = newIndex;
tree.nodeIndexesToIDs[newIndex] = parentID;
}
} else { // Some vacant spot.
// Pop the stack and append the value.
treeIndex = tree.stack[tree.stack.length - 1];
tree.stack.length--;
tree.nodes[treeIndex] = _value;
}
// Add label.
tree.IDsToNodeIndexes[_ID] = treeIndex;
tree.nodeIndexesToIDs[treeIndex] = _ID;
updateParents(self, _key, treeIndex, true, _value);
}
} else { // Existing node.
if (_value == 0) { // Zero value.
// Remove.
// Remember value and set to 0.
uint value = tree.nodes[treeIndex];
tree.nodes[treeIndex] = 0;
// Push to stack.
tree.stack.push(treeIndex);
// Clear label.
delete tree.IDsToNodeIndexes[_ID];
delete tree.nodeIndexesToIDs[treeIndex];
updateParents(self, _key, treeIndex, false, value);
} else if (_value != tree.nodes[treeIndex]) { // New, non zero value.
// Set.
bool plusOrMinus = tree.nodes[treeIndex] <= _value;
uint plusOrMinusValue = plusOrMinus ? _value - tree.nodes[treeIndex] : tree.nodes[treeIndex] - _value;
tree.nodes[treeIndex] = _value;
updateParents(self, _key, treeIndex, plusOrMinus, plusOrMinusValue);
}
}
}
/* Public Views */
/**
* @dev Query the leaves of a tree. Note that if `startIndex == 0`, the tree is empty and the root node will be returned.
* @param _key The key of the tree to get the leaves from.
* @param _cursor The pagination cursor.
* @param _count The number of items to return.
* @return The index at which leaves start, the values of the returned leaves, and whether there are more for pagination.
* `O(n)` where
* `n` is the maximum number of nodes ever appended.
*/
function queryLeafs(
SortitionSumTrees storage self,
bytes32 _key,
uint _cursor,
uint _count
) public view returns(uint startIndex, uint[] memory values, bool hasMore) {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
// Find the start index.
for (uint i = 0; i < tree.nodes.length; i++) {
if ((tree.K * i) + 1 >= tree.nodes.length) {
startIndex = i;
break;
}
}
// Get the values.
uint loopStartIndex = startIndex + _cursor;
values = new uint[](loopStartIndex + _count > tree.nodes.length ? tree.nodes.length - loopStartIndex : _count);
uint valuesIndex = 0;
for (uint j = loopStartIndex; j < tree.nodes.length; j++) {
if (valuesIndex < _count) {
values[valuesIndex] = tree.nodes[j];
valuesIndex++;
} else {
hasMore = true;
break;
}
}
}
/**
* @dev Draw an ID from a tree using a number. Note that this function reverts if the sum of all values in the tree is 0.
* @param _key The key of the tree.
* @param _drawnNumber The drawn number.
* @return The drawn ID.
* `O(k * log_k(n))` where
* `k` is the maximum number of childs per node in the tree,
* and `n` is the maximum number of nodes ever appended.
*/
function draw(SortitionSumTrees storage self, bytes32 _key, uint _drawnNumber) public view returns(bytes32 ID) {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
uint treeIndex = 0;
uint currentDrawnNumber = _drawnNumber % tree.nodes[0];
while ((tree.K * treeIndex) + 1 < tree.nodes.length) // While it still has children.
for (uint i = 1; i <= tree.K; i++) { // Loop over children.
uint nodeIndex = (tree.K * treeIndex) + i;
uint nodeValue = tree.nodes[nodeIndex];
if (currentDrawnNumber >= nodeValue) currentDrawnNumber -= nodeValue; // Go to the next child.
else { // Pick this child.
treeIndex = nodeIndex;
break;
}
}
ID = tree.nodeIndexesToIDs[treeIndex];
}
/** @dev Gets a specified ID's associated value.
* @param _key The key of the tree.
* @param _ID The ID of the value.
* @return The associated value.
*/
function stakeOf(SortitionSumTrees storage self, bytes32 _key, bytes32 _ID) public view returns(uint value) {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
uint treeIndex = tree.IDsToNodeIndexes[_ID];
if (treeIndex == 0) value = 0;
else value = tree.nodes[treeIndex];
}
function total(SortitionSumTrees storage self, bytes32 _key) public view returns (uint) {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
if (tree.nodes.length == 0) {
return 0;
} else {
return tree.nodes[0];
}
}
function numberOfNodes(SortitionSumTrees storage self, bytes32 _key) public view returns (uint256) {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
uint256 treeIndex = tree.nodes.length;
if (treeIndex < 2) {
return 0;
}
uint256 numberOfChildNodes = treeIndex - ((treeIndex - 2) / tree.K) - 1;
if (numberOfChildNodes < tree.stack.length) {
return 0;
}
return numberOfChildNodes - tree.stack.length;
}
/* Private */
/**
* @dev Update all the parents of a node.
* @param _key The key of the tree to update.
* @param _treeIndex The index of the node to start from.
* @param _plusOrMinus Wether to add (true) or substract (false).
* @param _value The value to add or substract.
* `O(log_k(n))` where
* `k` is the maximum number of childs per node in the tree,
* and `n` is the maximum number of nodes ever appended.
*/
function updateParents(SortitionSumTrees storage self, bytes32 _key, uint _treeIndex, bool _plusOrMinus, uint _value) private {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
uint parentIndex = _treeIndex;
while (parentIndex != 0) {
parentIndex = (parentIndex - 1) / tree.K;
tree.nodes[parentIndex] = _plusOrMinus ? tree.nodes[parentIndex] + _value : tree.nodes[parentIndex] - _value;
}
}
}
// File: contracts/DrawManager.sol
pragma solidity 0.5.16;
library DrawManager {
using SortitionSumTreeFactory for SortitionSumTreeFactory.SortitionSumTrees;
using SafeMath for uint256;
// The name of the tree
bytes32 public constant TREE_OF_STAKES = "TreeOfStakes";
// The number of branches per node
uint8 public constant MAX_BRANCHES_PER_NODE = 10;
struct State {
SortitionSumTreeFactory.SortitionSumTrees sortitionSumTrees;
}
/**
* @dev Creates the tree
*/
function create(State storage self) public {
self.sortitionSumTrees.createTree(TREE_OF_STAKES, MAX_BRANCHES_PER_NODE);
}
/**
* @dev Adds the specified amount to the user's deposit balance
* @param _addr The user address
* @param _amount The deposit amount
*/
function deposit(State storage self, address _addr, uint256 _amount) public {
bytes32 userId = bytes32(uint256(_addr));
uint256 currentAmount = self.sortitionSumTrees.stakeOf(TREE_OF_STAKES, userId);
currentAmount = currentAmount.add(_amount);
self.sortitionSumTrees.set(TREE_OF_STAKES, currentAmount, userId);
}
/**
* @dev Subtract all from the user's deposit balance
* @param _addr The user address
*/
function withdraw(State storage self, address _addr) public returns (uint256) {
bytes32 userId = bytes32(uint256(_addr));
uint256 currentAmount = self.sortitionSumTrees.stakeOf(TREE_OF_STAKES, userId);
return withdraw(self, _addr, currentAmount);
}
/**
* @dev Subtract the specified amount from the user's deposit balance
* @param _addr The user address
* @param _amount The withdraw amount
*/
function withdraw(State storage self, address _addr, uint256 _amount) public returns (uint256) {
bytes32 userId = bytes32(uint256(_addr));
uint256 currentAmount = self.sortitionSumTrees.stakeOf(TREE_OF_STAKES, userId);
uint256 remainingAmount = currentAmount.sub(_amount);
self.sortitionSumTrees.set(TREE_OF_STAKES, remainingAmount, userId);
return _amount;
}
/**
* Returns the user from the tree by provided random number.
* More about winner selection you can find here: https://www.poa.network/for-users/poa-mania/winner-selection
* @param _drawnNumber The random number
* @return The random user from all
*/
function draw(State storage self, uint256 _drawnNumber) public view returns (address) {
if (totalBalance(self) == 0) {
return address(0);
}
return address(uint256(self.sortitionSumTrees.draw(TREE_OF_STAKES, _drawnNumber)));
}
/**
* @return The deposit balance of the user
*/
function balanceOf(State storage self, address _addr) public view returns (uint256) {
bytes32 userId = bytes32(uint256(_addr));
return self.sortitionSumTrees.stakeOf(TREE_OF_STAKES, userId);
}
/**
* @return The sum of all deposit balances
*/
function totalBalance(State storage self) public view returns (uint256) {
return self.sortitionSumTrees.total(TREE_OF_STAKES);
}
/**
* @return The number of participants
*/
function numberOfParticipants(State storage self) public view returns (uint256) {
return self.sortitionSumTrees.numberOfNodes(TREE_OF_STAKES);
}
}
// File: contracts/Sacrifice.sol
pragma solidity 0.5.16;
contract Sacrifice {
constructor(address payable _recipient) public payable {
selfdestruct(_recipient);
}
}
// File: contracts/PoaMania.sol
pragma solidity 0.5.16;
/**
* @title PoaMania
* @dev This's the main contract of PoaMania.
*
* Note: all percentage values are between 0 and 1
* and represented as fixed point numbers with 18 decimals like in Ether
* 100% == 1 ether
*/
contract PoaMania is Ownable {
using SafeMath for uint256;
using DrawManager for DrawManager.State;
using Random for Random.State;
/**
* @dev Emitted at the end of the round
* @param roundId The round number
* @param winners The array of the winners
* @param prizes The array of the prizes
* @param fee The fee value (in tokens)
* @param feeReceiver The fee receiver
* @param jackpotShare The amount of tokens that goes to the Jackpot
* @param executorReward The reward for the transaction executor (in tokens)
* @param executor The transaction executor
*/
event Rewarded(
uint256 indexed roundId,
address[3] winners,
uint256[3] prizes,
uint256 fee,
address feeReceiver,
uint256 jackpotShare,
uint256 executorReward,
address executor
);
/**
* @dev Emitted when the Jackpot is drawn
* @param roundId The round number
* @param winner The jackpot winner
* @param prize The jackpot size
*/
event Jackpot(
uint256 indexed roundId,
address winner,
uint256 prize
);
/**
* @dev Emitted when a user deposits tokens
* @param user The user address
* @param amount The amount of deposited tokens
*/
event Deposited(address indexed user, uint256 amount);
/**
* @dev Emitted when a user withdraws tokens
* @param user The user address
* @param amount The amount of withdrawn tokens
*/
event Withdrawn(address indexed user, uint256 amount);
// The structure that is used to store the deposits of all users and determine the winners
DrawManager.State internal drawManager;
// The structure that is used for random
Random.State internal random;
// The current round number
uint256 public roundId;
// The timestamp when the current round was started
uint256 public startedAt;
// The average block time (in seconds)
uint256 public blockTime;
// The duration of the round (in seconds)
uint256 public roundDuration;
// The minimum allowable deposit
uint256 public minDeposit;
// The maximum allowable deposit
uint256 public maxDeposit;
// The fee of the lottery (in percentage)
uint256 public fee;
// The address of the fee receiver
address public feeReceiver;
// The reward for the round closer (in percentage)
uint256 public executorShare;
// The part of the prize that goes to the Jackpot (in percentage)
uint256 public jackpotShare;
// The Jackpot chance (in percentage)
uint256 public jackpotChance;
// The current Jackpot size
uint256 public jackpot;
/**
* The 1st and the 2nd prizes' sizes (in percentage)
* The 3rd one is calculated using 2 previous
*/
uint256[2] prizeSizes;
/**
* @dev Throws if deposits and withdrawals for the current round are locked
*/
modifier notLocked() {
uint256 lockStart = getLockStart();
require(block.timestamp < lockStart, "locked");
_;
}
function () external payable {}
/**
* @dev Initializes the contract
* @param _owner The owner of the contract
* @param _randomContract The address of the POSDAORandom contract
* @param _roundDuration The duration of the round (in seconds)
* @param _blockTime The average block time (in seconds)
* @param _minDeposit The minimum allowable deposit
* @param _maxDeposit The maximum allowable deposit
* @param _prizeSizes The array of prize sizes (in percentage)
* @param _fee The fee of the lottery (in percentage)
* @param _feeReceiver The address of the fee receiver
* @param _executorShare The reward for the round closer (in percentage)
* @param _jackpotShare The part of the prize that goes to the Jackpot (in percentage)
* @param _jackpotChance The Jackpot chance (in percentage)
*/
function initialize(
address _owner,
address _randomContract,
uint256 _roundDuration,
uint256 _blockTime,
uint256 _minDeposit,
uint256 _maxDeposit,
uint256[2] memory _prizeSizes,
uint256 _fee,
address _feeReceiver,
uint256 _executorShare,
uint256 _jackpotShare,
uint256 _jackpotChance
) public initializer {
require(_owner != address(0), "zero address");
// initializes all params
Ownable.initialize(_owner);
random.init(_randomContract);
_setBlockTime(_blockTime);
_setRoundDuration(_roundDuration);
_setFee(_fee);
_setFeeReceiver(_feeReceiver);
_setJackpotShare(_jackpotShare);
_setJackpotChance(_jackpotChance);
_setExecutorShare(_executorShare);
_validateSumOfShares();
_setPrizeSizes(_prizeSizes);
_setMaxDeposit(_maxDeposit);
_setMinDeposit(_minDeposit);
jackpot = 0;
// creates a tree of nodes
drawManager.create();
// starts the first round
_nextRound();
}
/**
* @dev Deposits into the pool and increases the user's deposit balance
*/
function deposit() external payable notLocked {
require(msg.value > 0, "zero value");
drawManager.deposit(msg.sender, msg.value);
// checks that the new deposit balance is between mim and max deposits
uint256 newDepositValue = balanceOf(msg.sender);
require(newDepositValue >= minDeposit, "should be greater than or equal to min deposit");
require(newDepositValue <= maxDeposit, "should be less than or equal to max deposit");
emit Deposited(msg.sender, msg.value);
}
/**
* @dev Withdraws all from the user's deposit balance
*/
function withdraw() public notLocked {
uint256 amount = balanceOf(msg.sender);
withdraw(amount);
}
/**
* @dev Withdraws the given amount from the user's deposit balance
* @param _amount The amount to withdraw
*/
function withdraw(uint256 _amount) public notLocked {
require(_amount > 0, "zero value");
drawManager.withdraw(msg.sender, _amount);
// checks that the new deposit balance is greater than min deposit or equal to 0
uint256 newDepositValue = balanceOf(msg.sender);
require(
newDepositValue >= minDeposit || newDepositValue == 0,
"should be greater than or equal to min deposit"
);
_send(msg.sender, _amount);
emit Withdrawn(msg.sender, _amount);
}
/**
* @dev Determines the winners and starts the next round
*/
function nextRound() public {
_reward();
_nextRound();
}
/**
* @dev Starts the next round
*/
function _nextRound() internal {
startedAt = block.timestamp;
roundId = roundId.add(1);
}
/**
* @dev Determines the winners, pays fees, etc.
*/
function _reward() internal {
require(block.timestamp > startedAt.add(roundDuration), "the round is not over yet");
uint256 totalReward = address(this).balance.sub(totalDepositedBalance()).sub(jackpot);
uint256 feeValue = _calculatePercentage(totalReward, fee);
uint256 jackpotShareValue = _calculatePercentage(totalReward, jackpotShare);
uint256 executorShareValue = _calculatePercentage(totalReward, executorShare);
// calculates the value of all 3 prizes
uint256 winnersTotalPrize = totalReward.sub(feeValue).sub(jackpotShareValue).sub(executorShareValue);
address[3] memory winners;
uint256[3] memory winnersCurrentDeposits;
uint256[3] memory prizeValues;
// calculates the value of each prize
prizeValues[0] = _calculatePercentage(winnersTotalPrize, prizeSizes[0]);
prizeValues[1] = _calculatePercentage(winnersTotalPrize, prizeSizes[1]);
prizeValues[2] = winnersTotalPrize.sub(prizeValues[0]).sub(prizeValues[1]);
// takes the random seed
uint256 seed = random.get();
// checks if the jackpot must be drawn
address jackpotWinner;
if (seed % 1 ether < jackpotChance && jackpot > 0) {
// gets a random participant
jackpotWinner = drawManager.draw(seed);
seed = random.next(seed);
}
// determines 3 winners
for (uint256 i = 0; i < 3; i++) {
// gets a random participant
winners[i] = drawManager.draw(seed);
// if the address is zero then there are no more participants
if (winners[i] == address(0)) break;
// withdraws the winner's entire deposit so that they can't get the next prizes of this round
winnersCurrentDeposits[i] = drawManager.withdraw(winners[i]);
seed = random.next(seed);
}
// returns winners' deposits back with the prizes they won
for (uint256 i = 0; i < 3; i++) {
// if the address is zero then there are no more winners
if (winners[i] == address(0)) break;
drawManager.deposit(winners[i], winnersCurrentDeposits[i].add(prizeValues[i]));
}
if (feeReceiver != address(0)) {
_send(address(uint160(feeReceiver)), feeValue);
}
// the reward for the Round Closer
drawManager.deposit(msg.sender, executorShareValue);
emit Rewarded(
roundId,
winners,
prizeValues,
feeValue,
feeReceiver,
jackpotShareValue,
executorShareValue,
msg.sender
);
if (jackpotWinner != address(0)) {
drawManager.deposit(jackpotWinner, jackpot);
emit Jackpot(roundId, jackpotWinner, jackpot);
jackpot = 0;
}
jackpot = jackpot.add(jackpotShareValue);
}
/**
* @dev Sets the round duration
* @param _roundDuration The round duration (in seconds)
*/
function setRoundDuration(uint256 _roundDuration) external onlyOwner {
_setRoundDuration(_roundDuration);
}
/**
* @dev Sets the fee of the lottery
* @param _fee The fee of the lottery (in percentage)
*/
function setFee(uint256 _fee) external onlyOwner {
_setFee(_fee);
_validateSumOfShares();
}
/**
* @dev Sets the fee receiver
* @param _feeReceiver The address of the fee receiver
*/
function setFeeReceiver(address _feeReceiver) external onlyOwner {
_setFeeReceiver(_feeReceiver);
}
/**
* @dev Sets the part of the prize that goes to the Jackpot
* @param _jackpotShare The jackpot share (in percentage)
*/
function setJackpotShare(uint256 _jackpotShare) external onlyOwner {
_setJackpotShare(_jackpotShare);
_validateSumOfShares();
}
/**
* @dev Sets the Jackpot chance
* @param _jackpotChance The jackpot chance (in percentage)
*/
function setJackpotChance(uint256 _jackpotChance) external onlyOwner {
_setJackpotChance(_jackpotChance);
}
/**
* @dev Sets the reward for the round closer
* @param _executorShare The reward for the round closer (in percentage)
*/
function setExecutorShare(uint256 _executorShare) external onlyOwner {
_setExecutorShare(_executorShare);
_validateSumOfShares();
}
/**
* @dev Sets the 1st and the 2nd prizes' sizes
* @param _prizeSizes The array of prize sizes (in percentage)
*/
function setPrizeSizes(uint256[2] calldata _prizeSizes) external onlyOwner {
_setPrizeSizes(_prizeSizes);
}
/**
* @dev Sets the average block time
* @param _blockTime The average block time (in seconds)
*/
function setBlockTime(uint256 _blockTime) external onlyOwner {
_setBlockTime(_blockTime);
}
/**
* @dev Sets the minimum allowable deposit
* @param _minDeposit The minimum deposit
*/
function setMinDeposit(uint256 _minDeposit) external onlyOwner {
_setMinDeposit(_minDeposit);
}
/**
* @dev Sets the maximum allowable deposit
* @param _maxDeposit The maximum deposit
*/
function setMaxDeposit(uint256 _maxDeposit) external onlyOwner {
_setMaxDeposit(_maxDeposit);
}
/**
* @return The deposit balance of the user
*/
function balanceOf(address _user) public view returns (uint256) {
return drawManager.balanceOf(_user);
}
/**
* @return The sum of all deposit balances
*/
function totalDepositedBalance() public view returns (uint256) {
return drawManager.totalBalance();
}
/**
* @return The number of participants
*/
function numberOfParticipants() public view returns (uint256) {
return drawManager.numberOfParticipants();
}
/**
* @return The array of prize sizes
*/
function getPrizeSizes() public view returns (uint256[2] memory) {
return prizeSizes;
}
/**
* @return The timestamp when deposits and withdrawals will be locked
*/
function getLockStart() public view returns (uint256) {
uint256 lockDuration = getLockDuration();
return startedAt.add(roundDuration).sub(lockDuration);
}
/**
* @dev Returns lock duration
*/
function getLockDuration() public view returns (uint256) {
uint256 randomUpdateInterval = random.getUpdateInterval();
return randomUpdateInterval.mul(2).mul(blockTime);
}
/**
* @return The params of the current round
*/
function getRoundInfo() external view returns (
uint256 _roundId,
uint256 _startedAt,
uint256 _roundDuration,
uint256 _blockTime,
uint256 _minDeposit,
uint256 _maxDeposit,
uint256 _jackpot,
uint256 _lockStart,
uint256 _totalDeposited
) {
return (
roundId,
startedAt,
roundDuration,
blockTime,
minDeposit,
maxDeposit,
jackpot,
getLockStart(),
totalDepositedBalance()
);
}
/**
* @return All shares of the total prize including prize sizes, fees, etc.
*/
function getShares() external view returns (
uint256[2] memory _prizeSizes,
uint256 _fee,
address _feeReceiver,
uint256 _executorShare,
uint256 _jackpotShare,
uint256 _jackpotChance
) {
return (
prizeSizes,
fee,
feeReceiver,
executorShare,
jackpotShare,
jackpotChance
);
}
/**
* @dev Sets the round duration
* Reverts if the value is less than 2 lock durations
* @param _roundDuration The round duration (in seconds)
*/
function _setRoundDuration(uint256 _roundDuration) internal {
uint256 lockDuration = getLockDuration();
require(_roundDuration >= lockDuration.mul(2), "should be greater than or equal to 2 lock durations");
roundDuration = _roundDuration;
}
/**
* @dev Sets the fee of the lottery
* @param _fee The fee of the lottery (in percentage)
*/
function _setFee(uint256 _fee) internal {
fee = _fee;
}
/**
* @dev Sets the fee receiver
* Reverts if the value is zero address
* @param _feeReceiver The address of the fee receiver
*/
function _setFeeReceiver(address _feeReceiver) internal {
require(_feeReceiver != address(0), "zero address");
feeReceiver = _feeReceiver;
}
/**
* @dev Sets the part of the prize that goes to the Jackpot
* @param _jackpotShare The jackpot share (in percentage)
*/
function _setJackpotShare(uint256 _jackpotShare) internal {
jackpotShare = _jackpotShare;
}
/**
* @dev Sets the Jackpot chance
* Reverts if the value is greater than 1 ether
* @param _jackpotChance The jackpot chance (in percentage)
*/
function _setJackpotChance(uint256 _jackpotChance) internal {
require(_jackpotChance <= 1 ether, "should be less than or equal to 1 ether");
jackpotChance = _jackpotChance;
}
/**
* @dev Sets the reward for the round closer
* @param _executorShare The reward for the round closer (in percentage)
*/
function _setExecutorShare(uint256 _executorShare) internal {
executorShare = _executorShare;
}
/**
* @dev Sets the 1st and the 2nd prizes' sizes
* Reverts if the sum of the 1st and the 2nd prizes is greater than 1 ether
* @param _prizeSizes The array of prize sizes (in percentage)
*/
function _setPrizeSizes(uint256[2] memory _prizeSizes) internal {
uint256 sum = _prizeSizes[0].add(_prizeSizes[1]);
require(sum > 0 && sum < 1 ether, "should be greater than 0 and less than 1 ether");
uint256 thirdPrize = uint256(1 ether).sub(sum);
require(
_prizeSizes[0] >= _prizeSizes[1] && _prizeSizes[1] >= thirdPrize,
"should satisfy: 1st prize >= 2nd prize >= 3rd prize"
);
prizeSizes = _prizeSizes;
}
/**
* @dev Sets the average block time
* Reverts if the value is zero
* @param _blockTime The average block time (in seconds)
*/
function _setBlockTime(uint256 _blockTime) internal {
require(_blockTime > 0, "should be greater than 0");
blockTime = _blockTime;
}
/**
* @dev Sets the minimum allowable deposit
* @param _minDeposit The minimum deposit
*/
function _setMinDeposit(uint256 _minDeposit) internal {
require(_minDeposit <= maxDeposit, "should be less than or equal to max deposit");
minDeposit = _minDeposit;
}
/**
* @dev Sets the maximum allowable deposit
* @param _maxDeposit The maximum deposit
*/
function _setMaxDeposit(uint256 _maxDeposit) internal {
require(_maxDeposit >= minDeposit, "should be greater than or equal to min deposit");
maxDeposit = _maxDeposit;
}
/**
* @dev Validates the sum of fee, jackpot share and executor share.
* Reverts if the sum is equal to or bigger than 1 ether
*/
function _validateSumOfShares() internal view {
uint256 sum = fee.add(jackpotShare).add(executorShare);
require(sum < 1 ether, "should be less than 1 ether");
}
/**
* @dev Returns the specified percentage of the value
* @param _value The given value
* @param _percentage The specified percentage
*/
function _calculatePercentage(uint256 _value, uint256 _percentage) internal pure returns (uint256) {
return _value.mul(_percentage).div(1 ether);
}
/**
* @dev Sends tokens to the specified address
* If the basic "send" method fails, tokens are sent using "selfdestruct" of the Sacrifice contract
* @param _to The address to send tokens to
* @param _value The amount of tokens to send
*/
function _send(address payable _to, uint256 _value) internal {
if (!_to.send(_value)) {
(new Sacrifice).value(_value)(_to);
}
}
}

Contract ABI

[{"type":"event","name":"Deposited","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Jackpot","inputs":[{"type":"uint256","name":"roundId","internalType":"uint256","indexed":true},{"type":"address","name":"winner","internalType":"address","indexed":false},{"type":"uint256","name":"prize","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Rewarded","inputs":[{"type":"uint256","name":"roundId","internalType":"uint256","indexed":true},{"type":"address[3]","name":"winners","internalType":"address[3]","indexed":false},{"type":"uint256[3]","name":"prizes","internalType":"uint256[3]","indexed":false},{"type":"uint256","name":"fee","internalType":"uint256","indexed":false},{"type":"address","name":"feeReceiver","internalType":"address","indexed":false},{"type":"uint256","name":"jackpotShare","internalType":"uint256","indexed":false},{"type":"uint256","name":"executorReward","internalType":"uint256","indexed":false},{"type":"address","name":"executor","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawn","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"fallback","stateMutability":"payable","payable":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"_user","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"blockTime","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":"executorShare","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"fee","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"feeReceiver","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLockDuration","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLockStart","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256[2]","name":"","internalType":"uint256[2]"}],"name":"getPrizeSizes","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"},{"type":"uint256","name":"_startedAt","internalType":"uint256"},{"type":"uint256","name":"_roundDuration","internalType":"uint256"},{"type":"uint256","name":"_blockTime","internalType":"uint256"},{"type":"uint256","name":"_minDeposit","internalType":"uint256"},{"type":"uint256","name":"_maxDeposit","internalType":"uint256"},{"type":"uint256","name":"_jackpot","internalType":"uint256"},{"type":"uint256","name":"_lockStart","internalType":"uint256"},{"type":"uint256","name":"_totalDeposited","internalType":"uint256"}],"name":"getRoundInfo","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256[2]","name":"_prizeSizes","internalType":"uint256[2]"},{"type":"uint256","name":"_fee","internalType":"uint256"},{"type":"address","name":"_feeReceiver","internalType":"address"},{"type":"uint256","name":"_executorShare","internalType":"uint256"},{"type":"uint256","name":"_jackpotShare","internalType":"uint256"},{"type":"uint256","name":"_jackpotChance","internalType":"uint256"}],"name":"getShares","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_randomContract","internalType":"address"},{"type":"uint256","name":"_roundDuration","internalType":"uint256"},{"type":"uint256","name":"_blockTime","internalType":"uint256"},{"type":"uint256","name":"_minDeposit","internalType":"uint256"},{"type":"uint256","name":"_maxDeposit","internalType":"uint256"},{"type":"uint256[2]","name":"_prizeSizes","internalType":"uint256[2]"},{"type":"uint256","name":"_fee","internalType":"uint256"},{"type":"address","name":"_feeReceiver","internalType":"address"},{"type":"uint256","name":"_executorShare","internalType":"uint256"},{"type":"uint256","name":"_jackpotShare","internalType":"uint256"},{"type":"uint256","name":"_jackpotChance","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"sender","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOwner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"jackpot","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"jackpotChance","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"jackpotShare","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxDeposit","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minDeposit","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"nextRound","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"numberOfParticipants","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"renounceOwnership","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"roundDuration","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"roundId","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setBlockTime","inputs":[{"type":"uint256","name":"_blockTime","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setExecutorShare","inputs":[{"type":"uint256","name":"_executorShare","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setFee","inputs":[{"type":"uint256","name":"_fee","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setFeeReceiver","inputs":[{"type":"address","name":"_feeReceiver","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setJackpotChance","inputs":[{"type":"uint256","name":"_jackpotChance","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setJackpotShare","inputs":[{"type":"uint256","name":"_jackpotShare","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setMaxDeposit","inputs":[{"type":"uint256","name":"_maxDeposit","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setMinDeposit","inputs":[{"type":"uint256","name":"_minDeposit","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setPrizeSizes","inputs":[{"type":"uint256[2]","name":"_prizeSizes","internalType":"uint256[2]"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setRoundDuration","inputs":[{"type":"uint256","name":"_roundDuration","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"startedAt","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDepositedBalance","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[],"constant":false}]
            

Deployed ByteCode

0x60806040526004361061023b5760003560e01c80638f32d59b1161012e578063c776fc89116100ab578063e239c4001161006f578063e239c40014610aec578063efdcd97414610b17578063f21f537d14610b68578063f2fde38b14610b93578063f7cb789a14610be45761023b565b8063c776fc89146109af578063d0e30db0146109ea578063d73fe0aa146109f4578063d8f9cecb14610a96578063ddca3f4314610ac15761023b565b8063b7b59dfa116100f2578063b7b59dfa1461085a578063bb371fdd14610895578063bdf0f1aa146108d0578063c492701c1461090b578063c4d66de81461095e5761023b565b80638f32d59b1461064b5780638fcc9cfb1461067a5780639aea63e6146106b55780639c965052146107d8578063b3f00674146108035761023b565b80636b31ee01116101bc578063758b1ce311610180578063758b1ce31461050057806379e9dc811461053b57806384bc76a6146105665780638cd221c9146105c95780638da5cb5b146105f45761023b565b80636b31ee01146104035780636efd17d61461042e57806370a0823114610459578063715018a6146104be5780637417040e146104d55761023b565b806347e405531161020357806347e405531461032057806348b15166146103375780635fc1cb94146103625780636083e59a1461039d57806369fe0e2d146103c85761023b565b80630604ce271461023d5780632e1a7d4d1461026857806336c92c3f146102a35780633ccfd60b146102de57806341b3d185146102f5575b005b34801561024957600080fd5b50610252610c0f565b6040518082815260200191505060405180910390f35b34801561027457600080fd5b506102a16004803603602081101561028b57600080fd5b8101908080359060200190929190505050610c15565b005b3480156102af57600080fd5b506102dc600480360360208110156102c657600080fd5b8101908080359060200190929190505050610ea6565b005b3480156102ea57600080fd5b506102f3610f2c565b005b34801561030157600080fd5b5061030a610fc7565b6040518082815260200191505060405180910390f35b34801561032c57600080fd5b50610335610fcd565b005b34801561034357600080fd5b5061034c610fdf565b6040518082815260200191505060405180910390f35b34801561036e57600080fd5b5061039b6004803603602081101561038557600080fd5b8101908080359060200190929190505050610fe5565b005b3480156103a957600080fd5b506103b2611073565b6040518082815260200191505060405180910390f35b3480156103d457600080fd5b50610401600480360360208110156103eb57600080fd5b8101908080359060200190929190505050611079565b005b34801561040f57600080fd5b50610418611107565b6040518082815260200191505060405180910390f35b34801561043a57600080fd5b5061044361110d565b6040518082815260200191505060405180910390f35b34801561046557600080fd5b506104a86004803603602081101561047c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611113565b6040518082815260200191505060405180910390f35b3480156104ca57600080fd5b506104d36111dd565b005b3480156104e157600080fd5b506104ea611318565b6040518082815260200191505060405180910390f35b34801561050c57600080fd5b506105396004803603602081101561052357600080fd5b81019080803590602001909291905050506113ac565b005b34801561054757600080fd5b50610550611432565b6040518082815260200191505060405180910390f35b34801561057257600080fd5b5061057b611438565b604051808a8152602001898152602001888152602001878152602001868152602001858152602001848152602001838152602001828152602001995050505050505050505060405180910390f35b3480156105d557600080fd5b506105de611488565b6040518082815260200191505060405180910390f35b34801561060057600080fd5b5061060961148e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561065757600080fd5b506106606114b8565b604051808215151515815260200191505060405180910390f35b34801561068657600080fd5b506106b36004803603602081101561069d57600080fd5b8101908080359060200190929190505050611517565b005b3480156106c157600080fd5b506107d660048036036101a08110156106d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061159d565b005b3480156107e457600080fd5b506107ed6118ce565b6040518082815260200191505060405180910390f35b34801561080f57600080fd5b5061081861190a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561086657600080fd5b506108936004803603604081101561087d57600080fd5b8101908080604001909192919290505050611930565b005b3480156108a157600080fd5b506108ce600480360360208110156108b857600080fd5b81019080803590602001909291905050506119ed565b005b3480156108dc57600080fd5b50610909600480360360208110156108f357600080fd5b8101908080359060200190929190505050611a73565b005b34801561091757600080fd5b50610920611af9565b6040518082600260200280838360005b8381101561094b578082015181840152602081019050610930565b5050505090500191505060405180910390f35b34801561096a57600080fd5b506109ad6004803603602081101561098157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b44565b005b3480156109bb57600080fd5b506109e8600480360360208110156109d257600080fd5b8101908080359060200190929190505050611d02565b005b6109f2611d90565b005b348015610a0057600080fd5b50610a09612042565b6040518087600260200280838360005b83811015610a34578082015181840152602081019050610a19565b505050509050018681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152602001828152602001965050505050505060405180910390f35b348015610aa257600080fd5b50610aab6120d6565b6040518082815260200191505060405180910390f35b348015610acd57600080fd5b50610ad661216a565b6040518082815260200191505060405180910390f35b348015610af857600080fd5b50610b01612170565b6040518082815260200191505060405180910390f35b348015610b2357600080fd5b50610b6660048036036020811015610b3a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612230565b005b348015610b7457600080fd5b50610b7d6122b6565b6040518082815260200191505060405180910390f35b348015610b9f57600080fd5b50610be260048036036020811015610bb657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122bc565b005b348015610bf057600080fd5b50610bf9612342565b6040518082815260200191505060405180910390f35b60755481565b6000610c1f6118ce565b9050804210610c96576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260068152602001807f6c6f636b6564000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008211610d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f7a65726f2076616c75650000000000000000000000000000000000000000000081525060200191505060405180910390fd5b606673de6179253917dd5d67248fb40d210c628cd03f8863f5a98e46909133856040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060206040518083038186803b158015610d9a57600080fd5b505af4158015610dae573d6000803e3d6000fd5b505050506040513d6020811015610dc457600080fd5b8101908080519060200190929190505050506000610de133611113565b9050606f5481101580610df45750600081145b610e49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613b91602e913960400191505060405180910390fd5b610e533384612348565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5846040518082815260200191505060405180910390a2505050565b610eae6114b8565b610f20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610f29816123e9565b50565b6000610f366118ce565b9050804210610fad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260068152602001807f6c6f636b6564000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000610fb833611113565b9050610fc381610c15565b5050565b606f5481565b610fd561246c565b610fdd61304d565b565b606d5481565b610fed6114b8565b61105f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61106881613072565b61107061307c565b50565b60705481565b6110816114b8565b6110f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6110fc8161312b565b61110461307c565b50565b60765481565b60745481565b6000606673de6179253917dd5d67248fb40d210c628cd03f8863b41297e09091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561119b57600080fd5b505af41580156111af573d6000803e3d6000fd5b505050506040513d60208110156111c557600080fd5b81019080805190602001909291905050509050919050565b6111e56114b8565b611257576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000606673de6179253917dd5d67248fb40d210c628cd03f886311d31a7190916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561136c57600080fd5b505af4158015611380573d6000803e3d6000fd5b505050506040513d602081101561139657600080fd5b8101908080519060200190929190505050905090565b6113b46114b8565b611426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61142f81613135565b50565b60735481565b6000806000806000806000806000606b54606c54606e54606d54606f546070546076546114636118ce565b61146b6120d6565b985098509850985098509850985098509850909192939495969798565b606b5481565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166114fb6131b5565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b61151f6114b8565b611591576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61159a816131bd565b50565b600060019054906101000a900460ff16806115bc57506115bb613222565b5b806115d357506000809054906101000a900460ff16155b611628576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613c13602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015611678576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600073ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff16141561171b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f7a65726f2061646472657373000000000000000000000000000000000000000081525060200191505060405180910390fd5b6117248d611b44565b606773fd2f68f276aaa39724edc354c78bd8743f10a3f763b1e50bf490918e6040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b1580156117aa57600080fd5b505af41580156117be573d6000803e3d6000fd5b505050506117cb8a613135565b6117d48b6123e9565b6117dd8661312b565b6117e685613239565b6117ef83613072565b6117f882613320565b6118018461338b565b61180961307c565b61181287613395565b61181b88613508565b611824896131bd565b6000607681905550606673de6179253917dd5d67248fb40d210c628cd03f886316f47ec190916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561187e57600080fd5b505af4158015611892573d6000803e3d6000fd5b5050505061189e61304d565b80156118bf5760008060016101000a81548160ff0219169083151502179055505b50505050505050505050505050565b6000806118d9612170565b9050611904816118f6606e54606c5461356d90919063ffffffff16565b6135f590919063ffffffff16565b91505090565b607260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6119386114b8565b6119aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6119ea816002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050613395565b50565b6119f56114b8565b611a67576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611a7081613508565b50565b611a7b6114b8565b611aed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611af681613320565b50565b611b01613a12565b6077600280602002604051908101604052809291908260028015611b3a576020028201915b815481526020019060010190808311611b26575b5050505050905090565b600060019054906101000a900460ff1680611b635750611b62613222565b5b80611b7a57506000809054906101000a900460ff16155b611bcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613c13602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015611c1f576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a38015611cfe5760008060016101000a81548160ff0219169083151502179055505b5050565b611d0a6114b8565b611d7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611d858161338b565b611d8d61307c565b50565b6000611d9a6118ce565b9050804210611e11576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260068152602001807f6c6f636b6564000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60003411611e87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f7a65726f2076616c75650000000000000000000000000000000000000000000081525060200191505060405180910390fd5b606673de6179253917dd5d67248fb40d210c628cd03f8863e3451b76909133346040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060006040518083038186803b158015611f1557600080fd5b505af4158015611f29573d6000803e3d6000fd5b505050506000611f3833611113565b9050606f54811015611f95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613b91602e913960400191505060405180910390fd5b607054811115611ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180613c41602b913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4346040518082815260200191505060405180910390a25050565b61204a613a12565b60008060008060006077607154607260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16607354607454607554856002806020026040519081016040528092919082600280156120bb576020028201915b8154815260200190600101908083116120a7575b50505050509550955095509550955095509550909192939495565b6000606673de6179253917dd5d67248fb40d210c628cd03f88639e8a5f5c90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561212a57600080fd5b505af415801561213e573d6000803e3d6000fd5b505050506040513d602081101561215457600080fd5b8101908080519060200190929190505050905090565b60715481565b600080606773fd2f68f276aaa39724edc354c78bd8743f10a3f763396e447490916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156121c557600080fd5b505af41580156121d9573d6000803e3d6000fd5b505050506040513d60208110156121ef57600080fd5b8101908080519060200190929190505050905061222a606d5461221c60028461363f90919063ffffffff16565b61363f90919063ffffffff16565b91505090565b6122386114b8565b6122aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6122b381613239565b50565b606c5481565b6122c46114b8565b612336576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61233f816136c5565b50565b606e5481565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050506123e557808260405161238f90613a34565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019150506040518091039082f0801580156123e0573d6000803e3d6000fd5b509050505b5050565b60006123f3612170565b905061240960028261363f90919063ffffffff16565b821015612461576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180613bbf6033913960400191505060405180910390fd5b81606e819055505050565b612483606e54606c5461356d90919063ffffffff16565b42116124f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f74686520726f756e64206973206e6f74206f766572207965740000000000000081525060200191505060405180910390fd5b600061253e60765461253061250a6120d6565b3073ffffffffffffffffffffffffffffffffffffffff16316135f590919063ffffffff16565b6135f590919063ffffffff16565b9050600061254e8260715461380b565b9050600061255e8360745461380b565b9050600061256e8460735461380b565b905060006125a98261259b8561258d888a6135f590919063ffffffff16565b6135f590919063ffffffff16565b6135f590919063ffffffff16565b90506125b3613a40565b6125bb613a62565b6125c3613a62565b6125dc8460776000600281106125d557fe5b015461380b565b816000600381106125e957fe5b60200201818152505061260b84607760016002811061260457fe5b015461380b565b8160016003811061261857fe5b6020020181815250506126688160016003811061263157fe5b602002015161265a8360006003811061264657fe5b6020020151876135f590919063ffffffff16565b6135f590919063ffffffff16565b8160026003811061267557fe5b6020020181815250506000606773fd2f68f276aaa39724edc354c78bd8743f10a3f76372d9dfe490916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156126d257600080fd5b505af41580156126e6573d6000803e3d6000fd5b505050506040513d60208110156126fc57600080fd5b810190808051906020019092919050505090506000607554670de0b6b3a7640000838161272557fe5b0610801561273557506000607654115b1561286957606673de6179253917dd5d67248fb40d210c628cd03f8863ddfe5e3e9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561279457600080fd5b505af41580156127a8573d6000803e3d6000fd5b505050506040513d60208110156127be57600080fd5b81019080805190602001909291905050509050606773fd2f68f276aaa39724edc354c78bd8743f10a3f763f471c5069091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561282b57600080fd5b505af415801561283f573d6000803e3d6000fd5b505050506040513d602081101561285557600080fd5b810190808051906020019092919050505091505b60008090505b6003811015612b2457606673de6179253917dd5d67248fb40d210c628cd03f8863ddfe5e3e9091856040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156128d257600080fd5b505af41580156128e6573d6000803e3d6000fd5b505050506040513d60208110156128fc57600080fd5b810190808051906020019092919050505086826003811061291957fe5b602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1686826003811061297457fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141561299a57612b24565b606673de6179253917dd5d67248fb40d210c628cd03f88634c9b9e9c90918884600381106129c457fe5b60200201516040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612a3057600080fd5b505af4158015612a44573d6000803e3d6000fd5b505050506040513d6020811015612a5a57600080fd5b8101908080519060200190929190505050858260038110612a7757fe5b602002018181525050606773fd2f68f276aaa39724edc354c78bd8743f10a3f763f471c5069091856040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015612ada57600080fd5b505af4158015612aee573d6000803e3d6000fd5b505050506040513d6020811015612b0457600080fd5b81019080805190602001909291905050509250808060010191505061286f565b5060008090505b6003811015612c7357600073ffffffffffffffffffffffffffffffffffffffff16868260038110612b5857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff161415612b7e57612c73565b606673de6179253917dd5d67248fb40d210c628cd03f8863e3451b769091888460038110612ba857fe5b6020020151612be0888660038110612bbc57fe5b60200201518a8760038110612bcd57fe5b602002015161356d90919063ffffffff16565b6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060006040518083038186803b158015612c4e57600080fd5b505af4158015612c62573d6000803e3d6000fd5b505050508080600101915050612b2b565b50600073ffffffffffffffffffffffffffffffffffffffff16607260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612cf757612cf6607260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612348565b5b606673de6179253917dd5d67248fb40d210c628cd03f8863e3451b769091338a6040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060006040518083038186803b158015612d8557600080fd5b505af4158015612d99573d6000803e3d6000fd5b50505050606b547f939c7aa4e354380dd02a08218dca03dc98cd946a3608a5a888a487d003f2bb9e86858c607260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d8d336040518088600360200280838360005b83811015612e15578082015181840152602081019050612dfa565b5050505090500187600360200280838360005b83811015612e43578082015181840152602081019050612e28565b505050509050018681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200197505050505050505060405180910390a2600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461302657606673de6179253917dd5d67248fb40d210c628cd03f8863e3451b769091836076546040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060006040518083038186803b158015612f9557600080fd5b505af4158015612fa9573d6000803e3d6000fd5b50505050606b547ffc61e5433984a216c29840c13f713b564e2967f2a449609c32e4b3182f6399f382607654604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a260006076819055505b61303b8860765461356d90919063ffffffff16565b60768190555050505050505050505050565b42606c8190555061306a6001606b5461356d90919063ffffffff16565b606b81905550565b8060748190555050565b60006130a960735461309b60745460715461356d90919063ffffffff16565b61356d90919063ffffffff16565b9050670de0b6b3a76400008110613128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f73686f756c64206265206c657373207468616e2031206574686572000000000081525060200191505060405180910390fd5b50565b8060718190555050565b600081116131ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f73686f756c642062652067726561746572207468616e2030000000000000000081525060200191505060405180910390fd5b80606d8190555050565b600033905090565b607054811115613218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180613c41602b913960400191505060405180910390fd5b80606f8190555050565b6000803090506000813b9050600081149250505090565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156132dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f7a65726f2061646472657373000000000000000000000000000000000000000081525060200191505060405180910390fd5b80607260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b670de0b6b3a7640000811115613381576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180613c6c6027913960400191505060405180910390fd5b8060758190555050565b8060738190555050565b60006133cc826001600281106133a757fe5b6020020151836000600281106133b957fe5b602002015161356d90919063ffffffff16565b90506000811180156133e55750670de0b6b3a764000081105b61343a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613c93602e913960400191505060405180910390fd5b600061345782670de0b6b3a76400006135f590919063ffffffff16565b90508260016002811061346657fe5b60200201518360006002811061347857fe5b60200201511015801561349c5750808360016002811061349457fe5b602002015110155b6134f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180613b5e6033913960400191505060405180910390fd5b826077906002613502929190613a84565b50505050565b606f54811015613563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613b91602e913960400191505060405180910390fd5b8060708190555050565b6000808284019050838110156135eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061363783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613842565b905092915050565b60008083141561365257600090506136bf565b600082840290508284828161366357fe5b04146136ba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613bf26021913960400191505060405180910390fd5b809150505b92915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561374b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613b386026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061383a670de0b6b3a764000061382c848661363f90919063ffffffff16565b61390290919063ffffffff16565b905092915050565b60008383111582906138ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156138b4578082015181840152602081019050613899565b50505050905090810190601f1680156138e15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600061394483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061394c565b905092915050565b600080831182906139f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156139bd5780820151818401526020810190506139a2565b50505050905090810190601f1680156139ea5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613a0457fe5b049050809150509392505050565b6040518060400160405280600290602082028038833980820191505090505090565b604e80613aea83390190565b6040518060600160405280600390602082028038833980820191505090505090565b6040518060600160405280600390602082028038833980820191505090505090565b8260028101928215613ab3579160200282015b82811115613ab2578251825591602001919060010190613a97565b5b509050613ac09190613ac4565b5090565b613ae691905b80821115613ae2576000816000905550600101613aca565b5090565b9056fe6080604052604051604e380380604e83398181016040526020811015602357600080fd5b81019080805190602001909291905050508073ffffffffffffffffffffffffffffffffffffffff16fffe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737373686f756c6420736174697366793a20317374207072697a65203e3d20326e64207072697a65203e3d20337264207072697a6573686f756c642062652067726561746572207468616e206f7220657175616c20746f206d696e206465706f73697473686f756c642062652067726561746572207468616e206f7220657175616c20746f2032206c6f636b206475726174696f6e73536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656473686f756c64206265206c657373207468616e206f7220657175616c20746f206d6178206465706f73697473686f756c64206265206c657373207468616e206f7220657175616c20746f203120657468657273686f756c642062652067726561746572207468616e203020616e64206c657373207468616e2031206574686572a265627a7a723158200380603ace1b6be2029c798d347f2512df90da7a1d4b1191dc8b95c6d819f19c64736f6c63430005100032

External libraries