Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- PooTogether
- Optimization enabled
- false
- Compiler version
- v0.6.12+commit.27d51765
- EVM Version
- istanbul
- Verified at
- 2026-04-22T07:41:53.119139Z
Constructor Arguments
0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c00000000000000000000000041654c630bcbc0c85c9bbd32856fc71c0f61ffb9
Arg [0] (address) : 0x5dbcf33d8c2e976c6b560249878e6f1491bca25c
Arg [1] (address) : 0x41654c630bcbc0c85c9bbd32856fc71c0f61ffb9
PooTogether.sol
/**
* @reviewers: [@clesaege, @unknownunknown1, @ferittuncer]
* @auditors: []
* @bounties: [<14 days 10 ETH max payout>]
* @deployments: []
*/
/**
* @title SortitionSumTreeFactory
* @author Enrique Piqueras - <epiquerass@gmail.com>
* @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;
}
/* internal */
/**
* @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) internal {
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 = new uint[](0);
tree.nodes = new uint[](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) internal {
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.pop();
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);
}
}
}
/* internal 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 startIndex The index at which leaves start
* @return values The values of the returned leaves
* @return hasMore 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
) internal 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 ID 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) internal 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 value The associated value.
*/
function stakeOf(SortitionSumTrees storage self, bytes32 _key, bytes32 _ID) internal 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) internal view returns (uint) {
SortitionSumTree storage tree = self.sortitionSumTrees[_key];
if (tree.nodes.length == 0) {
return 0;
} else {
return tree.nodes[0];
}
}
/* 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;
}
}
}
library UniformRandomNumber {
/// @author Brendan Asselstine
/// @notice Select a random number without modulo bias using a random seed and upper bound
/// @param _entropy The seed for randomness
/// @param _upperBound The upper bound of the desired number
/// @return A random number less than the _upperBound
function uniform(uint256 _entropy, uint256 _upperBound) internal pure returns (uint256) {
uint256 min = -_upperBound % _upperBound;
uint256 random = _entropy;
while (true) {
if (random >= min) {
break;
}
random = uint256(keccak256(abi.encodePacked(random)));
}
return random % _upperBound;
}
}
library SafeMath {
function mul(uint a, uint b) internal pure returns (uint) {
uint c = a * b;
require(a == 0 || c / a == b);
return c;
}
function div(uint a, uint b) internal pure returns (uint) {
require(b > 0);
uint c = a / b;
require(a == b * c + a % b);
return c;
}
function sub(uint a, uint b) internal pure returns (uint) {
require(b <= a);
return a - b;
}
function add(uint a, uint b) internal pure returns (uint) {
uint c = a + b;
require(c >= a);
return c;
}
function max64(uint64 a, uint64 b) internal pure returns (uint64) {
return a >= b ? a : b;
}
function min64(uint64 a, uint64 b) internal pure returns (uint64) {
return a < b ? a : b;
}
function max256(uint a, uint b) internal pure returns (uint) {
return a >= b ? a : b;
}
function min256(uint a, uint b) internal pure returns (uint) {
return a < b ? a : b;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface yVaultInterface is IERC20 {
function token() external view returns (address);
function balance() external view returns (uint);
function deposit(uint _amount) external;
function withdraw(uint _shares) external;
function getPricePerFullShare() external view returns (uint);
}
interface Uni {
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
/*
* @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.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual 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/access/Ownable.sol
/**
* @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.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @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(_owner == _msgSender(), "Ownable: caller is not the 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 virtual 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 virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
interface DistribInterface {
function distribute(uint entropy, address winner) external;
}
contract PooTogether is Ownable {
using SafeMath for uint;
// Terminology
// base = the base token of the vault (vault.token)
// share = the share tokeni, i.e. the vault token itself
// example: base is yCrv, share is yUSD
bytes32 public constant TREE_KEY = "PooPoo";
uint public totalBase;
mapping (address => uint) public perUserBase;
yVaultInterface public immutable vault;
DistribInterface public distributor;
uint public lockedUntilBlock;
bytes32 public secretHash;
// events
event Deposit(address indexed user, uint amountBase, uint amountShares, uint time);
event Withdraw(address indexed user, uint amountBase, uint amountShares, uint time);
event Locked(uint untilBlock, uint time);
event Unlocked(uint time);
// NOTE: we can only access the hash for the last 256 blocks (~ 55 minutes assuming 13.04s block times); we take the 40th to last block (~8 mins)
// Note: must be at least 40 for security properties to hold! We use `blockhash(block.number - 40)` for entropy to mitigate reorgs to manipulate the winner,
// but if the block taken is before the lock (LOCK_FOR_BLOCKS < 40), then the operator can manipulate the secret bsaed on the known block hash!
// 46 blocks is around 10 minutes
uint public constant LOCK_FOR_BLOCKS = 46;
// The unlock safety is the amount of blocks we wait after lockedUntilBlock before *anyone* (not only the operator) can unlock
uint public constant UNLOCK_SAFETY_BLOCKS = 200;
using SortitionSumTreeFactory for SortitionSumTreeFactory.SortitionSumTrees;
SortitionSumTreeFactory.SortitionSumTrees internal sortitionSumTrees;
constructor (yVaultInterface _vault, DistribInterface _distrib) public {
vault = _vault;
distributor = _distrib;
sortitionSumTrees.createTree(TREE_KEY, 4);
}
// Why we have locks:
// Outcome (winner) is affected by three factors: the secret (which uses commit-reveal),
// ...the entropy block (mined after the commit but before the reveal) and the overall sortition tree state (deposits)
// Deposits/withdrawals get locked once the secret is committed, so that the operator can't manipulate results using their inside knowledge
// of the secret, after the entropy block has been mined
// Miners can't manipulate cause they don't know the secret
// Why we can deposit/withdraw both base and shares
// cause with different vaults different things make sense - eg with yUSD most people would be holding yUSD
// while with USDT, most people might be holding USDT rather than the vault share token (yUSDT)
function deposit(uint amountBase) external {
require(lockedUntilBlock == 0, "pool is locked");
setUserBase(msg.sender, perUserBase[msg.sender].add(amountBase));
totalBase = totalBase.add(amountBase);
IERC20 token = IERC20(vault.token());
require(token.transferFrom(msg.sender, address(this), amountBase));
token.approve(address(vault), amountBase);
vault.deposit(amountBase);
emit Deposit(msg.sender, amountBase, toShares(amountBase), now);
}
function depositShares(uint amountShares) external {
require(lockedUntilBlock == 0, "pool is locked");
uint amountBase = toBase(amountShares);
setUserBase(msg.sender, perUserBase[msg.sender].add(amountBase));
totalBase = totalBase.add(amountBase);
require(vault.transferFrom(msg.sender, address(this), amountShares));
emit Deposit(msg.sender, amountBase, amountShares, now);
}
function withdraw(uint amountBase) external {
require(lockedUntilBlock == 0, "pool is locked");
require(perUserBase[msg.sender] >= amountBase, "insufficient funds");
setUserBase(msg.sender, perUserBase[msg.sender].sub(amountBase));
totalBase = totalBase.sub(amountBase);
// XXX this may be a problem cause shares sounds down
uint amountShares = toShares(amountBase);
vault.withdraw(amountShares);
require(IERC20(vault.token()).transfer(msg.sender, amountBase));
emit Withdraw(msg.sender, amountBase, amountShares, now);
}
function withdrawShares(uint amountShares) external {
require(lockedUntilBlock == 0, "pool is locked");
uint amountBase = toBase(amountShares);
require(perUserBase[msg.sender] >= amountBase, "insufficient funds");
setUserBase(msg.sender, perUserBase[msg.sender].sub(amountBase));
totalBase = totalBase.sub(amountBase);
require(vault.transfer(msg.sender, amountShares));
emit Withdraw(msg.sender, amountBase, amountShares, now);
}
function withdrawableShares(address user) external view returns (uint) {
return toShares(perUserBase[user]);
}
function setUserBase(address user, uint base) internal {
perUserBase[user] = base;
sortitionSumTrees.set(TREE_KEY, base, bytes32(uint(user)));
}
//
// Drawing system
//
function skimmableBase() public view returns (uint) {
uint ourWorthInBase = toBase(vault.balanceOf(address(this)));
// XXX what happens if somehow ourWorthInBase < totalBase - this shouldn't happen
uint skimmable = ourWorthInBase.sub(totalBase);
return skimmable;
}
function lock(bytes32 _secretHash) onlyOwner external {
require(lockedUntilBlock == 0, "pool is already locked");
lockedUntilBlock = block.number + LOCK_FOR_BLOCKS;
secretHash = _secretHash;
emit Locked(lockedUntilBlock, now);
}
function draw(bytes32 secret) onlyOwner external {
require(lockedUntilBlock > 0, "pool is not locked");
require(block.number >= lockedUntilBlock, "pool is not unlockable yet");
require(keccak256(abi.encodePacked(secret)) == secretHash, "secret does not match");
unlockInternal();
// skim the revenue and distribute it
// Note: if there are no participants, this would always be 0
uint skimmableShares = toShares(this.skimmableBase());
require(skimmableShares > 0, "no skimmable rewards");
// XXX if the distributor wants to receive the base then we withdraw the shares and transfer skimmable
require(vault.transfer(address(distributor), skimmableShares));
uint rand = entropy(secret);
address winner = winner(rand);
distributor.distribute(rand, winner);
// @TODO - or just use the distributor to mint, but that needs to be done safely (msg.sender == )
//poo.mint(winner, pooPerDraw)
}
function unlock() external {
require(lockedUntilBlock > 0, "pool is not locked");
require(block.number >= (lockedUntilBlock + UNLOCK_SAFETY_BLOCKS), "pool is not publicly unlockable yet");
unlockInternal();
}
function unlockInternal() internal {
// unlock pool
lockedUntilBlock = 0;
secretHash = bytes32(0);
emit Unlocked(now);
}
function winner(uint entropy) public view returns (address) {
uint randomToken = UniformRandomNumber.uniform(entropy, totalBase);
return address(uint256(sortitionSumTrees.draw(TREE_KEY, randomToken)));
}
function entropy(bytes32 secret) internal view returns (uint256) {
return uint256(keccak256(abi.encodePacked(blockhash(block.number - 40), secret)));
}
function toShares(uint256 tokens) internal view returns (uint256) {
return vault.totalSupply().mul(tokens).div(vault.balance());
}
function toBase(uint256 shares) internal view returns (uint256) {
uint256 supply = vault.totalSupply();
if (supply == 0 || shares == 0) return 0;
return (vault.balance().mul(shares)).div(supply);
}
// admin only (besides lock/draw)
function changeDistributor(DistribInterface _dist) onlyOwner external {
distributor = _dist;
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":200,"enabled":false},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"PooTogether.sol":"PooTogether"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_vault","internalType":"contract yVaultInterface"},{"type":"address","name":"_distrib","internalType":"contract DistribInterface"}]},{"type":"event","name":"Deposit","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amountBase","internalType":"uint256","indexed":false},{"type":"uint256","name":"amountShares","internalType":"uint256","indexed":false},{"type":"uint256","name":"time","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Locked","inputs":[{"type":"uint256","name":"untilBlock","internalType":"uint256","indexed":false},{"type":"uint256","name":"time","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":"Unlocked","inputs":[{"type":"uint256","name":"time","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amountBase","internalType":"uint256","indexed":false},{"type":"uint256","name":"amountShares","internalType":"uint256","indexed":false},{"type":"uint256","name":"time","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"LOCK_FOR_BLOCKS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"TREE_KEY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"UNLOCK_SAFETY_BLOCKS","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeDistributor","inputs":[{"type":"address","name":"_dist","internalType":"contract DistribInterface"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deposit","inputs":[{"type":"uint256","name":"amountBase","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositShares","inputs":[{"type":"uint256","name":"amountShares","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract DistribInterface"}],"name":"distributor","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"draw","inputs":[{"type":"bytes32","name":"secret","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"lock","inputs":[{"type":"bytes32","name":"_secretHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lockedUntilBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"perUserBase","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"secretHash","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"skimmableBase","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalBase","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract yVaultInterface"}],"name":"vault","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"winner","inputs":[{"type":"uint256","name":"entropy","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"amountBase","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawShares","inputs":[{"type":"uint256","name":"amountShares","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawableShares","inputs":[{"type":"address","name":"user","internalType":"address"}]}]
Contract Creation Code
0x60a06040523480156200001157600080fd5b506040516200336a3803806200336a833981810160405260408110156200003757600080fd5b810190808051906020019092919080519060200190929190505050600062000064620001c060201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001b87f506f6f506f6f000000000000000000000000000000000000000000000000000060046006620001c860201b6200215b179092919060201c565b505062000447565b600033905090565b6000836000016000848152602001908152602001600020905060008160000154146200025c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5472656520616c7265616479206578697374732e00000000000000000000000081525060200191505060405180910390fd5b60018211620002d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4b206d7573742062652067726561746572207468616e206f6e652e000000000081525060200191505060405180910390fd5b818160000181905550600067ffffffffffffffff81118015620002f557600080fd5b50604051908082528060200260200182016040528015620003255781602001602082028036833780820191505090505b508160010190805190602001906200033f929190620003d6565b50600067ffffffffffffffff811180156200035957600080fd5b50604051908082528060200260200182016040528015620003895781602001602082028036833780820191505090505b50816002019080519060200190620003a3929190620003d6565b50806002016000908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b82805482825590600052602060002090810192821562000415579160200282015b8281111562000414578251825591602001919060010190620003f7565b5b50905062000424919062000428565b5090565b5b808211156200044357600081600090555060010162000429565b5090565b60805160601c612ec4620004a6600039806108bf5280610bf85280610c835280610e40528061128f528061191e5280611ab05280611b615280611d515280612139528061236c5280612435528061270e52806127b35250612ec46000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c8063945fbc80116100c3578063d29e68031161007c578063d29e68031461044e578063d8162db71461046c578063e702cc661461048a578063f2fde38b146104a8578063f4c4c8d7146104ec578063fbfa77cf146105445761014d565b8063945fbc801461033e578063a69df4b514610396578063b6445e13146103a0578063b6b55f25146103be578063b8767dd9146103ec578063bfe109281461041a5761014d565b806344320333116101155780634432033314610252578063629374ab14610270578063715018a61461029e578063802cd15f146102a85780638da5cb5b146102ec5780639035d57b146103205761014d565b806301670ba91461015257806319810f3c146101805780631cbeae5e146101ae5780632e1a7d4d14610206578063336196a114610234575b600080fd5b61017e6004803603602081101561016857600080fd5b8101908080359060200190929190505050610578565b005b6101ac6004803603602081101561019657600080fd5b810190808035906020019092919050505061070d565b005b6101da600480360360208110156101c457600080fd5b81019080803590602001909291905050506109f4565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102326004803603602081101561021c57600080fd5b8101908080359060200190929190505050610a46565b005b61023c610e38565b6040518082815260200191505060405180910390f35b61025a610f28565b6040518082815260200191505060405180910390f35b61029c6004803603602081101561028657600080fd5b8101908080359060200190929190505050610f2d565b005b6102a661144f565b005b6102ea600480360360208110156102be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115d5565b005b6102f46116e1565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61032861170a565b6040518082815260200191505060405180910390f35b6103806004803603602081101561035457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061172e565b6040518082815260200191505060405180910390f35b61039e611746565b005b6103a8611826565b6040518082815260200191505060405180910390f35b6103ea600480360360208110156103d457600080fd5b810190808035906020019092919050505061182c565b005b6104186004803603602081101561040257600080fd5b8101908080359060200190929190505050611c54565b005b610422611ea4565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610456611eca565b6040518082815260200191505060405180910390f35b610474611ed0565b6040518082815260200191505060405180910390f35b610492611ed6565b6040518082815260200191505060405180910390f35b6104ea600480360360208110156104be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611edb565b005b61052e6004803603602081101561050257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506120e6565b6040518082815260200191505060405180910390f35b61054c612137565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61058061235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610640576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600454146106b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f706f6f6c20697320616c7265616479206c6f636b65640000000000000000000081525060200191505060405180910390fd5b602e4301600481905550806005819055507f907fece23ce39fbcbceb71e515043fe29408353fbb393b25b35eb8a70a4bad0b60045442604051808381526020018281526020019250505060405180910390a150565b600060045414610785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b600061079082612367565b905080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610847576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f696e73756666696369656e742066756e6473000000000000000000000000000081525060200191505060405180910390fd5b6108a23361089d83600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124f990919063ffffffff16565b612513565b6108b7816001546124f990919063ffffffff16565b6001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561094e57600080fd5b505af1158015610962573d6000803e3d6000fd5b505050506040513d602081101561097857600080fd5b810190808051906020019092919050505061099257600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca9482844260405180848152602001838152602001828152602001935050505060405180910390a25050565b600080610a03836001546125ac565b9050610a3b7f506f6f506f6f000000000000000000000000000000000000000000000000000082600661261c9092919063ffffffff16565b60001c915050919050565b600060045414610abe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b80600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b73576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f696e73756666696369656e742066756e6473000000000000000000000000000081525060200191505060405180910390fd5b610bce33610bc983600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124f990919063ffffffff16565b612513565b610be3816001546124f990919063ffffffff16565b6001819055506000610bf482612707565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610c6957600080fd5b505af1158015610c7d573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ce757600080fd5b505afa158015610cfb573d6000803e3d6000fd5b505050506040513d6020811015610d1157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610d9257600080fd5b505af1158015610da6573d6000803e3d6000fd5b505050506040513d6020811015610dbc57600080fd5b8101908080519060200190929190505050610dd657600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca9483834260405180848152602001838152602001828152602001935050505060405180910390a25050565b600080610f057f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610ec557600080fd5b505afa158015610ed9573d6000803e3d6000fd5b505050506040513d6020811015610eef57600080fd5b8101908080519060200190929190505050612367565b90506000610f1e600154836124f990919063ffffffff16565b9050809250505090565b602e81565b610f3561235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ff5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006004541161106d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f706f6f6c206973206e6f74206c6f636b6564000000000000000000000000000081525060200191505060405180910390fd5b6004544310156110e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f706f6f6c206973206e6f7420756e6c6f636b61626c652079657400000000000081525060200191505060405180910390fd5b60055481604051602001808281526020019150506040516020818303038152906040528051906020012014611182576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f73656372657420646f6573206e6f74206d61746368000000000000000000000081525060200191505060405180910390fd5b61118a612875565b60006112153073ffffffffffffffffffffffffffffffffffffffff1663336196a16040518163ffffffff1660e01b815260040160206040518083038186803b1580156111d557600080fd5b505afa1580156111e9573d6000803e3d6000fd5b505050506040513d60208110156111ff57600080fd5b8101908080519060200190929190505050612707565b90506000811161128d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6e6f20736b696d6d61626c65207265776172647300000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561134057600080fd5b505af1158015611354573d6000803e3d6000fd5b505050506040513d602081101561136a57600080fd5b810190808051906020019092919050505061138457600080fd5b600061138f836128c0565b9050600061139c826109f4565b9050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1fa8b0283836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561143157600080fd5b505af1158015611445573d6000803e3d6000fd5b5050505050505050565b61145761235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611517576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6115dd61235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461169d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b7f506f6f506f6f000000000000000000000000000000000000000000000000000081565b60026020528060005260406000206000915090505481565b6000600454116117be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f706f6f6c206973206e6f74206c6f636b6564000000000000000000000000000081525060200191505060405180910390fd5b60c86004540143101561181c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612e6c6023913960400191505060405180910390fd5b611824612875565b565b60015481565b6000600454146118a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b6118ff336118fa83600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128ff90919063ffffffff16565b612513565b611914816001546128ff90919063ffffffff16565b60018190555060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561198257600080fd5b505afa158015611996573d6000803e3d6000fd5b505050506040513d60208110156119ac57600080fd5b810190808051906020019092919050505090508073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611a4e57600080fd5b505af1158015611a62573d6000803e3d6000fd5b505050506040513d6020811015611a7857600080fd5b8101908080519060200190929190505050611a9257600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611b2357600080fd5b505af1158015611b37573d6000803e3d6000fd5b505050506040513d6020811015611b4d57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b6b55f25836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611bd257600080fd5b505af1158015611be6573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff167f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e83611c2c85612707565b4260405180848152602001838152602001828152602001935050505060405180910390a25050565b600060045414611ccc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b6000611cd782612367565b9050611d3433611d2f83600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128ff90919063ffffffff16565b612513565b611d49816001546128ff90919063ffffffff16565b6001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611dfe57600080fd5b505af1158015611e12573d6000803e3d6000fd5b505050506040513d6020811015611e2857600080fd5b8101908080519060200190929190505050611e4257600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e82844260405180848152602001838152602001828152602001935050505060405180910390a25050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60055481565b60045481565b60c881565b611ee361235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611fa3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612029576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612e466026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000612130600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612707565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000836000016000848152602001908152602001600020905060008160000154146121ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5472656520616c7265616479206578697374732e00000000000000000000000081525060200191505060405180910390fd5b60018211612264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4b206d7573742062652067726561746572207468616e206f6e652e000000000081525060200191505060405180910390fd5b818160000181905550600067ffffffffffffffff8111801561228557600080fd5b506040519080825280602002602001820160405280156122b45781602001602082028036833780820191505090505b508160010190805190602001906122cc929190612ddb565b50600067ffffffffffffffff811180156122e557600080fd5b506040519080825280602002602001820160405280156123145781602001602082028036833780820191505090505b5081600201908051906020019061232c929190612ddb565b50806002016000908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b600033905090565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156123d057600080fd5b505afa1580156123e4573d6000803e3d6000fd5b505050506040513d60208110156123fa57600080fd5b81019080805190602001909291905050509050600081148061241c5750600083145b1561242b5760009150506124f4565b6124f0816124e2857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561249957600080fd5b505afa1580156124ad573d6000803e3d6000fd5b505050506040513d60208110156124c357600080fd5b810190808051906020019092919050505061291e90919063ffffffff16565b61295090919063ffffffff16565b9150505b919050565b60008282111561250857600080fd5b818303905092915050565b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506125a87f506f6f506f6f0000000000000000000000000000000000000000000000000000828473ffffffffffffffffffffffffffffffffffffffff1660001b600661298f909392919063ffffffff16565b5050565b6000808283600003816125bb57fe5b06905060008490505b600115612608578181106125d757612608565b80604051602001808281526020019150506040516020818303038152906040528051906020012060001c90506125c4565b83818161261157fe5b069250505092915050565b60008084600001600085815260200190815260200160002090506000808260020160008154811061264957fe5b9060005260206000200154858161265c57fe5b0690505b82600201805490506001838560000154020110156126e5576000600190505b836000015481116126df576000818486600001540201905060008560020182815481106126a857fe5b906000526020600020015490508084106126c65780840393506126d0565b81945050506126df565b5050808060010191505061267f565b50612660565b8260040160008381526020019081526020016000205493505050509392505050565b600061286e7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561277257600080fd5b505afa158015612786573d6000803e3d6000fd5b505050506040513d602081101561279c57600080fd5b8101908080519060200190929190505050612860847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561281757600080fd5b505afa15801561282b573d6000803e3d6000fd5b505050506040513d602081101561284157600080fd5b810190808051906020019092919050505061291e90919063ffffffff16565b61295090919063ffffffff16565b9050919050565b60006004819055506000801b6005819055507ff27b6ce5b2f5e68ddb2fd95a8a909d4ecf1daaac270935fff052feacb24f1842426040518082815260200191505060405180910390a1565b600060284303408260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012060001c9050919050565b60008082840190508381101561291457600080fd5b8091505092915050565b6000808284029050600084148061293d57508284828161293a57fe5b04145b61294657600080fd5b8091505092915050565b600080821161295e57600080fd5b600082848161296957fe5b04905082848161297557fe5b0681840201841461298557600080fd5b8091505092915050565b6000846000016000858152602001908152602001600020905060008160030160008481526020019081526020016000205490506000811415612bbc5760008414612bb757600082600101805490501415612b0c57816002018054905090508160020184908060018154018082558091505060019003906000526020600020016000909190919091505560018114158015612a395750600082600001546001830381612a3657fe5b06145b15612b0757600082600001548281612a4d57fe5b0490506000836004016000838152602001908152602001600020549050600060018401905084600201856002018481548110612a8557fe5b9060005260206000200154908060018154018082558091505060019003906000526020600020016000909190919091505584600401600084815260200190815260200160002060009055808560030160008481526020019081526020016000208190555081856004016000838152602001908152602001600020819055505050505b612b74565b81600101600183600101805490500381548110612b2557fe5b9060005260206000200154905081600101805480612b3f57fe5b6001900381819060005260206000200160009055905583826002018281548110612b6557fe5b90600052602060002001819055505b80826003016000858152602001908152602001600020819055508282600401600083815260200190815260200160002081905550612bb6868683600188612d33565b5b612d2b565b6000841415612c73576000826002018281548110612bd657fe5b906000526020600020015490506000836002018381548110612bf457fe5b9060005260206000200181905550826001018290806001815401808255809150506001900390600052602060002001600090919091909150558260030160008581526020019081526020016000206000905582600401600083815260200190815260200160002060009055612c6d878784600085612d33565b50612d2a565b816002018181548110612c8257fe5b90600052602060002001548414612d2957600084836002018381548110612ca557fe5b906000526020600020015411159050600081612cdc5785846002018481548110612ccb57fe5b906000526020600020015403612cf9565b836002018381548110612ceb57fe5b906000526020600020015486035b905085846002018481548110612d0b57fe5b9060005260206000200181905550612d268888858585612d33565b50505b5b5b505050505050565b6000856000016000868152602001908152602001600020905060008490505b60008114612dd25781600001546001820381612d6a57fe5b04905083612d935782826002018281548110612d8257fe5b906000526020600020015403612db0565b82826002018281548110612da357fe5b9060005260206000200154015b826002018281548110612dbf57fe5b9060005260206000200181905550612d52565b50505050505050565b828054828255906000526020600020908101928215612e17579160200282015b82811115612e16578251825591602001919060010190612dfb565b5b509050612e249190612e28565b5090565b5b80821115612e41576000816000905550600101612e29565b509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373706f6f6c206973206e6f74207075626c69636c7920756e6c6f636b61626c6520796574a26469706673582212202714ab4e8917666b7481391d24fba90d1e0a45864dac1f06b1f615a85da8aafa64736f6c634300060c00330000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c00000000000000000000000041654c630bcbc0c85c9bbd32856fc71c0f61ffb9
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061014d5760003560e01c8063945fbc80116100c3578063d29e68031161007c578063d29e68031461044e578063d8162db71461046c578063e702cc661461048a578063f2fde38b146104a8578063f4c4c8d7146104ec578063fbfa77cf146105445761014d565b8063945fbc801461033e578063a69df4b514610396578063b6445e13146103a0578063b6b55f25146103be578063b8767dd9146103ec578063bfe109281461041a5761014d565b806344320333116101155780634432033314610252578063629374ab14610270578063715018a61461029e578063802cd15f146102a85780638da5cb5b146102ec5780639035d57b146103205761014d565b806301670ba91461015257806319810f3c146101805780631cbeae5e146101ae5780632e1a7d4d14610206578063336196a114610234575b600080fd5b61017e6004803603602081101561016857600080fd5b8101908080359060200190929190505050610578565b005b6101ac6004803603602081101561019657600080fd5b810190808035906020019092919050505061070d565b005b6101da600480360360208110156101c457600080fd5b81019080803590602001909291905050506109f4565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102326004803603602081101561021c57600080fd5b8101908080359060200190929190505050610a46565b005b61023c610e38565b6040518082815260200191505060405180910390f35b61025a610f28565b6040518082815260200191505060405180910390f35b61029c6004803603602081101561028657600080fd5b8101908080359060200190929190505050610f2d565b005b6102a661144f565b005b6102ea600480360360208110156102be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115d5565b005b6102f46116e1565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61032861170a565b6040518082815260200191505060405180910390f35b6103806004803603602081101561035457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061172e565b6040518082815260200191505060405180910390f35b61039e611746565b005b6103a8611826565b6040518082815260200191505060405180910390f35b6103ea600480360360208110156103d457600080fd5b810190808035906020019092919050505061182c565b005b6104186004803603602081101561040257600080fd5b8101908080359060200190929190505050611c54565b005b610422611ea4565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610456611eca565b6040518082815260200191505060405180910390f35b610474611ed0565b6040518082815260200191505060405180910390f35b610492611ed6565b6040518082815260200191505060405180910390f35b6104ea600480360360208110156104be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611edb565b005b61052e6004803603602081101561050257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506120e6565b6040518082815260200191505060405180910390f35b61054c612137565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61058061235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610640576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600454146106b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f706f6f6c20697320616c7265616479206c6f636b65640000000000000000000081525060200191505060405180910390fd5b602e4301600481905550806005819055507f907fece23ce39fbcbceb71e515043fe29408353fbb393b25b35eb8a70a4bad0b60045442604051808381526020018281526020019250505060405180910390a150565b600060045414610785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b600061079082612367565b905080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610847576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f696e73756666696369656e742066756e6473000000000000000000000000000081525060200191505060405180910390fd5b6108a23361089d83600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124f990919063ffffffff16565b612513565b6108b7816001546124f990919063ffffffff16565b6001819055507f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561094e57600080fd5b505af1158015610962573d6000803e3d6000fd5b505050506040513d602081101561097857600080fd5b810190808051906020019092919050505061099257600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca9482844260405180848152602001838152602001828152602001935050505060405180910390a25050565b600080610a03836001546125ac565b9050610a3b7f506f6f506f6f000000000000000000000000000000000000000000000000000082600661261c9092919063ffffffff16565b60001c915050919050565b600060045414610abe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b80600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b73576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f696e73756666696369656e742066756e6473000000000000000000000000000081525060200191505060405180910390fd5b610bce33610bc983600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124f990919063ffffffff16565b612513565b610be3816001546124f990919063ffffffff16565b6001819055506000610bf482612707565b90507f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610c6957600080fd5b505af1158015610c7d573d6000803e3d6000fd5b505050507f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ce757600080fd5b505afa158015610cfb573d6000803e3d6000fd5b505050506040513d6020811015610d1157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610d9257600080fd5b505af1158015610da6573d6000803e3d6000fd5b505050506040513d6020811015610dbc57600080fd5b8101908080519060200190929190505050610dd657600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca9483834260405180848152602001838152602001828152602001935050505060405180910390a25050565b600080610f057f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610ec557600080fd5b505afa158015610ed9573d6000803e3d6000fd5b505050506040513d6020811015610eef57600080fd5b8101908080519060200190929190505050612367565b90506000610f1e600154836124f990919063ffffffff16565b9050809250505090565b602e81565b610f3561235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ff5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006004541161106d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f706f6f6c206973206e6f74206c6f636b6564000000000000000000000000000081525060200191505060405180910390fd5b6004544310156110e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f706f6f6c206973206e6f7420756e6c6f636b61626c652079657400000000000081525060200191505060405180910390fd5b60055481604051602001808281526020019150506040516020818303038152906040528051906020012014611182576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f73656372657420646f6573206e6f74206d61746368000000000000000000000081525060200191505060405180910390fd5b61118a612875565b60006112153073ffffffffffffffffffffffffffffffffffffffff1663336196a16040518163ffffffff1660e01b815260040160206040518083038186803b1580156111d557600080fd5b505afa1580156111e9573d6000803e3d6000fd5b505050506040513d60208110156111ff57600080fd5b8101908080519060200190929190505050612707565b90506000811161128d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6e6f20736b696d6d61626c65207265776172647300000000000000000000000081525060200191505060405180910390fd5b7f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561134057600080fd5b505af1158015611354573d6000803e3d6000fd5b505050506040513d602081101561136a57600080fd5b810190808051906020019092919050505061138457600080fd5b600061138f836128c0565b9050600061139c826109f4565b9050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1fa8b0283836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561143157600080fd5b505af1158015611445573d6000803e3d6000fd5b5050505050505050565b61145761235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611517576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6115dd61235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461169d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b7f506f6f506f6f000000000000000000000000000000000000000000000000000081565b60026020528060005260406000206000915090505481565b6000600454116117be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f706f6f6c206973206e6f74206c6f636b6564000000000000000000000000000081525060200191505060405180910390fd5b60c86004540143101561181c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612e6c6023913960400191505060405180910390fd5b611824612875565b565b60015481565b6000600454146118a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b6118ff336118fa83600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128ff90919063ffffffff16565b612513565b611914816001546128ff90919063ffffffff16565b60018190555060007f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561198257600080fd5b505afa158015611996573d6000803e3d6000fd5b505050506040513d60208110156119ac57600080fd5b810190808051906020019092919050505090508073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611a4e57600080fd5b505af1158015611a62573d6000803e3d6000fd5b505050506040513d6020811015611a7857600080fd5b8101908080519060200190929190505050611a9257600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611b2357600080fd5b505af1158015611b37573d6000803e3d6000fd5b505050506040513d6020811015611b4d57600080fd5b8101908080519060200190929190505050507f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663b6b55f25836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611bd257600080fd5b505af1158015611be6573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff167f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e83611c2c85612707565b4260405180848152602001838152602001828152602001935050505060405180910390a25050565b600060045414611ccc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f706f6f6c206973206c6f636b656400000000000000000000000000000000000081525060200191505060405180910390fd5b6000611cd782612367565b9050611d3433611d2f83600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128ff90919063ffffffff16565b612513565b611d49816001546128ff90919063ffffffff16565b6001819055507f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611dfe57600080fd5b505af1158015611e12573d6000803e3d6000fd5b505050506040513d6020811015611e2857600080fd5b8101908080519060200190929190505050611e4257600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e82844260405180848152602001838152602001828152602001935050505060405180910390a25050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60055481565b60045481565b60c881565b611ee361235f565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611fa3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612029576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612e466026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000612130600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612707565b9050919050565b7f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c81565b6000836000016000848152602001908152602001600020905060008160000154146121ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5472656520616c7265616479206578697374732e00000000000000000000000081525060200191505060405180910390fd5b60018211612264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4b206d7573742062652067726561746572207468616e206f6e652e000000000081525060200191505060405180910390fd5b818160000181905550600067ffffffffffffffff8111801561228557600080fd5b506040519080825280602002602001820160405280156122b45781602001602082028036833780820191505090505b508160010190805190602001906122cc929190612ddb565b50600067ffffffffffffffff811180156122e557600080fd5b506040519080825280602002602001820160405280156123145781602001602082028036833780820191505090505b5081600201908051906020019061232c929190612ddb565b50806002016000908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b600033905090565b6000807f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156123d057600080fd5b505afa1580156123e4573d6000803e3d6000fd5b505050506040513d60208110156123fa57600080fd5b81019080805190602001909291905050509050600081148061241c5750600083145b1561242b5760009150506124f4565b6124f0816124e2857f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561249957600080fd5b505afa1580156124ad573d6000803e3d6000fd5b505050506040513d60208110156124c357600080fd5b810190808051906020019092919050505061291e90919063ffffffff16565b61295090919063ffffffff16565b9150505b919050565b60008282111561250857600080fd5b818303905092915050565b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506125a87f506f6f506f6f0000000000000000000000000000000000000000000000000000828473ffffffffffffffffffffffffffffffffffffffff1660001b600661298f909392919063ffffffff16565b5050565b6000808283600003816125bb57fe5b06905060008490505b600115612608578181106125d757612608565b80604051602001808281526020019150506040516020818303038152906040528051906020012060001c90506125c4565b83818161261157fe5b069250505092915050565b60008084600001600085815260200190815260200160002090506000808260020160008154811061264957fe5b9060005260206000200154858161265c57fe5b0690505b82600201805490506001838560000154020110156126e5576000600190505b836000015481116126df576000818486600001540201905060008560020182815481106126a857fe5b906000526020600020015490508084106126c65780840393506126d0565b81945050506126df565b5050808060010191505061267f565b50612660565b8260040160008381526020019081526020016000205493505050509392505050565b600061286e7f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff1663b69ef8a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561277257600080fd5b505afa158015612786573d6000803e3d6000fd5b505050506040513d602081101561279c57600080fd5b8101908080519060200190929190505050612860847f0000000000000000000000005dbcf33d8c2e976c6b560249878e6f1491bca25c73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561281757600080fd5b505afa15801561282b573d6000803e3d6000fd5b505050506040513d602081101561284157600080fd5b810190808051906020019092919050505061291e90919063ffffffff16565b61295090919063ffffffff16565b9050919050565b60006004819055506000801b6005819055507ff27b6ce5b2f5e68ddb2fd95a8a909d4ecf1daaac270935fff052feacb24f1842426040518082815260200191505060405180910390a1565b600060284303408260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012060001c9050919050565b60008082840190508381101561291457600080fd5b8091505092915050565b6000808284029050600084148061293d57508284828161293a57fe5b04145b61294657600080fd5b8091505092915050565b600080821161295e57600080fd5b600082848161296957fe5b04905082848161297557fe5b0681840201841461298557600080fd5b8091505092915050565b6000846000016000858152602001908152602001600020905060008160030160008481526020019081526020016000205490506000811415612bbc5760008414612bb757600082600101805490501415612b0c57816002018054905090508160020184908060018154018082558091505060019003906000526020600020016000909190919091505560018114158015612a395750600082600001546001830381612a3657fe5b06145b15612b0757600082600001548281612a4d57fe5b0490506000836004016000838152602001908152602001600020549050600060018401905084600201856002018481548110612a8557fe5b9060005260206000200154908060018154018082558091505060019003906000526020600020016000909190919091505584600401600084815260200190815260200160002060009055808560030160008481526020019081526020016000208190555081856004016000838152602001908152602001600020819055505050505b612b74565b81600101600183600101805490500381548110612b2557fe5b9060005260206000200154905081600101805480612b3f57fe5b6001900381819060005260206000200160009055905583826002018281548110612b6557fe5b90600052602060002001819055505b80826003016000858152602001908152602001600020819055508282600401600083815260200190815260200160002081905550612bb6868683600188612d33565b5b612d2b565b6000841415612c73576000826002018281548110612bd657fe5b906000526020600020015490506000836002018381548110612bf457fe5b9060005260206000200181905550826001018290806001815401808255809150506001900390600052602060002001600090919091909150558260030160008581526020019081526020016000206000905582600401600083815260200190815260200160002060009055612c6d878784600085612d33565b50612d2a565b816002018181548110612c8257fe5b90600052602060002001548414612d2957600084836002018381548110612ca557fe5b906000526020600020015411159050600081612cdc5785846002018481548110612ccb57fe5b906000526020600020015403612cf9565b836002018381548110612ceb57fe5b906000526020600020015486035b905085846002018481548110612d0b57fe5b9060005260206000200181905550612d268888858585612d33565b50505b5b5b505050505050565b6000856000016000868152602001908152602001600020905060008490505b60008114612dd25781600001546001820381612d6a57fe5b04905083612d935782826002018281548110612d8257fe5b906000526020600020015403612db0565b82826002018281548110612da357fe5b9060005260206000200154015b826002018281548110612dbf57fe5b9060005260206000200181905550612d52565b50505050505050565b828054828255906000526020600020908101928215612e17579160200282015b82811115612e16578251825591602001919060010190612dfb565b5b509050612e249190612e28565b5090565b5b80821115612e41576000816000905550600101612e29565b509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373706f6f6c206973206e6f74207075626c69636c7920756e6c6f636b61626c6520796574a26469706673582212202714ab4e8917666b7481391d24fba90d1e0a45864dac1f06b1f615a85da8aafa64736f6c634300060c0033