More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 353 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Settle Bet | 8851637 | 1832 days ago | IN | 0 ETH | 0.00052262 | ||||
Place Bet | 8851635 | 1832 days ago | IN | 0 ETH | 0.00057911 | ||||
Settle Bet | 8851615 | 1832 days ago | IN | 0 ETH | 0.00052262 | ||||
Place Bet | 8851612 | 1832 days ago | IN | 0 ETH | 0.00115758 | ||||
Settle Bet | 8851603 | 1832 days ago | IN | 0 ETH | 0.00046243 | ||||
Place Bet | 8851600 | 1832 days ago | IN | 0 ETH | 0.00115758 | ||||
Settle Bet | 8851594 | 1832 days ago | IN | 0 ETH | 0.00027453 | ||||
Settle Bet | 8851591 | 1832 days ago | IN | 0 ETH | 0.00027453 | ||||
Place Bet | 8851590 | 1832 days ago | IN | 0 ETH | 0.00115758 | ||||
Settle Bet | 8544672 | 1880 days ago | IN | 0 ETH | 0.00052198 | ||||
Place Bet | 8544668 | 1880 days ago | IN | 0 ETH | 0.00115758 | ||||
Settle Bet | 8083924 | 1952 days ago | IN | 0 ETH | 0.00022318 | ||||
Place Bet | 8083922 | 1952 days ago | IN | 0 ETH | 0.00069493 | ||||
Settle Bet | 8083915 | 1952 days ago | IN | 0 ETH | 0.00031415 | ||||
Place Bet | 8083913 | 1952 days ago | IN | 0 ETH | 0.00069525 | ||||
Settle Bet | 8083908 | 1952 days ago | IN | 0 ETH | 0.00031377 | ||||
Place Bet | 8083906 | 1952 days ago | IN | 0 ETH | 0.00069487 | ||||
Settle Bet | 8083901 | 1952 days ago | IN | 0 ETH | 0.00027804 | ||||
Place Bet | 8083899 | 1952 days ago | IN | 0 ETH | 0.00069448 | ||||
Settle Bet | 8083889 | 1952 days ago | IN | 0 ETH | 0.00031415 | ||||
Place Bet | 8083887 | 1952 days ago | IN | 0 ETH | 0.00069487 | ||||
Settle Bet | 8083879 | 1952 days ago | IN | 0 ETH | 0.00031415 | ||||
Place Bet | 8083877 | 1952 days ago | IN | 0 ETH | 0.00069525 | ||||
Settle Bet | 8083871 | 1952 days ago | IN | 0 ETH | 0.00031415 | ||||
Place Bet | 8083868 | 1952 days ago | IN | 0 ETH | 0.00069525 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
GoatClash
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-02-15 */ pragma solidity ^0.4.24; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); } /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two numbers, reverts on 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-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0); // Solidity only automatically asserts when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; uint256 private _totalSupply; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param owner address The address which owns the funds. * @param spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance( address owner, address spender ) public view returns (uint256) { return _allowed[owner][spender]; } /** * @dev Transfer token for a specified address * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public returns (bool) { require(spender != address(0)); _allowed[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 the amount of tokens to be transferred */ function transferFrom( address from, address to, uint256 value ) public returns (bool) { require(value <= _allowed[from][msg.sender]); _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); _transfer(from, to, value); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when allowed_[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance( address spender, uint256 addedValue ) public returns (bool) { require(spender != address(0)); _allowed[msg.sender][spender] = ( _allowed[msg.sender][spender].add(addedValue)); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when allowed_[_spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance( address spender, uint256 subtractedValue ) public returns (bool) { require(spender != address(0)); _allowed[msg.sender][spender] = ( _allowed[msg.sender][spender].sub(subtractedValue)); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { require(value <= _balances[from]); require(to != address(0)); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. * @param value The amount that will be created. */ function _mint(address account, uint256 value) internal { require(account != 0); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burn(address account, uint256 value) internal { require(account != 0); require(value <= _balances[account]); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burnFrom(address account, uint256 value) internal { require(value <= _allowed[account][msg.sender]); // Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted, // this function needs to emit an event with the updated approval. _allowed[account][msg.sender] = _allowed[account][msg.sender].sub( value); _burn(account, value); } } // GoatClash contract // Version 1.0 // The Goat Herd @ https://goat.cash // // Based on dice2.win Solidity contract. Extended to use ERC20 tokens in place of ETH, // betting logic and proofs unchanged. Original comments follow this text. // Note modified and added lines marked with comments. // // * dice2.win - fair games that pay Ether. Version 5. // // * Ethereum smart contract, deployed at 0xD1CEeeeee83F8bCF3BEDad437202b6154E9F5405. // // * Uses hybrid commit-reveal + block hash random number generation that is immune // to tampering by players, house and miners. Apart from being fully transparent, // this also allows arbitrarily high bets. // // * Refer to https://dice2.win/whitepaper.pdf for detailed description and proofs. contract GoatClash { // ADDED ERC20 token reference and setter ERC20 private _token; function token() public view returns(ERC20) { return _token; } function setToken(address erc20Token) external onlyOwner { _token = ERC20(erc20Token); } // *** Constants section // Each bet is deducted 1% in favour of the house, but no less than some minimum. // The lower bound is dictated by gas costs of the settleBet transaction, providing // headroom for up to 10 Gwei prices. uint constant HOUSE_EDGE_PERCENT = 2; uint constant HOUSE_EDGE_MINIMUM_AMOUNT = 1; // GOAT MODIFIED: changed min amount, this will cost us gas, boooo.. //uint constant HOUSE_EDGE_PERCENT = 1; //uint constant HOUSE_EDGE_MINIMUM_AMOUNT = 0.0003 ether; // Bets lower than this amount do not participate in jackpot rolls (and are // not deducted JACKPOT_FEE). // GOAT MODIFIED: changed min amount from 0.1 ether uint constant MIN_JACKPOT_BET = 5000 * (10 ** 18); // Chance to win jackpot (currently 0.1%) and fee deducted into jackpot fund. uint constant JACKPOT_MODULO = 1000; // GOAT MODIFIED: changed fee amount uint constant JACKPOT_FEE = 100 * (10 ** 18); // There is minimum and maximum bets. // GOAT MODIFIED // uint constant MIN_BET = 0.01 ether; // uint constant MAX_AMOUNT = 300000 ether; uint constant MIN_BET = 1 * (10 ** 18); uint constant MAX_AMOUNT = 1000000 * (10 ** 18); // Modulo is a number of equiprobable outcomes in a game: // - 2 for coin flip // - 6 for dice // - 6*6 = 36 for double dice // - 100 for etheroll // - 37 for roulette // etc. // It's called so because 256-bit entropy is treated like a huge integer and // the remainder of its division by modulo is considered bet outcome. uint constant MAX_MODULO = 100; // For modulos below this threshold rolls are checked against a bit mask, // thus allowing betting on any combination of outcomes. For example, given // modulo 6 for dice, 101000 mask (base-2, big endian) means betting on // 4 and 6; for games with modulos higher than threshold (Etheroll), a simple // limit is used, allowing betting on any outcome in [0, N) range. // // The specific value is dictated by the fact that 256-bit intermediate // multiplication result allows implementing population count efficiently // for numbers that are up to 42 bits, and 40 is the highest multiple of // eight below 42. uint constant MAX_MASK_MODULO = 40; // This is a check on bet mask overflow. uint constant MAX_BET_MASK = 2 ** MAX_MASK_MODULO; // EVM BLOCKHASH opcode can query no further than 256 blocks into the // past. Given that settleBet uses block hash of placeBet as one of // complementary entropy sources, we cannot process bets older than this // threshold. On rare occasions dice2.win croupier may fail to invoke // settleBet in this timespan due to technical issues or extreme Ethereum // congestion; such bets can be refunded via invoking refundBet. uint constant BET_EXPIRATION_BLOCKS = 250; // Some deliberately invalid address to initialize the secret signer with. // Forces maintainers to invoke setSecretSigner before processing any bets. address constant DUMMY_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // Standard contract ownership transfer. address public owner; address private nextOwner; // Adjustable max bet profit. Used to cap bets against dynamic odds. uint public maxProfit; // The address corresponding to a private key used to sign placeBet commits. address public secretSigner; // Accumulated jackpot fund. uint128 public jackpotSize; // Funds that are locked in potentially winning bets. Prevents contract from // committing to bets it cannot pay out. uint128 public lockedInBets; // A structure representing a single bet. struct Bet { // Wager amount in wei. uint amount; // Modulo of a game. uint8 modulo; // Number of winning outcomes, used to compute winning payment (* modulo/rollUnder), // and used instead of mask for games with modulo > MAX_MASK_MODULO. uint8 rollUnder; // Block number of placeBet tx. uint40 placeBlockNumber; // Bit mask representing winning bet outcomes (see MAX_MASK_MODULO comment). uint40 mask; // Address of a gambler, used to pay out winning bets. address gambler; } // Mapping from commits to all currently active & processed bets. mapping (uint => Bet) bets; // Croupier account. address public croupier; // Events that are issued to make statistic recovery easier. event FailedPayment(address indexed beneficiary, uint amount); event Payment(address indexed beneficiary, uint amount); event JackpotPayment(address indexed beneficiary, uint amount); // This event is emitted in placeBet to record commit in the logs. event Commit(uint commit); // Constructor. Deliberately does not take any parameters. constructor () public { owner = msg.sender; secretSigner = DUMMY_ADDRESS; croupier = DUMMY_ADDRESS; } // Standard modifier on methods invokable only by contract owner. modifier onlyOwner { require (msg.sender == owner, "OnlyOwner methods called by non-owner."); _; } // Standard modifier on methods invokable only by contract owner. modifier onlyCroupier { require (msg.sender == croupier, "OnlyCroupier methods called by non-croupier."); _; } // Standard contract ownership transfer implementation, function approveNextOwner(address _nextOwner) external onlyOwner { require (_nextOwner != owner, "Cannot approve current owner."); nextOwner = _nextOwner; } function acceptNextOwner() external { require (msg.sender == nextOwner, "Can only accept preapproved new owner."); owner = nextOwner; } // Fallback function deliberately left empty. It's primary use case // is to top up the bank roll. function () public payable { } // See comment for "secretSigner" variable. function setSecretSigner(address newSecretSigner) external onlyOwner { secretSigner = newSecretSigner; } // Change the croupier address. function setCroupier(address newCroupier) external onlyOwner { croupier = newCroupier; } // Change max bet reward. Setting this to zero effectively disables betting. function setMaxProfit(uint _maxProfit) public onlyOwner { require (_maxProfit < MAX_AMOUNT, "maxProfit should be a sane number."); maxProfit = _maxProfit; } // MODIFIED // This function is used to bump up the jackpot fund. Cannot be used to lower it. function increaseJackpot(uint increaseAmount) external onlyOwner { require (increaseAmount <= _token.balanceOf(address(this)), "Increase amount larger than balance."); require (jackpotSize + lockedInBets + increaseAmount <= _token.balanceOf(address(this)), "Not enough funds."); jackpotSize += uint128(increaseAmount); } // MODIFIED // Funds withdrawal to cover costs of dice2.win operation. function withdrawFunds(address beneficiary, uint withdrawAmount) external onlyOwner { require (withdrawAmount <= _token.balanceOf(address(this)), "Cannot withdraw more than balance."); require (jackpotSize + lockedInBets + withdrawAmount <= _token.balanceOf(address(this)), "Not enough funds."); sendFunds(beneficiary, withdrawAmount, withdrawAmount); } // MODIFIED // Contract may be destroyed only when there are no ongoing bets, // either settled or refunded. All funds are transferred to contract owner. function kill() external onlyOwner { require (lockedInBets == 0, "All bets should be processed (settled or refunded) before self-destruct."); // Any remaining funds locked in the Jackpot (which cannot be decreased) will only be withdrawn when contract is killed sendFunds(owner, _token.balanceOf(address(this)), _token.balanceOf(address(this))); selfdestruct(owner); } /// *** Betting logic // Bet states: // amount == 0 && gambler == 0 - 'clean' (can place a bet) // amount != 0 && gambler != 0 - 'active' (can be settled or refunded) // amount == 0 && gambler != 0 - 'processed' (can clean storage) // // NOTE: Storage cleaning is not implemented in this contract version; it will be added // with the next upgrade to prevent polluting Ethereum state with expired bets. // Bet placing transaction - issued by the player. // amount - ADDED: Token bet amount (amount must be already 'approved' by player) // betMask - bet outcomes bit mask for modulo <= MAX_MASK_MODULO, // [0, betMask) for larger modulos. // modulo - game modulo. // commitLastBlock - number of the maximum block where "commit" is still considered valid. // commit - Keccak256 hash of some secret "reveal" random number, to be supplied // by the dice2.win croupier bot in the settleBet transaction. Supplying // "commit" ensures that "reveal" cannot be changed behind the scenes // after placeBet have been mined. // r, s - components of ECDSA signature of (commitLastBlock, commit). v is // guaranteed to always equal 27. // // Commit, being essentially random 256-bit number, is used as a unique bet identifier in // the 'bets' mapping. // // Commits are signed with a block limit to ensure that they are used at most once - otherwise // it would be possible for a miner to place a bet with a known commit/reveal pair and tamper // with the blockhash. Croupier guarantees that commitLastBlock will always be not greater than // placeBet block number plus BET_EXPIRATION_BLOCKS. See whitepaper for details. function placeBet(uint amount, uint betMask, uint modulo, uint commitLastBlock, uint commit, bytes32 r, bytes32 s) external { // Check that the bet is in 'clean' state. Bet storage bet = bets[commit]; require (bet.gambler == address(0), "Bet should be in a 'clean' state."); // Validate input data ranges. // MODIFIED: Using amount parameter not msg.value; //uint amount = msg.value; require (amount <= _token.allowance(msg.sender, address(this)), "Bet amount not inserted."); require (modulo > 1 && modulo <= MAX_MODULO, "Modulo should be within range."); require (amount >= MIN_BET && amount <= MAX_AMOUNT, "Amount should be within range."); require (betMask > 0 && betMask < MAX_BET_MASK, "Mask should be within range."); // Check that commit is valid - it has not expired and its signature is valid. require (block.number <= commitLastBlock, "Commit has expired."); bytes32 signatureHash = keccak256(abi.encodePacked(uint40(commitLastBlock), commit)); require (secretSigner == ecrecover(signatureHash, 27, r, s), "ECDSA signature is not valid."); uint rollUnder; uint mask; if (modulo <= MAX_MASK_MODULO) { // Small modulo games specify bet outcomes via bit mask. // rollUnder is a number of 1 bits in this mask (population count). // This magic looking formula is an efficient way to compute population // count on EVM for numbers below 2**40. For detailed proof consult // the dice2.win whitepaper. rollUnder = ((betMask * POPCNT_MULT) & POPCNT_MASK) % POPCNT_MODULO; mask = betMask; } else { // Larger modulos specify the right edge of half-open interval of // winning bet outcomes. require (betMask > 0 && betMask <= modulo, "High modulo range, betMask larger than modulo."); rollUnder = betMask; } // Winning amount and jackpot increase. uint possibleWinAmount; uint jackpotFee; (possibleWinAmount, jackpotFee) = getDiceWinAmount(amount, modulo, rollUnder); // Enforce max profit limit. require (possibleWinAmount <= amount + maxProfit, "maxProfit limit violation."); // Lock funds. lockedInBets += uint128(possibleWinAmount); jackpotSize += uint128(jackpotFee); // Check whether contract has enough funds to process this bet. // Modified: Updated to ERC20 require (jackpotSize + lockedInBets <= _token.balanceOf(address(this)), "Cannot afford to lose this bet."); // ADDED deduct from approved tokens - moved to settleBet //deductFunds(msg.sender, amount); // Record commit in logs. emit Commit(commit); // Store bet parameters on blockchain. bet.amount = amount; bet.modulo = uint8(modulo); bet.rollUnder = uint8(rollUnder); bet.placeBlockNumber = uint40(block.number); bet.mask = uint40(mask); bet.gambler = msg.sender; } // This is the method used to settle 99% of bets. To process a bet with a specific // "commit", settleBet should supply a "reveal" number that would Keccak256-hash to // "commit". "blockHash" is the block hash of placeBet block as seen by croupier; it // is additionally asserted to prevent changing the bet outcomes on Ethereum reorgs. function settleBet(uint reveal, bytes32 blockHash) external onlyCroupier { uint commit = uint(keccak256(abi.encodePacked(reveal))); Bet storage bet = bets[commit]; uint placeBlockNumber = bet.placeBlockNumber; // Check that bet has not expired yet (see comment to BET_EXPIRATION_BLOCKS). require (block.number > placeBlockNumber, "settleBet in the same block as placeBet, or before."); require (block.number <= placeBlockNumber + BET_EXPIRATION_BLOCKS, "Blockhash can't be queried by EVM."); require (blockhash(placeBlockNumber) == blockHash, "Blockhash does not match."); require (bet.amount <= _token.allowance(bet.gambler, address(this)), "Bet amount not inserted."); // Settle bet using reveal and blockHash as entropy sources. settleBetCommon(bet, reveal, blockHash); } // This method is used to settle a bet that was mined into an uncle block. At this // point the player was shown some bet outcome, but the blockhash at placeBet height // is different because of Ethereum chain reorg. We supply a full merkle proof of the // placeBet transaction receipt to provide untamperable evidence that uncle block hash // indeed was present on-chain at some point. function settleBetUncleMerkleProof(uint reveal, uint40 canonicalBlockNumber) external onlyCroupier { // "commit" for bet settlement can only be obtained by hashing a "reveal". uint commit = uint(keccak256(abi.encodePacked(reveal))); Bet storage bet = bets[commit]; // Check that canonical block hash can still be verified. require (block.number <= canonicalBlockNumber + BET_EXPIRATION_BLOCKS, "Blockhash can't be queried by EVM."); // Verify placeBet receipt. requireCorrectReceipt(4 + 32 + 32 + 4); // Reconstruct canonical & uncle block hashes from a receipt merkle proof, verify them. bytes32 canonicalHash; bytes32 uncleHash; (canonicalHash, uncleHash) = verifyMerkleProof(commit, 4 + 32 + 32); require (blockhash(canonicalBlockNumber) == canonicalHash); // Settle bet using reveal and uncleHash as entropy sources. settleBetCommon(bet, reveal, uncleHash); } // Common settlement code for settleBet & settleBetUncleMerkleProof. function settleBetCommon(Bet storage bet, uint reveal, bytes32 entropyBlockHash) private { // Fetch bet parameters into local variables (to save gas). uint amount = bet.amount; uint modulo = bet.modulo; uint rollUnder = bet.rollUnder; address gambler = bet.gambler; // Check that bet is in 'active' state. require (amount != 0, "Bet should be in an 'active' state"); // Move bet into 'processed' state already. bet.amount = 0; // The RNG - combine "reveal" and blockhash of placeBet using Keccak256. Miners // are not aware of "reveal" and cannot deduce it from "commit" (as Keccak256 // preimage is intractable), and house is unable to alter the "reveal" after // placeBet have been mined (as Keccak256 collision finding is also intractable). bytes32 entropy = keccak256(abi.encodePacked(reveal, entropyBlockHash)); // Do a roll by taking a modulo of entropy. Compute winning amount. uint dice = uint(entropy) % modulo; uint diceWinAmount; uint _jackpotFee; (diceWinAmount, _jackpotFee) = getDiceWinAmount(amount, modulo, rollUnder); uint diceWin = 0; uint jackpotWin = 0; // Determine dice outcome. if (modulo <= MAX_MASK_MODULO) { // For small modulo games, check the outcome against a bit mask. if ((2 ** dice) & bet.mask != 0) { diceWin = diceWinAmount; } } else { // For larger modulos, check inclusion into half-open interval. if (dice < rollUnder) { diceWin = diceWinAmount; } } // Unlock the bet amount, regardless of the outcome. lockedInBets -= uint128(diceWinAmount); // Roll for a jackpot (if eligible). if (amount >= MIN_JACKPOT_BET) { // The second modulo, statistically independent from the "main" dice roll. // Effectively you are playing two games at once! uint jackpotRng = (uint(entropy) / modulo) % JACKPOT_MODULO; // Bingo! if (jackpotRng == 0) { jackpotWin = jackpotSize; jackpotSize = 0; } } // Log jackpot win. if (jackpotWin > 0) { emit JackpotPayment(gambler, jackpotWin); } // ADDED: Perform payment/deduct here to reduce gas costs (I guess this reduces contract interactions and therefore dApp ratings or something) // Lost bet if (diceWin + jackpotWin == 0) { deductFunds(gambler, amount); } else { // MODIFIED: only send funds on win (less orig amount) // Send the funds to gambler. sendFunds(gambler, diceWin + jackpotWin == 0 ? 1 wei : diceWin + jackpotWin - amount, diceWin); } // Send the funds to gambler. //sendFunds(gambler, diceWin + jackpotWin == 0 ? 1 wei : diceWin + jackpotWin, diceWin); } // MODIFIED: Removed as redundant due to settle bet changes - replaced with cancelBet() // Refund transaction - return the bet amount of a roll that was not processed in a // due timeframe. Processing such blocks is not possible due to EVM limitations (see // BET_EXPIRATION_BLOCKS comment above for details). In case you ever find yourself // in a situation like this, just contact the dice2.win support, however nothing // precludes you from invoking this method yourself. // function refundBet(uint commit) external { // // Check that bet is in 'active' state. // Bet storage bet = bets[commit]; // uint amount = bet.amount; // require (amount != 0, "Bet should be in an 'active' state"); // // Check that bet has already expired. // require (block.number > bet.placeBlockNumber + BET_EXPIRATION_BLOCKS, "Blockhash can't be queried by EVM."); // // Move bet into 'processed' state, release funds. // bet.amount = 0; // uint diceWinAmount; // uint jackpotFee; // (diceWinAmount, jackpotFee) = getDiceWinAmount(amount, bet.modulo, bet.rollUnder); // lockedInBets -= uint128(diceWinAmount); // jackpotSize -= uint128(jackpotFee); // // Send the refund. // sendFunds(bet.gambler, amount, amount); // } // ADDED // A bet which failed to be settled in time (see refund transaction comments) will still // count in locked in values and must be corrected. function cancelBet(uint commit) external onlyCroupier { // Check that bet is in 'active' state. Bet storage bet = bets[commit]; uint amount = bet.amount; require (amount != 0, "Bet should be in an 'active' state"); // Check that bet has already expired. //require (block.number > bet.placeBlockNumber + BET_EXPIRATION_BLOCKS, "Blockhash can't be queried by EVM."); // Move bet into 'processed' state, release funds. bet.amount = 0; uint diceWinAmount; uint jackpotFee; (diceWinAmount, jackpotFee) = getDiceWinAmount(amount, bet.modulo, bet.rollUnder); lockedInBets -= uint128(diceWinAmount); jackpotSize -= uint128(jackpotFee); } // Get the expected win amount after house edge is subtracted. function getDiceWinAmount(uint amount, uint modulo, uint rollUnder) private pure returns (uint winAmount, uint jackpotFee) { require (0 < rollUnder && rollUnder <= modulo, "Win probability out of range."); jackpotFee = amount >= MIN_JACKPOT_BET ? JACKPOT_FEE : 0; uint houseEdge = amount * HOUSE_EDGE_PERCENT / 100; if (houseEdge < HOUSE_EDGE_MINIMUM_AMOUNT) { houseEdge = HOUSE_EDGE_MINIMUM_AMOUNT; } require (houseEdge + jackpotFee <= amount, "Bet doesn't even cover house edge."); winAmount = (amount - houseEdge - jackpotFee) * modulo / rollUnder; } // Helper routine to process the payment. // function sendFunds(address beneficiary, uint amount, uint successLogAmount) internal { // if (beneficiary.send(amount)) { // emit Payment(beneficiary, successLogAmount); // } else { // emit FailedPayment(beneficiary, amount); // } // } // MODIFIED // Override helper routine to process the payment in ERC20 function sendFunds(address beneficiary, uint amount, uint successLogAmount) private { if (_token.transfer(beneficiary, amount)) { emit Payment(beneficiary, successLogAmount); } else { emit FailedPayment(beneficiary, amount); } } // ADDED // Helper routine to process the payment in ERC20 function deductFunds(address player, uint amount) private { if (_token.transferFrom(player, address(this), amount)) { emit Payment(address(this), amount); } else { emit FailedPayment(address(this), amount); } } // This are some constants making O(1) population count in placeBet possible. // See whitepaper for intuition and proofs behind it. uint constant POPCNT_MULT = 0x0000000000002000000000100000000008000000000400000000020000000001; uint constant POPCNT_MASK = 0x0001041041041041041041041041041041041041041041041041041041041041; uint constant POPCNT_MODULO = 0x3F; // *** Merkle proofs. // This helpers are used to verify cryptographic proofs of placeBet inclusion into // uncle blocks. They are used to prevent bet outcome changing on Ethereum reorgs without // compromising the security of the smart contract. Proof data is appended to the input data // in a simple prefix length format and does not adhere to the ABI. // Invariants checked: // - receipt trie entry contains a (1) successful transaction (2) directed at this smart // contract (3) containing commit as a payload. // - receipt trie entry is a part of a valid merkle proof of a block header // - the block header is a part of uncle list of some block on canonical chain // The implementation is optimized for gas cost and relies on the specifics of Ethereum internal data structures. // Read the whitepaper for details. // Helper to verify a full merkle proof starting from some seedHash (usually commit). "offset" is the location of the proof // beginning in the calldata. function verifyMerkleProof(uint seedHash, uint offset) pure private returns (bytes32 blockHash, bytes32 uncleHash) { // (Safe) assumption - nobody will write into RAM during this method invocation. uint scratchBuf1; assembly { scratchBuf1 := mload(0x40) } uint uncleHeaderLength; uint blobLength; uint shift; uint hashSlot; // Verify merkle proofs up to uncle block header. Calldata layout is: // - 2 byte big-endian slice length // - 2 byte big-endian offset to the beginning of previous slice hash within the current slice (should be zeroed) // - followed by the current slice verbatim for (;; offset += blobLength) { assembly { blobLength := and(calldataload(sub(offset, 30)), 0xffff) } if (blobLength == 0) { // Zero slice length marks the end of uncle proof. break; } assembly { shift := and(calldataload(sub(offset, 28)), 0xffff) } require (shift + 32 <= blobLength, "Shift bounds check."); offset += 4; assembly { hashSlot := calldataload(add(offset, shift)) } require (hashSlot == 0, "Non-empty hash slot."); assembly { calldatacopy(scratchBuf1, offset, blobLength) mstore(add(scratchBuf1, shift), seedHash) seedHash := sha3(scratchBuf1, blobLength) uncleHeaderLength := blobLength } } // At this moment the uncle hash is known. uncleHash = bytes32(seedHash); // Construct the uncle list of a canonical block. uint scratchBuf2 = scratchBuf1 + uncleHeaderLength; uint unclesLength; assembly { unclesLength := and(calldataload(sub(offset, 28)), 0xffff) } uint unclesShift; assembly { unclesShift := and(calldataload(sub(offset, 26)), 0xffff) } require (unclesShift + uncleHeaderLength <= unclesLength, "Shift bounds check."); offset += 6; assembly { calldatacopy(scratchBuf2, offset, unclesLength) } memcpy(scratchBuf2 + unclesShift, scratchBuf1, uncleHeaderLength); assembly { seedHash := sha3(scratchBuf2, unclesLength) } offset += unclesLength; // Verify the canonical block header using the computed sha3Uncles. assembly { blobLength := and(calldataload(sub(offset, 30)), 0xffff) shift := and(calldataload(sub(offset, 28)), 0xffff) } require (shift + 32 <= blobLength, "Shift bounds check."); offset += 4; assembly { hashSlot := calldataload(add(offset, shift)) } require (hashSlot == 0, "Non-empty hash slot."); assembly { calldatacopy(scratchBuf1, offset, blobLength) mstore(add(scratchBuf1, shift), seedHash) // At this moment the canonical block hash is known. blockHash := sha3(scratchBuf1, blobLength) } } // Helper to check the placeBet receipt. "offset" is the location of the proof beginning in the calldata. // RLP layout: [triePath, str([status, cumGasUsed, bloomFilter, [[address, [topics], data]])] function requireCorrectReceipt(uint offset) view private { uint leafHeaderByte; assembly { leafHeaderByte := byte(0, calldataload(offset)) } require (leafHeaderByte >= 0xf7, "Receipt leaf longer than 55 bytes."); offset += leafHeaderByte - 0xf6; uint pathHeaderByte; assembly { pathHeaderByte := byte(0, calldataload(offset)) } if (pathHeaderByte <= 0x7f) { offset += 1; } else { require (pathHeaderByte >= 0x80 && pathHeaderByte <= 0xb7, "Path is an RLP string."); offset += pathHeaderByte - 0x7f; } uint receiptStringHeaderByte; assembly { receiptStringHeaderByte := byte(0, calldataload(offset)) } require (receiptStringHeaderByte == 0xb9, "Receipt string is always at least 256 bytes long, but less than 64k."); offset += 3; uint receiptHeaderByte; assembly { receiptHeaderByte := byte(0, calldataload(offset)) } require (receiptHeaderByte == 0xf9, "Receipt is always at least 256 bytes long, but less than 64k."); offset += 3; uint statusByte; assembly { statusByte := byte(0, calldataload(offset)) } require (statusByte == 0x1, "Status should be success."); offset += 1; uint cumGasHeaderByte; assembly { cumGasHeaderByte := byte(0, calldataload(offset)) } if (cumGasHeaderByte <= 0x7f) { offset += 1; } else { require (cumGasHeaderByte >= 0x80 && cumGasHeaderByte <= 0xb7, "Cumulative gas is an RLP string."); offset += cumGasHeaderByte - 0x7f; } uint bloomHeaderByte; assembly { bloomHeaderByte := byte(0, calldataload(offset)) } require (bloomHeaderByte == 0xb9, "Bloom filter is always 256 bytes long."); offset += 256 + 3; uint logsListHeaderByte; assembly { logsListHeaderByte := byte(0, calldataload(offset)) } require (logsListHeaderByte == 0xf8, "Logs list is less than 256 bytes long."); offset += 2; uint logEntryHeaderByte; assembly { logEntryHeaderByte := byte(0, calldataload(offset)) } require (logEntryHeaderByte == 0xf8, "Log entry is less than 256 bytes long."); offset += 2; uint addressHeaderByte; assembly { addressHeaderByte := byte(0, calldataload(offset)) } require (addressHeaderByte == 0x94, "Address is 20 bytes long."); uint logAddress; assembly { logAddress := and(calldataload(sub(offset, 11)), 0xffffffffffffffffffffffffffffffffffffffff) } require (logAddress == uint(address(this))); } // Memory copy. function memcpy(uint dest, uint src, uint len) pure private { // Full 32 byte words for(; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Remaining bytes uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"erc20Token","type":"address"}],"name":"setToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"commit","type":"uint256"}],"name":"cancelBet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"secretSigner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"jackpotSize","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"croupier","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"reveal","type":"uint256"},{"name":"canonicalBlockNumber","type":"uint40"}],"name":"settleBetUncleMerkleProof","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxProfit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"withdrawAmount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"reveal","type":"uint256"},{"name":"blockHash","type":"bytes32"}],"name":"settleBet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"acceptNextOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nextOwner","type":"address"}],"name":"approveNextOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"increaseAmount","type":"uint256"}],"name":"increaseJackpot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newSecretSigner","type":"address"}],"name":"setSecretSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lockedInBets","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"betMask","type":"uint256"},{"name":"modulo","type":"uint256"},{"name":"commitLastBlock","type":"uint256"},{"name":"commit","type":"uint256"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"placeBet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newCroupier","type":"address"}],"name":"setCroupier","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_maxProfit","type":"uint256"}],"name":"setMaxProfit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"FailedPayment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Payment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"JackpotPayment","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"commit","type":"uint256"}],"name":"Commit","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b5033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506146798061010b6000396000f300608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063144fa6d714610114578063357401f51461015757806341c0e1b5146101845780634d61537f1461019b57806357246d23146101f25780636b5c5f391461024157806374e048d5146102985780638da5cb5b146102d6578063b539cd551461032d578063c107532914610358578063ca722cdc146103a5578063d06c54fb146103e0578063d579fd44146103f7578063d6d30a511461043a578063d702087f14610467578063df88126f146104aa578063e5f3e7b5146104f9578063f8bb201c1461056a578063fbd668a9146105ad578063fc0c546a146105da575b005b34801561012057600080fd5b50610155600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610631565b005b34801561016357600080fd5b506101826004803603810190808035906020019092919050505061075f565b005b34801561019057600080fd5b50610199610a0b565b005b3480156101a757600080fd5b506101b0610e3e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101fe57600080fd5b50610207610e64565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561024d57600080fd5b50610256610e86565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102a457600080fd5b506102d460048036038101908080359060200190929190803564ffffffffff169060200190929190505050610eac565b005b3480156102e257600080fd5b506102eb611130565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561033957600080fd5b50610342611156565b6040518082815260200191505060405180910390f35b34801561036457600080fd5b506103a3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061115c565b005b3480156103b157600080fd5b506103de6004803603810190808035906020019092919080356000191690602001909291905050506115aa565b005b3480156103ec57600080fd5b506103f5611af0565b005b34801561040357600080fd5b50610438600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c40565b005b34801561044657600080fd5b5061046560048036038101908080359060200190929190505050611e35565b005b34801561047357600080fd5b506104a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122d1565b005b3480156104b657600080fd5b506104bf612400565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561050557600080fd5b50610568600480360381019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080356000191690602001909291908035600019169060200190929190505050612422565b005b34801561057657600080fd5b506105ab600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613008565b005b3480156105b957600080fd5b506105d860048036038101908080359060200190929190505050613137565b005b3480156105e657600080fd5b506105ef6132d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561071c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610850576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4f6e6c7943726f7570696572206d6574686f64732063616c6c6564206279206e81526020017f6f6e2d63726f75706965722e000000000000000000000000000000000000000081525060400191505060405180910390fd5b600660008681526020019081526020016000209350836000015492506000831415151561090b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f4265742073686f756c6420626520696e20616e2027616374697665272073746181526020017f746500000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008460000181905550610948838560010160009054906101000a900460ff1660ff168660010160019054906101000a900460ff1660ff166132fc565b809250819350505081600560108282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555080600560008282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610af6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000600560109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141515610bea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260488152602001807f416c6c20626574732073686f756c642062652070726f6365737365642028736581526020017f74746c6564206f7220726566756e64656429206265666f72652073656c662d6481526020017f657374727563742e00000000000000000000000000000000000000000000000081525060600191505060405180910390fd5b610e03600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610ccc57600080fd5b505af1158015610ce0573d6000803e3d6000fd5b505050506040513d6020811015610cf657600080fd5b81019080805190602001909291905050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b505050506040513d6020811015610ded57600080fd5b8101908080519060200190929190505050613488565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a90046fffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610f9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4f6e6c7943726f7570696572206d6574686f64732063616c6c6564206279206e81526020017f6f6e2d63726f75706965722e000000000000000000000000000000000000000081525060400191505060405180910390fd5b85604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515610ff25780518252602082019150602081019050602083039250610fcd565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060019004935060066000858152602001908152602001600020925060fa8564ffffffffff160143111515156110e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f426c6f636b686173682063616e2774206265207175657269656420627920455681526020017f4d2e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6110ec6048613633565b6110f7846044613d19565b809250819350505081600019168564ffffffffff16406000191614151561111d57600080fd5b61112883878361405a565b505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611247576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561130357600080fd5b505af1158015611317573d6000803e3d6000fd5b505050506040513d602081101561132d57600080fd5b810190808051906020019092919050505081111515156113db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f43616e6e6f74207769746864726177206d6f7265207468616e2062616c616e6381526020017f652e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561149757600080fd5b505af11580156114ab573d6000803e3d6000fd5b505050506040513d60208110156114c157600080fd5b810190808051906020019092919050505081600560109054906101000a90046fffffffffffffffffffffffffffffffff16600560009054906101000a90046fffffffffffffffffffffffffffffffff16016fffffffffffffffffffffffffffffffff16011115151561159b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4e6f7420656e6f7567682066756e64732e00000000000000000000000000000081525060200191505060405180910390fd5b6115a6828283613488565b5050565b6000806000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4f6e6c7943726f7570696572206d6574686f64732063616c6c6564206279206e81526020017f6f6e2d63726f75706965722e000000000000000000000000000000000000000081525060400191505060405180910390fd5b84604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156116ef57805182526020820191506020810190506020830392506116ca565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206001900492506006600084815260200190815260200160002091508160010160029054906101000a900464ffffffffff1664ffffffffff16905080431115156117f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001807f736574746c6542657420696e207468652073616d6520626c6f636b206173207081526020017f6c6163654265742c206f72206265666f72652e0000000000000000000000000081525060400191505060405180910390fd5b60fa81014311151515611894576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f426c6f636b686173682063616e2774206265207175657269656420627920455681526020017f4d2e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b8360001916814060001916141515611914576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f426c6f636b6861736820646f6573206e6f74206d617463682e0000000000000081525060200191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e83600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16306040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015611a2857600080fd5b505af1158015611a3c573d6000803e3d6000fd5b505050506040513d6020811015611a5257600080fd5b8101908080519060200190929190505050826000015411151515611ade576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f42657420616d6f756e74206e6f7420696e7365727465642e000000000000000081525060200191505060405180910390fd5b611ae982868661405a565b5050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611bdb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f43616e206f6e6c792061636365707420707265617070726f766564206e65772081526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611d2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611df1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f43616e6e6f7420617070726f76652063757272656e74206f776e65722e00000081525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611fdc57600080fd5b505af1158015611ff0573d6000803e3d6000fd5b505050506040513d602081101561200657600080fd5b810190808051906020019092919050505081111515156120b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e63726561736520616d6f756e74206c6172676572207468616e2062616c6181526020017f6e63652e0000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561217057600080fd5b505af1158015612184573d6000803e3d6000fd5b505050506040513d602081101561219a57600080fd5b810190808051906020019092919050505081600560109054906101000a90046fffffffffffffffffffffffffffffffff16600560009054906101000a90046fffffffffffffffffffffffffffffffff16016fffffffffffffffffffffffffffffffff160111151515612274576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4e6f7420656e6f7567682066756e64732e00000000000000000000000000000081525060200191505060405180910390fd5b80600560008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600560109054906101000a90046fffffffffffffffffffffffffffffffff1681565b600080600080600080600660008a81526020019081526020016000209550600073ffffffffffffffffffffffffffffffffffffffff1686600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561252e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f4265742073686f756c6420626520696e20612027636c65616e2720737461746581526020017f2e0000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561261e57600080fd5b505af1158015612632573d6000803e3d6000fd5b505050506040513d602081101561264857600080fd5b81019080805190602001909291905050508d111515156126d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f42657420616d6f756e74206e6f7420696e7365727465642e000000000000000081525060200191505060405180910390fd5b60018b1180156126e1575060648b11155b1515612755576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4d6f64756c6f2073686f756c642062652077697468696e2072616e67652e000081525060200191505060405180910390fd5b670de0b6b3a76400008d10158015612777575069d3c21bcecceda10000008d11155b15156127eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f416d6f756e742073686f756c642062652077697468696e2072616e67652e000081525060200191505060405180910390fd5b60008c1180156127fe5750602860020a8c105b1515612872576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d61736b2073686f756c642062652077697468696e2072616e67652e0000000081525060200191505060405180910390fd5b8943111515156128ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f436f6d6d69742068617320657870697265642e0000000000000000000000000081525060200191505060405180910390fd5b8989604051602001808364ffffffffff1664ffffffffff167b01000000000000000000000000000000000000000000000000000000028152600501828152602001925050506040516020818303038152906040526040518082805190602001908083835b602083101515612973578051825260208201915060208101905060208303925061294e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450600185601b8a8a604051600081526020016040526040518085600019166000191681526020018460ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000865af1158015612a17573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612ae5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4543445341207369676e6174757265206973206e6f742076616c69642e00000081525060200191505060405180910390fd5b60288b111515612b4357603f7e010410410410410410410410410410410410410410410410410410410410417920000000001000000000080000000004000000000200000000018e0216811515612b3857fe5b0693508b9250612bf1565b60008c118015612b5357508a8c11155b1515612bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f48696768206d6f64756c6f2072616e67652c206265744d61736b206c6172676581526020017f72207468616e206d6f64756c6f2e00000000000000000000000000000000000081525060400191505060405180910390fd5b8b93505b612bfc8d8c866132fc565b80925081935050506003548d018211151515612c80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6d617850726f666974206c696d69742076696f6c6174696f6e2e00000000000081525060200191505060405180910390fd5b81600560108282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555080600560008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015612df057600080fd5b505af1158015612e04573d6000803e3d6000fd5b505050506040513d6020811015612e1a57600080fd5b8101908080519060200190929190505050600560109054906101000a90046fffffffffffffffffffffffffffffffff16600560009054906101000a90046fffffffffffffffffffffffffffffffff16016fffffffffffffffffffffffffffffffff1611151515612ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f43616e6e6f74206166666f726420746f206c6f73652074686973206265742e0081525060200191505060405180910390fd5b7f5bdd2fc99022530157777690475b670d3872f32262eb1d47d9ba8000dad58f87896040518082815260200191505060405180910390a18c86600001819055508a8660010160006101000a81548160ff021916908360ff160217905550838660010160016101000a81548160ff021916908360ff160217905550438660010160026101000a81548164ffffffffff021916908364ffffffffff160217905550828660010160076101000a81548164ffffffffff021916908364ffffffffff1602179055503386600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156130f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613222576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b69d3c21bcecceda1000000811015156132c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f6d617850726f6669742073686f756c6420626520612073616e65206e756d626581526020017f722e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b8060038190555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060008360001080156133115750848411155b1515613385576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f57696e2070726f626162696c697479206f7574206f662072616e67652e00000081525060200191505060405180910390fd5b69010f0cf064dd5920000086101561339e5760006133a9565b68056bc75e2d631000005b91506064600287028115156133ba57fe5b04905060018110156133cb57600190505b858282011115151561346b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f42657420646f65736e2774206576656e20636f76657220686f7573652065646781526020017f652e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b838583838903030281151561347c57fe5b04925050935093915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561354c57600080fd5b505af1158015613560573d6000803e3d6000fd5b505050506040513d602081101561357657600080fd5b8101908080519060200190929190505050156135df578273ffffffffffffffffffffffffffffffffffffffff167fd4f43975feb89f48dd30cabbb32011045be187d1e11c8ea9faa43efc35282519826040518082815260200191505060405180910390a261362e565b8273ffffffffffffffffffffffffffffffffffffffff167fac464fe4d3a86b9121261ac0a01dd981bfe0777c7c9d9c8f4473d31a9c0f9d2d836040518082815260200191505060405180910390a25b505050565b60008060008060008060008060008060008b3560001a9a5060f78b101515156136ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f52656365697074206c656166206c6f6e676572207468616e203535206279746581526020017f732e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60f68b038c019b508b3560001a9950607f8a11151561370e5760018c019b5061379d565b60808a10158015613720575060b78a11155b1515613794576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f5061746820697320616e20524c5020737472696e672e0000000000000000000081525060200191505060405180910390fd5b607f8a038c019b505b8b3560001a985060b989141515613868576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001807f5265636569707420737472696e6720697320616c77617973206174206c65617381526020017f7420323536206279746573206c6f6e672c20627574206c657373207468616e2081526020017f36346b2e0000000000000000000000000000000000000000000000000000000081525060600191505060405180910390fd5b60038c019b508b3560001a975060f988141515613913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001807f5265636569707420697320616c77617973206174206c6561737420323536206281526020017f79746573206c6f6e672c20627574206c657373207468616e2036346b2e00000081525060400191505060405180910390fd5b60038c019b508b3560001a9650600187141515613998576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5374617475732073686f756c6420626520737563636573732e0000000000000081525060200191505060405180910390fd5b60018c019b508b3560001a9550607f861115156139ba5760018c019b50613a49565b608086101580156139cc575060b78611155b1515613a40576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43756d756c61746976652067617320697320616e20524c5020737472696e672e81525060200191505060405180910390fd5b607f86038c019b505b8b3560001a945060b985141515613aee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f426c6f6f6d2066696c74657220697320616c776179732032353620627974657381526020017f206c6f6e672e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6101038c019b508b3560001a935060f884141515613b9a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4c6f6773206c697374206973206c657373207468616e2032353620627974657381526020017f206c6f6e672e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60028c019b508b3560001a925060f883141515613c45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4c6f6720656e747279206973206c657373207468616e2032353620627974657381526020017f206c6f6e672e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60028c019b508b3560001a9150609482141515613cca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f41646472657373206973203230206279746573206c6f6e672e0000000000000081525060200191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff600b8d03351690503073ffffffffffffffffffffffffffffffffffffffff1681141515613d0b57600080fd5b505050505050505050505050565b60008060008060008060008060008060405197505b61ffff601e8c03351695506000861415613d4757613e6c565b61ffff601c8c0335169450856020860111151515613dcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f536869667420626f756e647320636865636b2e0000000000000000000000000081525060200191505060405180910390fd5b60048b019a50848b01359350600084141515613e51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4e6f6e2d656d707479206861736820736c6f742e00000000000000000000000081525060200191505060405180910390fd5b858b89378b858901528588209b50859650858b019a50613d2e565b8b6001029850868801925061ffff601c8c033516915061ffff601a8c03351690508187820111151515613f07576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f536869667420626f756e647320636865636b2e0000000000000000000000000081525060200191505060405180910390fd5b60068b019a50818b8437613f1e8184018989614424565b8183209b50818b019a5061ffff601e8c033516955061ffff601c8c0335169450856020860111151515613fb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f536869667420626f756e647320636865636b2e0000000000000000000000000081525060200191505060405180910390fd5b60048b019a50848b0135935060008414151561403d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4e6f6e2d656d707479206861736820736c6f742e00000000000000000000000081525060200191505060405180910390fd5b858b89378b85890152858820995050505050505050509250929050565b60008060008060008060008060008060008d600001549a508d60010160009054906101000a900460ff1660ff1699508d60010160019054906101000a900460ff1660ff1698508d600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16975060008b14151515614166576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f4265742073686f756c6420626520696e20616e2027616374697665272073746181526020017f746500000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008e600001819055508c8c604051602001808381526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831015156141d557805182526020820191506020810190506020830392506141b0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020965089876001900481151561421357fe5b0695506142218b8b8b6132fc565b8095508196505050600092506000915060288a11151561426f5760008e60010160079054906101000a900464ffffffffff1664ffffffffff168760020a1614151561426a578492505b61427c565b8886101561427b578492505b5b84600560108282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555069010f0cf064dd592000008b101515614380576103e88a88600190048115156142fb57fe5b0481151561430557fe5b069050600081141561437f57600560009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1691506000600560006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b5b60008211156143d8578773ffffffffffffffffffffffffffffffffffffffff167fc388db0e8aa560a59633c094a0d0aa21322cd6234836fd5bac00fc5ae63b5783836040518082815260200191505060405180910390a25b600082840114156143f2576143ed888c61446f565b614414565b6144138860008486011461440a578c8486010361440d565b60015b85613488565b5b5050505050505050505050505050565b60005b60208210151561444c5782518452602084019350602083019250602082039150614427565b6001826020036101000a0390508019835116818551168181178652505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8330846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561456757600080fd5b505af115801561457b573d6000803e3d6000fd5b505050506040513d602081101561459157600080fd5b8101908080519060200190929190505050156145fa573073ffffffffffffffffffffffffffffffffffffffff167fd4f43975feb89f48dd30cabbb32011045be187d1e11c8ea9faa43efc35282519826040518082815260200191505060405180910390a2614649565b3073ffffffffffffffffffffffffffffffffffffffff167fac464fe4d3a86b9121261ac0a01dd981bfe0777c7c9d9c8f4473d31a9c0f9d2d826040518082815260200191505060405180910390a25b50505600a165627a7a72305820c5bb85a448c1aba45506ca12f8112a196e888dc594d45b8f1fe14e25626ea88e0029
Deployed Bytecode
0x608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063144fa6d714610114578063357401f51461015757806341c0e1b5146101845780634d61537f1461019b57806357246d23146101f25780636b5c5f391461024157806374e048d5146102985780638da5cb5b146102d6578063b539cd551461032d578063c107532914610358578063ca722cdc146103a5578063d06c54fb146103e0578063d579fd44146103f7578063d6d30a511461043a578063d702087f14610467578063df88126f146104aa578063e5f3e7b5146104f9578063f8bb201c1461056a578063fbd668a9146105ad578063fc0c546a146105da575b005b34801561012057600080fd5b50610155600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610631565b005b34801561016357600080fd5b506101826004803603810190808035906020019092919050505061075f565b005b34801561019057600080fd5b50610199610a0b565b005b3480156101a757600080fd5b506101b0610e3e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101fe57600080fd5b50610207610e64565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561024d57600080fd5b50610256610e86565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102a457600080fd5b506102d460048036038101908080359060200190929190803564ffffffffff169060200190929190505050610eac565b005b3480156102e257600080fd5b506102eb611130565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561033957600080fd5b50610342611156565b6040518082815260200191505060405180910390f35b34801561036457600080fd5b506103a3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061115c565b005b3480156103b157600080fd5b506103de6004803603810190808035906020019092919080356000191690602001909291905050506115aa565b005b3480156103ec57600080fd5b506103f5611af0565b005b34801561040357600080fd5b50610438600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c40565b005b34801561044657600080fd5b5061046560048036038101908080359060200190929190505050611e35565b005b34801561047357600080fd5b506104a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122d1565b005b3480156104b657600080fd5b506104bf612400565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561050557600080fd5b50610568600480360381019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080356000191690602001909291908035600019169060200190929190505050612422565b005b34801561057657600080fd5b506105ab600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613008565b005b3480156105b957600080fd5b506105d860048036038101908080359060200190929190505050613137565b005b3480156105e657600080fd5b506105ef6132d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561071c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610850576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4f6e6c7943726f7570696572206d6574686f64732063616c6c6564206279206e81526020017f6f6e2d63726f75706965722e000000000000000000000000000000000000000081525060400191505060405180910390fd5b600660008681526020019081526020016000209350836000015492506000831415151561090b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f4265742073686f756c6420626520696e20616e2027616374697665272073746181526020017f746500000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008460000181905550610948838560010160009054906101000a900460ff1660ff168660010160019054906101000a900460ff1660ff166132fc565b809250819350505081600560108282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555080600560008282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610af6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000600560109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141515610bea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260488152602001807f416c6c20626574732073686f756c642062652070726f6365737365642028736581526020017f74746c6564206f7220726566756e64656429206265666f72652073656c662d6481526020017f657374727563742e00000000000000000000000000000000000000000000000081525060600191505060405180910390fd5b610e03600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610ccc57600080fd5b505af1158015610ce0573d6000803e3d6000fd5b505050506040513d6020811015610cf657600080fd5b81019080805190602001909291905050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b505050506040513d6020811015610ded57600080fd5b8101908080519060200190929190505050613488565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a90046fffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610f9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4f6e6c7943726f7570696572206d6574686f64732063616c6c6564206279206e81526020017f6f6e2d63726f75706965722e000000000000000000000000000000000000000081525060400191505060405180910390fd5b85604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083101515610ff25780518252602082019150602081019050602083039250610fcd565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060019004935060066000858152602001908152602001600020925060fa8564ffffffffff160143111515156110e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f426c6f636b686173682063616e2774206265207175657269656420627920455681526020017f4d2e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6110ec6048613633565b6110f7846044613d19565b809250819350505081600019168564ffffffffff16406000191614151561111d57600080fd5b61112883878361405a565b505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611247576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561130357600080fd5b505af1158015611317573d6000803e3d6000fd5b505050506040513d602081101561132d57600080fd5b810190808051906020019092919050505081111515156113db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f43616e6e6f74207769746864726177206d6f7265207468616e2062616c616e6381526020017f652e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561149757600080fd5b505af11580156114ab573d6000803e3d6000fd5b505050506040513d60208110156114c157600080fd5b810190808051906020019092919050505081600560109054906101000a90046fffffffffffffffffffffffffffffffff16600560009054906101000a90046fffffffffffffffffffffffffffffffff16016fffffffffffffffffffffffffffffffff16011115151561159b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4e6f7420656e6f7567682066756e64732e00000000000000000000000000000081525060200191505060405180910390fd5b6115a6828283613488565b5050565b6000806000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4f6e6c7943726f7570696572206d6574686f64732063616c6c6564206279206e81526020017f6f6e2d63726f75706965722e000000000000000000000000000000000000000081525060400191505060405180910390fd5b84604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831015156116ef57805182526020820191506020810190506020830392506116ca565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206001900492506006600084815260200190815260200160002091508160010160029054906101000a900464ffffffffff1664ffffffffff16905080431115156117f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001807f736574746c6542657420696e207468652073616d6520626c6f636b206173207081526020017f6c6163654265742c206f72206265666f72652e0000000000000000000000000081525060400191505060405180910390fd5b60fa81014311151515611894576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f426c6f636b686173682063616e2774206265207175657269656420627920455681526020017f4d2e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b8360001916814060001916141515611914576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f426c6f636b6861736820646f6573206e6f74206d617463682e0000000000000081525060200191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e83600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16306040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015611a2857600080fd5b505af1158015611a3c573d6000803e3d6000fd5b505050506040513d6020811015611a5257600080fd5b8101908080519060200190929190505050826000015411151515611ade576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f42657420616d6f756e74206e6f7420696e7365727465642e000000000000000081525060200191505060405180910390fd5b611ae982868661405a565b5050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611bdb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f43616e206f6e6c792061636365707420707265617070726f766564206e65772081526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611d2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611df1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f43616e6e6f7420617070726f76652063757272656e74206f776e65722e00000081525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f20576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611fdc57600080fd5b505af1158015611ff0573d6000803e3d6000fd5b505050506040513d602081101561200657600080fd5b810190808051906020019092919050505081111515156120b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e63726561736520616d6f756e74206c6172676572207468616e2062616c6181526020017f6e63652e0000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561217057600080fd5b505af1158015612184573d6000803e3d6000fd5b505050506040513d602081101561219a57600080fd5b810190808051906020019092919050505081600560109054906101000a90046fffffffffffffffffffffffffffffffff16600560009054906101000a90046fffffffffffffffffffffffffffffffff16016fffffffffffffffffffffffffffffffff160111151515612274576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4e6f7420656e6f7567682066756e64732e00000000000000000000000000000081525060200191505060405180910390fd5b80600560008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600560109054906101000a90046fffffffffffffffffffffffffffffffff1681565b600080600080600080600660008a81526020019081526020016000209550600073ffffffffffffffffffffffffffffffffffffffff1686600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561252e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001807f4265742073686f756c6420626520696e20612027636c65616e2720737461746581526020017f2e0000000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561261e57600080fd5b505af1158015612632573d6000803e3d6000fd5b505050506040513d602081101561264857600080fd5b81019080805190602001909291905050508d111515156126d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f42657420616d6f756e74206e6f7420696e7365727465642e000000000000000081525060200191505060405180910390fd5b60018b1180156126e1575060648b11155b1515612755576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4d6f64756c6f2073686f756c642062652077697468696e2072616e67652e000081525060200191505060405180910390fd5b670de0b6b3a76400008d10158015612777575069d3c21bcecceda10000008d11155b15156127eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f416d6f756e742073686f756c642062652077697468696e2072616e67652e000081525060200191505060405180910390fd5b60008c1180156127fe5750602860020a8c105b1515612872576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d61736b2073686f756c642062652077697468696e2072616e67652e0000000081525060200191505060405180910390fd5b8943111515156128ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f436f6d6d69742068617320657870697265642e0000000000000000000000000081525060200191505060405180910390fd5b8989604051602001808364ffffffffff1664ffffffffff167b01000000000000000000000000000000000000000000000000000000028152600501828152602001925050506040516020818303038152906040526040518082805190602001908083835b602083101515612973578051825260208201915060208101905060208303925061294e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450600185601b8a8a604051600081526020016040526040518085600019166000191681526020018460ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000865af1158015612a17573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612ae5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4543445341207369676e6174757265206973206e6f742076616c69642e00000081525060200191505060405180910390fd5b60288b111515612b4357603f7e010410410410410410410410410410410410410410410410410410410410417920000000001000000000080000000004000000000200000000018e0216811515612b3857fe5b0693508b9250612bf1565b60008c118015612b5357508a8c11155b1515612bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f48696768206d6f64756c6f2072616e67652c206265744d61736b206c6172676581526020017f72207468616e206d6f64756c6f2e00000000000000000000000000000000000081525060400191505060405180910390fd5b8b93505b612bfc8d8c866132fc565b80925081935050506003548d018211151515612c80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6d617850726f666974206c696d69742076696f6c6174696f6e2e00000000000081525060200191505060405180910390fd5b81600560108282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555080600560008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015612df057600080fd5b505af1158015612e04573d6000803e3d6000fd5b505050506040513d6020811015612e1a57600080fd5b8101908080519060200190929190505050600560109054906101000a90046fffffffffffffffffffffffffffffffff16600560009054906101000a90046fffffffffffffffffffffffffffffffff16016fffffffffffffffffffffffffffffffff1611151515612ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f43616e6e6f74206166666f726420746f206c6f73652074686973206265742e0081525060200191505060405180910390fd5b7f5bdd2fc99022530157777690475b670d3872f32262eb1d47d9ba8000dad58f87896040518082815260200191505060405180910390a18c86600001819055508a8660010160006101000a81548160ff021916908360ff160217905550838660010160016101000a81548160ff021916908360ff160217905550438660010160026101000a81548164ffffffffff021916908364ffffffffff160217905550828660010160076101000a81548164ffffffffff021916908364ffffffffff1602179055503386600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156130f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613222576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4f6e6c794f776e6572206d6574686f64732063616c6c6564206279206e6f6e2d81526020017f6f776e65722e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b69d3c21bcecceda1000000811015156132c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f6d617850726f6669742073686f756c6420626520612073616e65206e756d626581526020017f722e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b8060038190555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060008360001080156133115750848411155b1515613385576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f57696e2070726f626162696c697479206f7574206f662072616e67652e00000081525060200191505060405180910390fd5b69010f0cf064dd5920000086101561339e5760006133a9565b68056bc75e2d631000005b91506064600287028115156133ba57fe5b04905060018110156133cb57600190505b858282011115151561346b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f42657420646f65736e2774206576656e20636f76657220686f7573652065646781526020017f652e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b838583838903030281151561347c57fe5b04925050935093915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561354c57600080fd5b505af1158015613560573d6000803e3d6000fd5b505050506040513d602081101561357657600080fd5b8101908080519060200190929190505050156135df578273ffffffffffffffffffffffffffffffffffffffff167fd4f43975feb89f48dd30cabbb32011045be187d1e11c8ea9faa43efc35282519826040518082815260200191505060405180910390a261362e565b8273ffffffffffffffffffffffffffffffffffffffff167fac464fe4d3a86b9121261ac0a01dd981bfe0777c7c9d9c8f4473d31a9c0f9d2d836040518082815260200191505060405180910390a25b505050565b60008060008060008060008060008060008b3560001a9a5060f78b101515156136ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f52656365697074206c656166206c6f6e676572207468616e203535206279746581526020017f732e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60f68b038c019b508b3560001a9950607f8a11151561370e5760018c019b5061379d565b60808a10158015613720575060b78a11155b1515613794576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f5061746820697320616e20524c5020737472696e672e0000000000000000000081525060200191505060405180910390fd5b607f8a038c019b505b8b3560001a985060b989141515613868576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001807f5265636569707420737472696e6720697320616c77617973206174206c65617381526020017f7420323536206279746573206c6f6e672c20627574206c657373207468616e2081526020017f36346b2e0000000000000000000000000000000000000000000000000000000081525060600191505060405180910390fd5b60038c019b508b3560001a975060f988141515613913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001807f5265636569707420697320616c77617973206174206c6561737420323536206281526020017f79746573206c6f6e672c20627574206c657373207468616e2036346b2e00000081525060400191505060405180910390fd5b60038c019b508b3560001a9650600187141515613998576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5374617475732073686f756c6420626520737563636573732e0000000000000081525060200191505060405180910390fd5b60018c019b508b3560001a9550607f861115156139ba5760018c019b50613a49565b608086101580156139cc575060b78611155b1515613a40576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43756d756c61746976652067617320697320616e20524c5020737472696e672e81525060200191505060405180910390fd5b607f86038c019b505b8b3560001a945060b985141515613aee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f426c6f6f6d2066696c74657220697320616c776179732032353620627974657381526020017f206c6f6e672e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6101038c019b508b3560001a935060f884141515613b9a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4c6f6773206c697374206973206c657373207468616e2032353620627974657381526020017f206c6f6e672e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60028c019b508b3560001a925060f883141515613c45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f4c6f6720656e747279206973206c657373207468616e2032353620627974657381526020017f206c6f6e672e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60028c019b508b3560001a9150609482141515613cca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f41646472657373206973203230206279746573206c6f6e672e0000000000000081525060200191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff600b8d03351690503073ffffffffffffffffffffffffffffffffffffffff1681141515613d0b57600080fd5b505050505050505050505050565b60008060008060008060008060008060405197505b61ffff601e8c03351695506000861415613d4757613e6c565b61ffff601c8c0335169450856020860111151515613dcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f536869667420626f756e647320636865636b2e0000000000000000000000000081525060200191505060405180910390fd5b60048b019a50848b01359350600084141515613e51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4e6f6e2d656d707479206861736820736c6f742e00000000000000000000000081525060200191505060405180910390fd5b858b89378b858901528588209b50859650858b019a50613d2e565b8b6001029850868801925061ffff601c8c033516915061ffff601a8c03351690508187820111151515613f07576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f536869667420626f756e647320636865636b2e0000000000000000000000000081525060200191505060405180910390fd5b60068b019a50818b8437613f1e8184018989614424565b8183209b50818b019a5061ffff601e8c033516955061ffff601c8c0335169450856020860111151515613fb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f536869667420626f756e647320636865636b2e0000000000000000000000000081525060200191505060405180910390fd5b60048b019a50848b0135935060008414151561403d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4e6f6e2d656d707479206861736820736c6f742e00000000000000000000000081525060200191505060405180910390fd5b858b89378b85890152858820995050505050505050509250929050565b60008060008060008060008060008060008d600001549a508d60010160009054906101000a900460ff1660ff1699508d60010160019054906101000a900460ff1660ff1698508d600101600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16975060008b14151515614166576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f4265742073686f756c6420626520696e20616e2027616374697665272073746181526020017f746500000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008e600001819055508c8c604051602001808381526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831015156141d557805182526020820191506020810190506020830392506141b0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020965089876001900481151561421357fe5b0695506142218b8b8b6132fc565b8095508196505050600092506000915060288a11151561426f5760008e60010160079054906101000a900464ffffffffff1664ffffffffff168760020a1614151561426a578492505b61427c565b8886101561427b578492505b5b84600560108282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555069010f0cf064dd592000008b101515614380576103e88a88600190048115156142fb57fe5b0481151561430557fe5b069050600081141561437f57600560009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1691506000600560006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b5b60008211156143d8578773ffffffffffffffffffffffffffffffffffffffff167fc388db0e8aa560a59633c094a0d0aa21322cd6234836fd5bac00fc5ae63b5783836040518082815260200191505060405180910390a25b600082840114156143f2576143ed888c61446f565b614414565b6144138860008486011461440a578c8486010361440d565b60015b85613488565b5b5050505050505050505050505050565b60005b60208210151561444c5782518452602084019350602083019250602082039150614427565b6001826020036101000a0390508019835116818551168181178652505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8330846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561456757600080fd5b505af115801561457b573d6000803e3d6000fd5b505050506040513d602081101561459157600080fd5b8101908080519060200190929190505050156145fa573073ffffffffffffffffffffffffffffffffffffffff167fd4f43975feb89f48dd30cabbb32011045be187d1e11c8ea9faa43efc35282519826040518082815260200191505060405180910390a2614649565b3073ffffffffffffffffffffffffffffffffffffffff167fac464fe4d3a86b9121261ac0a01dd981bfe0777c7c9d9c8f4473d31a9c0f9d2d826040518082815260200191505060405180910390a25b50505600a165627a7a72305820c5bb85a448c1aba45506ca12f8112a196e888dc594d45b8f1fe14e25626ea88e0029
Swarm Source
bzzr://c5bb85a448c1aba45506ca12f8112a196e888dc594d45b8f1fe14e25626ea88e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.